From 44f748134f2dd19f28eb7940ac089000051e9901 Mon Sep 17 00:00:00 2001 From: Miloslav Ciz Date: Fri, 3 Jan 2025 01:15:24 +0100 Subject: [PATCH] Continue menu --- assets.h | 5 +- game.h | 293 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 204 insertions(+), 94 deletions(-) diff --git a/assets.h b/assets.h index d15e664..3cf4152 100644 --- a/assets.h +++ b/assets.h @@ -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 diff --git a/game.h b/game.h index e973397..8b621b6 100644 --- a/game.h +++ b/game.h @@ -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)