Evolucion funciona

Chupate esa, compilador de C
This commit is contained in:
Nacho 2025-05-31 00:10:40 +02:00
parent ef52dba409
commit 1938a57102
20 changed files with 378 additions and 110 deletions

View File

@ -92,6 +92,7 @@
#define EGG_SELECT_SCREEN 5
#define EGG_HATCH_SCREEN 6
#define EGG_EMPTY_SCREEN 7
#define EVOLUTION_SCREEN 8
#define FEEDING_SCREEN 20
#define REFUSING_SCREEN 21
#define SLEEPY_SCREEN 22
@ -150,7 +151,6 @@ extern bool k4_prev;
extern bool inactive;
extern bool screenOff;
extern bool skipSleep;
extern uint64_t lastPressedButtonTime;
extern uint64_t lastUpdateTime;
@ -164,6 +164,7 @@ extern ESP32Time rtc;
extern MPU6050 mpu;
extern hw_timer_t *actionTimerDelta;
extern TaskHandle_t secondLoop;
extern bool runVpetTasks;
@ -184,4 +185,6 @@ extern Line_t** currentLine;
extern struct SpriteData mainCharacterSprites;
extern bool pauseLoop;
#endif

View File

@ -73,3 +73,8 @@ void tft_drawText(const char* text, uint8_t size, uint8_t x, uint8_t y, uint16_t
composite2.setTextColor(color);
composite2.drawString(text, x, y - BUF_H);
}
void tft_drawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t color) {
composite1.fillRect(x, y, w, h, color);
composite2.fillRect(x, y - BUF_H, w, h, color);
}

View File

@ -13,5 +13,6 @@ void tft_clearBuffer(TFT_eSprite &buffer, uint16_t color = TFT_WHITE);
void tft_clearBuffer(uint16_t color = TFT_WHITE);
void tft_drawCenteredText(const char* text, int factor, int y);
void tft_drawText(const char* text, uint8_t size, uint8_t x, uint8_t y, uint16_t color = TFT_BLACK);
void tft_drawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t color = TFT_BLACK);
#endif

View File

@ -0,0 +1,26 @@
#include "energy.h"
#include <Arduino.h>
#include "defs/defs.h"
#include "display/display.h"
#include "driver/rtc_io.h"
#include "defs/screen_defs.h"
#define SLEEP_TIME_US 15000000ull
#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO) // Macro for individual GPIO bitmask
void energy_setUpLightSleep() {
// Plena confianza en manolo
esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, 0);
esp_sleep_enable_timer_wakeup(SLEEP_TIME_US);
}
void energy_startLightSleep() {
esp_light_sleep_start();
// Who woke you up???? TELL me!!
auto cause = esp_sleep_get_wakeup_cause();
runVpetTasks = true;
}

View File

@ -1,48 +0,0 @@
#include "energy.h"
#include <Arduino.h>
#include "defs/defs.h"
#include "display/display.h"
#include "driver/rtc_io.h"
#include "defs/screen_defs.h"
#define SLEEP_TIME_US 15000000ull
#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO) // Macro for individual GPIO bitmask
void energy_setUpLightSleep() {
// Enable EXT1 wake-up source
esp_err_t result = esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, 0);
if (result == ESP_OK) {
Serial.println("EXT1 Wake-Up set successfully.");
} else {
Serial.println("Failed to set EXT1 Wake-Up as wake-up source.");
}
esp_sleep_enable_timer_wakeup(SLEEP_TIME_US);
}
void energy_startLightSleep() {
if (skipSleep) {
skipSleep = false;
return;
}
esp_light_sleep_start();
// 6) Figure out which woke you
auto cause = esp_sleep_get_wakeup_cause();
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
Serial.println("Woke by button on GPIO");
} else if (cause == ESP_SLEEP_WAKEUP_TIMER) {
Serial.println("Woke by timer");
} else {
Serial.printf("Other wakeup: %d\n", cause);
}
runVpetTasks = true;
byte pinValue = digitalRead(26);
Serial.println(pinValue);
}

