Cosas, muchas cosas

- Carga de lineas,  estadisticas y forma de cuidar al bicho funciona  ahora, perfesto
- Empece a hacer la parte de cambio o evolución, no se como llamarlo aun

Vamos a implementar un poco mas los huevitos
This commit is contained in:
Nacho 2025-05-25 23:56:39 +02:00
parent 0f7702659f
commit 0186f3e436
13 changed files with 331 additions and 16 deletions

4
.gitignore vendored
View File

@ -6,7 +6,9 @@
.vscode/
*.bin
*.line
*.egg
*.cm
__pycache__/
venv/
sprites/
sprites/
eggs/

View File

@ -2,18 +2,19 @@ import re
import sys
import logging
def process_npet_file(origFp, outputName):
def process_npet_file(origFp, eggFp, outputName):
file_header = origFp.readline()
matches = re.findall(r"\[\s*([0-9a-fA-F]+)\s*\|\s*([^|]+?)\s*\|\s*([0-9a-fA-F]+)\s*\]", file_header)
matches = re.findall(r"\[\s*([0-9a-fA-F]+)\s*\|\s*([^|]+?)\s*\|\s*([0-9a-fA-F]+)\s*\|\s*([0-9a-fA-F]+)\s*\]", file_header)
if len(matches[0]) != 3:
if len(matches[0]) != 4:
logging.error("Cabecera invalida")
return
id, nombre, numChara = matches[0]
id, nombre, numChara, hatchTime = matches[0]
id = int(id, 16)
numChara = int(numChara, 16)
hatchTime = int(hatchTime, 16)
logging.info(f"Encontrado cabecera id={id}, nombre={nombre}, numchara={numChara}")
@ -23,6 +24,12 @@ def process_npet_file(origFp, outputName):
destFp.write(id.to_bytes(1, "big"))
destFp.write(nombre.encode("utf8").ljust(16, b"\0"))
eggSpriteData = eggFp.read()
destFp.write(eggSpriteData)
destFp.write(hatchTime.to_bytes(2, "big"))
destFp.write(numChara.to_bytes(1, "big"))
for i in range(numChara):
@ -104,7 +111,7 @@ def process_nevo_file(origFp, outputName):
destFp = open(outputName, "wb")
destFp.write(b"NEVO")
destFp.write(id.to_bytes(1, "big"))
destFp.write(length.to_bytes(1, "big"))
@ -163,7 +170,10 @@ if __name__ == "__main__":
header = origFp.readline()
if "NPET" in header:
logging.info("Cabecera NPET encontrada!")
process_npet_file(origFp, newFile)
origFileName = "".join(origFile.split(".")[0:-1]) + ".egg"
eggFp = open(origFileName, "rb")
process_npet_file(origFp, eggFp, newFile)
eggFp.close()
elif "NEVO" in header:
logging.info("Cabecera NEVO encontrada!")

View File

@ -12,8 +12,6 @@
platform = espressif32
board = esp32dev
framework = arduino
upload_port = /dev/ttyUSB0
upload_speed = 921600
monitor_speed = 115200
monitor_port = /dev/ttyUSB0
monitor_filters = esp32_exception_decoder

View File

@ -22,7 +22,6 @@ def split_image(filename: str) -> list[bytearray]:
h = y + 16
tile = image.crop((x, y, w, h))
tile.save(f"tile_{i}.png")
tiles.append(tile)

View File

