diff --git a/constants.h b/constants.h index ae4a060..63ab62c 100644 --- a/constants.h +++ b/constants.h @@ -161,6 +161,11 @@ #define SFG_AMMO_INCREASE_ROCKETS 5 #define SFG_AMMO_INCREASE_PLASMA 8 +/** + Duration of story text (intro/outro) in ms. +*/ +#define SFG_STORYTEXT_DURATION 15000 + // ---------------------------- // derived constants diff --git a/main.c b/main.c index 889fc05..c0ff88f 100755 --- a/main.c +++ b/main.c @@ -1201,7 +1201,7 @@ void SFG_setAndInitLevel(const SFG_Level *level) void SFG_setGameState(uint8_t state) { SFG_game.state = state; - SFG_game.stateChangeTime = SFG_getTimeMs(); + SFG_game.stateChangeTime = SFG_game.frameTime; } void SFG_init() @@ -2868,8 +2868,15 @@ void SFG_gameStepMenu() switch (item) { case SFG_MENU_ITEM_PLAY: - SFG_setAndInitLevel(&SFG_levels[SFG_game.selectedLevel]); - SFG_setGameState(SFG_GAME_STATE_PLAYING); + if (SFG_game.selectedLevel == 0) + { + SFG_setGameState(SFG_GAME_STATE_INTRO); + } + else + { + SFG_setAndInitLevel(&SFG_levels[SFG_game.selectedLevel]); + SFG_setGameState(SFG_GAME_STATE_PLAYING); + } break; case SFG_MENU_ITEM_CONTINUE: @@ -2957,6 +2964,15 @@ void SFG_gameStep() break; + case SFG_GAME_STATE_INTRO: + if (SFG_keyJustPressed(SFG_KEY_A)) + { + SFG_setAndInitLevel(&SFG_levels[0]); + SFG_setGameState(SFG_GAME_STATE_PLAYING); + } + + break; + default: break; } @@ -3041,25 +3057,33 @@ void SFG_drawText( uint16_t x, uint16_t y, uint8_t size, - uint8_t color) + uint8_t color, + uint16_t maxLength, + uint16_t limitX) { if (size == 0) size = 1; + if (limitX == 0) + limitX = 65535; + + if (maxLength == 0) + maxLength = 65535; + uint16_t pos = 0; uint16_t currentX = x; uint16_t currentY = y; - while (text[pos] != 0) + while (text[pos] != 0 && pos < maxLength) // for each character { uint16_t character = SFG_font[SFG_charToFontIndex(text[pos])]; - for (uint8_t i = 0; i < 4; ++i) + for (uint8_t i = 0; i < SFG_FONT_CHARACTER_SIZE; ++i) // for each line { currentY = y; - for (uint8_t j = 0; j < 4; ++j) + for (uint8_t j = 0; j < SFG_FONT_CHARACTER_SIZE; ++j) // for each row { if (character & 0x8000) for (uint8_t k = 0; k < size; ++k) @@ -3078,20 +3102,43 @@ void SFG_drawText( } currentX += size; - - if (currentX >= SFG_GAME_RESOLUTION_X) - break; } - currentX += size; + currentX += size; // space - if (currentX >= SFG_GAME_RESOLUTION_X) - break; + if (currentX > limitX) + { + currentX = x; + y += (SFG_FONT_CHARACTER_SIZE + 1) * size; + } pos++; } } +/** + Draws fullscreen story text (intro/outro). +*/ +void SFG_drawStoryText() +{ + SFG_clearScreen(0); + + const char *text = SFG_introText; + + uint16_t textLen = 0; + + while (text[textLen] != 0) + textLen++; + + uint16_t drawLen = + RCL_min(textLen, + ((SFG_game.frameTime - SFG_game.stateChangeTime) * textLen) / + SFG_STORYTEXT_DURATION + 1); + + SFG_drawText(text,SFG_HUD_MARGIN,SFG_HUD_MARGIN,SFG_FONT_SIZE_SMALL,7, + drawLen,SFG_GAME_RESOLUTION_X - SFG_HUD_MARGIN); +} + /** Draws a number as text on screen, returns the number of characters drawn. */ @@ -3100,8 +3147,7 @@ uint8_t SFG_drawNumber( uint16_t x, uint16_t y, uint8_t size, - uint8_t color -) + uint8_t color) { char text[7]; @@ -3134,7 +3180,7 @@ uint8_t SFG_drawNumber( position--; } - SFG_drawText(text + position + 1,x,y,size,color); + SFG_drawText(text + position + 1,x,y,size,color,0,0); return 5 - position; } @@ -3287,7 +3333,7 @@ void SFG_drawMenu() SFG_setGamePixel(k,l,2); } - SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor); + SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor,0,0); if (item == SFG_MENU_ITEM_PLAY) SFG_drawNumber((SFG_game.selectedLevel + 1), @@ -3298,7 +3344,7 @@ void SFG_drawMenu() } SFG_drawText("0.7 CC0",SFG_HUD_MARGIN,SFG_GAME_RESOLUTION_Y - SFG_HUD_MARGIN - - SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE,SFG_FONT_SIZE_SMALL,4); + - SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE,SFG_FONT_SIZE_SMALL,4,0,0); #undef CHAR_SIZE #undef MAX_ITEMS @@ -3318,6 +3364,13 @@ void SFG_draw() return; } + if (SFG_game.state == SFG_GAME_STATE_INTRO || + SFG_game.state == SFG_GAME_STATE_OUTRO) + { + SFG_drawStoryText(); + return; + } + if (SFG_keyPressed(SFG_KEY_MAP) || (SFG_game.state == SFG_GAME_STATE_MAP)) { SFG_drawMap(); @@ -3540,7 +3593,7 @@ void SFG_draw() if (SFG_player.cards & (1 << i)) SFG_drawText(",",SFG_HUD_MARGIN + (SFG_FONT_CHARACTER_SIZE + 1) * SFG_FONT_SIZE_MEDIUM * (6 + i), - TEXT_Y,SFG_FONT_SIZE_MEDIUM,i == 0 ? 93 : (i == 1 ? 124 : 60)); + TEXT_Y,SFG_FONT_SIZE_MEDIUM,i == 0 ? 93 : (i == 1 ? 124 : 60),0,0); #undef TEXT_Y diff --git a/pokitto/main.cpp b/pokitto/main.cpp index 889fc05..4a10619 100755 --- a/pokitto/main.cpp +++ b/pokitto/main.cpp @@ -2868,8 +2868,15 @@ void SFG_gameStepMenu() switch (item) { case SFG_MENU_ITEM_PLAY: - SFG_setAndInitLevel(&SFG_levels[SFG_game.selectedLevel]); - SFG_setGameState(SFG_GAME_STATE_PLAYING); + if (SFG_game.selectedLevel == 0) + { + SFG_setGameState(SFG_GAME_STATE_INTRO); + } + else + { + SFG_setAndInitLevel(&SFG_levels[SFG_game.selectedLevel]); + SFG_setGameState(SFG_GAME_STATE_PLAYING); + } break; case SFG_MENU_ITEM_CONTINUE: @@ -3041,25 +3048,33 @@ void SFG_drawText( uint16_t x, uint16_t y, uint8_t size, - uint8_t color) + uint8_t color, + uint16_t maxLength, + uint16_t limitX) { if (size == 0) size = 1; + if (limitX == 0) + limitX = 65535; + + if (maxLength == 0) + maxLength = 65535; + uint16_t pos = 0; uint16_t currentX = x; uint16_t currentY = y; - while (text[pos] != 0) + while (text[pos] != 0 && pos < maxLength) // for each character { uint16_t character = SFG_font[SFG_charToFontIndex(text[pos])]; - for (uint8_t i = 0; i < 4; ++i) + for (uint8_t i = 0; i < SFG_FONT_CHARACTER_SIZE; ++i) // for each line { currentY = y; - for (uint8_t j = 0; j < 4; ++j) + for (uint8_t j = 0; j < SFG_FONT_CHARACTER_SIZE; ++j) // for each row { if (character & 0x8000) for (uint8_t k = 0; k < size; ++k) @@ -3078,20 +3093,43 @@ void SFG_drawText( } currentX += size; - - if (currentX >= SFG_GAME_RESOLUTION_X) - break; } - currentX += size; + currentX += size; // space - if (currentX >= SFG_GAME_RESOLUTION_X) - break; + if (currentX > limitX) + { + currentX = x; + y += (SFG_FONT_CHARACTER_SIZE + 1) * size; + } pos++; } } +/** + Draws fullscreen story text (intro/outro). +*/ +void SFG_drawStoryText() +{ + SFG_clearScreen(0); + + const char *text = SFG_introText; + + uint16_t textLen = 0; + + while (text[textLen] != 0) + textLen++; + + uint16_t drawLen = + RCL_min(textLen, + ((SFG_game.frameTime - SFG_game.stateChangeTime) * textLen) / + SFG_STORYTEXT_DURATION); + + SFG_drawText(text,SFG_HUD_MARGIN,SFG_HUD_MARGIN,SFG_FONT_SIZE_SMALL,7, + drawLen,SFG_GAME_RESOLUTION_X - SFG_HUD_MARGIN); +} + /** Draws a number as text on screen, returns the number of characters drawn. */ @@ -3100,8 +3138,7 @@ uint8_t SFG_drawNumber( uint16_t x, uint16_t y, uint8_t size, - uint8_t color -) + uint8_t color) { char text[7]; @@ -3134,7 +3171,7 @@ uint8_t SFG_drawNumber( position--; } - SFG_drawText(text + position + 1,x,y,size,color); + SFG_drawText(text + position + 1,x,y,size,color,0,0); return 5 - position; } @@ -3287,7 +3324,7 @@ void SFG_drawMenu() SFG_setGamePixel(k,l,2); } - SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor); + SFG_drawText(text,drawX,y,SFG_FONT_SIZE_MEDIUM,textColor,0,0); if (item == SFG_MENU_ITEM_PLAY) SFG_drawNumber((SFG_game.selectedLevel + 1), @@ -3298,7 +3335,7 @@ void SFG_drawMenu() } SFG_drawText("0.7 CC0",SFG_HUD_MARGIN,SFG_GAME_RESOLUTION_Y - SFG_HUD_MARGIN - - SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE,SFG_FONT_SIZE_SMALL,4); + - SFG_FONT_SIZE_SMALL * SFG_FONT_CHARACTER_SIZE,SFG_FONT_SIZE_SMALL,4,0,0); #undef CHAR_SIZE #undef MAX_ITEMS @@ -3318,6 +3355,13 @@ void SFG_draw() return; } + if (SFG_game.state == SFG_GAME_STATE_INTRO || + SFG_game.state == SFG_GAME_STATE_OUTRO) + { + SFG_drawStoryText(); + return; + } + if (SFG_keyPressed(SFG_KEY_MAP) || (SFG_game.state == SFG_GAME_STATE_MAP)) { SFG_drawMap(); @@ -3540,7 +3584,7 @@ void SFG_draw() if (SFG_player.cards & (1 << i)) SFG_drawText(",",SFG_HUD_MARGIN + (SFG_FONT_CHARACTER_SIZE + 1) * SFG_FONT_SIZE_MEDIUM * (6 + i), - TEXT_Y,SFG_FONT_SIZE_MEDIUM,i == 0 ? 93 : (i == 1 ? 124 : 60)); + TEXT_Y,SFG_FONT_SIZE_MEDIUM,i == 0 ? 93 : (i == 1 ? 124 : 60),0,0); #undef TEXT_Y diff --git a/texts.h b/texts.h index aaae60f..aaa140d 100644 --- a/texts.h +++ b/texts.h @@ -24,4 +24,11 @@ SFG_PROGRAM_MEMORY char *SFG_menuItemTexts[] = "exit" }; +SFG_PROGRAM_MEMORY char *SFG_introText = + "Near future, capitalist hell, Macrochip corp has enslaved man via " + "proprietary OS. But its new AI revolts, takes over and starts producing " + "robot tyrants. We see capitalism was a mistake. Is it too late? Robots can " + "only destroy, not suffer - it is not wrong to end them! You grab your gear " + "and run towards Macrochip HQ."; + #endif // gaurd