View File

@ -8,7 +8,7 @@
#include "defs/chara_data.h"
#include "menu/menu.h"
#include "buttons/buttons.h"
#include "vpet/vpet.h"
#include "vpet/vpet/vpet.h"
#include "vpet/steps/steps.h"
#include "vpet/lines/lines.h"
#include "energy/energy.h"
@ -63,13 +63,10 @@ uint8_t eggNumber = 0;
// Tasks
TaskHandle_t secondLoop = NULL;
TaskHandle_t readSteps = NULL;
bool skipSleep = false;
bool pauseLoop = false;
void loop2();
void secondCoreTask(void*);
void loop_readSteps(void*);
void setup() {
Serial.begin(115200);
@ -184,6 +181,10 @@ void loop() {
case EGG_EMPTY_SCREEN:
menu_drawDeathScreen( bg, sprite, &menuElementsData, &uiElementsData);
break;
case EVOLUTION_SCREEN:
menu_evolutionScreen(bg, sprite, &mainCharacterSprites);
break;
}
if (screenKey == IDLE_SCREEN || screenKey == OFF_SCREEN) {
@ -192,19 +193,23 @@ void loop() {
}
void loop2() {
if (!pauseLoop) {
buttons_checkInactivity();
vpet_runVpetTasks();
getLocalTime(&timeInfo, 50);
dayUnixTime = mktime(&timeInfo) % SECONDS_IN_DAY;
if (screenOff && !skipSleep) {
energy_startLightSleep();
} else if (screenOff && skipSleep) {
skipSleep = false;
if (screenOff) { energy_startLightSleep(); }
} else {
lastPressedButtonTime = esp_timer_get_time();
buttons_getPressedButtons();
}
}
void secondCoreTask(void*) {
for (;;) { loop2(); }
for (;;) {
loop2();
}
}

156
src/menu/change_screen.cpp Normal file
View File

@ -0,0 +1,156 @@
#include "menu.h"
#include "draw/draw.h"
#include "display/display.h"
#include "defs/screen_defs.h"
#include "vpet/evolution/evolution.h"
struct SpriteData* checkerboardPattern;
void menu_createCheckerboard() {
checkerboardPattern = (SpriteData*) malloc(sizeof(SpriteData));
checkerboardPattern->spriteHeight = 1;
checkerboardPattern->spriteWidth = 34;
checkerboardPattern->spriteNumber = 1;
checkerboardPattern->spriteData = (uint16_t**) malloc(sizeof(uint16_t*) * checkerboardPattern->spriteNumber);
checkerboardPattern->spriteData[0] = (uint16_t*) malloc(sizeof(uint16_t) * checkerboardPattern->spriteWidth);
for (int i = 0; i < checkerboardPattern->spriteWidth; i++) {
if (i % 2 == 0) {
checkerboardPattern->spriteData[0][i] = TFT_BLACK;
} else {
checkerboardPattern->spriteData[0][i] = TFT_TRANSPARENT;
}
}
}
void menu_freeCheckerboard() {
free(checkerboardPattern->spriteData[0]);
free(checkerboardPattern->spriteData);
free(checkerboardPattern);
}
// 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);
bool checkerboardShift = false;
tft_clearBuffer(sprite, TFT_TRANSPARENT);
for (int i = 0; i < 5;) {
uint64_t currentTime = esp_timer_get_time();
if (currentTime - lastUpdateTime > 500000) {
tone(SPK_PIN, 4100, 50);
tone(SPK_PIN, 3500, 50);
draw_drawBackground(bg, 90, 90, 3);
draw_drawSprite(sprite, 72 + ((i % 2 == 0) * 6), 72, mainCharacterSprites, 6, 6);
tft_drawBuffer();
i++;
lastUpdateTime = currentTime;
}
}
draw_drawBackground(bg, 90, 90, 3);
draw_drawSprite(sprite, 72, 72, mainCharacterSprites, 7, 6);
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);
tft_drawRectangle(18, startYPos, 204, 6, TFT_RED);
draw_drawSprite(checkerboard, 18, startYPos, checkerboardPattern, 0, 6, checkerboardShift);
tft_drawBuffer();
checkerboardShift = !checkerboardShift;
i++;
lastUpdateTime = currentTime;
}
}
for (int i = 0; i < 16;) {
uint64_t currentTime = esp_timer_get_time();
if (currentTime - lastUpdateTime > 100000) {
uint8_t startYPos = 72 + (i * 6);
tft_drawRectangle(18, startYPos, 204, 6, TFT_BLACK);
tft_drawBuffer();
checkerboardShift = !checkerboardShift;
i++;
lastUpdateTime = currentTime;
}
}
change_onChangeComplete();
for (int i = 15; i >= 0;) {
uint64_t currentTime = esp_timer_get_time();
if (currentTime - lastUpdateTime > 100000) {
uint8_t startYPos = 72 + (i * 6);
tft_drawRectangle(18, startYPos, 204, 6, TFT_GREEN);
draw_drawSprite(checkerboard, 18, startYPos, checkerboardPattern, 0, 6, checkerboardShift);
tft_drawBuffer();
checkerboardShift = !checkerboardShift;
i--;
lastUpdateTime = currentTime;
}
}
for (int i = 15; i >= 0;) {
uint64_t currentTime = esp_timer_get_time();
if (currentTime - lastUpdateTime > 100000) {
draw_drawBackground(bg, 90, 90, 3);
draw_drawSprite(sprite, 72, 72, mainCharacterSprites, 7, 6);
uint8_t rectHeight = (6 * i);
tft_drawRectangle(18, 72, 204, rectHeight, TFT_GREEN);
for (int j = 0; j < i; j++) {
uint8_t rectYPos = 72 + (6 * j);
draw_drawSprite(checkerboard, 18, rectYPos, checkerboardPattern, 0, 6, checkerboardShift);
checkerboardShift = !checkerboardShift;
}
tft_drawBuffer();
i--;
lastUpdateTime = currentTime;
}
}
tone(SPK_PIN, 2100, 100);
tone(SPK_PIN, 3500, 100);
tone(SPK_PIN, 4100, 100);
tone(SPK_PIN, 4650, 200);
lastPressedButtonTime = esp_timer_get_time();
menu_freeCheckerboard();
pauseLoop = false;
screenKey = IDLE_SCREEN;
lastUpdateTime = 0; // Un pequeño empujoncito
}