@ -7,11 +7,20 @@ struct CharacterData {
// Calculated at runtime
uint8_t hunger;
uint8_t strength;
uint8_t effort;
uint8_t careMistakes;
uint8_t weight;
uint8_t age;
uint8_t poopNumber;
uint8_t careMistakes;
uint8_t effort;
uint8_t overfeed;
uint8_t sleepDisturbances;
uint16_t stageTotalBattled;
uint16_t stageTotalWon;
uint16_t charaTotalBattled;
uint16_t charaTotalWon;
int32_t sleepCareMistakeCounter = 0;
int32_t evoLeftTimer;
@ -30,12 +39,14 @@ struct CharacterData {
bool dead = false;
// Obtained from structure
uint8_t idLine;
uint8_t idChara;
char charaName[40];
uint8_t hp;
uint8_t ap;
uint8_t bp;
uint8_t stage;
uint8_t attribute;
@ -45,6 +56,7 @@ struct CharacterData {
uint32_t evoTime;
uint16_t initialStatsReductionTime = 600;
uint8_t minWeight;
};
#endif

53
src/defs/file_chara.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef FILE_CHARA_H
#define FILE_CHARA_H
#include <stdint.h>
#include "sprite_data.h"
struct Egg_t {
uint8_t id;
char fileName[20];
char name[16];
SpriteData eggSprite;
};
typedef struct __attribute__((packed)) {
uint8_t id;
char name[16];
uint8_t hp, ap, bp;
uint8_t stage;
uint8_t attribute;
uint8_t attackSprite;
uint32_t sleepTime;
uint32_t wakeTime;
uint32_t changeTime;
uint16_t depleteTime;
uint8_t minWeight;
} LineChara_t;
typedef struct __attribute__((packed)) {
uint8_t currentChara, nextChara;
uint8_t minCareMistake, maxCareMistake;
uint8_t minSleepDist, maxSleepDist;
uint8_t minOverfeeds, maxOverfeeds;
uint8_t minTraining, maxTraining;
uint8_t totalBattles, wonBattles;
} CareMistakes_t;
struct LineCare_t {
uint8_t lineId;
uint8_t numCareMistakesData;
CareMistakes_t* careMistakeData;
};
struct Line_t {
uint8_t id;
char name[16];
uint8_t charaNumber;
uint16_t hatchTime;
LineChara_t* characters;
};
#endif

View File

@ -10,6 +10,7 @@
#include "buttons/buttons.h"
#include "vpet/vpet.h"
#include "vpet/steps/steps.h"
#include "vpet/lines/lines.h"
const char* TAG = "[MAIN]";
@ -44,7 +45,7 @@ void secondCoreTask(void*);
void setup() {
Serial.begin(115200);
delay(100); // Give MPU6050 and ESP32 time to power up
Wire.begin(MPU_SDA_PIN, MPU_SCL_PIN); // I2C init before MPU6050
mpu.initialize();
@ -59,8 +60,6 @@ void setup() {
storage_initBackground("/bg.bin", bg);
debug_printFreeMemory();
pinMode(K1_PIN, INPUT_PULLUP);
pinMode(K2_PIN, INPUT_PULLUP);
pinMode(K3_PIN, INPUT_PULLUP);
@ -75,6 +74,12 @@ void setup() {
charaData.strengthCareMistakeTimer = 60;
xTaskCreatePinnedToCore(secondCoreTask, "VPET_EVAL", 4096, NULL, 0, &secondLoop, 0);
debug_printFreeMemory();
lines_testLines(); // REMOVE
debug_printFreeMemory();
}

View File

View File

View File

@ -0,0 +1,106 @@
#include "lines.h"
#include "memory/memory.h"
#include "SPIFFS.h"
const char lineHeader[5] = "NPET";
const uint8_t headerSize = 4;
struct Egg_t* lines_getAvailableLines(uint8_t* count) {
File root = SPIFFS.open("/lines");
File lineFile = root.openNextFile();
uint8_t allocCount = 0;
char header[5];
while (lineFile) {
printf("[LINES] Opening file %s\n", lineFile.name());
uint8_t readBytes = lineFile.readBytes(header, headerSize);
if (strncmp(header, lineHeader, headerSize) == 0 && readBytes == headerSize) {
allocCount++;
}
lineFile = root.openNextFile();
}
struct Egg_t* availableLines = (struct Egg_t*) malloc(sizeof(struct Egg_t) * allocCount);
root.close();
printf("[LINES] Found %i lines.\n", allocCount);
allocCount = 0;
root = SPIFFS.open("/lines");
lineFile = root.openNextFile("r");
while (lineFile) {
uint16_t bytesRead = lineFile.readBytes(header, headerSize);
bytesRead += lineFile.read(&availableLines[allocCount].id, 1);
bytesRead += lineFile.readBytes(availableLines[allocCount].name, 16);
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteWidth, 1);
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteHeight, 1);
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteNumber, 1); // Se coloca el cursor al principio de los datos de sprite
availableLines[allocCount].eggSprite.spriteNumber = 1; // Inutil, pero es que necesito hacer la lectura
availableLines[allocCount].eggSprite.spriteData = memory_allocate(
availableLines[allocCount].eggSprite.spriteNumber,
availableLines[allocCount].eggSprite.spriteWidth,
availableLines[allocCount].eggSprite.spriteHeight
);
uint8_t highByte;
uint8_t lowByte;
for (int i = 0; i < availableLines[allocCount].eggSprite.spriteWidth * availableLines[allocCount].eggSprite.spriteHeight; i++) {
bytesRead += lineFile.read(&highByte, 1);
bytesRead += lineFile.read(&lowByte, 1);
uint16_t pixel = (highByte << 8) | lowByte;
availableLines[allocCount].eggSprite.spriteData[0][i] = pixel;
}
strcpy(availableLines[allocCount].fileName, lineFile.name());
lineFile.close();
allocCount++;
lineFile = root.openNextFile();
}
root.close();
*count = allocCount;
return availableLines;
}
void lines_testLines() {
uint8_t countedLines;
struct Egg_t* availableLines = lines_getAvailableLines(&countedLines);
char fullPath[8 + strlen(availableLines[0].fileName)];
snprintf(fullPath, 20, "/lines/%s", availableLines[0].fileName);
lines_freeEggList(availableLines, countedLines);
printf("[DEBUG] fullPath=%s\n", fullPath);
availableLines = (Egg_t*) malloc(sizeof(Egg_t));
struct Line_t* singleLine = lines_getSingleLine(fullPath, availableLines);
lines_freeEggList(availableLines, 1);
struct LineCare_t* lineCareData = lines_getLineCareMistakes(availableLines->fileName);
for (int i = 0; i < lineCareData->numCareMistakesData; i++) {
printf(
"[DEBUG] Chara %d changes into chara %d\n",
lineCareData->careMistakeData[i].currentChara,
lineCareData->careMistakeData[i].nextChara
);
}
}

View File

@ -0,0 +1,30 @@
#include "lines.h"
#include "defs/file_chara.h"
#include "SPIFFS.h"
struct LineCare_t* lines_getLineCareMistakes(const char* fileName) {
char careMistakesPath[strlen(fileName) + 8];
snprintf(careMistakesPath, strlen(fileName) + 8, "/care/%s", fileName);
File careMistakesFile = SPIFFS.open(careMistakesPath);
uint8_t bytesRead = 0;
LineCare_t* careMistakesData = (LineCare_t*) malloc(sizeof(LineCare_t));
careMistakesFile.seek(4, SeekCur);
bytesRead += careMistakesFile.read(&careMistakesData->lineId, 1);
bytesRead += careMistakesFile.read(&careMistakesData->numCareMistakesData, 1);
careMistakesData->careMistakeData = (CareMistakes_t*) malloc(
sizeof(CareMistakes_t) * careMistakesData->numCareMistakesData
);
for (int i = 0; i < careMistakesData->numCareMistakesData; i++) {
bytesRead += careMistakesFile.read((uint8_t*) &careMistakesData->careMistakeData[i], sizeof(CareMistakes_t));
}
return careMistakesData;
}

View File

@ -0,0 +1,86 @@
#include "lines.h"
#include "memory/memory.h"
#include <SPIFFS.h>
struct Line_t* lines_getSingleLine(const char* fileName, Egg_t* selectedEgg) {
File lineFile = SPIFFS.open(fileName);
struct Line_t* selectedLine = (struct Line_t*) malloc(sizeof(struct Line_t));
if (selectedLine == NULL) {
printf("[LINES] Fallo reserva\n");
}
uint8_t buffer[4];
lineFile.seek(4, SeekCur);
uint8_t bytesRead = lineFile.read(&selectedLine->id, 1);
bytesRead += lineFile.readBytes(selectedLine->name, 16);
lines_getSingleEggSprites(lineFile, selectedEgg);
bytesRead += lineFile.read(buffer, 2);
selectedLine->hatchTime = (buffer[0] << 8) | buffer[1];
bytesRead += lineFile.read(&selectedLine->charaNumber, 1);
printf("[DEBUG] SelectedLine numChara=%d hatchTime=%d\n", selectedLine->charaNumber, selectedLine->hatchTime);
selectedLine->characters = (LineChara_t*) malloc(selectedLine->charaNumber * sizeof(LineChara_t));
for (int i = 0; i < selectedLine->charaNumber; i++) {
bytesRead += lineFile.read((uint8_t*) &selectedLine->characters[i], sizeof(LineChara_t));
}
return selectedLine;
}
void lines_getSingleEggSprites(File &lineFile, Egg_t* selectedEgg) {
// Ahora si, vamos a ver cuantos sprites hay que reservar
// Importante tener el nombre de archivo del huevo en todo momento
strcpy(selectedEgg->fileName, lineFile.name());
// Ahora se lee los datos
lineFile.read(&(selectedEgg->eggSprite.spriteWidth), 1);
lineFile.read(&(selectedEgg->eggSprite.spriteHeight), 1);
lineFile.read(&(selectedEgg->eggSprite.spriteNumber), 1);
selectedEgg->eggSprite.spriteData = memory_allocate(
selectedEgg->eggSprite.spriteNumber,
selectedEgg->eggSprite.spriteWidth,
selectedEgg->eggSprite.spriteHeight
);
uint16_t size = selectedEgg->eggSprite.spriteWidth * selectedEgg->eggSprite.spriteHeight;
uint8_t highByte;
uint8_t lowByte;
for (int spr = 0; spr < selectedEgg->eggSprite.spriteNumber; spr++) {
for (int i= 0; i < size; i++) {
lineFile.read(&highByte, 1);
lineFile.read(&lowByte, 1);
uint16_t pixel = (highByte << 8) | lowByte;
selectedEgg->eggSprite.spriteData[spr][i] = pixel;
}
}
}
// Son las 22:35, que estoy haciendo?
// Pues claro
void lines_freeEggList(Egg_t* eggList, uint8_t eggNumber) {
for (int i = 0; i < eggNumber; i++) {
for (int j = 0; j < eggList[i].eggSprite.spriteNumber; j++) {
free(eggList[i].eggSprite.spriteData[j]);
}
free(eggList[i].eggSprite.spriteData);
}
free(eggList);
}

14
src/vpet/lines/lines.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef LINES_H
#define LINES_H
#include "defs/file_chara.h"
#include <FS.h>
struct Egg_t* lines_getAvailableLines(uint8_t* count);
struct Line_t* lines_getSingleLine(const char* fileName, Egg_t* eggList);
void lines_getSingleEggSprites(fs::File &lineFile, Egg_t* eggList);
void lines_freeEggList(Egg_t* eggList, uint8_t eggNumber);
struct LineCare_t* lines_getLineCareMistakes(const char* fileName);
void lines_testLines();
#endif