From 00a4dea6c67a30c0814b3f9914c407d6a3488256 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Sun, 1 Feb 2015 18:48:13 -0800 Subject: [PATCH] Add proper scaling for the 24x24 icon. --- source/3ds/util.cpp | 87 +++++++++++++++++++++++++-------------------- source/3ds/util.h | 2 ++ source/cmd.cpp | 48 ++++++++++++++++++++++--- 3 files changed, 93 insertions(+), 44 deletions(-) diff --git a/source/3ds/util.cpp b/source/3ds/util.cpp index 849a4fc..0ad4dd2 100644 --- a/source/3ds/util.cpp +++ b/source/3ds/util.cpp @@ -33,44 +33,53 @@ u16 pack_color(u8 r, u8 g, u8 b, u8 a, PixelFormat format) { } } +u8* load_image(const char* image, u32 width, u32 height) { + unsigned char *img; + unsigned int imgWidth, imgHeight; + if(lodepng_decode32_file(&img, &imgWidth, &imgHeight, image)) { + printf("ERROR: Could not load png file.\n"); + return NULL; + } + + if(width == 0) { + width = imgWidth; + } + + if(height == 0) { + height = imgHeight; + } + + if(imgWidth != width || imgHeight != height) { + printf("ERROR: Image must be exactly %d x %d in size.\n", width, height); + return NULL; + } + + return img; +} + +u16* image_data_to_tiles(u8* img, u32 width, u32 height, PixelFormat format, u32* size) { + u16* converted = (u16*) malloc(width * height * sizeof(u16)); + u32 n = 0; + for(int y = 0; y < height; y += 8) { + for(int x = 0; x < width; x += 8) { + for(int k = 0; k < 8 * 8; k++) { + u32 xx = (u32) (TILE_ORDER[k] & 0x7); + u32 yy = (u32) (TILE_ORDER[k] >> 3); + + u8* pixel = img + (((y + yy) * width + (x + xx)) * 4); + converted[n++] = pack_color(pixel[0], pixel[1], pixel[2], pixel[3], format); + } + } + } + + if(size != NULL) { + *size = width * height * (u32) sizeof(u16); + } + + return converted; +} + u16* image_to_tiles(const char* image, u32 width, u32 height, PixelFormat format, u32* size) { - unsigned char* img; - unsigned int imgWidth, imgHeight; - if(lodepng_decode32_file(&img, &imgWidth, &imgHeight, image)) { - printf("ERROR: Could not load png file.\n"); - return NULL; - } - - if(width == 0) { - width = imgWidth; - } - - if(height == 0) { - height = imgHeight; - } - - if(imgWidth != width || imgHeight != height) { - printf("ERROR: Image must be exactly %d x %d in size.\n", width, height); - return NULL; - } - - u16* converted = (u16*) malloc(width * height * sizeof(u16)); - u32 n = 0; - for(int y = 0; y < height; y += 8) { - for(int x = 0; x < width; x += 8) { - for(int k = 0; k < 8 * 8; k++) { - u32 xx = (u32) (TILE_ORDER[k] & 0x7); - u32 yy = (u32) (TILE_ORDER[k] >> 3); - - u8* pixel = img + (((y + yy) * width + (x + xx)) * 4); - converted[n++] = pack_color(pixel[0], pixel[1], pixel[2], pixel[3], format); - } - } - } - - if(size != NULL) { - *size = width * height * (u32) sizeof(u16); - } - - return converted; + u8* img = load_image(image, width, height); + return image_data_to_tiles(img, width, height, format, size); } \ No newline at end of file diff --git a/source/3ds/util.h b/source/3ds/util.h index 4556201..6a6689d 100644 --- a/source/3ds/util.h +++ b/source/3ds/util.h @@ -10,6 +10,8 @@ typedef enum { void utf8_to_utf16(u16* dst, const char* src, size_t max_len); u16 pack_color(u8 r, u8 g, u8 b, u8 a, PixelFormat format); +u8* load_image(const char* image, u32 width, u32 height); +u16* image_data_to_tiles(u8* img, u32 width, u32 height, PixelFormat format, u32* size); u16* image_to_tiles(const char* image, u32 width, u32 height, PixelFormat format, u32* size); #endif \ No newline at end of file diff --git a/source/cmd.cpp b/source/cmd.cpp index e97ac73..2a0db9a 100644 --- a/source/cmd.cpp +++ b/source/cmd.cpp @@ -111,18 +111,56 @@ int cmd_make_banner(const char* image, const char* audio, char* cgfxFile, char* } int cmd_make_smdh(char* shortTitle, char* longTitle, char* publisher, char* icon, char* output) { - u16* icon48 = image_to_tiles(icon, 48, 48, RGB565, NULL); + u8* icon48Data = load_image(icon, 48, 48); + if(icon48Data == NULL) { + return 1; + } + + u16* icon48 = image_data_to_tiles(icon48Data, 48, 48, RGB565, NULL); if(icon48 == NULL) { return 1; } - u16 icon24[24 * 24]; - for(int y = 0; y < 24; y++) { - for(int x = 0; x < 24; x++) { - icon24[y * 24 + x] = icon48[y * 48 + x]; + u8 icon24Data[24 * 24 * 4]; + for(int y = 0; y < 48; y += 2) { + for(int x = 0; x < 48; x += 2) { + int i1 = (y * 48 + x) * 4; + u8 r1 = icon48Data[i1 + 0]; + u8 g1 = icon48Data[i1 + 1]; + u8 b1 = icon48Data[i1 + 2]; + u8 a1 = icon48Data[i1 + 3]; + + int i2 = (y * 48 + (x + 1)) * 4; + u8 r2 = icon48Data[i2 + 0]; + u8 g2 = icon48Data[i2 + 1]; + u8 b2 = icon48Data[i2 + 2]; + u8 a2 = icon48Data[i2 + 3]; + + int i3 = ((y + 1) * 48 + x) * 4; + u8 r3 = icon48Data[i3 + 0]; + u8 g3 = icon48Data[i3 + 1]; + u8 b3 = icon48Data[i3 + 2]; + u8 a3 = icon48Data[i3 + 3]; + + int i4 = ((y + 1) * 48 + (x + 1)) * 4; + u8 r4 = icon48Data[i4 + 0]; + u8 g4 = icon48Data[i4 + 1]; + u8 b4 = icon48Data[i4 + 2]; + u8 a4 = icon48Data[i4 + 3]; + + int id = ((y / 2) * 24 + (x / 2)) * 4; + icon24Data[id + 0] = (u8) ((r1 + r2 + r3 + r4) / 4); + icon24Data[id + 1] = (u8) ((g1 + g2 + g3 + g4) / 4); + icon24Data[id + 2] = (u8) ((b1 + b2 + b3 + b4) / 4); + icon24Data[id + 3] = (u8) ((a1 + a2 + a3 + a4) / 4); } } + u16* icon24 = image_data_to_tiles(icon24Data, 24, 24, RGB565, NULL); + if(icon24 == NULL) { + return 1; + } + SMDH smdh; for(int i = 0; i < 0x10; i++) { utf8_to_utf16(smdh.titles[i].shortTitle, shortTitle, 0x40);