Continue menu

This commit is contained in:
Miloslav Ciz 2025-01-03 01:15:24 +01:00
parent 9e0cb3c944
commit 44f748134f
2 changed files with 204 additions and 94 deletions

View file

@ -33,7 +33,7 @@ static const char *LCR_texts[] =
};
static const char *LCR_internalResourceFile =
"testmap;"
"Mtestmap;"
"0 :*H1k0J"
":=s0s0 :fd190" // big concrete
@ -76,7 +76,8 @@ static const char *LCR_internalResourceFile =
":-k5k0 :f5120"
" map end "
"#map2;1 :*H1k0J :,s0s0 :fd190 "
"#Mmap2;1 :*H1k0J :,s0s0 :fd190 "
"#Mmap3;1 :*H1k0J :,s0s0 :fd190 "
;
#define LCR_IMAGE_SIZE 64 ///< one-dimension resolution of bitmap image

293
game.h
View file

@ -173,7 +173,7 @@ uint8_t LCR_gameGetNextAudioSample(void);
#define LCR_GAME_STATE_RUN_STARTING 0x01
#define LCR_GAME_STATE_RUN 0x02
#define LCR_GAME_STATE_RUN_FINISHED 0x03
#define LCR_GAME_STATE_END 0xff
// TODO: move to consts?
#define LCR_MENU_MAX_ITEMS 9
@ -206,10 +206,11 @@ struct
{
int state; ///< -1 if reading external res. f., else pos.
// indices and counts are among the resources of the same type
unsigned char loadedItemCount;
char loadedItemNames[LCR_RESOURCE_ITEM_CHUNK * LCR_MENU_STRING_SIZE];
unsigned int loadedItemsIndices[LCR_RESOURCE_ITEM_CHUNK]; // absolute
unsigned int itemsTotal; // total of items of this type
unsigned int firstItemIndex;
unsigned int itemsTotal;
} resourceFile;
} LCR_game;
@ -347,7 +348,7 @@ char LCR_gameGetNextResourceStrChar(void)
Seeks to the Nth resource string in the global resource file, after its name,
so that the pure resource string will now be available for reading.
*/
void LCR_seekResourceByIndex(unsigned int index)
void LCR_seekResourceByIndex(unsigned int index, char magicNumber)
{
char c;
@ -357,11 +358,12 @@ void LCR_seekResourceByIndex(unsigned int index)
while (index)
{
if (c == magicNumber)
index--;
do
c = LCR_gameGetNextResourceFileChar();
while (c != LCR_RESOURCE_FILE_SEPARATOR && c != 0);
index--;
}
do // skip magic number and name
@ -372,7 +374,7 @@ void LCR_seekResourceByIndex(unsigned int index)
void LCR_gameStartRun(void)
{
LCR_seekResourceByIndex(0); // TODO
LCR_seekResourceByIndex(0,'M'); // TODO
LCR_mapLoadFromStr(LCR_gameGetNextResourceStrChar);
LCR_rendererLoadMap();
@ -396,13 +398,9 @@ LCR_game.resourceFile.loadedItemCount = 0;
LCR_game.resourceFile.itemsTotal = 0;
for (int i = 0; i < LCR_RESOURCE_ITEM_CHUNK; ++i)
{
for (int j = 0; j < LCR_MENU_STRING_SIZE; ++j)
LCR_game.resourceFile.loadedItemNames[i * LCR_MENU_STRING_SIZE + j] = 0;
LCR_game.resourceFile.loadedItemsIndices[i] = 0;
}
LCR_game.menuSelectedTab = 0;
LCR_game.menuSelectedItem = 0;
@ -416,12 +414,76 @@ LCR_game.menuSelectedItem = 0;
}
/**
Loads up to LCR_RESOURCE_ITEM_CHUNK items of given type (0 = map, 1 = replay)
into RAM, starting at given index (among items of the same type).
Loads up to LCR_RESOURCE_ITEM_CHUNK items of given type, starting at given
index (among items of the same type).
*/
void LCR_gameLoadResourceFileChunk(uint8_t type, unsigned int startIndex)
void LCR_gameLoadResourceFileChunk(unsigned int startIndex, char magicNumber)
{
// TODO
LCR_LOG1("loading resources");
char c;
unsigned char state = 0;
for (int i = 0; i < LCR_RESOURCE_ITEM_CHUNK * LCR_MENU_STRING_SIZE; ++i)
LCR_game.resourceFile.loadedItemNames[i] = 0;
LCR_game.resourceFile.loadedItemCount = 0;
LCR_game.resourceFile.firstItemIndex = startIndex;
LCR_game.resourceFile.itemsTotal = 0;
LCR_gameRewindResourceFile();
/* 3 iterations: in first we seek to the start index, in second we load the
names, in third we just read the rest to get the total count. */
for (int i = 0; i < 3; ++i)
while (1)
{
if (i == 0 && !startIndex)
break;
c = LCR_gameGetNextResourceFileChar();
if (c == 0)
return;
if (state == 0) // second magic char
{
state = 255;
if (c == magicNumber)
{
LCR_game.resourceFile.itemsTotal++;
if (i == 0)
startIndex--;
else if (i == 1)
state = 1;
}
}
else if (i == 1 && state != 255)
{
if (c == LCR_RESOURCE_FILE_SEPARATOR2 ||
state >= 1 + LCR_MENU_STRING_SIZE - 1)
{
state = 255;
LCR_game.resourceFile.loadedItemCount++;
if (LCR_game.resourceFile.loadedItemCount >= LCR_RESOURCE_ITEM_CHUNK)
break;
}
LCR_game.resourceFile.loadedItemNames[LCR_MENU_STRING_SIZE *
LCR_game.resourceFile.loadedItemCount + state - 1] = c;
state++;
}
if (c == LCR_RESOURCE_FILE_SEPARATOR)
state = 0;
}
}
void LCR_gameEnd(void)
@ -512,10 +574,119 @@ void LCR_gameDraw3DView(void)
}
}
void LCR_gameHandleInput(void)
{
int tabSwitchedTo = 0;
int scrolled = 0;
switch (LCR_game.state)
{
case LCR_GAME_STATE_MENU:
if (LCR_game.keyStates[LCR_KEY_RIGHT] == 1)
{
LCR_LOG1("menu tab right");
LCR_game.menuSelectedTab =
(LCR_game.menuSelectedTab + 1) % LCR_MENU_TABS;
tabSwitchedTo = LCR_game.menuSelectedTab;
LCR_game.menuSelectedItem = 0;
}
else if (LCR_game.keyStates[LCR_KEY_LEFT] == 1)
{
LCR_LOG1("menu tab left");
LCR_game.menuSelectedTab =
(LCR_game.menuSelectedTab + LCR_MENU_TABS - 1) % LCR_MENU_TABS;
tabSwitchedTo = LCR_game.menuSelectedTab;
LCR_game.menuSelectedItem = 0;
}
else if (LCR_game.keyStates[LCR_KEY_UP] == 1)
{
LCR_LOG1("menu item up");
if (LCR_game.menuSelectedItem != 0)
LCR_game.menuSelectedItem--;
else if (LCR_game.menuSelectedTab != 0 &&
LCR_game.resourceFile.firstItemIndex != 0)
{
LCR_game.menuSelectedItem = LCR_RESOURCE_ITEM_CHUNK - 1;
scrolled = -1;
}
}
else if (LCR_game.keyStates[LCR_KEY_DOWN] == 1)
{
LCR_LOG1("menu item down");
if (LCR_game.menuSelectedTab == 0)
{
if (LCR_game.menuSelectedItem < 4)
LCR_game.menuSelectedItem++;
}
else if (LCR_game.menuSelectedItem <
LCR_game.resourceFile.loadedItemCount - 1)
LCR_game.menuSelectedItem++;
else if (LCR_game.resourceFile.firstItemIndex +
LCR_RESOURCE_ITEM_CHUNK < LCR_game.resourceFile.itemsTotal)
{
LCR_game.menuSelectedItem = 0;
scrolled = 1;
}
}
else if (LCR_game.keyStates[LCR_KEY_B] == 1)
{
LCR_LOG1("menu quit");
LCR_gameSetState(LCR_GAME_STATE_RUN);
}
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
{
LCR_LOG1("menu confirm");
switch (LCR_game.menuSelectedTab)
{
case 0:
switch (LCR_game.menuSelectedItem)
{
case 4:
LCR_gameSetState(LCR_GAME_STATE_END);
break;
default: break;
}
break;
default: break;
}
}
break;
case LCR_GAME_STATE_RUN_STARTING:
if (LCR_game.time - LCR_game.stateStartTime
>= 1000 * LCR_SETTING_COUNTDOWN_SECONDS)
LCR_gameSetState(LCR_GAME_STATE_RUN);
// fall through
default:
if (LCR_game.keyStates[LCR_KEY_B] == 1)
{
LCR_LOG1("menu open");
LCR_gameSetState(LCR_GAME_STATE_MENU);
}
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
LCR_gameResetRun();
break;
}
if (tabSwitchedTo)
LCR_gameLoadResourceFileChunk(0,tabSwitchedTo == 1 ? 'M' : 'R');
}
uint8_t LCR_gameStep(uint32_t time)
{
uint32_t sleep = 0;
int paused = 0;
int paused =
LCR_game.state == LCR_GAME_STATE_MENU ||
LCR_game.state == LCR_GAME_STATE_RUN_STARTING;
LCR_LOG2("game step start");
@ -525,71 +696,7 @@ uint8_t LCR_gameStep(uint32_t time)
LCR_game.keyStates[i] = LCR_keyPressed(i) ?
(LCR_game.keyStates[i] < 255 ? LCR_game.keyStates[i] + 1 : 255) : 0;
switch (LCR_game.state)
{
case LCR_GAME_STATE_MENU:
paused = 1;
if (LCR_game.keyStates[LCR_KEY_RIGHT] == 1)
{
LCR_LOG1("menu tab right");
LCR_game.menuSelectedTab =
(LCR_game.menuSelectedTab + 1) % LCR_MENU_TABS;
LCR_game.menuSelectedItem = 0;
}
else if (LCR_game.keyStates[LCR_KEY_LEFT] == 1)
{
LCR_LOG1("menu tab left");
LCR_game.menuSelectedTab =
(LCR_game.menuSelectedTab + LCR_MENU_TABS - 1) % LCR_MENU_TABS;
LCR_game.menuSelectedItem = 0;
}
else if (LCR_game.keyStates[LCR_KEY_UP] == 1)
{
LCR_LOG1("menu item up");
LCR_game.menuSelectedItem -= LCR_game.menuSelectedItem ? 1 : 0;
}
else if (LCR_game.keyStates[LCR_KEY_DOWN] == 1)
{
LCR_LOG1("menu item down");
LCR_game.menuSelectedItem +=
(LCR_game.menuSelectedItem < (LCR_game.menuSelectedTab ?
LCR_game.resourceFile.loadedItemCount : 5) - 1) ? 1 : 0;
}
else if (LCR_game.keyStates[LCR_KEY_B] == 1)
{
LCR_LOG1("menu quit");
LCR_gameSetState(LCR_GAME_STATE_RUN);
}
break;
case LCR_GAME_STATE_RUN_STARTING:
paused = 1;
if (LCR_game.time - LCR_game.stateStartTime
>= 1000 * LCR_SETTING_COUNTDOWN_SECONDS)
LCR_gameSetState(LCR_GAME_STATE_RUN);
// fall through
default:
if (LCR_game.keyStates[LCR_KEY_B] == 1)
LCR_gameSetState(LCR_GAME_STATE_MENU);
else if (LCR_game.keyStates[LCR_KEY_A] == 1)
LCR_gameResetRun();
break;
}
/*
if (LCR_game.keyStates[LCR_KEY_B] == 1)
LCR_game.controlMode = LCR_game.controlMode == LCR_CONTROL_MODE_FREECAM ?
LCR_CONTROL_MODE_DRIVE : LCR_CONTROL_MODE_FREECAM;
else if (LCR_game.keyStates[LCR_KEY_B] == 30)
LCR_gameResetRun();
*/
LCR_gameHandleInput();
LCR_GameUnit offsets[5];
@ -627,7 +734,6 @@ uint8_t LCR_gameStep(uint32_t time)
}
*/
// handle simulation:
while (time >= LCR_game.nextRacingTickTime)
{
@ -690,17 +796,20 @@ uint8_t LCR_gameStep(uint32_t time)
items[0] = LCR_texts[LCR_game.menuSelectedTab];
switch (LCR_game.menuSelectedTab)
{
case 0:
for (int i = 0; i < 5; ++i)
items[1 + i] = LCR_texts[4 + i];
if (LCR_game.menuSelectedTab == 0)
{
for (int i = 0; i < 5; ++i)
items[1 + i] = LCR_texts[4 + i];
itemCount = 6;
break;
itemCount = 6;
}
else
{
for (int i = 0; i < LCR_game.resourceFile.loadedItemCount; ++i)
items[i + 1] = LCR_game.resourceFile.loadedItemNames + i * LCR_MENU_STRING_SIZE;
default: break;
}
itemCount = LCR_game.resourceFile.loadedItemCount + 1;
}
LCR_rendererDrawMenu(items,itemCount,LCR_game.menuSelectedItem);
}
@ -723,7 +832,7 @@ uint8_t LCR_gameStep(uint32_t time)
LCR_game.frame++;
LCR_LOG2("game step end");
return 1;
return LCR_game.state != LCR_GAME_STATE_END;
}
uint8_t LCR_gameGetNextAudioSample(void)