mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
converted all bitmaps to RGB565
This commit is contained in:
parent
a42dbedf82
commit
256f2465d8
@ -4,34 +4,24 @@
|
|||||||
#include "vff.h"
|
#include "vff.h"
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
static void Screenshot_CvtAndTranspose(u8 *dest, u16 *fb, u32 w, u32 stride)
|
static void Screenshot_Transpose(u16 *dest, const u16 *fb, u32 w, u32 stride)
|
||||||
{
|
{
|
||||||
for (u32 y = 0; y < SCREEN_HEIGHT; y++) {
|
for (u32 y = 0; y < SCREEN_HEIGHT; y++) {
|
||||||
for (u32 x = 0; x < w; x++) {
|
for (u32 x = 0; x < w; x++)
|
||||||
u8 r, g, b;
|
*(dest++) = GetColor(fb, x, y);
|
||||||
u16 rgb_s = GetColor(fb, x, y);
|
|
||||||
|
|
||||||
r = ((rgb_s >> 11) & 0x1F) << 3;
|
|
||||||
g = ((rgb_s >> 5) & 0x3F) << 2;
|
|
||||||
b = (rgb_s & 0x1F) << 3;
|
|
||||||
|
|
||||||
*(dest++) = r;
|
|
||||||
*(dest++) = g;
|
|
||||||
*(dest++) = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest += stride;
|
dest += stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateScreenshot(void) {
|
void CreateScreenshot(void) {
|
||||||
|
u8 *png;
|
||||||
|
u16 *buffer;
|
||||||
DsTime dstime;
|
DsTime dstime;
|
||||||
size_t png_size;
|
size_t png_size;
|
||||||
u8 *png, *buffer;
|
|
||||||
char filename[64];
|
char filename[64];
|
||||||
u32 snapbuf_size, snap_w, snap_h, bot_offset;
|
u32 snapbuf_size, snap_w, snap_h, bot_offset;
|
||||||
|
|
||||||
snapbuf_size = (SCREEN_WIDTH_TOP * SCREEN_HEIGHT * 3) * 2;
|
snapbuf_size = (SCREEN_WIDTH_TOP * SCREEN_HEIGHT * BYTES_PER_PIXEL) * 2;
|
||||||
snap_w = SCREEN_WIDTH_TOP;
|
snap_w = SCREEN_WIDTH_TOP;
|
||||||
snap_h = SCREEN_HEIGHT * 2;
|
snap_h = SCREEN_HEIGHT * 2;
|
||||||
|
|
||||||
@ -45,12 +35,13 @@ void CreateScreenshot(void) {
|
|||||||
buffer = malloc(snapbuf_size);
|
buffer = malloc(snapbuf_size);
|
||||||
if (!buffer) return;
|
if (!buffer) return;
|
||||||
|
|
||||||
memset(buffer, 0x1F, snapbuf_size); // gray background
|
for (unsigned i = snapbuf_size/4; i < snapbuf_size/2; i++)
|
||||||
|
buffer[i] = RGB(0x1F, 0x1F, 0x1F); // gray background
|
||||||
|
|
||||||
bot_offset = ((400 * SCREEN_HEIGHT) + 40) * 3;
|
bot_offset = (SCREEN_WIDTH_TOP * SCREEN_HEIGHT) + 40;
|
||||||
|
|
||||||
Screenshot_CvtAndTranspose(buffer, TOP_SCREEN, SCREEN_WIDTH_TOP, 0);
|
Screenshot_Transpose(buffer, TOP_SCREEN, SCREEN_WIDTH_TOP, 0);
|
||||||
Screenshot_CvtAndTranspose(buffer + bot_offset, BOT_SCREEN, SCREEN_WIDTH_BOT, 80 * 3);
|
Screenshot_Transpose(buffer + bot_offset, BOT_SCREEN, SCREEN_WIDTH_BOT, 80);
|
||||||
|
|
||||||
png = PNG_Compress(buffer, snap_w, snap_h, &png_size);
|
png = PNG_Compress(buffer, snap_w, snap_h, &png_size);
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ void ClearScreenF(bool clear_main, bool clear_alt, u32 color)
|
|||||||
if (clear_alt) ClearScreen(ALT_SCREEN, color);
|
if (clear_alt) ClearScreen(ALT_SCREEN, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 GetColor(u16 *screen, int x, int y)
|
u16 GetColor(const u16 *screen, int x, int y)
|
||||||
{
|
{
|
||||||
return screen[PIXEL_OFFSET(x, y)];
|
return screen[PIXEL_OFFSET(x, y)];
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ void DrawRectangle(u16 *screen, int x, int y, u32 width, u32 height, u32 color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBitmap(u16 *screen, int x, int y, u32 w, u32 h, const u8* bitmap)
|
void DrawBitmap(u16 *screen, int x, int y, u32 w, u32 h, const u16* bitmap)
|
||||||
{
|
{
|
||||||
// on negative values: center the bitmap
|
// on negative values: center the bitmap
|
||||||
if (x < 0) x = (SCREEN_WIDTH(screen) - w) >> 1;
|
if (x < 0) x = (SCREEN_WIDTH(screen) - w) >> 1;
|
||||||
@ -183,10 +183,8 @@ void DrawBitmap(u16 *screen, int x, int y, u32 w, u32 h, const u8* bitmap)
|
|||||||
|
|
||||||
screen += PIXEL_OFFSET(x, y);
|
screen += PIXEL_OFFSET(x, y);
|
||||||
while(h--) {
|
while(h--) {
|
||||||
for (u32 i = 0; i < w; i++) {
|
for (u32 i = 0; i < w; i++)
|
||||||
screen[i * SCREEN_HEIGHT] = RGB(bitmap[2], bitmap[1], bitmap[0]);
|
screen[i * SCREEN_HEIGHT] = *(bitmap++);
|
||||||
bitmap += 3;
|
|
||||||
}
|
|
||||||
screen--;
|
screen--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,7 +390,7 @@ void ShowString(const char *format, ...)
|
|||||||
} else ClearScreenF(true, false, COLOR_STD_BG);
|
} else ClearScreenF(true, false, COLOR_STD_BG);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowIconString(u8* icon, int w, int h, const char *format, ...)
|
void ShowIconString(u16* icon, int w, int h, const char *format, ...)
|
||||||
{
|
{
|
||||||
static const u32 icon_offset = 10;
|
static const u32 icon_offset = 10;
|
||||||
u32 str_width, str_height, tot_height;
|
u32 str_width, str_height, tot_height;
|
||||||
|
@ -48,13 +48,13 @@ bool ShowUnlockSequence(u32 seqlvl, const char *format, ...);
|
|||||||
u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h);
|
u8* GetFontFromPbm(const void* pbm, const u32 pbm_size, u32* w, u32* h);
|
||||||
bool SetFontFromPbm(const void* pbm, const u32 pbm_size);
|
bool SetFontFromPbm(const void* pbm, const u32 pbm_size);
|
||||||
|
|
||||||
u16 GetColor(u16 *screen, int x, int y);
|
u16 GetColor(const u16 *screen, int x, int y);
|
||||||
|
|
||||||
void ClearScreen(u16 *screen, u32 color);
|
void ClearScreen(u16 *screen, u32 color);
|
||||||
void ClearScreenF(bool clear_main, bool clear_alt, u32 color);
|
void ClearScreenF(bool clear_main, bool clear_alt, u32 color);
|
||||||
void DrawPixel(u16 *screen, int x, int y, u32 color);
|
void DrawPixel(u16 *screen, int x, int y, u32 color);
|
||||||
void DrawRectangle(u16 *screen, int x, int y, u32 width, u32 height, u32 color);
|
void DrawRectangle(u16 *screen, int x, int y, u32 width, u32 height, u32 color);
|
||||||
void DrawBitmap(u16 *screen, int x, int y, u32 w, u32 h, const u8* bitmap);
|
void DrawBitmap(u16 *screen, int x, int y, u32 w, u32 h, const u16* bitmap);
|
||||||
void DrawQrCode(u16 *screen, const u8* qrcode);
|
void DrawQrCode(u16 *screen, const u8* qrcode);
|
||||||
|
|
||||||
void DrawCharacter(u16 *screen, int character, int x, int y, u32 color, u32 bgcolor);
|
void DrawCharacter(u16 *screen, int character, int x, int y, u32 color, u32 bgcolor);
|
||||||
@ -74,7 +74,7 @@ void FormatNumber(char* str, u64 number);
|
|||||||
void FormatBytes(char* str, u64 bytes);
|
void FormatBytes(char* str, u64 bytes);
|
||||||
|
|
||||||
void ShowString(const char *format, ...);
|
void ShowString(const char *format, ...);
|
||||||
void ShowIconString(u8* icon, int w, int h, const char *format, ...);
|
void ShowIconString(u16* icon, int w, int h, const char *format, ...);
|
||||||
bool ShowPrompt(bool ask, const char *format, ...);
|
bool ShowPrompt(bool ask, const char *format, ...);
|
||||||
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...);
|
u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...);
|
||||||
u32 ShowFileScrollPrompt(u32 n, const DirEntry** entries, bool hide_ext, const char *format, ...);
|
u32 ShowFileScrollPrompt(u32 n, const DirEntry** entries, bool hide_ext, const char *format, ...);
|
||||||
|
@ -52,7 +52,7 @@ u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TWL icon: 32x32 pixel, 8x8 tiles
|
// TWL icon: 32x32 pixel, 8x8 tiles
|
||||||
u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) {
|
u32 GetTwlIcon(u16* icon, const TwlIconData* twl_icon) {
|
||||||
const u32 h = TWLICON_DIM_ICON; // fixed size
|
const u32 h = TWLICON_DIM_ICON; // fixed size
|
||||||
const u32 w = TWLICON_DIM_ICON; // fixed size
|
const u32 w = TWLICON_DIM_ICON; // fixed size
|
||||||
const u16* palette = twl_icon->palette;
|
const u16* palette = twl_icon->palette;
|
||||||
@ -60,13 +60,17 @@ u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) {
|
|||||||
for (u32 y = 0; y < h; y += 8) {
|
for (u32 y = 0; y < h; y += 8) {
|
||||||
for (u32 x = 0; x < w; x += 8) {
|
for (u32 x = 0; x < w; x += 8) {
|
||||||
for (u32 i = 0; i < 8*8; i++) {
|
for (u32 i = 0; i < 8*8; i++) {
|
||||||
|
u16 pix555;
|
||||||
|
u8 r, g, b;
|
||||||
u32 ix = x + (i & 0x7);
|
u32 ix = x + (i & 0x7);
|
||||||
u32 iy = y + (i >> 3);
|
u32 iy = y + (i >> 3);
|
||||||
u16 pix555 = palette[((i%2) ? (*pix4 >> 4) : *pix4) & 0xF];
|
|
||||||
u8* pix888 = icon + ((iy * w) + ix) * 3;
|
pix555 = palette[((i%2) ? (*pix4 >> 4) : *pix4) & 0xF];
|
||||||
*(pix888++) = ((pix555 >> 10) & 0x1F) << 3; // B
|
r = pix555 & 0x1F;
|
||||||
*(pix888++) = ((pix555 >> 5) & 0x1F) << 3; // G
|
g = ((pix555 >> 5) & 0x1F) << 1;
|
||||||
*(pix888++) = ((pix555 >> 0) & 0x1F) << 3; // R
|
g |= (g >> 1) & 1;
|
||||||
|
b = (pix555 >> 10) & 0x1F;
|
||||||
|
icon[(iy * w) + ix] = (r << 11) | (g << 5) | b;
|
||||||
if (i % 2) pix4++;
|
if (i % 2) pix4++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
(v == 0x0003) ? 0x1240 : (v == 0x0103) ? 0x23C0 : 0x0000)
|
(v == 0x0003) ? 0x1240 : (v == 0x0103) ? 0x23C0 : 0x0000)
|
||||||
#define TWLICON_SIZE_DESC 128
|
#define TWLICON_SIZE_DESC 128
|
||||||
#define TWLICON_DIM_ICON 32
|
#define TWLICON_DIM_ICON 32
|
||||||
#define TWLICON_SIZE_ICON (TWLICON_DIM_ICON * TWLICON_DIM_ICON * 3) // w * h * bpp (rgb888)
|
#define TWLICON_SIZE_ICON (TWLICON_DIM_ICON * TWLICON_DIM_ICON * 2) // w * h * bpp (rgb565)
|
||||||
#define NDS_LOGO_CRC16 0xCF56
|
#define NDS_LOGO_CRC16 0xCF56
|
||||||
|
|
||||||
#define TWL_UNITCODE_NTR 0x00
|
#define TWL_UNITCODE_NTR 0x00
|
||||||
@ -126,7 +126,7 @@ typedef struct {
|
|||||||
u32 ValidateTwlHeader(TwlHeader* twl);
|
u32 ValidateTwlHeader(TwlHeader* twl);
|
||||||
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon);
|
u32 LoadTwlMetaData(const char* path, TwlHeader* hdr, TwlIconData* icon);
|
||||||
u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon);
|
u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon);
|
||||||
u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon);
|
u32 GetTwlIcon(u16* icon, const TwlIconData* twl_icon);
|
||||||
|
|
||||||
u32 FindNitroRomDir(u32 dirid, u32* fileid, u8** fnt_entry, TwlHeader* hdr, u8* fnt, u8* fat);
|
u32 FindNitroRomDir(u32 dirid, u32* fileid, u8** fnt_entry, TwlHeader* hdr, u8* fnt, u8* fat);
|
||||||
u32 NextNitroRomEntry(u32* fileid, u8** fnt_entry);
|
u32 NextNitroRomEntry(u32* fileid, u8** fnt_entry);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, \
|
32, 33, 40, 41, 34, 35, 42, 43, 48, 49, 56, 57, 50, 51, 58, 59, \
|
||||||
36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63
|
36, 37, 44, 45, 38, 39, 46, 47, 52, 53, 60, 61, 54, 55, 62, 63
|
||||||
|
|
||||||
u32 ConvertSmdhIcon(u8* icon, const u16* smdh_icon, u32 w, u32 h) {
|
u32 ConvertSmdhIcon(u16* icon, const u16* smdh_icon, u32 w, u32 h) {
|
||||||
const u32 lut[8*8] = { SMDH_LUT };
|
const u32 lut[8*8] = { SMDH_LUT };
|
||||||
u16* pix565 = (u16*) smdh_icon;
|
u16* pix565 = (u16*) smdh_icon;
|
||||||
for (u32 y = 0; y < h; y += 8) {
|
for (u32 y = 0; y < h; y += 8) {
|
||||||
@ -16,11 +16,7 @@ u32 ConvertSmdhIcon(u8* icon, const u16* smdh_icon, u32 w, u32 h) {
|
|||||||
for (u32 i = 0; i < 8*8; i++) {
|
for (u32 i = 0; i < 8*8; i++) {
|
||||||
u32 ix = x + (lut[i] & 0x7);
|
u32 ix = x + (lut[i] & 0x7);
|
||||||
u32 iy = y + (lut[i] >> 3);
|
u32 iy = y + (lut[i] >> 3);
|
||||||
u8* pix888 = icon + ((iy * w) + ix) * 3;
|
icon[(iy * w) + ix] = *(pix565++);
|
||||||
*(pix888++) = ((*pix565 >> 0) & 0x1F) << 3; // B
|
|
||||||
*(pix888++) = ((*pix565 >> 5) & 0x3F) << 2; // G
|
|
||||||
*(pix888++) = ((*pix565 >> 11) & 0x1F) << 3; // R
|
|
||||||
pix565++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,11 +48,11 @@ u32 GetSmdhPublisher(char* pub, const Smdh* smdh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// small icons are 24x24 => 0x6C0 byte in RGB888
|
// small icons are 24x24 => 0x6C0 byte in RGB888
|
||||||
u32 GetSmdhIconSmall(u8* icon, const Smdh* smdh) {
|
u32 GetSmdhIconSmall(u16* icon, const Smdh* smdh) {
|
||||||
return ConvertSmdhIcon(icon, smdh->icon_small, SMDH_DIM_ICON_SMALL, SMDH_DIM_ICON_SMALL);
|
return ConvertSmdhIcon(icon, smdh->icon_small, SMDH_DIM_ICON_SMALL, SMDH_DIM_ICON_SMALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// big icons are 48x48 => 0x1B00 byte in RGB888
|
// big icons are 48x48 => 0x1B00 byte in RGB888
|
||||||
u32 GetSmdhIconBig(u8* icon, const Smdh* smdh) {
|
u32 GetSmdhIconBig(u16* icon, const Smdh* smdh) {
|
||||||
return ConvertSmdhIcon(icon, smdh->icon_big, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG);
|
return ConvertSmdhIcon(icon, smdh->icon_big, SMDH_DIM_ICON_BIG, SMDH_DIM_ICON_BIG);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#define SMDH_SIZE_PUBLISHER 64
|
#define SMDH_SIZE_PUBLISHER 64
|
||||||
#define SMDH_DIM_ICON_SMALL 24
|
#define SMDH_DIM_ICON_SMALL 24
|
||||||
#define SMDH_DIM_ICON_BIG 48
|
#define SMDH_DIM_ICON_BIG 48
|
||||||
#define SMDH_SIZE_ICON_SMALL (SMDH_DIM_ICON_SMALL * SMDH_DIM_ICON_SMALL * 3) // w * h * bpp (rgb888)
|
#define SMDH_SIZE_ICON_SMALL (SMDH_DIM_ICON_SMALL * SMDH_DIM_ICON_SMALL * 2) // w * h * bpp (rgb565)
|
||||||
#define SMDH_SIZE_ICON_BIG (SMDH_DIM_ICON_BIG * SMDH_DIM_ICON_BIG * 3) // w * h * bpp (rgb888)
|
#define SMDH_SIZE_ICON_BIG (SMDH_DIM_ICON_BIG * SMDH_DIM_ICON_BIG * 2) // w * h * bpp (rgb565)
|
||||||
|
|
||||||
// see: https://www.3dbrew.org/wiki/SMDH#Application_Titles
|
// see: https://www.3dbrew.org/wiki/SMDH#Application_Titles
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -42,5 +42,5 @@ typedef struct {
|
|||||||
u32 GetSmdhDescShort(char* desc, const Smdh* smdh);
|
u32 GetSmdhDescShort(char* desc, const Smdh* smdh);
|
||||||
u32 GetSmdhDescLong(char* desc, const Smdh* smdh);
|
u32 GetSmdhDescLong(char* desc, const Smdh* smdh);
|
||||||
u32 GetSmdhPublisher(char* pub, const Smdh* smdh);
|
u32 GetSmdhPublisher(char* pub, const Smdh* smdh);
|
||||||
u32 GetSmdhIconSmall(u8* icon, const Smdh* smdh);
|
u32 GetSmdhIconSmall(u16* icon, const Smdh* smdh);
|
||||||
u32 GetSmdhIconBig(u8* icon, const Smdh* smdh);
|
u32 GetSmdhIconBig(u16* icon, const Smdh* smdh);
|
||||||
|
@ -115,10 +115,10 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 SplashInit(const char* modestr) {
|
u32 SplashInit(const char* modestr) {
|
||||||
|
u16* bitmap;
|
||||||
u64 splash_size;
|
u64 splash_size;
|
||||||
u32 splash_width, splash_height;
|
u32 splash_width, splash_height;
|
||||||
u8* splash = FindVTarFileInfo(VRAM0_SPLASH_PNG, &splash_size);
|
u8* splash = FindVTarFileInfo(VRAM0_SPLASH_PNG, &splash_size);
|
||||||
u8* bitmap = NULL;
|
|
||||||
const char* namestr = FLAVOR " " VERSION;
|
const char* namestr = FLAVOR " " VERSION;
|
||||||
const char* loadstr = "booting...";
|
const char* loadstr = "booting...";
|
||||||
const u32 pos_xb = 10;
|
const u32 pos_xb = 10;
|
||||||
@ -131,7 +131,10 @@ u32 SplashInit(const char* modestr) {
|
|||||||
if (splash) {
|
if (splash) {
|
||||||
bitmap = PNG_Decompress(splash, splash_size, &splash_width, &splash_height);
|
bitmap = PNG_Decompress(splash, splash_size, &splash_width, &splash_height);
|
||||||
if (bitmap) DrawBitmap(TOP_SCREEN, -1, -1, splash_width, splash_height, bitmap);
|
if (bitmap) DrawBitmap(TOP_SCREEN, -1, -1, splash_width, splash_height, bitmap);
|
||||||
} else DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(" VRAM0_SPLASH_PNG " not found)");
|
} else {
|
||||||
|
DrawStringF(TOP_SCREEN, 10, 10, COLOR_STD_FONT, COLOR_TRANSPARENT, "(" VRAM0_SPLASH_PNG " not found)");
|
||||||
|
bitmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr),
|
if (modestr) DrawStringF(TOP_SCREEN, SCREEN_WIDTH_TOP - 10 - GetDrawStringWidth(modestr),
|
||||||
SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr);
|
SCREEN_HEIGHT - 10 - GetDrawStringHeight(modestr), COLOR_STD_FONT, COLOR_TRANSPARENT, modestr);
|
||||||
@ -144,7 +147,7 @@ u32 SplashInit(const char* modestr) {
|
|||||||
DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, loadstr);
|
DrawStringF(BOT_SCREEN, pos_xu, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, loadstr);
|
||||||
DrawStringF(BOT_SCREEN, pos_xb, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "built: " DBUILTL);
|
DrawStringF(BOT_SCREEN, pos_xb, pos_yu, COLOR_STD_FONT, COLOR_STD_BG, "built: " DBUILTL);
|
||||||
|
|
||||||
if (bitmap) free(bitmap);
|
free(bitmap);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +497,7 @@ u32 SdFormatMenu(const char* slabel) {
|
|||||||
u32 FileGraphicsViewer(const char* path) {
|
u32 FileGraphicsViewer(const char* path) {
|
||||||
const u32 max_size = SCREEN_SIZE(ALT_SCREEN);
|
const u32 max_size = SCREEN_SIZE(ALT_SCREEN);
|
||||||
u64 filetype = IdentifyFileType(path);
|
u64 filetype = IdentifyFileType(path);
|
||||||
u8* bitmap = NULL;
|
u16* bitmap = NULL;
|
||||||
u8* input = (u8*)malloc(max_size);
|
u8* input = (u8*)malloc(max_size);
|
||||||
u32 w = 0;
|
u32 w = 0;
|
||||||
u32 h = 0;
|
u32 h = 0;
|
||||||
@ -519,8 +522,8 @@ u32 FileGraphicsViewer(const char* path) {
|
|||||||
ClearScreenF(true, true, COLOR_STD_BG);
|
ClearScreenF(true, true, COLOR_STD_BG);
|
||||||
} else ret = 1;
|
} else ret = 1;
|
||||||
|
|
||||||
if (bitmap) free(bitmap);
|
free(bitmap);
|
||||||
if (input) free(input);
|
free(input);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,43 +5,68 @@
|
|||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
#ifndef MONITOR_HEAP
|
#ifndef MONITOR_HEAP
|
||||||
static inline void _rgb_swap(u8 *img, size_t sz)
|
// dest and src can overlap
|
||||||
|
static inline void _rgb24_to_rgb565(u16 *dest, const u8 *src, size_t dim)
|
||||||
{
|
{
|
||||||
// maybe process in batches of 3 pixels / 12 bytes at a time?
|
for (size_t i = 0; i < dim; i++) {
|
||||||
for (size_t i = 0; i < sz; i+=3) {
|
u8 r, g, b;
|
||||||
u8 c = img[i];
|
|
||||||
img[i] = img[i + 2];
|
r = *(src++) >> 3;
|
||||||
img[i + 2] = c;
|
g = *(src++) >> 2;
|
||||||
|
b = *(src++) >> 3;
|
||||||
|
*(dest++) = r << 11 | g << 5 | b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h)
|
// dest and src CAN NOT overlap
|
||||||
|
static inline void _rgb565_to_rgb24(u8 *dest, const u16 *src, size_t dim)
|
||||||
{
|
{
|
||||||
u8 *img;
|
for (size_t i = 0; i < dim; i++) {
|
||||||
u32 res;
|
u16 rgb = *(src++);
|
||||||
size_t w_, h_;
|
|
||||||
|
*(dest++) = (rgb >> 11) << 3;
|
||||||
|
*(dest++) = ((rgb >> 5) & 0x3F) << 2;
|
||||||
|
*(dest++) = (rgb & 0x1F) << 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h)
|
||||||
|
{
|
||||||
|
u16 *img;
|
||||||
|
unsigned res;
|
||||||
|
size_t width, height;
|
||||||
|
|
||||||
img = NULL;
|
img = NULL;
|
||||||
res = lodepng_decode24(&img, &w_, &h_, png, png_len);
|
res = lodepng_decode24((u8**)&img, &width, &height, png, png_len);
|
||||||
if (res) {
|
if (res) {
|
||||||
free(img);
|
free(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
_rgb_swap(img, w_ * h_ * 3);
|
|
||||||
if (w) *w = w_;
|
|
||||||
if (h) *h = h_;
|
|
||||||
|
|
||||||
return img;
|
_rgb24_to_rgb565(img, (const u8*)img, width * height);
|
||||||
|
if (w) *w = width;
|
||||||
|
if (h) *h = height;
|
||||||
|
|
||||||
|
// the allocated buffer will be w*h*3 bytes long, but only w*h*2 bytes will be used
|
||||||
|
// however, this is not a problem and it'll all be freed with a regular free() call
|
||||||
|
return (u16*)img;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *PNG_Compress(const u8 *fb, u32 w, u32 h, size_t *png_sz)
|
u8 *PNG_Compress(const u16 *fb, u32 w, u32 h, size_t *png_sz)
|
||||||
{
|
{
|
||||||
u8 *img;
|
u8 *img, *buf;
|
||||||
u32 res;
|
unsigned res;
|
||||||
size_t png_size;
|
size_t png_size;
|
||||||
|
|
||||||
img = NULL;
|
img = NULL;
|
||||||
res = lodepng_encode24(&img, &png_size, fb, w, h);
|
|
||||||
|
buf = malloc(w * h * 3);
|
||||||
|
if (!buf) return NULL;
|
||||||
|
|
||||||
|
_rgb565_to_rgb24(buf, fb, w * h);
|
||||||
|
res = lodepng_encode24(&img, &png_size, buf, w, h);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
free(img);
|
free(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
|
|
||||||
#define PNG_MAGIC 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
|
#define PNG_MAGIC 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
|
||||||
|
|
||||||
u8 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h);
|
u16 *PNG_Decompress(const u8 *png, size_t png_len, u32 *w, u32 *h);
|
||||||
u8 *PNG_Compress(const u8 *fb, u32 w, u32 h, size_t *png_sz);
|
u8 *PNG_Compress(const u16 *fb, u32 w, u32 h, size_t *png_sz);
|
||||||
|
@ -1971,7 +1971,7 @@ u32 LoadSmdhFromGameFile(const char* path, Smdh* smdh) {
|
|||||||
u32 ShowSmdhTitleInfo(Smdh* smdh) {
|
u32 ShowSmdhTitleInfo(Smdh* smdh) {
|
||||||
const u8 smdh_magic[] = { SMDH_MAGIC };
|
const u8 smdh_magic[] = { SMDH_MAGIC };
|
||||||
const u32 lwrap = 24;
|
const u32 lwrap = 24;
|
||||||
u8 icon[SMDH_SIZE_ICON_BIG];
|
u16 icon[SMDH_SIZE_ICON_BIG];
|
||||||
char desc_l[SMDH_SIZE_DESC_LONG+1];
|
char desc_l[SMDH_SIZE_DESC_LONG+1];
|
||||||
char desc_s[SMDH_SIZE_DESC_SHORT+1];
|
char desc_s[SMDH_SIZE_DESC_SHORT+1];
|
||||||
char pub[SMDH_SIZE_PUBLISHER+1];
|
char pub[SMDH_SIZE_PUBLISHER+1];
|
||||||
@ -1992,7 +1992,7 @@ u32 ShowSmdhTitleInfo(Smdh* smdh) {
|
|||||||
|
|
||||||
u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon) {
|
u32 ShowTwlIconTitleInfo(TwlIconData* twl_icon) {
|
||||||
const u32 lwrap = 24;
|
const u32 lwrap = 24;
|
||||||
u8 icon[TWLICON_SIZE_ICON];
|
u16 icon[TWLICON_SIZE_ICON];
|
||||||
char desc[TWLICON_SIZE_DESC+1];
|
char desc[TWLICON_SIZE_DESC+1];
|
||||||
if ((GetTwlIcon(icon, twl_icon) != 0) ||
|
if ((GetTwlIcon(icon, twl_icon) != 0) ||
|
||||||
(GetTwlTitle(desc, twl_icon) != 0))
|
(GetTwlTitle(desc, twl_icon) != 0))
|
||||||
|
@ -1840,7 +1840,7 @@ bool ExecuteGM9Script(const char* path_script) {
|
|||||||
if (preview_mode > 2) {
|
if (preview_mode > 2) {
|
||||||
char* preview_str = get_var("PREVIEW_MODE", NULL);
|
char* preview_str = get_var("PREVIEW_MODE", NULL);
|
||||||
u32 bitmap_width, bitmap_height;
|
u32 bitmap_width, bitmap_height;
|
||||||
u8* bitmap = NULL;
|
u16* bitmap = NULL;
|
||||||
|
|
||||||
u8* png = (u8*) malloc(SCREEN_SIZE_TOP);
|
u8* png = (u8*) malloc(SCREEN_SIZE_TOP);
|
||||||
if (png) {
|
if (png) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user