Here's some code I wrote in my spare time for flowCE menu structure:
Code: /*
*--------------------------------------
* Program Name: Flow
* Version: 0.5 alpha
* Author: LogicalJoe
* Copyright:
* License: none, (just please give me some credit!)
* Description: FlowCE Menu structure
* Begun: December 27, 2017
*--------------------------------------
*/
/* Keep these headers */
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <tice.h>
/* Standard headers (recommended) */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <LJ.h>
#include <BASIC.h>
#include <graphx.h>
#include <keypadc.h>
#include <fileioc.h>
/* Put your function prototypes here */
void TitleW(char *title);
void KeyPress(void);
void menu_engine(uint8_t a, uint8_t Z, uint8_t s, uint8_t d);
void PrintCenter(char *title, uint8_t a);
void PrintPretty(char *title);
void Back(void);
void PackMenu(void);
/* Put all your globals here */
static const char *Flow_AppVar = "FlowSv";
/* please adjust colors to match your set */
/* red, green, blue, yellow, orange, light blue, pink, brown, purple, white, gray, light green, tan, dark blue, dark green */
static const uint16_t Classic[15] = {224,5,24,231,228,31,250,160,152,255,149/*(gray)*/,7,197/*tan*/,16,2};
/* orange, tan, white, dark tan, dark orange, brown, dark purple, pink tan, white pink, greenwhite, slightly darker green, medium green, gray, darkwhite, aqua blue */
static const uint8_t Honeycomb[15] = {228,197,255,164,227,160,144,211,254,247,174,141,149/*gray*/,223/*darkwhite*/,31};
static const uint8_t Pretty_Pink[5] = {248,220,152,224,216};
static const uint8_t Holiday_Gift[5] = {5,224,231,255,7};
/* red, dark blue, yellow, darkgreen, orange, light blue, purple/pink, brown */
static const uint8_t PT_[15] = {224,24,231,2,228,127,209,128,144,1,103,221,255,255,255}; // complete (?) [PT's 84pcse colors]
static const char *Themes[5] = {"classic","Honeycomb","Pretty Pink", "Holiday Gift", "PT_"};
ti_var_t file;
uint8_t S,E,Z,T=0;
uint8_t a,A; //A & a are just for loops
matrix_t matA[];
uint8_t Theme[15];
bool quit = false, U=false;
uint8_t numPacks = 0;
uint8_t nameLength;
void main(void) {
/* Fill in the body of the main function here */
/* Clear the homescreen */
os_ClrHomeFull();
/* Print a few strings */
PrintText("Get DoorsCE to run this:", 1, 1);
PrintText("http://dcs.cemetech.net", 1, 2);
KeyPress();
os_ClrHomeFull();
ti_CloseAll();
file = ti_Open(Flow_AppVar, "r");
if (file) {
ti_Read(Theme, sizeof(Theme), 1, file);
ti_Read(&T, sizeof(T), 1, file);
ti_Read(&U, sizeof(U), 1, file);
} else {
for(A=0;A<15;A++) // very important.
Theme[A]=Classic[A];
}
gfx_Begin(gfx_8bpp);
gfx_SetTextBGColor(0);
while (quit == false) {
gfx_SetTextTransparentColor(0);
gfx_ZeroScreen();
// TitleW("flowCE");
gfx_SetTextScale(4,4);
gfx_SetTextXY((320-gfx_GetStringWidth("flowCE"))/2,20);
for(a=0;a<4;a++) {
gfx_SetTextFGColor(Theme[a%5]);
gfx_PrintChar("flowCE"[a]);
}
gfx_SetTextFGColor(255);
gfx_PrintString("CE");
gfx_SetTextScale(2,2); // this code will place flowCE in original colors
PrintCenter("free play", 60);
PrintCenter("time trial", 80);
PrintCenter("settings", 110);
PrintCenter("about", 130);
PrintCenter("more games", 160);
PrintCenter("quit", 180);
menu_engine(5,Z,60,37);
if (kb_Data[7] & kb_Left)
quit = true;
if (kb_Data[1] & kb_2nd) {
if (Z == 0) {
while(!(kb_Data[7] & kb_Left)) { // keeps them in until they press left
PackMenu();
}
Z=0;
}
if (Z==2) {
Z=0;
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("settings");
gfx_SetTextXY(160-gfx_GetStringWidth("theme: Holiday Gift")/2, 60);
gfx_PrintString("theme: ");
PrintPretty(Themes[T]);
if (U==1) {
gfx_PrintStringXY("color labels: ON", 160-gfx_GetStringWidth("color labels: OFF")/2, 80);
} else {
PrintCenter("color labels: OFF", 80);
}
PrintCenter("reset progress", 100);
menu_engine(2,Z,54,15);
if (kb_Data[1] & kb_2nd) {
if (Z==1) {
U=1-U;
}
if (Z==0) {
Z=T;
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("themes");
gfx_SetTextScale(1,1);
PrintCenter("Color your game and boards!", 60);
gfx_SetTextFGColor(Classic[0]);
gfx_PrintStringXY("Classic Theme", 30, 80);
gfx_SetTextFGColor(Honeycomb[0]);
gfx_PrintStringXY("Honeycomb", 30, 100);
gfx_SetTextFGColor(Pretty_Pink[0]);
gfx_PrintStringXY("Pretty Pink", 30, 120);
gfx_SetTextFGColor(Holiday_Gift[0]);
gfx_PrintStringXY("Holiday Gift", 30, 140);
gfx_SetTextFGColor(PT_[0]);
gfx_PrintStringXY("PT_", 30, 160);
gfx_SetColor(255);
gfx_FillCircle_NoClip(160,83+20*T,4);
for(A=0;A<5;A++) {
gfx_SetColor(Classic[A]);
gfx_FillCircle_NoClip(15*A+224,83,5); //it is 224 and not 225 so it is exactly 30 pixels from the edge
}
for(A=0;A<5;A++) {
gfx_SetColor(Honeycomb[A]);
gfx_FillCircle_NoClip(15*A+224,103,5);
}
for(A=0;A<5;A++) {
gfx_SetColor(Pretty_Pink[A]);
gfx_FillCircle_NoClip(15*A+224,123,5);
}
for(A=0;A<5;A++) {
gfx_SetColor(Holiday_Gift[A]);
gfx_FillCircle_NoClip(15*A+224,143,5);
}
for(A=0;A<5;A++) {
gfx_SetColor(PT_[A]);
gfx_FillCircle_NoClip(15*A+224,163,5);
}
menu_engine(4,T,60,15);
if (kb_Data[1] & kb_2nd) {
T=Z;
if (T == 0)
for(A=0;A<15;A++)
Theme[A]=Classic[A];
if (T == 1)
for(A=0;A<15;A++)
Theme[A]=Honeycomb[A];
if (T == 2)
for(A=0;A<15;A++)
Theme[A]=Pretty_Pink[A];
if (T == 3)
for(A=0;A<15;A++)
Theme[A]=Holiday_Gift[A];
if (T == 4)
for(A=0;A<15;A++)
Theme[A]=PT_[A];
}
}
//while (kb_AnyKey());
Z=0;
}
while (kb_AnyKey());
}
}
Z=2;
}
if (Z==3) {
Z=0;
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
gfx_SetTextScale(4,4);
TitleW("about");
PrintCenter("FlowCE v1.2", 60);
gfx_SetTextScale(1,1);
PrintCenter("LogicalJoe & JonBush", 80);
PrintCenter("email@somesite.com", 100);
gfx_SetTextScale(2,2);
PrintCenter("how to play", 120);
PrintCenter("send feedback", 140);
PrintCenter("review program",160);
menu_engine(3, Z, 115,37);
if (kb_Data[1] & kb_2nd) {
if (Z==1) {
U=1-U;
}
if (Z==0) {
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("help");
gfx_SetTextScale(1,1);
gfx_PrintStringXY("Use 2nd to select a pipe and connect matching", 7, 60);
gfx_PrintStringXY("colors with pipe, creating a flow", 7, 70);
gfx_PrintStringXY("Pair all colors, and cover the entire", 7, 90);
gfx_PrintStringXY("board with pipe to solve each puzzle", 7, 100);
gfx_PrintStringXY("But watch out, pipes will break if they", 7, 120);
gfx_PrintStringXY("cross or overlap!", 7, 130);
gfx_PrintStringXY("Too easy? Try selecting a larger board", 7, 150);
gfx_PrintStringXY("or different level pack. Or see how fast", 7, 160);
gfx_PrintStringXY("you can solve in Time Trial mode.", 7, 170);
Back();
KeyPress();
}
}
if (Z==1) {
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("feadback");
gfx_SetTextScale(1,1);
PrintCenter("to the provided emails", 60);
Back();
KeyPress();
}
}
if (Z==2) {
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("review");
gfx_SetTextScale(1,1);
PrintCenter("at Cemetech.net", 60);
Back();
KeyPress();
}
}
while (kb_AnyKey());
}
}
Z=3;
}
if (Z==4) {
Z=T;
while(!(kb_Data[7] & kb_Left)) {
gfx_ZeroScreen();
TitleW("more games");
gfx_SetTextScale(1,1);
gfx_PrintStringXY("Dial by LogicalJoe", 7, 60);
gfx_PrintStringXY("RubEX by LogicalJoe", 7, 70);
gfx_PrintStringXY("SnakeCE by LogicalJoe", 7, 80);
gfx_PrintStringXY("Fractals by LogicalJoe", 7, 90);
Back();
KeyPress();
}
Z=4;
}
if (Z==5)
quit = true;
}
while (kb_AnyKey());
}
/* save to the save file */
ti_CloseAll();
file = ti_Open(Flow_AppVar, "w");
if (file) {
ti_Write(Theme, sizeof(Theme), 1, file);
ti_Write(&T, sizeof(T), 1, file);
ti_Write(&U, sizeof(U), 1, file);
/* archive the save file (why doesn't everyone do this?) */
ti_SetArchiveStatus(true, file);
}
ti_CloseAll();
gfx_End();
}
/* Put other functions here */
void KeyPress(void) {
while (kb_AnyKey()); //this loops until there are no keys being pressed
while (!kb_AnyKey()) //then this takes over and waits for a press
kb_Scan();
}
void menu_engine(uint8_t a, uint8_t b, uint8_t s, uint8_t d) {
Back();
while (kb_AnyKey());
gfx_SetColor(26);
gfx_FillCircle_NoClip(d,10+25*b+s,8);
while (!((kb_Data[1] & kb_2nd) || (kb_Data[7] & kb_Left))) {
KeyPress();
gfx_SetColor(0);
gfx_FillCircle_NoClip(d,10+25*b+s,8);
if (kb_Data[7] & kb_Down && b != a)
b++;
if (kb_Data[7] & kb_Up && b != 0)
b--;
gfx_SetColor(26);
gfx_FillCircle_NoClip(d,10+25*b+s,8);
}
Z=b;
}
void PrintPretty(char *title) {
for(a=0;a<strlen(title);a++) {
gfx_SetTextFGColor(Theme[a%5]);
gfx_PrintChar(title[a]);
}
gfx_SetTextFGColor(255);
}
void TitleW(char *title) {
gfx_SetTextScale(4,4);
gfx_SetTextXY((320-gfx_GetStringWidth(title))/2,20);
PrintPretty(title);
gfx_SetTextScale(2,2);
}
void PrintCenter(char *title, uint8_t a) {
gfx_PrintStringXY(title, 160-gfx_GetStringWidth(title)/2, a);
}
void Back(void) {
gfx_SetColor(255);
gfx_Circle(6,6,5);
gfx_SetTextScale(1,1);
gfx_SetTextFGColor(255);
gfx_PrintCharXY(27,3,3);
}
void PackMenu(void) {
/* all the game code goes here. */
while (!(kb_Data[7] & kb_Left)) { // probably a good idea to remove this loop
gfx_ZeroScreen();
Back();
gfx_SetTextScale(3,3);
gfx_SetTextXY((320-gfx_GetStringWidth("flowCE"))/2,20);
PrintPretty("flowCE");
gfx_SetTextScale(2,2); // removable, just place "Flow" at top of screen
KeyPress();
/*
* colors are now contained in Theme[]
* for lables, add this when drawing circles:
*
* if (U = true) {
* gfx_TextScale(floor([Circle radii]/8)) // as long as [Circle radii] > 7
* gfx_SetTextXY([circle center X]-gfx_GetCharWidth(65+[color location in list])/2, [circle center Y] - 4*floor([Circle radii]/8));
* gfx_PrintChar(65+[color location in list]);
* }
*
* Please not this was off the top of my head and may need some editing...
* you should be able to get away with black on all of them...
*/
// also, if the level and/or pack selection screens were in the Theme colors, that would look cool
}
}
I hope this ends up being useful!