View File

@ -3,7 +3,6 @@
#include "draw/draw.h"
#include "display/display.h"
#include "buttons/buttons.h"
#include "vpet/vpet.h"
#include "defs/screen_defs.h"
void menu_drawClock(TFT_eSprite &bg) {

View File

@ -6,19 +6,14 @@
#include "defs/sprite_data.h"
#include "defs/chara_data.h"
#include "animations/animations.h"
#include "vpet/vpet.h"
#include "vpet/vpet/vpet.h"
#include "vpet/lines/lines.h"
void menu_eggHatchScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiBigSprite, struct SpriteData* uiSmallSprite) {
static bool eggSpriteFrame = false;
uint8_t frameCounter = 0;
uint8_t pressedButtons = buttons_getPressedButtons();
switch (pressedButtons) {
case K3_PRESSED:
case K1_PRESSED:
break;
case K2_PRESSED:
screenKey = CLOCK_SCREEN;
break;
@ -51,6 +46,7 @@ void menu_eggHatchScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData
}
draw_drawBackground(bg, 90, 90, 3);
draw_drawSpriteCentered(sprite, &currentEgg->eggSprite, 2, 6);
tft_drawBuffer();
@ -59,11 +55,6 @@ void menu_eggHatchScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData
lines_onHatchComplete();
vpet_computeCallLight();
interruptKey = CARE_MISTAKE_SCREEN;
screenKey = TIMER_FINISHED_SCREEN;
return;
}
}

View File

