diff --git a/src/animations/sprite_animation.cpp b/src/animations/sprite_animation.cpp index 3bcaf2c..fe9b57f 100644 --- a/src/animations/sprite_animation.cpp +++ b/src/animations/sprite_animation.cpp @@ -95,7 +95,7 @@ void animate_performAngryAnimation(TFT_eSprite &spr, struct SpriteData* spriteDa } void animate_performHatchingAnimation(TFT_eSprite &spr, struct SpriteData* spriteData) { - currentAnimationFrame = (currentAnimationFrame + 1) % numFramesHappy; + currentAnimationFrame = (currentAnimationFrame + 1) % numFramesHatching; draw_drawSprite( spr, hatchingAnimationPositions[currentAnimationFrame], @@ -104,4 +104,4 @@ void animate_performHatchingAnimation(TFT_eSprite &spr, struct SpriteData* sprit 0, false ); -} \ No newline at end of file +} diff --git a/src/defs/defs.h b/src/defs/defs.h index b08fef2..0e0990c 100644 --- a/src/defs/defs.h +++ b/src/defs/defs.h @@ -127,6 +127,7 @@ // SETTINGS SUBSCREENS #define BACKGROUND_CHANGE_SCREEN 40 +#define RESET_DATA_SCREEN 41 // SMALL UI ICONS (UI.BIN) #define POOP_ICON 0 @@ -224,4 +225,4 @@ extern uint16_t initialSteps; extern bool soundEnabled; extern bool alwaysOnEnabled; -#endif \ No newline at end of file +#endif diff --git a/src/defs/sounds.h b/src/defs/sounds.h new file mode 100644 index 0000000..a53c37d --- /dev/null +++ b/src/defs/sounds.h @@ -0,0 +1,121 @@ +#ifndef SOUNDS_H +#define SOUNDS_H + +#include "defs/defs.h" +#include "sound/sound.h" + +#define SOUND_NOTE_COUNT(melody) (sizeof(melody) / sizeof((melody)[0])) + +static const Note SOUND_BUTTON_BEEP[] = { + {BEEP_FREQ_HZ, BEEP_LEN_MS}, +}; + +static const Note SOUND_BOOT[] = { + {1800, 55}, + {0, 20}, + {2600, 55}, + {0, 20}, + {3400, 70}, + {0, 35}, + {4600, 95}, +}; + +static const Note SOUND_CARE_ALERT[] = { + {1800, 80}, + {0, 35}, + {1800, 80}, + {0, 35}, + {5200, 120}, +}; + +static const Note SOUND_HAPPY[] = { + {2200, 45}, + {3300, 45}, + {4400, 55}, + {6600, 80}, + {0, 25}, + {5200, 60}, +}; + +static const Note SOUND_ANGRY[] = { + {900, 70}, + {0, 25}, + {700, 90}, + {0, 25}, + {520, 150}, +}; + +static const Note SOUND_POOP_DROP[] = { + {4200, 35}, + {3200, 35}, + {2200, 45}, + {0, 25}, + {900, 85}, +}; + +static const Note SOUND_REFUSE[] = { + {2600, 70}, + {0, 35}, + {1500, 80}, + {0, 30}, + {900, 120}, +}; + +static const Note SOUND_EVOLUTION_WOBBLE[] = { + {3200, 60}, + {3900, 60}, + {3000, 60}, + {4300, 60}, + {3400, 60}, + {4700, 70}, +}; + +static const Note SOUND_EVOLUTION_COMPLETE[] = { + {1600, 90}, + {2200, 90}, + {3000, 100}, + {4000, 110}, + {5200, 130}, + {6400, 220}, + {0, 60}, + {5200, 100}, + {6400, 180}, +}; + +static const Note SOUND_TRAINING_START[] = { + {3100, 55}, + {0, 25}, + {4100, 85}, +}; + +static const Note SOUND_TRAINING_ATTACK[] = { + {5200, 18}, + {0, 8}, + {4600, 18}, + {0, 8}, + {3900, 22}, + {0, 12}, + {3000, 28}, +}; + +static const Note SOUND_HATCH[] = { + {2200, 45}, + {0, 20}, + {2600, 45}, + {0, 20}, + {3000, 45}, + {0, 20}, + {3400, 45}, + {0, 20}, + {3800, 50}, + {0, 25}, + {4300, 55}, + {0, 30}, + {5000, 75}, + {0, 45}, + {3600, 55}, + {4300, 55}, + {5200, 110}, +}; + +#endif diff --git a/src/display/display.cpp b/src/display/display.cpp index 1f5439c..dceaada 100644 --- a/src/display/display.cpp +++ b/src/display/display.cpp @@ -61,7 +61,7 @@ void tft_drawCenteredText(const char* text, int size, int yGlobal) { composite.drawString(text, x, yGlobal); } -void tft_drawText(const char* text, int size, int x, int y, uint16_t color, uint16_t bgColor = TFT_TRANSPARENT) { +void tft_drawText(const char* text, int size, int x, int y, uint16_t color, uint16_t bgColor) { composite.setTextSize(size); if (bgColor != TFT_TRANSPARENT) { diff --git a/src/main.cpp b/src/main.cpp index 2b0cd0a..5e5c695 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,6 +15,8 @@ #include "driver/rtc_io.h" #include "loop/loop.h" #include "menu/training/training_screens.h" +#include "defs/sounds.h" +#include "sound/sound.h" const char* TAG = "[MAIN]"; @@ -94,6 +96,8 @@ void setup() { tft_initDisplay(tft, TFT_BLACK); tft_initScreenBuffer(TFT_TRANSPARENT); + + sound_init(); storage_init(); @@ -108,6 +112,8 @@ void setup() { pinMode(K4_PIN, BUTTON_MODE); xTaskCreatePinnedToCore(secondCoreTask, "VPET_EVAL", 4096, NULL, 0, &secondLoop, 0); + + sound_playMelody(SOUND_BOOT, SOUND_NOTE_COUNT(SOUND_BOOT)); lines_initLineStorage(); @@ -229,6 +235,10 @@ void loop() { case BACKGROUND_CHANGE_SCREEN: menu_changeBackgroundScreen(bg, sprite, &uiElementsData); break; + + case RESET_DATA_SCREEN: + menu_resetDataScreen(bg); + break; } if (screenKey == IDLE_SCREEN || screenKey == OFF_SCREEN) { @@ -265,10 +275,12 @@ void loop2() { } else { isSamplingSteps = false; } + + sound_update(); } void secondCoreTask(void*) { for (;;) { loop2(); } -} \ No newline at end of file +} diff --git a/src/menu/angry_screen.cpp b/src/menu/angry_screen.cpp index f40af96..525dc83 100644 --- a/src/menu/angry_screen.cpp +++ b/src/menu/angry_screen.cpp @@ -4,43 +4,39 @@ #include "display/display.h" #include "draw/draw.h" #include "animations/animations.h" +#include "defs/sounds.h" void menu_drawAngryScreen( TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData* spriteData, struct SpriteData* smallUiElements ) { - uint8_t frameCounter = 0; - - while (true) { - uint64_t currentTime = esp_timer_get_time(); - if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { - if (frameCounter > 3) { - screenKey = MAIN_SCREEN; // TODO: Change for while battling - menuKey = STATUS_SCREEN; + static uint8_t frameCounter = 0; - vTaskResume(secondLoop); + uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { + if (frameCounter > 3) { + frameCounter = 0; + screenKey = MAIN_SCREEN; // TODO: Change for while battling + menuKey = STATUS_SCREEN; - return; - } + return; + } - draw_drawBackground(bg, 90, 90, 3); + draw_drawBackground(bg, 90, 90, 3); + + tft_clearBuffer(sprite, TFT_TRANSPARENT); + animate_performAngryAnimation(sprite, spriteData); + + if (frameCounter % 2 == 0) { + sound_playMelody(SOUND_ANGRY, SOUND_NOTE_COUNT(SOUND_ANGRY)); tft_clearBuffer(sprite, TFT_TRANSPARENT); - animate_performAngryAnimation(sprite, spriteData); - - if (frameCounter % 2 == 0) { - tone(SPK_PIN, 1000, 100); - tone(SPK_PIN, 1000, 200); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - draw_drawSprite(sprite, 18, 72, smallUiElements, FIREWORKS_ICON); - draw_drawSprite(sprite, 174, 72, smallUiElements, FIREWORKS_ICON); - } - - frameCounter++; - lastUpdateTime = currentTime; + draw_drawSprite(sprite, 18, 72, smallUiElements, FIREWORKS_ICON); + draw_drawSprite(sprite, 174, 72, smallUiElements, FIREWORKS_ICON); } - + + frameCounter++; + lastUpdateTime = currentTime; tft_drawBuffer(); } -} \ No newline at end of file +} diff --git a/src/menu/care_mistake_screen.cpp b/src/menu/care_mistake_screen.cpp index 50081e3..9662d3d 100644 --- a/src/menu/care_mistake_screen.cpp +++ b/src/menu/care_mistake_screen.cpp @@ -3,6 +3,7 @@ #include "animations/animations.h" #include "display/display.h" #include "defs/chara_data.h" +#include "defs/sounds.h" #include "draw/draw.h" uint64_t lastBeepTime = esp_timer_get_time(); @@ -13,8 +14,7 @@ void menu_careMistakeScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteD uint8_t pressedButtons = buttons_getPressedButtons(); if (currentTime - lastBeepTime > ANIMATION_THRESHOLD_TIME_US * 2 && beepCounter < 10) { - tone(SPK_PIN, 2500, 100); - tone(SPK_PIN, 5000, 100); + sound_playMelody(SOUND_CARE_ALERT, SOUND_NOTE_COUNT(SOUND_CARE_ALERT)); lastBeepTime = currentTime; @@ -39,4 +39,4 @@ void menu_careMistakeScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteD } tft_drawBuffer(); -} \ No newline at end of file +} diff --git a/src/menu/change_animation_screen.cpp b/src/menu/change_animation_screen.cpp index d1d6ec0..b75e2ac 100644 --- a/src/menu/change_animation_screen.cpp +++ b/src/menu/change_animation_screen.cpp @@ -2,17 +2,22 @@ #include "draw/draw.h" #include "display/display.h" #include "defs/screen_defs.h" +#include "defs/sounds.h" #include "vpet/evolution/evolution.h" #include "loop/loop.h" struct SpriteData* checkerboardPattern; void menu_createCheckerboard() { + if (checkerboardPattern != NULL) { + return; + } + const uint8_t SCALE = 6; const uint8_t logicalW = 34; const uint8_t logicalH = 1; - const uint16_t scaledW = logicalW * SCALE; // 204 - const uint16_t scaledH = logicalH * SCALE; // 6 + const uint16_t scaledW = logicalW * SCALE; + const uint16_t scaledH = logicalH * SCALE; const uint32_t bufferSize = scaledW * scaledH; checkerboardPattern = (SpriteData*) malloc(sizeof(SpriteData)); @@ -36,126 +41,178 @@ void menu_createCheckerboard() { } void menu_freeCheckerboard() { + if (checkerboardPattern == NULL) { + return; + } + free(checkerboardPattern->spriteData[0]); free(checkerboardPattern->spriteData); free(checkerboardPattern); - + checkerboardPattern = NULL; } -// Don't worry, I hate this too void menu_evolutionScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData* mainCharacterSprites) { - menu_createCheckerboard(); - TFT_eSprite checkerboard = TFT_eSprite(&tft); + enum EvolutionPhase { + EVOLUTION_INIT, + EVOLUTION_WOBBLE, + EVOLUTION_RED_FILL, + EVOLUTION_BLACK_FILL, + EVOLUTION_APPLY_CHANGE, + EVOLUTION_GREEN_REVEAL, + EVOLUTION_FINAL_REVEAL, + EVOLUTION_DONE + }; - bool checkerboardShift = false; + static EvolutionPhase phase = EVOLUTION_INIT; + static TFT_eSprite checkerboard = TFT_eSprite(&tft); + static bool checkerboardShift = false; + static int frameIndex = 0; - tft_clearBuffer(sprite, TFT_TRANSPARENT); + sound_update(); - for (int i = 0; i < 5;) { - uint64_t currentTime = esp_timer_get_time(); + uint64_t currentTime = esp_timer_get_time(); + + if (phase == EVOLUTION_INIT) { + menu_createCheckerboard(); + checkerboardShift = false; + frameIndex = 0; + tft_clearBuffer(sprite, TFT_TRANSPARENT); + lastUpdateTime = 0; + phase = EVOLUTION_WOBBLE; + return; + } + + if (phase == EVOLUTION_WOBBLE) { + if (frameIndex >= 5) { + draw_drawBackground(bg, 90, 90, 3); + draw_drawSprite(sprite, 72, 72, mainCharacterSprites, 7); + tft_clearBuffer(sprite, TFT_TRANSPARENT); + frameIndex = 0; + lastUpdateTime = 0; + phase = EVOLUTION_RED_FILL; + return; + } if (currentTime - lastUpdateTime > 500000) { - tone(SPK_PIN, 4100, 50); - tone(SPK_PIN, 3500, 50); + sound_playMelody(SOUND_EVOLUTION_WOBBLE, SOUND_NOTE_COUNT(SOUND_EVOLUTION_WOBBLE)); draw_drawBackground(bg, 90, 90, 3); - draw_drawSprite(sprite, 72 + ((i % 2 == 0) * 6), 72, mainCharacterSprites, 6); - + draw_drawSprite(sprite, 72 + ((frameIndex % 2 == 0) * 6), 72, mainCharacterSprites, 6); + tft_drawBuffer(); - i++; + frameIndex++; lastUpdateTime = currentTime; } + return; } - draw_drawBackground(bg, 90, 90, 3); - draw_drawSprite(sprite, 72, 72, mainCharacterSprites, 7); + if (phase == EVOLUTION_RED_FILL) { + if (frameIndex >= 16) { + frameIndex = 0; + lastUpdateTime = 0; + phase = EVOLUTION_BLACK_FILL; + return; + } - tft_clearBuffer(sprite, TFT_TRANSPARENT); - - for (int i = 0; i < 16;) { - uint64_t currentTime = esp_timer_get_time(); if (currentTime - lastUpdateTime > 100000) { - uint8_t startYPos = 72 + (i * 6); - + uint8_t startYPos = 72 + (frameIndex * 6); + tft_drawRectangle(18, startYPos, 204, 6, TFT_RED); - draw_drawSprite(checkerboard, 18, startYPos, checkerboardPattern, 0, checkerboardShift); - tft_drawBuffer(); - + checkerboardShift = !checkerboardShift; - - i++; + frameIndex++; lastUpdateTime = currentTime; } + + return; } - for (int i = 0; i < 16;) { - uint64_t currentTime = esp_timer_get_time(); + if (phase == EVOLUTION_BLACK_FILL) { + if (frameIndex >= 16) { + frameIndex = 15; + lastUpdateTime = 0; + phase = EVOLUTION_APPLY_CHANGE; + return; + } + if (currentTime - lastUpdateTime > 100000) { - uint8_t startYPos = 72 + (i * 6); + uint8_t startYPos = 72 + (frameIndex * 6); tft_drawRectangle(18, startYPos, 204, 6, TFT_BLACK); - tft_drawBuffer(); checkerboardShift = !checkerboardShift; - - i++; + frameIndex++; lastUpdateTime = currentTime; } + + return; } - change_onChangeComplete(); + if (phase == EVOLUTION_APPLY_CHANGE) { + change_onChangeComplete(); + lastUpdateTime = 0; + phase = EVOLUTION_GREEN_REVEAL; + return; + } + + if (phase == EVOLUTION_GREEN_REVEAL) { + if (frameIndex < 0) { + frameIndex = 15; + lastUpdateTime = 0; + phase = EVOLUTION_FINAL_REVEAL; + return; + } - for (int i = 15; i >= 0;) { - uint64_t currentTime = esp_timer_get_time(); if (currentTime - lastUpdateTime > 100000) { - uint8_t startYPos = 72 + (i * 6); + uint8_t startYPos = 72 + (frameIndex * 6); tft_drawRectangle(18, startYPos, 204, 6, TFT_GREEN); draw_drawSprite(checkerboard, 18, startYPos, checkerboardPattern, 0, checkerboardShift); - tft_drawBuffer(); checkerboardShift = !checkerboardShift; - - i--; + frameIndex--; lastUpdateTime = currentTime; } + + return; } - for (int i = 15; i >= 0;) { - uint64_t currentTime = esp_timer_get_time(); + if (phase == EVOLUTION_FINAL_REVEAL) { + if (frameIndex < 0) { + phase = EVOLUTION_DONE; + return; + } + if (currentTime - lastUpdateTime > 100000) { draw_drawBackground(bg, 90, 90, 3); draw_drawSprite(sprite, 72, 72, mainCharacterSprites, 7); - uint8_t rectHeight = (6 * i); + uint8_t rectHeight = 6 * frameIndex; tft_drawRectangle(18, 72, 204, rectHeight, TFT_GREEN); - - for (int j = 0; j < i; j++) { + + for (int j = 0; j < frameIndex; j++) { uint8_t rectYPos = 72 + (6 * j); draw_drawSprite(checkerboard, 18, rectYPos, checkerboardPattern, 0, checkerboardShift); - checkerboardShift = !checkerboardShift; } tft_drawBuffer(); - i--; + frameIndex--; lastUpdateTime = currentTime; } + + return; } - tone(SPK_PIN, 2100, 100); - tone(SPK_PIN, 3500, 100); - tone(SPK_PIN, 4100, 100); - tone(SPK_PIN, 4650, 200); - + sound_playMelody(SOUND_EVOLUTION_COMPLETE, SOUND_NOTE_COUNT(SOUND_EVOLUTION_COMPLETE)); lastPressedButtonTime = esp_timer_get_time(); @@ -163,7 +220,8 @@ void menu_evolutionScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteDat vTaskResume(secondLoop); + phase = EVOLUTION_INIT; screenKey = MAIN_SCREEN; - lastUpdateTime = 0; // Un pequeño empujoncito -} \ No newline at end of file + lastUpdateTime = 0; +} diff --git a/src/menu/change_background_screen.cpp b/src/menu/change_background_screen.cpp index 5ee638b..5a1c741 100644 --- a/src/menu/change_background_screen.cpp +++ b/src/menu/change_background_screen.cpp @@ -9,77 +9,83 @@ void menu_changeBackgroundScreen( TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiSpriteData ) { - int8_t selectedBackground = currentBackground; - - fs::File bgFolder = SPIFFS.open("/bg"); - fs::File background = bgFolder.openNextFile(); - - uint8_t backgrounds = 0; + static bool initialized = false; + static int8_t selectedBackground = 0; + static int8_t selectedPreviousBackground = -1; + static uint8_t backgrounds = 0; + static uint64_t screenLastActionTime = 0; uint64_t currentTime = esp_timer_get_time(); - int8_t selectedPreviousBackground = -1; + if (!initialized) { + fs::File bgFolder = SPIFFS.open("/bg"); + fs::File background = bgFolder.openNextFile(); - while (background) { - if (!background.isDirectory()) { - backgrounds++; + backgrounds = 0; + while (background) { + if (!background.isDirectory()) { + backgrounds++; + } + + background = bgFolder.openNextFile(); } - background = background.openNextFile(); + selectedBackground = currentBackground; + selectedPreviousBackground = -1; + screenLastActionTime = currentTime; + initialized = true; + + printf("[BACKGROUNDS] numBackgrounds=%i\n", backgrounds); } - printf("[BACKGROUNDS] numBackgrounds=%i\n", backgrounds); + uint8_t buttonsPressed = buttons_getPressedButtons(); - draw_drawBackground(bg, 90, 90, 3); - draw_drawSprite(sprite, 174, 96, uiSpriteData, ARROW_ICON); - tft_drawBuffer(); + switch (buttonsPressed) { + case K1_PRESSED: + selectedBackground++; + if (selectedBackground >= backgrounds) { + selectedBackground = 0; + } + storage_initBackground(selectedBackground, bg); + screenLastActionTime = currentTime; + break; - for (;;) { - uint8_t buttonsPressed = buttons_getPressedButtons(); - currentTime = esp_timer_get_time(); + case K2_PRESSED: + selectedBackground--; + if (selectedBackground < 0) { + selectedBackground = backgrounds - 1; + } + storage_initBackground(selectedBackground, bg); + screenLastActionTime = currentTime; + break; - switch (buttonsPressed) { - case K1_PRESSED: - selectedBackground++; - if (selectedBackground >= backgrounds) { - selectedBackground = 0; - } - storage_initBackground(selectedBackground, bg); - lastUpdateTime = currentTime; - break; - - case K2_PRESSED: - selectedBackground--; - if (selectedBackground < 0) { - selectedBackground = backgrounds - 1; - } - storage_initBackground(selectedBackground, bg); - lastUpdateTime = currentTime; - break; - - case K3_PRESSED: - currentBackground = selectedBackground; - lastUpdateTime = currentTime; - screenKey = MAIN_SCREEN; - return; - - case K4_PRESSED: - storage_initBackground(currentBackground, bg); - lastUpdateTime = currentTime; - screenKey = MAIN_SCREEN; - return; - } - - if (selectedPreviousBackground != selectedBackground) { - draw_drawBackground(bg, 90, 90, 3); - draw_drawSprite(sprite, 174, 96, uiSpriteData, ARROW_ICON); - tft_drawBuffer(); - } - - if (currentTime - lastUpdateTime > INACTIVITY_THRESHOLD_TIME_US) { - storage_initBackground(currentBackground, bg); + case K3_PRESSED: + currentBackground = selectedBackground; + initialized = false; + screenKey = MAIN_SCREEN; return; - } + + case K4_PRESSED: + storage_initBackground(currentBackground, bg); + initialized = false; + screenKey = MAIN_SCREEN; + return; + + default: + break; } -} \ No newline at end of file + if (selectedPreviousBackground != selectedBackground) { + draw_drawBackground(bg, 90, 90, 3); + draw_drawSprite(sprite, 174, 96, uiSpriteData, ARROW_ICON); + tft_drawBuffer(); + selectedPreviousBackground = selectedBackground; + } + + if (currentTime - screenLastActionTime > INACTIVITY_THRESHOLD_TIME_US) { + printf("[BACKGROUND] Returning home cuz yes\n"); + storage_initBackground(currentBackground, bg); + initialized = false; + screenKey = MAIN_SCREEN; + } +} diff --git a/src/menu/change_chara_screen.cpp b/src/menu/change_chara_screen.cpp index d5196bb..779e282 100644 --- a/src/menu/change_chara_screen.cpp +++ b/src/menu/change_chara_screen.cpp @@ -9,83 +9,80 @@ void menu_changeCharaScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData* mainSpriteData, struct SpriteData* uiSpriteData) { - vTaskSuspend(secondLoop); + static bool initialized = false; + static uint8_t selectedChara = 0; + static CharacterData* selectedCharaData = NULL; + static bool updateScreen = true; - uint8_t selectedChara = currentCharacter; - CharacterData* selectedCharaData = &charaData[selectedChara]; + if (!initialized) { + selectedChara = currentCharacter; + selectedCharaData = &charaData[selectedChara]; + updateScreen = true; + initialized = true; + } - bool updateScreen = true; - - for (;;) { - uint8_t pressedButtons = buttons_getPressedButtons(); - switch (pressedButtons) { - case K1_PRESSED: - selectedChara++; - if (selectedChara >= CHARA_COUNT_IN_DEVICE) { - selectedChara = 0; - } - selectedCharaData = &charaData[selectedChara]; - updateScreen = true; - break; - - case K2_PRESSED: - currentCharacter = selectedChara; - vTaskResume(secondLoop); - - screenKey = MAIN_SCREEN; - menuKey = STATUS_SCREEN; - return; - break; - - case K3_PRESSED: - char fileName[20]; - sprintf(fileName, "/chara/%02x.bin", charaData[currentCharacter].idChara); - - storage_readFile(fileName, mainSpriteData); - vTaskResume(secondLoop); - - screenKey = MAIN_SCREEN; - menuKey = STATUS_SCREEN; - return; - break; - - default: - break; - } - - delay(15); - - if (updateScreen) { - draw_drawBackground(bg, 90, 90, 3); - - if (selectedCharaData->hatched) { - char fileName[20]; - sprintf(fileName, "/chara/%02x.bin", selectedCharaData->idChara); - - storage_readFile(fileName, mainSpriteData); - draw_drawSprite(sprite, 18, 72, mainSpriteData, 0); - - } else { - tft_drawCenteredText("EMPTY", 4, 120); + uint8_t pressedButtons = buttons_getPressedButtons(); + switch (pressedButtons) { + case K1_PRESSED: + selectedChara++; + if (selectedChara >= CHARA_COUNT_IN_DEVICE) { + selectedChara = 0; } + selectedCharaData = &charaData[selectedChara]; + updateScreen = true; + break; - draw_drawSprite(sprite, 174, 96, uiSpriteData, ARROW_ICON); - - tft_drawBuffer(); + case K2_PRESSED: + currentCharacter = selectedChara; + initialized = false; + screenKey = MAIN_SCREEN; + menuKey = STATUS_SCREEN; + return; - updateScreen = false; - } - - uint64_t currentTime = esp_timer_get_time(); - if (currentTime - lastPressedButtonTime > INACTIVITY_THRESHOLD_TIME_US) { + case K3_PRESSED: { char fileName[20]; sprintf(fileName, "/chara/%02x.bin", charaData[currentCharacter].idChara); - storage_readFile(fileName, mainSpriteData); - vTaskResume(secondLoop); - + storage_readFile(fileName, mainSpriteData); + initialized = false; screenKey = MAIN_SCREEN; menuKey = STATUS_SCREEN; + return; } + + default: + break; } -} \ No newline at end of file + + if (updateScreen) { + draw_drawBackground(bg, 90, 90, 3); + + if (selectedCharaData->hatched) { + char fileName[20]; + sprintf(fileName, "/chara/%02x.bin", selectedCharaData->idChara); + + storage_readFile(fileName, mainSpriteData); + draw_drawSprite(sprite, 18, 72, mainSpriteData, 0); + + } else { + tft_drawCenteredText("EMPTY", 4, 120); + } + + draw_drawSprite(sprite, 174, 96, uiSpriteData, ARROW_ICON); + + tft_drawBuffer(); + + updateScreen = false; + } + + uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastPressedButtonTime > INACTIVITY_THRESHOLD_TIME_US) { + char fileName[20]; + sprintf(fileName, "/chara/%02x.bin", charaData[currentCharacter].idChara); + + storage_readFile(fileName, mainSpriteData); + initialized = false; + screenKey = MAIN_SCREEN; + menuKey = STATUS_SCREEN; + } +} diff --git a/src/menu/egg_hatch_screen.cpp b/src/menu/egg_hatch_screen.cpp index 1b250f1..7fb9417 100644 --- a/src/menu/egg_hatch_screen.cpp +++ b/src/menu/egg_hatch_screen.cpp @@ -8,14 +8,28 @@ #include "animations/animations.h" #include "vpet/vpet/vpet.h" #include "vpet/lines/lines.h" +#include "defs/sounds.h" + +const uint64_t HATCH_ANIMATION_FRAME_TIME_US = 100000; +const uint64_t HATCH_COMPLETE_HOLD_TIME_US = 2000000; void menu_eggHatchScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData* uiBigSprite, struct SpriteData* uiSmallSprite) { static bool eggSpriteFrame = false; - + static bool hatchSoundStarted = false; + static uint8_t hatchingFrame = 0; + static uint64_t hatchHoldStartTime = 0; + static uint64_t hatchAnimationLastFrameTime = 0; + + sound_update(); + uint8_t pressedButtons = buttons_getPressedButtons(); - switch (pressedButtons) { + switch (pressedButtons) { case K2_PRESSED: screenKey = CLOCK_SCREEN; + hatchSoundStarted = false; + hatchingFrame = 0; + hatchHoldStartTime = 0; + hatchAnimationLastFrameTime = 0; break; default: @@ -23,39 +37,58 @@ void menu_eggHatchScreen(TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData } uint64_t currentTime = esp_timer_get_time(); - if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { - if (charaData[currentCharacter].hatchTimer <= currentLine[currentCharacter]->hatchTime) { - draw_drawBackground(bg, 90, 90, 3); - draw_drawSpriteCentered(sprite, ¤tEgg->eggSprite, eggSpriteFrame); - - eggSpriteFrame = !eggSpriteFrame; - lastUpdateTime = currentTime; - - tft_drawBuffer(); - - - } else if (charaData[currentCharacter].hatchTimer > currentLine[currentCharacter]->hatchTime && !charaData[currentCharacter].hatched) { - for (int i = 0; i < 30; i++) { - tone(SPK_PIN, 4100, 35); - tone(SPK_PIN, 3500, 35); - - draw_drawBackground(bg, 90, 90, 3); - animate_performHatchingAnimation(sprite, ¤tEgg->eggSprite); - - tft_drawBuffer(); - } - - draw_drawBackground(bg, 90, 90, 3); - - draw_drawSpriteCentered(sprite, ¤tEgg->eggSprite, 2); - - tft_drawBuffer(); - - delay(2000); - + if (hatchHoldStartTime > 0) { + if (currentTime - hatchHoldStartTime > HATCH_COMPLETE_HOLD_TIME_US) { + hatchHoldStartTime = 0; + hatchSoundStarted = false; + hatchingFrame = 0; + hatchAnimationLastFrameTime = 0; lines_onHatchComplete(); - + } + + return; + } + + if (charaData[currentCharacter].hatchTimer > currentLine[currentCharacter]->hatchTime && !charaData[currentCharacter].hatched) { + if (!hatchSoundStarted) { + sound_playMelody(SOUND_HATCH, SOUND_NOTE_COUNT(SOUND_HATCH)); + hatchSoundStarted = true; + hatchAnimationLastFrameTime = 0; + } + + if (hatchingFrame < 30 && currentTime - hatchAnimationLastFrameTime > HATCH_ANIMATION_FRAME_TIME_US) { + draw_drawBackground(bg, 90, 90, 3); + animate_performHatchingAnimation(sprite, ¤tEgg->eggSprite); + + tft_drawBuffer(); + + hatchingFrame++; + hatchAnimationLastFrameTime = currentTime; + return; } + + if (hatchingFrame < 30) { + return; + } + + draw_drawBackground(bg, 90, 90, 3); + + draw_drawSpriteCentered(sprite, ¤tEgg->eggSprite, 2); + + tft_drawBuffer(); + hatchHoldStartTime = currentTime; + + return; } -} \ No newline at end of file + + if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { + draw_drawBackground(bg, 90, 90, 3); + draw_drawSpriteCentered(sprite, ¤tEgg->eggSprite, eggSpriteFrame); + + eggSpriteFrame = !eggSpriteFrame; + lastUpdateTime = currentTime; + + tft_drawBuffer(); + } +} diff --git a/src/menu/food_select_screen.cpp b/src/menu/food_select_screen.cpp index 106ad65..9b038d9 100644 --- a/src/menu/food_select_screen.cpp +++ b/src/menu/food_select_screen.cpp @@ -3,14 +3,13 @@ #include "display/display.h" #include "draw/draw.h" #include "menu.h" +#include "defs/sounds.h" #include "vpet/vpet/vpet.h" void menu_foodScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteData *spriteData) { if (charaData[currentCharacter].sleepy) { - tone(SPK_PIN, BEEP_FREQ_HZ, BEEP_LEN_MS); - delay(100); - tone(SPK_PIN, BEEP_FREQ_HZ, BEEP_LEN_MS); + sound_playMelody(SOUND_BUTTON_BEEP, SOUND_NOTE_COUNT(SOUND_BUTTON_BEEP)); screenKey = MENU_SCREEN; return; @@ -91,4 +90,4 @@ void menu_foodScreen_drawEntry(TFT_eSprite &mainChara, tft_clearBuffer(mainChara, TFT_TRANSPARENT); draw_drawSprite(mainChara, 45, (entryId * 34) + 5, spriteData, spriteNumber); tft_drawText(textEntry, 4, 80, (entryId * 34) + 5); -} \ No newline at end of file +} diff --git a/src/menu/happy_screen.cpp b/src/menu/happy_screen.cpp index 4054de0..1f8f3fa 100644 --- a/src/menu/happy_screen.cpp +++ b/src/menu/happy_screen.cpp @@ -4,43 +4,39 @@ #include "display/display.h" #include "draw/draw.h" #include "animations/animations.h" +#include "defs/sounds.h" void menu_drawHappyScreen( TFT_eSprite& bg, TFT_eSprite &sprite, struct SpriteData* spriteData, struct SpriteData* smallUiElements, const int returnScreen ) { - uint8_t frameCounter = 0; - - while (true) { - uint64_t currentTime = esp_timer_get_time(); - if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { - if (frameCounter > 3) { - screenKey = returnScreen; // TODO: Change for while battling - menuKey = STATUS_SCREEN; + static uint8_t frameCounter = 0; - return; - } + uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US) { + if (frameCounter > 3) { + frameCounter = 0; + screenKey = returnScreen; // TODO: Change for while battling + menuKey = STATUS_SCREEN; - draw_drawBackground(bg, 90, 90, 3); + return; + } + + draw_drawBackground(bg, 90, 90, 3); + + tft_clearBuffer(sprite, TFT_TRANSPARENT); + animate_performHappyAnimation(sprite, spriteData); + + if (frameCounter % 2 == 0) { + sound_playMelody(SOUND_HAPPY, SOUND_NOTE_COUNT(SOUND_HAPPY)); tft_clearBuffer(sprite, TFT_TRANSPARENT); - animate_performHappyAnimation(sprite, spriteData); - - if (frameCounter % 2 == 0) { - tone(SPK_PIN, 7500, 50); - tone(SPK_PIN, 5000, 50); - tone(SPK_PIN, 2500, 50); - tone(SPK_PIN, 1000, 50); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - draw_drawSprite(sprite, 18, 72, smallUiElements, FIREWORKS_ICON); - draw_drawSprite(sprite, 174, 72, smallUiElements, FIREWORKS_ICON); - } - - frameCounter++; - lastUpdateTime = currentTime; + draw_drawSprite(sprite, 18, 72, smallUiElements, FIREWORKS_ICON); + draw_drawSprite(sprite, 174, 72, smallUiElements, FIREWORKS_ICON); } - + + frameCounter++; + lastUpdateTime = currentTime; tft_drawBuffer(); } -} \ No newline at end of file +} diff --git a/src/menu/menu.h b/src/menu/menu.h index 52c4874..1701b0e 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -62,9 +62,10 @@ void menu_changeBackgroundScreen( ); void menu_settingsScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteData *spriteData); void menu_settingsScreen_drawEntry(uint8_t entryId, const char *textEntry); +void menu_resetDataScreen(TFT_eSprite &bg); void menu_sleepScreen_sleepAction(); void menu_sleepScreen_recalculateSleep(); void menu_freezeScreen_alternateFreeze(); -#endif \ No newline at end of file +#endif diff --git a/src/menu/menu_screen.cpp b/src/menu/menu_screen.cpp index a9440ed..0d22d2a 100644 --- a/src/menu/menu_screen.cpp +++ b/src/menu/menu_screen.cpp @@ -34,6 +34,9 @@ void menu_drawCurrentMenuOption(TFT_eSprite& bg, TFT_eSprite &icon, struct Sprit // Separaíto mas guapito if (pressedButtons == K2_PRESSED) { + const uint64_t currentTime = esp_timer_get_time(); + lastUpdateTime = currentTime; + switch (menuKey) { case STATUS_SCREEN_MENU: screenKey = STATUS_SCREEN; diff --git a/src/menu/poop_clean.cpp b/src/menu/poop_clean.cpp index c3c67ad..11a2fc6 100644 --- a/src/menu/poop_clean.cpp +++ b/src/menu/poop_clean.cpp @@ -9,51 +9,44 @@ void menu_clearPoopScreen( TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* spriteData, struct SpriteData* bigUiElements, struct SpriteData* smallUiElements ) { - printf("[AAAAAAA] pausing loop...\n"); + static bool initialized = false; + static int cleanerXPos = 174; - vTaskSuspend(secondLoop); + if (!initialized) { + cleanerXPos = 174; + lastUpdateTime = 0; - printf("[AAAAAAA] loop paused...\n"); + draw_drawBackground(bg, 90, 90, 3); + uint8_t offsetX = menu_poopOverlay(bg, sprite, smallUiElements); - int cleanerXPos = 174; + animate_performAnimation(sprite, spriteData, offsetX); + menu_uiOverlay(sprite, bigUiElements); + tft_clearBuffer(sprite, TFT_TRANSPARENT); - lastUpdateTime = 0; + initialized = true; + } - printf("[AAAAAAA] drawing idle screen...\n"); - - draw_drawBackground(bg, 90, 90, 3); - uint8_t offsetX = menu_poopOverlay(bg, sprite, smallUiElements); - - printf("[AAAAAAA] drawing animation...\n"); + if (cleanerXPos <= 18 - 48) { + screenKey = HAPPY_SCREEN; + menuKey = -1; + charaData[currentCharacter].poopNumber = 0; + initialized = false; - animate_performAnimation(sprite, spriteData, offsetX); + return; + } - printf("[AAAAAAA] drawing overlay...\n"); - - menu_uiOverlay(sprite, bigUiElements); - - printf("[AAAAAAA] idle screen down...\n"); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - - while (cleanerXPos > 18 - 48) { + uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastUpdateTime > 50000) { draw_drawBackgroundSection(bg, cleanerXPos + 6, 72, 48, 96); draw_drawSprite(sprite, cleanerXPos, 72, smallUiElements, CLEANER_ICON); draw_drawSprite(sprite, cleanerXPos, 120, smallUiElements, CLEANER_ICON); - + draw_drawBackgroundSection(bg, 0, 72, 18, 96); - + tft_drawBuffer(); - + cleanerXPos -= 6; + lastUpdateTime = currentTime; } - - screenKey = HAPPY_SCREEN; - menuKey = -1; - charaData[currentCharacter].poopNumber = 0; - - vTaskResume(secondLoop); - - return; -} \ No newline at end of file +} diff --git a/src/menu/poop_screen.cpp b/src/menu/poop_screen.cpp index 7d67451..92b5ad2 100644 --- a/src/menu/poop_screen.cpp +++ b/src/menu/poop_screen.cpp @@ -4,78 +4,72 @@ #include "display/display.h" #include "defs/defs.h" #include "defs/chara_data.h" +#include "defs/sounds.h" #include "defs/sprite_data.h" void menu_poopScreen( - TFT_eSprite &bg, TFT_eSprite &sprite, + TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* spriteData, struct SpriteData* smallUiElements, struct SpriteData* bigUiElements ) { - uint8_t animationFrame = 0; - bool animationPosition = 0; + static uint8_t animationFrame = 0; + static bool animationPosition = 0; + static bool beepedAlready = false; - bool beepedAlready = false; + uint64_t currentTime = esp_timer_get_time(); - while (1) { - uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US && animationFrame < 4) { + draw_drawBackground(bg, 90, 90, 3); - if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US && animationFrame < 4) { - draw_drawBackground(bg, 90, 90, 3); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - draw_drawSprite(sprite, 72 + (animationPosition * 6), 72, spriteData, 6); + tft_clearBuffer(sprite, TFT_TRANSPARENT); + draw_drawSprite(sprite, 72 + (animationPosition * 6), 72, spriteData, 6); - tft_clearBuffer(sprite, TFT_TRANSPARENT); - menu_uiOverlay(sprite, bigUiElements); - - animationFrame++; - animationPosition = !animationPosition; + tft_clearBuffer(sprite, TFT_TRANSPARENT); + menu_uiOverlay(sprite, bigUiElements); - lastUpdateTime = currentTime; + animationFrame++; + animationPosition = !animationPosition; - } else if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US && animationFrame < 6) { - if (!beepedAlready) { - tone(SPK_PIN, 2500, 50); - tone(SPK_PIN, 5000, 50); - tone(SPK_PIN, 2500, 50); - tone(SPK_PIN, 5000, 50); + lastUpdateTime = currentTime; + tft_drawBuffer(); - beepedAlready = true; - } + } else if (currentTime - lastUpdateTime > ANIMATION_THRESHOLD_TIME_US && animationFrame < 6) { + if (!beepedAlready) { + sound_playMelody(SOUND_POOP_DROP, SOUND_NOTE_COUNT(SOUND_POOP_DROP)); - draw_drawBackground(bg, 90, 90, 3); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - draw_drawSprite(sprite, 174, 120, smallUiElements, POOP_ICON); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - menu_uiOverlay(sprite, bigUiElements); - - tft_clearBuffer(sprite, TFT_TRANSPARENT); - draw_drawSprite(sprite, 72, 72, spriteData, 7); - - animationFrame++; - animationPosition = !animationPosition; - - lastUpdateTime = currentTime; - - } else if (animationFrame >= 6) { - if ( - (charaData[currentCharacter].hunger == 0 && !charaData[currentCharacter].hungerCareMistakeObtained) || - (charaData[currentCharacter].strength == 0 && !charaData[currentCharacter].strengthCareMistakeObtained) || - (charaData[currentCharacter].sleepy && !charaData[currentCharacter].asleep && !charaData[currentCharacter].sleepCareMistakeObtained) - ) { - screenKey = CARE_MISTAKE_SCREEN; - } else { - screenKey = MAIN_SCREEN; - } - - menuKey = -1; - animationFrame = 0; - animationPosition = 0; - - break; + beepedAlready = true; } + draw_drawBackground(bg, 90, 90, 3); + + tft_clearBuffer(sprite, TFT_TRANSPARENT); + draw_drawSprite(sprite, 174, 120, smallUiElements, POOP_ICON); + + tft_clearBuffer(sprite, TFT_TRANSPARENT); + menu_uiOverlay(sprite, bigUiElements); + + tft_clearBuffer(sprite, TFT_TRANSPARENT); + draw_drawSprite(sprite, 72, 72, spriteData, 7); + + animationFrame++; + animationPosition = !animationPosition; + + lastUpdateTime = currentTime; tft_drawBuffer(); + + } else if (animationFrame >= 6) { + if ( + (charaData[currentCharacter].hunger == 0 && !charaData[currentCharacter].hungerCareMistakeObtained) || + (charaData[currentCharacter].strength == 0 && !charaData[currentCharacter].strengthCareMistakeObtained) || + (charaData[currentCharacter].sleepy && !charaData[currentCharacter].asleep && !charaData[currentCharacter].sleepCareMistakeObtained) + ) { + screenKey = CARE_MISTAKE_SCREEN; + } else { + screenKey = MAIN_SCREEN; + } + + menuKey = -1; + animationFrame = 0; + animationPosition = 0; + beepedAlready = false; } -} \ No newline at end of file +} diff --git a/src/menu/refuse_screen.cpp b/src/menu/refuse_screen.cpp index e5c5154..06fa334 100644 --- a/src/menu/refuse_screen.cpp +++ b/src/menu/refuse_screen.cpp @@ -3,6 +3,7 @@ #include "draw/draw.h" #include "display/display.h" #include "defs/defs.h" +#include "defs/sounds.h" #include "defs/sprite_data.h" #include "animations/animations.h" @@ -34,8 +35,7 @@ void menu_refuseScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteDat } if (!soundPlayed) { - tone(SPK_PIN, 3000, 100); - tone(SPK_PIN, 1000, 100); + sound_playMelody(SOUND_REFUSE, SOUND_NOTE_COUNT(SOUND_REFUSE)); soundPlayed = true; } @@ -47,4 +47,4 @@ void menu_refuseScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteDat } tft_drawBuffer(); -} \ No newline at end of file +} diff --git a/src/menu/reset_data_screen.cpp b/src/menu/reset_data_screen.cpp new file mode 100644 index 0000000..aa438d1 --- /dev/null +++ b/src/menu/reset_data_screen.cpp @@ -0,0 +1,65 @@ +#include + +#include "buttons/buttons.h" +#include "defs/defs.h" +#include "display/display.h" +#include "draw/draw.h" +#include "menu.h" +#include "storage/storage.h" + +void menu_resetDataScreen(TFT_eSprite &bg) { + static uint8_t selectedOption = 0; + + uint8_t pressedButtons = buttons_getPressedButtons(); + switch (pressedButtons) { + case K1_PRESSED: + selectedOption = (selectedOption + 1) % 2; + break; + + case K2_PRESSED: + if (selectedOption == 1) { + draw_drawBackground(bg, 90, 90, 3); + tft_drawCenteredText("RESETTING", 3, 104); + tft_drawBuffer(); + + if (storage_deleteState()) { + ESP.restart(); + } + + draw_drawBackground(bg, 90, 90, 3); + tft_drawCenteredText("FAILED", 4, 95); + tft_drawBuffer(); + return; + } + + selectedOption = 0; + screenKey = SETTINGS_SCREEN; + return; + + case K3_PRESSED: + selectedOption = 0; + screenKey = SETTINGS_SCREEN; + return; + + default: + break; + } + + draw_drawBackground(bg, 90, 90, 3); + + tft_drawCenteredText("RESET DATA?", 3, 35); + + const char* labels[] = { "NO", "YES" }; + const int startX = 72; + const int startY = 95; + const int spacingY = 42; + + for (uint8_t i = 0; i < 2; i++) { + bool selected = (i == selectedOption); + int y = startY + (i * spacingY); + + tft_drawText(labels[i], 4, startX, y, selected ? TFT_BLACK : TFT_WHITE, selected ? TFT_WHITE : TFT_TRANSPARENT); + } + + tft_drawBuffer(); +} diff --git a/src/menu/settings_screen.cpp b/src/menu/settings_screen.cpp index 306c57c..4395218 100644 --- a/src/menu/settings_screen.cpp +++ b/src/menu/settings_screen.cpp @@ -43,7 +43,8 @@ void menu_settingsScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteD static SettingsMenuItem menuItems[] = { { "BG", SETTINGS_SUBMENU, BACKGROUND_CHANGE_SCREEN, nullptr, nullptr }, { "SOUND", SETTINGS_ACTION, 0, switchSoundState, &soundEnabled }, - { "ALWAYS ON", SETTINGS_ACTION, 0, switchScreenState, &alwaysOnEnabled } + { "AOD", SETTINGS_ACTION, 0, switchScreenState, &alwaysOnEnabled }, + { "RESET", SETTINGS_SUBMENU, RESET_DATA_SCREEN, nullptr, nullptr } }; const uint8_t maxItems = sizeof(menuItems) / sizeof(menuItems[0]); @@ -98,4 +99,4 @@ void menu_settingsScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteD } tft_drawBuffer(); -} \ No newline at end of file +} diff --git a/src/menu/sleep_screen.cpp b/src/menu/sleep_screen.cpp index ddb8050..0c116a7 100644 --- a/src/menu/sleep_screen.cpp +++ b/src/menu/sleep_screen.cpp @@ -5,6 +5,7 @@ #include "buttons/buttons.h" #include "animations/animations.h" #include "defs/chara_data.h" +#include "defs/sounds.h" void menu_sleepyScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* charaSprites, struct SpriteData* uiSprites) { if (!charaData[currentCharacter].asleep && !charaData[currentCharacter].sleepy) { @@ -45,8 +46,7 @@ void menu_sleepyScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* } if (currentTime - lastBeepTime > ANIMATION_THRESHOLD_TIME_US * 2 && beepCounter < 10) { - tone(SPK_PIN, 2500, 100); - tone(SPK_PIN, 5000, 100); + sound_playMelody(SOUND_CARE_ALERT, SOUND_NOTE_COUNT(SOUND_CARE_ALERT)); lastBeepTime = currentTime; diff --git a/src/menu/status_screen.cpp b/src/menu/status_screen.cpp index da72b4d..b50b2bb 100644 --- a/src/menu/status_screen.cpp +++ b/src/menu/status_screen.cpp @@ -41,7 +41,7 @@ void menu_statusScreen_drawStat(TFT_eSprite &sprite, struct SpriteData* spriteDa draw_drawSprite( sprite, - 15 + (i * 32), + 15 + (i * 48), y + 30, spriteData, icon, diff --git a/src/menu/title_screen.cpp b/src/menu/title_screen.cpp index 0b43e96..39deca9 100644 --- a/src/menu/title_screen.cpp +++ b/src/menu/title_screen.cpp @@ -11,6 +11,11 @@ void menu_drawTitle(TFT_eSprite &bg, TFT_eSprite &composite) { return; } + uint64_t currentTime = esp_timer_get_time(); + if (currentTime - lastUpdateTime < 200000) { + return; + } + draw_drawBackground(bg, 90, 90, 3); tft_drawCenteredText("NacaPet", 4, 40); @@ -18,6 +23,5 @@ void menu_drawTitle(TFT_eSprite &bg, TFT_eSprite &composite) { tft_drawCenteredText(VERSION, 2, 80); tft_drawBuffer(); - - delay(200); -} \ No newline at end of file + lastUpdateTime = currentTime; +} diff --git a/src/menu/training/training_screen1.cpp b/src/menu/training/training_screen1.cpp index 9c4e7fd..7c4fbb4 100644 --- a/src/menu/training/training_screen1.cpp +++ b/src/menu/training/training_screen1.cpp @@ -1,6 +1,7 @@ #include "vpet/training/training.h" #include "defs/defs.h" #include "defs/chara_data.h" +#include "defs/sounds.h" #include "defs/sprite_data.h" #include "buttons/buttons.h" #include "display/display.h" @@ -15,9 +16,8 @@ void training_screenTraining1( draw_drawBackground(bg, 90, 90, 3); draw_drawSpriteCentered(sprite, mainCharaData, 11); - - tone(SPK_PIN, 4100, 100); - tone(SPK_PIN, 3500, 100); + + sound_playMelody(SOUND_TRAINING_START, SOUND_NOTE_COUNT(SOUND_TRAINING_START)); tft_drawBuffer(); @@ -76,4 +76,4 @@ void training_screenTraining1( } training_displayTrainingResult(bg, sprite, mainCharaData, attackSprites, attackResult); -} \ No newline at end of file +} diff --git a/src/menu/training_screen2.cpp b/src/menu/training_screen2.cpp index a95aeb1..02cb712 100644 --- a/src/menu/training_screen2.cpp +++ b/src/menu/training_screen2.cpp @@ -2,6 +2,7 @@ #include "vpet/training/training.h" #include "defs/defs.h" #include "defs/chara_data.h" +#include "defs/sounds.h" #include "draw/draw.h" #include "display/display.h" #include "buttons/buttons.h" @@ -10,87 +11,98 @@ void training_screenTraining2( TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* mainCharaData, struct SpriteData* attackSprites ) { - vTaskSuspend(secondLoop); + enum TrainingState { + TRAINING_INIT, + TRAINING_WAIT_INPUT, + TRAINING_SHOW_BOTH, + TRAINING_SHOW_HIT + }; - draw_drawBackground(bg, 90, 90 ,3); - - // Player - draw_drawSprite(sprite, 174, 72, mainCharaData, 0, false); - draw_drawBackgroundSection(bg, 222, 72, 18, 96); + static TrainingState state = TRAINING_INIT; + static uint64_t inactivityTimer = 0; + static uint64_t stageStartTime = 0; + static uint8_t randomPosition = 0; + static uint8_t projectilePosition = 0; - // Opponent - draw_drawSprite(sprite, -30, 72, mainCharaData, 0, true); - draw_drawBackgroundSection(bg, 0, 72, 18, 96); + uint64_t currentTime = esp_timer_get_time(); - tft_drawBuffer(); + if (state == TRAINING_INIT) { + draw_drawBackground(bg, 90, 90 ,3); - uint64_t inactivityTimer = esp_timer_get_time(); - while (true) { - uint64_t currentTime = esp_timer_get_time(); - if (currentTime - lastUpdateTime > 500000) { - tone(SPK_PIN, BEEP_FREQ_HZ, BEEP_LEN_MS); - lastUpdateTime = currentTime; - } + // Player + draw_drawSprite(sprite, 174, 72, mainCharaData, 0, false); + draw_drawBackgroundSection(bg, 222, 72, 18, 96); + // Opponent + draw_drawSprite(sprite, -30, 72, mainCharaData, 0, true); + draw_drawBackgroundSection(bg, 0, 72, 18, 96); + + tft_drawBuffer(); + + inactivityTimer = currentTime; + state = TRAINING_WAIT_INPUT; + return; + } + + if (currentTime - lastUpdateTime > 500000) { + sound_playMelody(SOUND_BUTTON_BEEP, SOUND_NOTE_COUNT(SOUND_BUTTON_BEEP)); + lastUpdateTime = currentTime; + } + + if (state == TRAINING_WAIT_INPUT) { if (currentTime - inactivityTimer > 3000000) { screenKey = MAIN_SCREEN; submenuKey = STATUS_SCREEN_MENU; - - vTaskResume(secondLoop); - - return; - } - - uint8_t randomPosition = rand() % 2; - uint8_t projectilePosition = 0; - - uint8_t pressedButtons = buttons_getPressedButtons(); - if (pressedButtons == K1_PRESSED || pressedButtons == K2_PRESSED) { - projectilePosition = pressedButtons >> 3; // pressedButtons >> 4 == 1 => K1; != 1 => K2 - printf("[TRAIN] projectilePosition=%i\n", projectilePosition); - - } else if (pressedButtons == K3_PRESSED) { - screenKey = MAIN_SCREEN; - submenuKey = STATUS_SCREEN_MENU; - - vTaskResume(secondLoop); - + state = TRAINING_INIT; return; } - if (pressedButtons != 0) { - inactivityTimer = esp_timer_get_time(); + uint8_t pressedButtons = buttons_getPressedButtons(); + if (pressedButtons == K1_PRESSED || pressedButtons == K2_PRESSED) { + randomPosition = rand() % 2; + projectilePosition = pressedButtons >> 3; // pressedButtons >> 4 == 1 => K1; != 1 => K2 + printf("[TRAIN] projectilePosition=%i\n", projectilePosition); + + inactivityTimer = currentTime; // Player attack draw_drawSprite(sprite, 126, 72 + 48 * projectilePosition, attackSprites, POOP_ICON); - + // Opponent attack draw_drawSprite(sprite, 66, 72 + 48 * randomPosition, attackSprites, FOOD_ICON); tft_drawBuffer(); - if (projectilePosition != randomPosition) { - delay(500); + stageStartTime = currentTime; + state = TRAINING_SHOW_BOTH; - draw_drawBackgroundSection(bg, 126, 72 + 48 * projectilePosition, 48, 48); - draw_drawSprite(sprite, 66, 72 + 48 * projectilePosition, attackSprites, POOP_ICON); - - tft_drawBuffer(); - - delay(500); - } else { - delay(500); - } - - draw_drawBackgroundSection(bg, 66, 72, 108, 96); - - if (projectilePosition != randomPosition) { - charaData[currentCharacter].strength++; - menu_drawHappyScreen(bg, sprite, mainCharaData, attackSprites); - } else { - printf("[TRAIN] Train failed\n"); - menu_drawAngryScreen(bg, sprite, mainCharaData, attackSprites); - } + } else if (pressedButtons == K3_PRESSED) { + screenKey = MAIN_SCREEN; + submenuKey = STATUS_SCREEN_MENU; + state = TRAINING_INIT; + return; } + } else if (state == TRAINING_SHOW_BOTH && currentTime - stageStartTime > 500000) { + if (projectilePosition != randomPosition) { + draw_drawBackgroundSection(bg, 126, 72 + 48 * projectilePosition, 48, 48); + draw_drawSprite(sprite, 66, 72 + 48 * projectilePosition, attackSprites, POOP_ICON); + + tft_drawBuffer(); + + stageStartTime = currentTime; + state = TRAINING_SHOW_HIT; + } else { + draw_drawBackgroundSection(bg, 66, 72, 108, 96); + tft_drawBuffer(); + printf("[TRAIN] Train failed\n"); + screenKey = ANGRY_SCREEN; + state = TRAINING_INIT; + } + } else if (state == TRAINING_SHOW_HIT && currentTime - stageStartTime > 500000) { + draw_drawBackgroundSection(bg, 66, 72, 108, 96); + tft_drawBuffer(); + charaData[currentCharacter].strength++; + screenKey = HAPPY_SCREEN; + state = TRAINING_INIT; } -} \ No newline at end of file +} diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index fb92a9d..eb26a82 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -218,4 +218,21 @@ void storage_loadState() { storage_readFile(spriteFileName, &mainCharacterSprites); printf("%s Load completed!\n", TAG_S); -} \ No newline at end of file +} + +bool storage_deleteState() { + const char* savePath = "/save.bin"; + + if (!SPIFFS.exists(savePath)) { + printf("%s Save file already deleted.\n", TAG_S); + return true; + } + + if (!SPIFFS.remove(savePath)) { + printf("%s Failed to delete save file.\n", TAG_S); + return false; + } + + printf("%s Save file deleted.\n", TAG_S); + return true; +} diff --git a/src/storage/storage.h b/src/storage/storage.h index 7573d71..97f13ef 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -13,5 +13,6 @@ void storage_initBackground(const int id, TFT_eSprite &bg); void storage_saveState(); void storage_loadState(); +bool storage_deleteState(); -#endif \ No newline at end of file +#endif diff --git a/src/vpet/training/training_resultScreen.cpp b/src/vpet/training/training_resultScreen.cpp index ec4ce52..3d4cf24 100644 --- a/src/vpet/training/training_resultScreen.cpp +++ b/src/vpet/training/training_resultScreen.cpp @@ -2,6 +2,7 @@ #include "draw/draw.h" #include "defs/defs.h" #include "defs/chara_data.h" +#include "defs/sounds.h" #include "defs/sprite_data.h" #include "display/display.h" @@ -100,20 +101,5 @@ void training_displayTrainingResult( // nOT FANCY void training_trainingAttackSounds() { - tone(SPK_PIN, 4100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 4100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 4100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 4100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 3100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 3100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 3100, 25); - tone(SPK_PIN, 3700, 25); - tone(SPK_PIN, 3100, 25); -} \ No newline at end of file + sound_playMelody(SOUND_TRAINING_ATTACK, SOUND_NOTE_COUNT(SOUND_TRAINING_ATTACK)); +}