mirror of
https://github.com/nacabaro/nacapet.git
synced 2026-06-05 14:02:53 +00:00
Compare commits
5 Commits
0b5c56b5e3
...
f8f7c7a9b6
| Author | SHA1 | Date | |
|---|---|---|---|
| f8f7c7a9b6 | |||
| 24ebd8a5af | |||
| 82a7d76b92 | |||
| 2ae5bc8bd4 | |||
| dc44a695be |
@ -20,18 +20,14 @@ lib_deps =
|
|||||||
fbiego/ESP32Time@^2.0.6
|
fbiego/ESP32Time@^2.0.6
|
||||||
electroniccats/MPU6050@^1.4.3
|
electroniccats/MPU6050@^1.4.3
|
||||||
|
|
||||||
; --- Hardware & Memory Topology ---
|
|
||||||
board_build.arduino.psram = enabled
|
board_build.arduino.psram = enabled
|
||||||
board_upload.flash_size = 16MB
|
board_upload.flash_size = 16MB
|
||||||
board_build.partitions = default_16MB.csv
|
board_build.partitions = default_16MB.csv
|
||||||
|
|
||||||
; FIX 2: Explicitly matches the 'mode:DIO' your ROM is reporting
|
|
||||||
board_build.flash_mode = dio
|
board_build.flash_mode = dio
|
||||||
board_build.arduino.memory_type = dio_opi
|
board_build.arduino.memory_type = dio_opi
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
; FIX 1: Forces all Serial.print logs to stay on the hardware UART port
|
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=0
|
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||||
-DDEV_UNIT
|
-DDEV_UNIT
|
||||||
-DDEBUG
|
-DDEBUG
|
||||||
@ -44,20 +40,17 @@ platform = espressif32
|
|||||||
board = esp32-s3-devkitc-1
|
board = esp32-s3-devkitc-1
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
; Flash and PSRAM settings for 4MB Flash / 2MB PSRAM (Quad SPI)
|
|
||||||
board_upload.flash_size = 4MB
|
board_upload.flash_size = 4MB
|
||||||
board_build.arduino.memory_type = qio_qspi
|
board_build.arduino.memory_type = qio_qspi
|
||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
board_build.psram_type = qio
|
board_build.psram_type = qio
|
||||||
|
|
||||||
; Required flag to enable PSRAM in code
|
|
||||||
build_flags =
|
build_flags =
|
||||||
-DBOARD_HAS_PSRAM
|
-DBOARD_HAS_PSRAM
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
-DARDUINO_USB_MODE=1
|
-DARDUINO_USB_MODE=1
|
||||||
-DDEV_UNIT
|
-DDEV_UNIT
|
||||||
|
|
||||||
; Ensure partition table fits 4MB
|
|
||||||
board_build.partitions = default.csv
|
board_build.partitions = default.csv
|
||||||
lib_deps = TFT_eSPI, fbiego/ESP32Time@^2.0.6, electroniccats/MPU6050@^1.4.3
|
lib_deps = TFT_eSPI, fbiego/ESP32Time@^2.0.6, electroniccats/MPU6050@^1.4.3
|
||||||
upload_port = COM5
|
upload_port = COM5
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern int currentBackground;
|
||||||
|
|
||||||
struct BackgroundData {
|
struct BackgroundData {
|
||||||
uint8_t backgroundWidth;
|
uint8_t backgroundWidth;
|
||||||
uint8_t backgroundHeight;
|
uint8_t backgroundHeight;
|
||||||
|
|||||||
@ -164,6 +164,8 @@
|
|||||||
|
|
||||||
#define CHARA_COUNT_IN_DEVICE 5
|
#define CHARA_COUNT_IN_DEVICE 5
|
||||||
|
|
||||||
|
#define SPRITE_SCALE 6
|
||||||
|
|
||||||
extern int screenKey;
|
extern int screenKey;
|
||||||
extern int menuKey;
|
extern int menuKey;
|
||||||
extern int submenuKey;
|
extern int submenuKey;
|
||||||
|
|||||||
@ -61,6 +61,9 @@ uint32_t dayUnixTime = 0;
|
|||||||
Egg_t* eggSelection = NULL;
|
Egg_t* eggSelection = NULL;
|
||||||
uint8_t eggNumber = 0;
|
uint8_t eggNumber = 0;
|
||||||
|
|
||||||
|
// Background stuff
|
||||||
|
int currentBackground = 0;
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
TaskHandle_t secondLoop = NULL;
|
TaskHandle_t secondLoop = NULL;
|
||||||
|
|
||||||
@ -92,7 +95,7 @@ void setup() {
|
|||||||
storage_readFile("/menu.bin", &menuElementsData);
|
storage_readFile("/menu.bin", &menuElementsData);
|
||||||
storage_readFile("/ui.bin", &uiElementsData);
|
storage_readFile("/ui.bin", &uiElementsData);
|
||||||
|
|
||||||
storage_initBackground("/bg2.bin", bg);
|
storage_initBackground(currentBackground, bg);
|
||||||
|
|
||||||
pinMode(K1_PIN, BUTTON_MODE);
|
pinMode(K1_PIN, BUTTON_MODE);
|
||||||
pinMode(K2_PIN, BUTTON_MODE);
|
pinMode(K2_PIN, BUTTON_MODE);
|
||||||
|
|||||||
77
src/menu/change_background_screen.cpp
Normal file
77
src/menu/change_background_screen.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "menu.h"
|
||||||
|
#include "defs/sprite_data.h"
|
||||||
|
#include "buttons/buttons.h"
|
||||||
|
#include "draw/draw.h"
|
||||||
|
#include "storage/storage.h"
|
||||||
|
#include "display/display.h"
|
||||||
|
#include "defs/screen_defs.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
uint64_t currentTime = esp_timer_get_time();
|
||||||
|
|
||||||
|
int8_t selectedPreviousBackground = 0;
|
||||||
|
|
||||||
|
while (background) {
|
||||||
|
if (!background.isDirectory()) {
|
||||||
|
backgrounds++;
|
||||||
|
}
|
||||||
|
|
||||||
|
background = background.openNextFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
uint8_t buttonsPressed = buttons_getPressedButtons();
|
||||||
|
currentTime = esp_timer_get_time();
|
||||||
|
|
||||||
|
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;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case K4_PRESSED:
|
||||||
|
storage_initBackground(currentBackground, bg);
|
||||||
|
lastUpdateTime = currentTime;
|
||||||
|
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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -53,11 +53,13 @@ void menu_drawAngryScreen(
|
|||||||
struct SpriteData* spriteData, struct SpriteData* smallUiElements
|
struct SpriteData* spriteData, struct SpriteData* smallUiElements
|
||||||
);
|
);
|
||||||
void menu_drawFridgeScreen(TFT_eSprite &bg, TFT_eSprite& sprite, struct SpriteData* smallUiElements, struct SpriteData* bigUiElements);
|
void menu_drawFridgeScreen(TFT_eSprite &bg, TFT_eSprite& sprite, struct SpriteData* smallUiElements, struct SpriteData* bigUiElements);
|
||||||
|
|
||||||
void training_screenTraining2(
|
void training_screenTraining2(
|
||||||
TFT_eSprite &bg, TFT_eSprite &sprite,
|
TFT_eSprite &bg, TFT_eSprite &sprite,
|
||||||
struct SpriteData* mainCharaData, struct SpriteData* attackSprites
|
struct SpriteData* mainCharaData, struct SpriteData* attackSprites
|
||||||
);
|
);
|
||||||
|
void menu_changeBackgroundScreen(
|
||||||
|
TFT_eSprite &bg, TFT_eSprite &sprite, struct SpriteData* uiSpriteData
|
||||||
|
);
|
||||||
|
|
||||||
void menu_sleepScreen_sleepAction();
|
void menu_sleepScreen_sleepAction();
|
||||||
void menu_sleepScreen_recalculateSleep();
|
void menu_sleepScreen_recalculateSleep();
|
||||||
|
|||||||
124
src/storage/read_file.cpp
Normal file
124
src/storage/read_file.cpp
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#include "storage.h"
|
||||||
|
#include "memory/memory.h"
|
||||||
|
#include "defs/defs.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char* TAG_SR = "[STORAGE]";
|
||||||
|
|
||||||
|
|
||||||
|
void storage_readFile(const char* path, struct SpriteData* spriteData) {
|
||||||
|
File file = SPIFFS.open(path, "r");
|
||||||
|
if (!file) {
|
||||||
|
printf("%s Failed to open file for reading\n", TAG_SR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t width, height, spriteNumber;
|
||||||
|
|
||||||
|
file.read(&width, 1);
|
||||||
|
file.read(&height, 1);
|
||||||
|
file.read(&spriteNumber, 1);
|
||||||
|
|
||||||
|
if (spriteData->spriteData != NULL) {
|
||||||
|
memory_free(spriteData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t scaledW = width * SPRITE_SCALE;
|
||||||
|
const uint8_t scaledH = height * SPRITE_SCALE;
|
||||||
|
|
||||||
|
uint16_t** scaled =
|
||||||
|
(uint16_t**) ps_malloc(spriteNumber * sizeof(uint16_t*));
|
||||||
|
|
||||||
|
if (!scaled) {
|
||||||
|
printf("%s PSRAM alloc failed for pointer table\n", TAG_SR);
|
||||||
|
file.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < spriteNumber; i++) {
|
||||||
|
|
||||||
|
scaled[i] =
|
||||||
|
(uint16_t*) ps_malloc(scaledW * scaledH * sizeof(uint16_t));
|
||||||
|
|
||||||
|
if (!scaled[i]) {
|
||||||
|
printf("%s PSRAM alloc failed for sprite %d\n", TAG_SR, i);
|
||||||
|
|
||||||
|
for (uint8_t j = 0; j < i; j++) {
|
||||||
|
free(scaled[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(scaled);
|
||||||
|
file.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t* spriteBuf =
|
||||||
|
(uint16_t*) malloc(width * height * sizeof(uint16_t));
|
||||||
|
|
||||||
|
if (!spriteBuf) {
|
||||||
|
printf("%s scratch alloc failed\n", TAG_SR);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < spriteNumber; i++) {
|
||||||
|
free(scaled[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(scaled);
|
||||||
|
file.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"%s Read header: width=%d, height=%d, numSprites=%d -> scaled to %dx%d\n",
|
||||||
|
TAG_SR,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
spriteNumber,
|
||||||
|
scaledW,
|
||||||
|
scaledH
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int sprN = 0; sprN < spriteNumber; sprN++) {
|
||||||
|
|
||||||
|
// Read original sprite into temporary buffer
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
|
||||||
|
uint8_t hi, lo;
|
||||||
|
|
||||||
|
file.read(&hi, 1);
|
||||||
|
file.read(&lo, 1);
|
||||||
|
|
||||||
|
spriteBuf[y * width + x] =
|
||||||
|
(lo << 8) | hi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upscale sprite
|
||||||
|
utils_upscaleSprite(
|
||||||
|
spriteBuf,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
scaled[sprN]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(spriteBuf);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
spriteData->spriteWidth = scaledW;
|
||||||
|
spriteData->spriteHeight = scaledH;
|
||||||
|
spriteData->spriteNumber = spriteNumber;
|
||||||
|
spriteData->spriteData = scaled;
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"%s Loaded & upscaled %s (%d sprites, each %dx%d px)\n",
|
||||||
|
TAG_SR,
|
||||||
|
path,
|
||||||
|
spriteNumber,
|
||||||
|
scaledW,
|
||||||
|
scaledH
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
const char* TAG_S = "[STORAGE]";
|
const char* TAG_S = "[STORAGE]";
|
||||||
|
|
||||||
#define SPRITE_SCALE 6
|
|
||||||
|
|
||||||
void storage_init() {
|
void storage_init() {
|
||||||
if (!SPIFFS.begin(true)) {
|
if (!SPIFFS.begin(true)) {
|
||||||
printf("%s Failed to mount file system\n", TAG_S);
|
printf("%s Failed to mount file system\n", TAG_S);
|
||||||
@ -19,95 +17,11 @@ void storage_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void storage_readFile(const char* path, struct SpriteData* spriteData) {
|
void storage_initBackground(const int id, TFT_eSprite& bg) {
|
||||||
File file = SPIFFS.open(path, "r");
|
char path[15];
|
||||||
if (!file) {
|
|
||||||
printf("%s Failed to open file for reading\n", TAG_S);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t width, height, spriteNumber;
|
snprintf(path, 15, "/bg/%i.bin", id);
|
||||||
|
|
||||||
file.read(&width, 1);
|
|
||||||
file.read(&height, 1);
|
|
||||||
file.read(&spriteNumber, 1);
|
|
||||||
|
|
||||||
if (spriteData->spriteData != NULL) {
|
|
||||||
memory_free(spriteData);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t scaledW = width * SPRITE_SCALE;
|
|
||||||
const uint8_t scaledH = height * SPRITE_SCALE;
|
|
||||||
|
|
||||||
uint16_t** scaled = (uint16_t**) ps_malloc(spriteNumber * sizeof(uint16_t*));
|
|
||||||
if (!scaled) {
|
|
||||||
printf("%s PSRAM alloc failed for pointer table\n", TAG_S);
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (uint8_t i = 0; i < spriteNumber; i++) {
|
|
||||||
scaled[i] = (uint16_t*) ps_malloc(scaledW * scaledH * sizeof(uint16_t));
|
|
||||||
if (!scaled[i]) {
|
|
||||||
printf("%s PSRAM alloc failed for sprite %d\n", TAG_S, i);
|
|
||||||
for (uint8_t j = 0; j < i; j++) free(scaled[j]);
|
|
||||||
free(scaled);
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t* rowBuf = (uint16_t*) malloc(width * sizeof(uint16_t));
|
|
||||||
if (!rowBuf) {
|
|
||||||
printf("%s scratch alloc failed\n", TAG_S);
|
|
||||||
for (uint8_t i = 0; i < spriteNumber; i++) free(scaled[i]);
|
|
||||||
free(scaled);
|
|
||||||
file.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"%s Read header: width=%d, height=%d, numSprites=%d -> scaled to %dx%d\n",
|
|
||||||
TAG_S, width, height, spriteNumber, scaledW, scaledH
|
|
||||||
);
|
|
||||||
|
|
||||||
for (int sprN = 0; sprN < spriteNumber; sprN++) {
|
|
||||||
uint16_t* dst = scaled[sprN];
|
|
||||||
|
|
||||||
for (int srcY = 0; srcY < height; srcY++) {
|
|
||||||
for (int srcX = 0; srcX < width; srcX++) {
|
|
||||||
uint8_t hi, lo;
|
|
||||||
file.read(&hi, 1);
|
|
||||||
file.read(&lo, 1);
|
|
||||||
rowBuf[srcX] = (lo << 8) | hi;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int dy = 0; dy < SPRITE_SCALE; dy++) {
|
|
||||||
uint16_t* dstRow = dst + (srcY * SPRITE_SCALE + dy) * scaledW;
|
|
||||||
|
|
||||||
for (int srcX = 0; srcX < width; srcX++) {
|
|
||||||
uint16_t color = rowBuf[srcX];
|
|
||||||
uint16_t* dstPixel = dstRow + srcX * SPRITE_SCALE;
|
|
||||||
for (int dx = 0; dx < SPRITE_SCALE; dx++) {
|
|
||||||
dstPixel[dx] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(rowBuf);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
spriteData->spriteWidth = scaledW;
|
|
||||||
spriteData->spriteHeight = scaledH;
|
|
||||||
spriteData->spriteNumber = spriteNumber;
|
|
||||||
spriteData->spriteData = scaled;
|
|
||||||
|
|
||||||
printf("%s Loaded & upscaled %s (%d sprites, each %dx%d px)\n",
|
|
||||||
TAG_S, path, spriteNumber, scaledW, scaledH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void storage_initBackground(const char* path, TFT_eSprite& bg) {
|
|
||||||
File file = SPIFFS.open(path, "r");
|
File file = SPIFFS.open(path, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
printf("%s Failed to open file for reading\n", TAG_S);
|
printf("%s Failed to open file for reading\n", TAG_S);
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
void storage_init();
|
void storage_init();
|
||||||
void storage_readFile(const char* path, struct SpriteData* spriteData);
|
void storage_readFile(const char* path, struct SpriteData* spriteData);
|
||||||
void storage_initBackground(const char* path, TFT_eSprite &bg);
|
void storage_initBackground(const int id, TFT_eSprite &bg);
|
||||||
|
|
||||||
void storage_saveState();
|
void storage_saveState();
|
||||||
void storage_loadState();
|
void storage_loadState();
|
||||||
|
|||||||
41
src/utils/upscale_sprite.cpp
Normal file
41
src/utils/upscale_sprite.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
#include "defs/defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upscale a sprite using nearest-neighbor scaling.
|
||||||
|
*
|
||||||
|
* @param src Pointer to source sprite pixels
|
||||||
|
* @param srcWidth Original sprite width
|
||||||
|
* @param srcHeight Original sprite height
|
||||||
|
* @param dst Destination buffer for upscaled sprite
|
||||||
|
*/
|
||||||
|
void utils_upscaleSprite(
|
||||||
|
const uint16_t* src,
|
||||||
|
uint8_t srcWidth,
|
||||||
|
uint8_t srcHeight,
|
||||||
|
uint16_t* dst
|
||||||
|
) {
|
||||||
|
const uint8_t scaledW = srcWidth * SPRITE_SCALE;
|
||||||
|
|
||||||
|
for (int srcY = 0; srcY < srcHeight; srcY++) {
|
||||||
|
|
||||||
|
for (int dy = 0; dy < SPRITE_SCALE; dy++) {
|
||||||
|
|
||||||
|
uint16_t* dstRow =
|
||||||
|
dst + ((srcY * SPRITE_SCALE + dy) * scaledW);
|
||||||
|
|
||||||
|
for (int srcX = 0; srcX < srcWidth; srcX++) {
|
||||||
|
|
||||||
|
uint16_t color = src[srcY * srcWidth + srcX];
|
||||||
|
|
||||||
|
uint16_t* dstPixel =
|
||||||
|
dstRow + (srcX * SPRITE_SCALE);
|
||||||
|
|
||||||
|
for (int dx = 0; dx < SPRITE_SCALE; dx++) {
|
||||||
|
dstPixel[dx] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/utils/utils.h
Normal file
14
src/utils/utils.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
void utils_upscaleSprite(
|
||||||
|
const uint16_t* src,
|
||||||
|
uint8_t srcWidth,
|
||||||
|
uint8_t srcHeight,
|
||||||
|
uint16_t* dst
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,23 +1,24 @@
|
|||||||
#include "lines.h"
|
#include "lines.h"
|
||||||
#include "memory/memory.h"
|
#include "memory/memory.h"
|
||||||
#include "defs/defs.h"
|
#include "defs/defs.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
|
|
||||||
const char lineHeader[5] = "NPET";
|
const char lineHeader[5] = "NPET";
|
||||||
const uint8_t headerSize = 4;
|
const uint8_t headerSize = 4;
|
||||||
|
|
||||||
void lines_getAvailableLines() {
|
void lines_getAvailableLines() {
|
||||||
if (eggSelection != NULL) {
|
if (eggSelection != NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::File root = SPIFFS.open("/lines");
|
fs::File root = SPIFFS.open("/lines");
|
||||||
fs::File lineFile = root.openNextFile();
|
fs::File lineFile = root.openNextFile();
|
||||||
|
|
||||||
uint8_t allocCount = 0;
|
uint8_t allocCount = 0;
|
||||||
char header[5];
|
char header[5];
|
||||||
|
|
||||||
while (lineFile) {
|
while (lineFile) {
|
||||||
printf("[LINES] Opening file %s\n", lineFile.name());
|
printf("[LINES] Opening file %s\n", lineFile.name());
|
||||||
@ -40,39 +41,69 @@ void lines_getAvailableLines() {
|
|||||||
lineFile = root.openNextFile("r");
|
lineFile = root.openNextFile("r");
|
||||||
|
|
||||||
while (lineFile) {
|
while (lineFile) {
|
||||||
uint16_t bytesRead = lineFile.readBytes(header, headerSize);
|
uint16_t bytesRead = 0;
|
||||||
|
|
||||||
|
bytesRead += lineFile.readBytes(header, headerSize);
|
||||||
bytesRead += lineFile.read(&availableLines[allocCount].id, 1);
|
bytesRead += lineFile.read(&availableLines[allocCount].id, 1);
|
||||||
bytesRead += lineFile.readBytes(availableLines[allocCount].name, 16);
|
bytesRead += lineFile.readBytes(availableLines[allocCount].name, 16);
|
||||||
|
|
||||||
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteWidth, 1);
|
uint8_t originalWidth;
|
||||||
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteHeight, 1);
|
uint8_t originalHeight;
|
||||||
bytesRead += lineFile.read(&availableLines[allocCount].eggSprite.spriteNumber, 1); // Se coloca el cursor al principio de los datos de sprite
|
uint8_t spriteCount;
|
||||||
|
|
||||||
availableLines[allocCount].eggSprite.spriteNumber = 1; // Inutil, pero es que necesito hacer la lectura
|
bytesRead += lineFile.read(&originalWidth, 1);
|
||||||
|
bytesRead += lineFile.read(&originalHeight, 1);
|
||||||
|
bytesRead += lineFile.read(&spriteCount, 1);
|
||||||
|
|
||||||
availableLines[allocCount].eggSprite.spriteData = memory_allocate(
|
const uint8_t scaledWidth = originalWidth * SPRITE_SCALE;
|
||||||
availableLines[allocCount].eggSprite.spriteNumber,
|
const uint8_t scaledHeight = originalHeight * SPRITE_SCALE;
|
||||||
availableLines[allocCount].eggSprite.spriteWidth,
|
|
||||||
availableLines[allocCount].eggSprite.spriteHeight
|
availableLines[allocCount].eggSprite.spriteWidth = scaledWidth;
|
||||||
);
|
availableLines[allocCount].eggSprite.spriteHeight = scaledHeight;
|
||||||
|
availableLines[allocCount].eggSprite.spriteNumber = 1;
|
||||||
|
availableLines[allocCount].eggSprite.spriteData = memory_allocate(1, scaledWidth, scaledHeight);
|
||||||
|
|
||||||
|
uint16_t* spriteBuffer =
|
||||||
|
(uint16_t*) malloc(
|
||||||
|
originalWidth *
|
||||||
|
originalHeight *
|
||||||
|
sizeof(uint16_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!spriteBuffer) {
|
||||||
|
printf("[LINES] Failed to allocate sprite buffer\n");
|
||||||
|
|
||||||
|
lineFile.close();
|
||||||
|
lineFile = root.openNextFile();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t highByte;
|
uint8_t highByte;
|
||||||
uint8_t lowByte;
|
uint8_t lowByte;
|
||||||
|
|
||||||
for (int i = 0; i < availableLines[allocCount].eggSprite.spriteWidth * availableLines[allocCount].eggSprite.spriteHeight; i++) {
|
for (int i = 0; i < originalWidth * originalHeight; i++) {
|
||||||
bytesRead += lineFile.read(&highByte, 1);
|
|
||||||
bytesRead += lineFile.read(&lowByte, 1);
|
bytesRead += lineFile.read(&lowByte, 1);
|
||||||
|
bytesRead += lineFile.read(&highByte, 1);
|
||||||
|
|
||||||
uint16_t pixel = (highByte << 8) | lowByte;
|
spriteBuffer[i] = (highByte << 8) | lowByte;
|
||||||
|
|
||||||
availableLines[allocCount].eggSprite.spriteData[0][i] = pixel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
utils_upscaleSprite(
|
||||||
|
spriteBuffer,
|
||||||
|
originalWidth,
|
||||||
|
originalHeight,
|
||||||
|
availableLines[allocCount].eggSprite.spriteData[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
free(spriteBuffer);
|
||||||
|
|
||||||
strcpy(availableLines[allocCount].fileName, lineFile.name());
|
strcpy(availableLines[allocCount].fileName, lineFile.name());
|
||||||
|
|
||||||
lineFile.close();
|
lineFile.close();
|
||||||
|
|
||||||
allocCount++;
|
allocCount++;
|
||||||
|
|
||||||
lineFile = root.openNextFile();
|
lineFile = root.openNextFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,4 +111,4 @@ void lines_getAvailableLines() {
|
|||||||
|
|
||||||
eggNumber = allocCount;
|
eggNumber = allocCount;
|
||||||
eggSelection = availableLines;
|
eggSelection = availableLines;
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#include "lines.h"
|
#include "lines.h"
|
||||||
#include "memory/memory.h"
|
#include "memory/memory.h"
|
||||||
#include "defs/defs.h"
|
#include "defs/defs.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include <SPIFFS.h>
|
#include <SPIFFS.h>
|
||||||
@ -40,37 +41,76 @@ void lines_getSingleLine(const char* fileName) {
|
|||||||
currentLine[currentCharacter] = selectedLine;
|
currentLine[currentCharacter] = selectedLine;
|
||||||
currentEgg = selectedEgg;
|
currentEgg = selectedEgg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lines_getSingleEggSprites(fs::File &lineFile, Egg_t* selectedEgg) {
|
void lines_getSingleEggSprites(fs::File &lineFile, Egg_t* selectedEgg) {
|
||||||
|
|
||||||
// Importante tener el nombre de archivo del huevo en todo momento
|
// Importante tener el nombre de archivo del huevo en todo momento
|
||||||
strcpy(selectedEgg->fileName, lineFile.name());
|
strcpy(selectedEgg->fileName, lineFile.name());
|
||||||
|
|
||||||
// Ahora se lee los datos
|
// Leer dimensiones originales
|
||||||
lineFile.read(&(selectedEgg->eggSprite.spriteWidth), 1);
|
uint8_t originalWidth;
|
||||||
lineFile.read(&(selectedEgg->eggSprite.spriteHeight), 1);
|
uint8_t originalHeight;
|
||||||
|
|
||||||
|
lineFile.read(&originalWidth, 1);
|
||||||
|
lineFile.read(&originalHeight, 1);
|
||||||
lineFile.read(&(selectedEgg->eggSprite.spriteNumber), 1);
|
lineFile.read(&(selectedEgg->eggSprite.spriteNumber), 1);
|
||||||
|
|
||||||
|
const uint8_t scaledWidth = originalWidth * SPRITE_SCALE;
|
||||||
|
const uint8_t scaledHeight = originalHeight * SPRITE_SCALE;
|
||||||
|
|
||||||
|
// Guardar dimensiones escaladas
|
||||||
|
selectedEgg->eggSprite.spriteWidth = scaledWidth;
|
||||||
|
selectedEgg->eggSprite.spriteHeight = scaledHeight;
|
||||||
|
|
||||||
|
// Reservar memoria para sprites escalados
|
||||||
selectedEgg->eggSprite.spriteData = memory_allocate(
|
selectedEgg->eggSprite.spriteData = memory_allocate(
|
||||||
selectedEgg->eggSprite.spriteNumber,
|
selectedEgg->eggSprite.spriteNumber,
|
||||||
selectedEgg->eggSprite.spriteWidth,
|
scaledWidth,
|
||||||
selectedEgg->eggSprite.spriteHeight
|
scaledHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
uint16_t size = selectedEgg->eggSprite.spriteWidth * selectedEgg->eggSprite.spriteHeight;
|
const uint16_t originalSize =
|
||||||
|
originalWidth * originalHeight;
|
||||||
|
|
||||||
|
// Buffer temporal en SRAM
|
||||||
|
uint16_t* spriteBuffer =
|
||||||
|
(uint16_t*) malloc(
|
||||||
|
originalSize * sizeof(uint16_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!spriteBuffer) {
|
||||||
|
printf("[LINES] Failed to allocate sprite buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t highByte;
|
uint8_t highByte;
|
||||||
uint8_t lowByte;
|
uint8_t lowByte;
|
||||||
|
|
||||||
for (int spr = 0; spr < selectedEgg->eggSprite.spriteNumber; spr++) {
|
for (
|
||||||
for (int i= 0; i < size; i++) {
|
int spr = 0;
|
||||||
lineFile.read(&highByte, 1);
|
spr < selectedEgg->eggSprite.spriteNumber;
|
||||||
|
spr++
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Leer sprite original
|
||||||
|
for (int i = 0; i < originalSize; i++) {
|
||||||
|
|
||||||
lineFile.read(&lowByte, 1);
|
lineFile.read(&lowByte, 1);
|
||||||
|
lineFile.read(&highByte, 1);
|
||||||
|
|
||||||
uint16_t pixel = (highByte << 8) | lowByte;
|
spriteBuffer[i] =
|
||||||
|
(highByte << 8) | lowByte;
|
||||||
selectedEgg->eggSprite.spriteData[spr][i] = pixel;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Escalar sprite
|
||||||
|
utils_upscaleSprite(
|
||||||
|
spriteBuffer,
|
||||||
|
originalWidth,
|
||||||
|
originalHeight,
|
||||||
|
selectedEgg->eggSprite.spriteData[spr]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(spriteBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Son las 22:35, que estoy haciendo?
|
// Son las 22:35, que estoy haciendo?
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user