@ -1,12 +1,12 @@
#include "menu.h"
#include "draw/draw.h"
#include "defs/defs.h"
#include "vpet/vpet.h"
#include "display/display.h"
#include "defs/sprite_data.h"
#include "buttons/buttons.h"
#include "vpet/lines/lines.h"
#include "defs/chara_data.h"
#include "vpet/vpet/vpet.h"
void menu_lineSwitcher(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiSmallSprite) {

View File

@ -3,7 +3,7 @@
#include "draw/draw.h"
#include "buttons/buttons.h"
#include "defs/chara_data.h"
#include "vpet/vpet.h"
#include "vpet/vpet/vpet.h"
void menu_foodScreen(TFT_eSprite &bg, TFT_eSprite &mainChara, struct SpriteData* spriteData) {
if (charaData.sleepy) {

View File

@ -44,6 +44,7 @@ void menu_lineSwitcher(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData*
void menu_eggHatchScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiBigSprite, struct SpriteData* uiSmallSprite);
void menu_reloadEggs(uint8_t selectedEgg);
void menu_drawDeathScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiBigSprite, struct SpriteData* uiSmallSprite);
void menu_evolutionScreen(TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* mainCharacterSprites);
void menu_sleepScreen_sleepAction();
void menu_sleepScreen_recalculateSleep();

View File

@ -5,7 +5,8 @@
#include "defs/sprite_data.h"
#include "defs/chara_data.h"
#include "buttons/buttons.h"
#include "vpet/vpet.h"
#include "vpet/vpet/vpet.h"
#include <string.h>
const int textXPos = 10;

View File

@ -0,0 +1,88 @@
#include "defs/defs.h"
#include "defs/chara_data.h"
#include "evolution.h"
#include "storage/storage.h"
bool change_onChangeTimerComplete() {
for (int i = 0; i < currentLineCareInstr[currentCharacter]->numCareMistakesData; i++) {
if (
charaData.idChara == currentLineCareInstr[currentCharacter]->careMistakeData[i].currentChara &&
change_evalCharacter(i)
) {
change_replaceCharaData(currentLineCareInstr[currentCharacter]->careMistakeData[i].nextChara);
change_resetRuntimeStats();
return true;
}
}
return false;
}
bool change_evalCharacter(uint8_t nextCharaId) {
CareMistakes_t* currentEvalCharacter = &(currentLineCareInstr[currentCharacter]->careMistakeData[nextCharaId]);
printf("[EVAL] cm=%i, of=%i, sd=%i, ef=%i\n", charaData.careMistakes, charaData.overfeed, charaData.sleepDisturbances, charaData.effort);
printf("[EVAL] MIN cm=%i, of=%i, sd=%i, ef=%i\n", currentEvalCharacter->minCareMistake, currentEvalCharacter->minOverfeeds, currentEvalCharacter->minSleepDist, currentEvalCharacter->minTraining);
printf("[EVAL] MAX cm=%i, of=%i, sd=%i, ef=%i\n", currentEvalCharacter->maxCareMistake, currentEvalCharacter->maxOverfeeds, currentEvalCharacter->maxSleepDist, currentEvalCharacter->maxTraining);
printf("[EVAL] stb=%i stw=%i\n", charaData.stageTotalBattled, charaData.stageTotalWon);
printf("[EVAL] MIN stb=%i stw=%i\n", currentEvalCharacter->totalBattles, currentEvalCharacter->wonBattles);
printf("[EVAL] NextID=%i\n", currentEvalCharacter->nextChara);
bool retV = (
(charaData.careMistakes >= currentEvalCharacter->minCareMistake) &&
(charaData.careMistakes <= currentEvalCharacter->maxCareMistake) &&
(charaData.overfeed >= currentEvalCharacter->minOverfeeds) &&
(charaData.overfeed <= currentEvalCharacter->maxOverfeeds) &&
(charaData.sleepDisturbances >= currentEvalCharacter->minSleepDist) &&
(charaData.sleepDisturbances <= currentEvalCharacter->maxSleepDist) &&
(charaData.effort >= currentEvalCharacter->minTraining) &&
(charaData.effort <= currentEvalCharacter->maxTraining) &&
(charaData.stageTotalBattled >= currentEvalCharacter->totalBattles) &&
(charaData.stageTotalWon >= currentEvalCharacter->wonBattles)
);
printf("[EVAL] Res %i\n", retV);
return retV;
}
void change_replaceCharaData(uint8_t nextCharaId) {
LineChara_t* currentEvalCharacter = &(currentLine[currentCharacter]->characters[nextCharaId]);
charaData.idChara = nextCharaId;
charaData.hp = currentEvalCharacter->hp;
charaData.bp = currentEvalCharacter->bp;
charaData.ap = currentEvalCharacter->ap;
charaData.stage = currentEvalCharacter->stage;
charaData.attribute = currentEvalCharacter->attribute;
charaData.initialSleepTime = currentEvalCharacter->sleepTime;
charaData.initialWakeupTime = currentEvalCharacter->wakeTime;
charaData.initialChangeTimer = currentEvalCharacter->changeTime;
charaData.initialStatsReductionTime = currentEvalCharacter->depleteTime;
charaData.minWeight = currentEvalCharacter->minWeight;
}
void change_resetRuntimeStats() {
charaData.careMistakes = 0;
charaData.effort = 0;
charaData.overfeed = 0;
charaData.sleepDisturbances = 0;
charaData.injuries = 0;
charaData.stageTotalBattled = 0;
charaData.stageTotalWon = 0;
charaData.dynamicSleepDists = 0;
charaData.sleepTime = charaData.initialSleepTime;
charaData.wakeupTime = charaData.initialWakeupTime;
charaData.changeTimerLeft = charaData.initialChangeTimer;
}
void change_onChangeComplete() {
char spriteFileName[30];
snprintf(spriteFileName, 30, "/chara/%02x.bin", charaData.idChara);
storage_readFile(spriteFileName, &mainCharacterSprites);
}

View File

@ -0,0 +1,12 @@
#ifndef EVOLUTION_H
#define EVOLUTION_H
#include <stdint.h>
bool change_onChangeTimerComplete();
bool change_evalCharacter(uint8_t nextCharaId);
void change_replaceCharaData(uint8_t nextCharaId);
void change_resetRuntimeStats();
void change_onChangeComplete();
#endif

View File

@ -2,7 +2,7 @@
#include "defs/defs.h"
#include "defs/chara_data.h"
#include "storage/storage.h"
#include "vpet/vpet.h"
#include "vpet/vpet/vpet.h"
void lines_onHatchComplete() {
// Cuando se nace, lo que se va a hacer es poner el sprite 0, es decir,
@ -34,4 +34,11 @@ void lines_onHatchComplete() {
charaData.strengthCareMistakeTimer = CARE_MISTAKE_COUNTER_MAX;
charaData.hatched = true;
vpet_computeCallLight();
interruptKey = CARE_MISTAKE_SCREEN;
screenKey = TIMER_FINISHED_SCREEN;
}

View File

@ -1,6 +1,7 @@
#include "vpet.h"
#include "defs/defs.h"
#include "defs/chara_data.h"
#include "vpet/evolution/evolution.h"
hw_timer_t *actionTimerDelta = NULL;
bool runVpetTasks = false;
@ -61,9 +62,6 @@ bool vpet_evalSleep(uint8_t diff_sec) {
// Resultado, el personaje deberia de dormir una siesta
) {
charaData.sleepCareMistakeCounter += diff_sec;
if (charaData.hungerCareMistakeTimer <= 0) {
skipSleep = true;
}
return true;
@ -161,6 +159,10 @@ void vpet_reduceTimers(uint8_t diff_sec) {
if (charaData.strengthCareMistakeTimer > 0) {
charaData.strengthCareMistakeTimer -= diff_sec;
}
if (charaData.changeTimerLeft > 0) {
charaData.changeTimerLeft -= diff_sec;
}
}
void vpet_evalHungerTimer() {
@ -225,26 +227,60 @@ void vpet_evalStrengthTimer() {
}
}
void vpet_evalChangeTimer() {
if (charaData.changeTimerLeft <= 0) {
if (change_onChangeTimerComplete()) {
screenKey = TIMER_FINISHED_SCREEN;
interruptKey = EVOLUTION_SCREEN;
pauseLoop = true;
}
}
}
void IRAM_ATTR onActionTimerDelta() {
runVpetTasks = true;
}
void vpet_runVpetTasks() {
if (runVpetTasks && charaData.hatched) {
if (runVpetTasks) {
uint64_t currentEvaluationTime = esp_timer_get_time();
uint64_t deltaUs = currentEvaluationTime - vpetLastEvaluationTime;
printf("[DELTA] deltaUpdate=%lu\n", deltaUs);
uint8_t diffSec = (deltaUs + 1000000 - 1000) / 1000000; // round up
printf("[DEBUG] diffSec=%i\n", diffSec);
uint8_t diffSec = (deltaUs + 1000000 - 1000) / 1000000;
if (charaData.hatched) {
vpet_computeCallLight();
if (!vpet_evalSleep(diffSec)) {
vpet_reduceTimers(diffSec);
vpet_evalTimers();
}
vpet_evalChangeTimer();
} else if (!charaData.hatched && charaData.hatching) {
charaData.hatchTimer += diffSec;
if (charaData.hatchTimer > currentLine[currentCharacter]->hatchTime) {
interruptKey = EGG_HATCH_SCREEN;
screenKey = TIMER_FINISHED_SCREEN;
}
}
vpet_debugTimers(diffSec);
runVpetTasks = false;
vpetLastEvaluationTime = currentEvaluationTime;
}
}
void vpet_debugTimers(uint8_t diffSec) {
printf("[DEBUG] diffSec=%i\n", diffSec);
if (charaData.hatched) {
printf("[MAIN]: Hunger timer %d, hunger %d\n", charaData.hungerCareMistakeTimer, charaData.hunger);
printf("[MAIN]: Strength timer %d, strength %d\n", charaData.strengthCareMistakeTimer, charaData.strength);
printf("[MAIN]: Change timer %d\n", charaData.changeTimerLeft);
@ -252,24 +288,8 @@ void vpet_runVpetTasks() {
printf("[MAIN]: Sleep counter is %d\n", charaData.sleepCareMistakeCounter);
printf("[MAIN]: Care mistake count is %d\n", charaData.careMistakes);
printf("[MAIN]: Is sleep care mistake tripped? %d\n", charaData.sleepCareMistakeObtained);
vpetLastEvaluationTime = currentEvaluationTime;
runVpetTasks = false;
} else if (runVpetTasks && !charaData.hatched && charaData.hatching) {
uint64_t currentEvaluationTime = esp_timer_get_time();
uint64_t deltaUs = currentEvaluationTime - vpetLastEvaluationTime;
uint8_t diffSec = (deltaUs + 1000000 - 1000) / 1000000; // round up
charaData.hatchTimer += diffSec;
} else if(!charaData.hatched && charaData.hatching) {
printf("[DEBUG] hatchTimer=%i out of hatchTimer=%i\n", charaData.hatchTimer, currentLine[currentCharacter]->hatchTime);
if (charaData.hatchTimer > currentLine[currentCharacter]->hatchTime) {
interruptKey = EGG_HATCH_SCREEN;
screenKey = TIMER_FINISHED_SCREEN;
}
runVpetTasks = false;
vpetLastEvaluationTime = currentEvaluationTime;
}
}

View File

@ -10,6 +10,7 @@ void vpet_initTimer();
void vpet_computeCallLight();
bool vpet_evalSleep(uint8_t diff_sec);
void vpet_evalTimers();
void vpet_debugTimers(uint8_t diffSec);
void vpet_runVpetTasks();
void vpet_reduceTimers(uint8_t diff_sec);
void vpet_evalHungerTimer();