From dc44a695be4011a969286d29193314835b173f06 Mon Sep 17 00:00:00 2001 From: Nacho Date: Thu, 28 May 2026 01:31:03 +0200 Subject: [PATCH] Create upscale sprite function --- src/storage/read_file.cpp | 124 +++++++++++++++++++++++++++++++++++ src/storage/storage.cpp | 90 ------------------------- src/utils/upscale_sprite.cpp | 41 ++++++++++++ src/utils/utils.h | 14 ++++ 4 files changed, 179 insertions(+), 90 deletions(-) create mode 100644 src/storage/read_file.cpp create mode 100644 src/utils/upscale_sprite.cpp create mode 100644 src/utils/utils.h diff --git a/src/storage/read_file.cpp b/src/storage/read_file.cpp new file mode 100644 index 0000000..9ba71ce --- /dev/null +++ b/src/storage/read_file.cpp @@ -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 + ); +} \ No newline at end of file diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index 15484a0..745685c 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -8,8 +8,6 @@ const char* TAG_S = "[STORAGE]"; -#define SPRITE_SCALE 6 - void storage_init() { if (!SPIFFS.begin(true)) { printf("%s Failed to mount file system\n", TAG_S); @@ -19,94 +17,6 @@ void storage_init() { } -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_S); - 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_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"); if (!file) { diff --git a/src/utils/upscale_sprite.cpp b/src/utils/upscale_sprite.cpp new file mode 100644 index 0000000..d41fbef --- /dev/null +++ b/src/utils/upscale_sprite.cpp @@ -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; + } + } + } + } +} \ No newline at end of file diff --git a/src/utils/utils.h b/src/utils/utils.h new file mode 100644 index 0000000..5a295f8 --- /dev/null +++ b/src/utils/utils.h @@ -0,0 +1,14 @@ +#ifndef UTILS_H +#define UTILS_H + +#include + + +void utils_upscaleSprite( + const uint16_t* src, + uint8_t srcWidth, + uint8_t srcHeight, + uint16_t* dst +); + +#endif