From 4cc5ffff32ac34c8402b39c5af6cf015da51c6e3 Mon Sep 17 00:00:00 2001 From: "Colton G. Rushton" Date: Thu, 21 May 2020 12:52:40 -0300 Subject: [PATCH 01/24] Undo the bettercamera update This screwed up the bettercamera for whatever reason. Urgent hotfix. Please test --- src/game/bettercamera.inc.h | 57 +++++++++++-------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h index 1dbe2f3b..9e34a656 100644 --- a/src/game/bettercamera.inc.h +++ b/src/game/bettercamera.inc.h @@ -74,9 +74,9 @@ struct newcam_hardpos newcam_fixedcam[] = #endif // noaccel s16 newcam_yaw; //Z axis rotation -f32 newcam_yaw_acc; +s8 newcam_yaw_acc; s16 newcam_tilt = 1500; //Y axis rotation -f32 newcam_tilt_acc; +s8 newcam_tilt_acc; u16 newcam_distance = 750; //The distance the camera stays from the player u16 newcam_distance_target = 750; //The distance the player camera tries to reach. f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario. @@ -187,20 +187,13 @@ void newcam_diagnostics(void) print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance); } -static s16 newcam_adjust_value(s16 var, s16 val, s8 max) +static s16 newcam_adjust_value(s16 var, s16 val) { - if (val > 0) - { - var += val; - if (var > max) - var = max; - } - else if (val < 0) - { - var += val; - if (var < max) - var = max; - } + var += val; + if (var > 100) + var = 100; + if (var < -100) + var = -100; return var; } @@ -240,8 +233,6 @@ static int ivrt(u8 axis) static void newcam_rotate_button(void) { - f32 intendedXMag; - f32 intendedYMag; if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) //8 directional camera rotation input for buttons. { if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0) @@ -272,33 +263,27 @@ static void newcam_rotate_button(void) if (newcam_modeflags & NC_FLAG_XTURN) { if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel, 100); + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel); else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel, -100); + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel); else - if (!newcam_analogue) - { #ifdef noaccel newcam_yaw_acc = 0; #else newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); #endif - } } if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel, 100); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel); else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel, -100); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel); else - if (!newcam_analogue) - { #ifdef noaccel newcam_tilt_acc = 0; #else newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); #endif - } newcam_framessincec[0] += 1; newcam_framessincec[1] += 1; @@ -330,8 +315,6 @@ static void newcam_rotate_button(void) if (newcam_analogue == 1) //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable. { //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button - intendedXMag = gPlayer2Controller->stickX*1.25; - intendedYMag = gPlayer2Controller->stickY*1.25; if (ABS(gPlayer2Controller->stickX) > 20 && newcam_modeflags & NC_FLAG_XTURN) { if (newcam_modeflags & NC_FLAG_8D) @@ -360,24 +343,16 @@ static void newcam_rotate_button(void) } } else - { - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-gPlayer2Controller->stickX/8, intendedXMag); - } + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,(-gPlayer2Controller->stickX/4)); } else - if (newcam_analogue) - { newcam_cstick_down = 0; newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); - } if (ABS(gPlayer2Controller->stickY) > 20 && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-gPlayer2Controller->stickY/8, intendedYMag); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,(-gPlayer2Controller->stickY/4)); else - if (newcam_analogue) - { newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); - } } if (newcam_mouse == 1) @@ -439,9 +414,9 @@ static void newcam_update_values(void) {//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90. u8 waterflag = 0; if (newcam_modeflags & NC_FLAG_XTURN) - newcam_yaw += ((ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10)))); + newcam_yaw += (ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10))); if (((newcam_tilt < 12000 && newcam_tilt_acc*ivrt(1) > 0) || (newcam_tilt > -12000 && newcam_tilt_acc*ivrt(1) < 0)) && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt += ((ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10)))); + newcam_tilt += (ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10))); else { if (newcam_tilt > 12000) From d139e23177f9d7f97348286f995f32426742979e Mon Sep 17 00:00:00 2001 From: "Colton G. Rushton" Date: Thu, 21 May 2020 13:40:02 -0300 Subject: [PATCH 02/24] Unrevert the bettercamera update but this time actually fix it --- src/game/bettercamera.inc.h | 57 ++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h index 9e34a656..e6d3bf6f 100644 --- a/src/game/bettercamera.inc.h +++ b/src/game/bettercamera.inc.h @@ -74,9 +74,9 @@ struct newcam_hardpos newcam_fixedcam[] = #endif // noaccel s16 newcam_yaw; //Z axis rotation -s8 newcam_yaw_acc; +s16 newcam_yaw_acc; s16 newcam_tilt = 1500; //Y axis rotation -s8 newcam_tilt_acc; +s16 newcam_tilt_acc; u16 newcam_distance = 750; //The distance the camera stays from the player u16 newcam_distance_target = 750; //The distance the player camera tries to reach. f32 newcam_pos_target[3]; //The position the camera is basing calculations off. *usually* Mario. @@ -187,13 +187,20 @@ void newcam_diagnostics(void) print_text_fmt_int(32,32,"DISTANCE %d",newcam_distance); } -static s16 newcam_adjust_value(s16 var, s16 val) +static s16 newcam_adjust_value(s16 var, s16 val, s16 max) { - var += val; - if (var > 100) - var = 100; - if (var < -100) - var = -100; + if (val > 0) + { + var += val; + if (var > max) + var = max; + } + else if (val < 0) + { + var += val; + if (var < max) + var = max; + } return var; } @@ -233,6 +240,8 @@ static int ivrt(u8 axis) static void newcam_rotate_button(void) { + f32 intendedXMag; + f32 intendedYMag; if ((newcam_modeflags & NC_FLAG_8D || newcam_modeflags & NC_FLAG_4D) && newcam_modeflags & NC_FLAG_XTURN) //8 directional camera rotation input for buttons. { if ((gPlayer1Controller->buttonPressed & L_CBUTTONS) && newcam_analogue == 0) @@ -263,27 +272,33 @@ static void newcam_rotate_button(void) if (newcam_modeflags & NC_FLAG_XTURN) { if ((gPlayer1Controller->buttonDown & L_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel); + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,accel, 100); else if ((gPlayer1Controller->buttonDown & R_CBUTTONS) && newcam_analogue == 0) - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel); + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-accel, -100); else + if (!newcam_analogue) + { #ifdef noaccel newcam_yaw_acc = 0; #else newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); #endif + } } if (gPlayer1Controller->buttonDown & U_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,accel, 100); else if (gPlayer1Controller->buttonDown & D_CBUTTONS && newcam_modeflags & NC_FLAG_YTURN && newcam_analogue == 0) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-accel, -100); else + if (!newcam_analogue) + { #ifdef noaccel newcam_tilt_acc = 0; #else newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); #endif + } newcam_framessincec[0] += 1; newcam_framessincec[1] += 1; @@ -315,6 +330,8 @@ static void newcam_rotate_button(void) if (newcam_analogue == 1) //There's not much point in keeping this behind a check, but it wouldn't hurt, just incase any 2player shenanigans ever happen, it makes it easy to disable. { //The joystick values cap at 80, so divide by 8 to get the same net result at maximum turn as the button + intendedXMag = gPlayer2Controller->stickX*1.25; + intendedYMag = gPlayer2Controller->stickY*1.25; if (ABS(gPlayer2Controller->stickX) > 20 && newcam_modeflags & NC_FLAG_XTURN) { if (newcam_modeflags & NC_FLAG_8D) @@ -343,16 +360,24 @@ static void newcam_rotate_button(void) } } else - newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,(-gPlayer2Controller->stickX/4)); + { + newcam_yaw_acc = newcam_adjust_value(newcam_yaw_acc,-gPlayer2Controller->stickX/8, intendedXMag); + } } else + if (newcam_analogue) + { newcam_cstick_down = 0; newcam_yaw_acc -= (newcam_yaw_acc*newcam_degrade); + } if (ABS(gPlayer2Controller->stickY) > 20 && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,(-gPlayer2Controller->stickY/4)); + newcam_tilt_acc = newcam_adjust_value(newcam_tilt_acc,-gPlayer2Controller->stickY/8, intendedYMag); else + if (newcam_analogue) + { newcam_tilt_acc -= (newcam_tilt_acc*newcam_degrade); + } } if (newcam_mouse == 1) @@ -414,9 +439,9 @@ static void newcam_update_values(void) {//For tilt, this just limits it so it doesn't go further than 90 degrees either way. 90 degrees is actually 16384, but can sometimes lead to issues, so I just leave it shy of 90. u8 waterflag = 0; if (newcam_modeflags & NC_FLAG_XTURN) - newcam_yaw += (ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10))); + newcam_yaw += ((ivrt(0)*(newcam_yaw_acc*(newcam_sensitivityX/10)))); if (((newcam_tilt < 12000 && newcam_tilt_acc*ivrt(1) > 0) || (newcam_tilt > -12000 && newcam_tilt_acc*ivrt(1) < 0)) && newcam_modeflags & NC_FLAG_YTURN) - newcam_tilt += (ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10))); + newcam_tilt += ((ivrt(1)*(newcam_tilt_acc*(newcam_sensitivityY/10)))); else { if (newcam_tilt > 12000) From 1298cd601734bfd5a1455f4d241272da74d7a429 Mon Sep 17 00:00:00 2001 From: IvanDSM Date: Thu, 21 May 2020 14:19:20 -0300 Subject: [PATCH 03/24] Add commit hash to window title for nightly builds. This also adds a flag for detecting nightly builds in the code. --- Makefile | 9 +++++++++ src/pc/gfx/gfx_sdl2.c | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae8b01a4..9356281c 100644 --- a/Makefile +++ b/Makefile @@ -123,6 +123,15 @@ endif endif endif +# Stuff for showing the git hash in the intro on nightly builds +# From https://stackoverflow.com/questions/44038428/include-git-commit-hash-and-or-branch-name-in-c-c-source +ifeq ($(shell git rev-parse --abbrev-ref HEAD),nightly) + $(info Hello Caldera!!! I'm here all week!) + GIT_HASH=`git rev-parse --short HEAD` + COMPILE_TIME=`date -u +'%Y-%m-%d %H:%M:%S UTC'` + VERSION_CFLAGS += -DNIGHTLY -DGIT_HASH="\"$(GIT_HASH)\"" -DCOMPILE_TIME="\"$(COMPILE_TIME)\"" +endif + # Microcode ifeq ($(GRUCODE),f3dex) # Fast3DEX diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index e86a100c..19ef621f 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -156,13 +156,18 @@ static void gfx_sdl_init(void) { else if (gCLIOpts.FullScreen == 2) configWindow.fullscreen = false; - const char* window_title = + const char window_title[96] = #ifndef USE_GLES "Super Mario 64 PC port (OpenGL)"; #else "Super Mario 64 PC port (OpenGL_ES2)"; #endif + #ifdef NIGHTLY + strcat(window_title, " nightly "); + strcat(window_title, GIT_HASH); + #endif + wnd = SDL_CreateWindow( window_title, configWindow.x, configWindow.y, configWindow.w, configWindow.h, From aaf6eab582b7f1642effcb3de519e963a989fb9c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 22 May 2020 00:27:51 +0300 Subject: [PATCH 04/24] fix text rendering on JP and (maybe) EU also cache converted IA1 characters so it wouldn't reconvert them every goddamn time they're rendered --- include/macros.h | 16 +++++++++++ src/game/ingame_menu.c | 62 +++++++++++++++++++++++++----------------- src/game/save_file.c | 7 +---- 3 files changed, 54 insertions(+), 31 deletions(-) diff --git a/include/macros.h b/include/macros.h index bcace7fb..478d6ce2 100644 --- a/include/macros.h +++ b/include/macros.h @@ -51,4 +51,20 @@ #define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr)) #define VIRTUAL_TO_PHYSICAL2(addr) ((void *)(addr)) +// Byteswap macros +#define BSWAP16(x) \ + ( (((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00) ) +#define BSWAP32(x) \ + ( (((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \ + (((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) ) + +// Convenience macros for endian conversions +#if IS_BIG_ENDIAN +#define BE_TO_HOST16(x) (x) +#define BE_TO_HOST32(x) (x) +#else +#define BE_TO_HOST16(x) BSWAP16(x) +#define BE_TO_HOST32(x) BSWAP32(x) +#endif + #endif diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 4ef6ecf8..8661568e 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -19,6 +19,7 @@ #include "print.h" #include "engine/math_util.h" #include "course_table.h" +#include "macros.h" #include "pc/cheats.h" #ifdef BETTERCAMERA #include "bettercamera.h" @@ -127,6 +128,16 @@ u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; s32 gDialogResponse = 0; +#if defined(VERSION_JP) || defined(VERSION_SH) || defined(VERSION_EU) +#ifdef VERSION_EU +#define CHCACHE_BUFLEN (8 * 8) // EU only converts 8x8 characters +#else +#define CHCACHE_BUFLEN (8 * 16) // JP only converts 8x16 or 16x8 characters +#endif +// stores char data unpacked from ia1 to ia8 or ia1 to ia4 +// so that it won't be reconverted every time a character is rendered +static struct CachedChar { u8 used; u8 data[CHCACHE_BUFLEN]; } charCache[256]; +#endif // VERSION void create_dl_identity_matrix(void) { Mtx *matrix = (Mtx *) alloc_display_list(sizeof(Mtx)); @@ -206,23 +217,19 @@ void create_dl_ortho_matrix(void) { gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH) } -static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { +#if defined(VERSION_JP) || defined(VERSION_SH) +static inline void alloc_ia8_text_from_i1(u8 *out, u16 *in, s16 width, s16 height) { s32 inPos; u16 bitMask; - u8 *out; + u16 inWord; s16 outPos = 0; - out = alloc_display_list((u32) width * (u32) height); - - if (out == NULL) { - return NULL; - } - for (inPos = 0; inPos < (width * height) / 16; inPos++) { + inWord = BE_TO_HOST16(in[inPos]); bitMask = 0x8000; while (bitMask != 0) { - if (in[inPos] & bitMask) { + if (inWord & bitMask) { out[outPos] = 0xFF; } else { out[outPos] = 0x00; @@ -232,10 +239,17 @@ static u8 *alloc_ia8_text_from_i1(u16 *in, s16 width, s16 height) { outPos++; } } - - return out; } +static inline u8 *convert_ia8_char(u8 c, u16 *tex, s16 w, s16 h) { + if (!charCache[c].used) { + charCache[c].used = 1; + alloc_ia8_text_from_i1(charCache[c].data, tex, w, h); + } + return charCache[c].data; +} +#endif + void render_generic_char(u8 c) { void **fontLUT; void *packedTexture; @@ -247,7 +261,7 @@ void render_generic_char(u8 c) { packedTexture = segmented_to_virtual(fontLUT[c]); #if defined(VERSION_JP) || defined(VERSION_SH) - unpackedTexture = alloc_ia8_text_from_i1(packedTexture, 8, 16); + unpackedTexture = convert_ia8_char(c, packedTexture, 8, 16); gDPPipeSync(gDisplayListHead++); gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_8b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); @@ -265,20 +279,12 @@ void render_generic_char(u8 c) { } #ifdef VERSION_EU -u8 *alloc_ia4_tex_from_i1(u8 *in, s16 width, s16 height) { +static inline void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) { u32 size = (u32) width * (u32) height; - u8 *out; s32 inPos; - s16 outPos; + s16 outPos = 0; u8 bitMask; - outPos = 0; - out = (u8 *) alloc_display_list(size); - - if (out == NULL) { - return NULL; - } - for (inPos = 0; inPos < (width * height) / 4; inPos++) { bitMask = 0x80; while (bitMask != 0) { @@ -289,8 +295,14 @@ u8 *alloc_ia4_tex_from_i1(u8 *in, s16 width, s16 height) { outPos++; } } +} - return out; +static inline u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { + if (!charCache[c].used) { + charCache[c].used = 1; + alloc_ia4_tex_from_i1(charCache[c].data, tex, w, h); + } + return charCache[c].data; } void render_generic_char_at_pos(s16 xPos, s16 yPos, u8 c) { @@ -300,7 +312,7 @@ void render_generic_char_at_pos(s16 xPos, s16 yPos, u8 c) { fontLUT = segmented_to_virtual(main_font_lut); packedTexture = segmented_to_virtual(fontLUT[c]); - unpackedTexture = alloc_ia4_tex_from_i1(packedTexture, 8, 8); + unpackedTexture = convert_ia4_char(c, packedTexture, 8, 8); gDPPipeSync(gDisplayListHead++); gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); @@ -1025,7 +1037,7 @@ void render_generic_dialog_char_at_pos(struct DialogEntry *dialog, s16 x, s16 y, fontLUT = segmented_to_virtual(main_font_lut); packedTexture = segmented_to_virtual(fontLUT[c]); - unpackedTexture = alloc_ia4_tex_from_i1(packedTexture, 8, 8); + unpackedTexture = convert_ia4_char(c, packedTexture, 8, 8); gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, VIRTUAL_TO_PHYSICAL(unpackedTexture)); gSPDisplayList(gDisplayListHead++, dl_ia_text_tex_settings); diff --git a/src/game/save_file.c b/src/game/save_file.c index d7899314..9facaf3c 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -11,17 +11,12 @@ #include "level_table.h" #include "course_table.h" #include "thread6.h" +#include "macros.h" #include "pc/ini.h" #define MENU_DATA_MAGIC 0x4849 #define SAVE_FILE_MAGIC 0x4441 -#define BSWAP16(x) \ - ( (((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00) ) -#define BSWAP32(x) \ - ( (((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \ - (((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) ) - STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match"); extern struct SaveBuffer gSaveBuffer; From a9d16ea76adf4106492b8f96d173cdfd9712a1c1 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 22 May 2020 01:35:26 +0300 Subject: [PATCH 05/24] unfuck BSWAP16 macro, replace it with BE_TO_HOST16() in audio --- include/macros.h | 5 ++--- src/audio/data.c | 6 +++--- src/audio/effects.c | 8 ++++---- src/audio/effects.h | 10 ++++------ src/game/ingame_menu.c | 8 ++++---- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/include/macros.h b/include/macros.h index 478d6ce2..f93642fb 100644 --- a/include/macros.h +++ b/include/macros.h @@ -52,9 +52,8 @@ #define VIRTUAL_TO_PHYSICAL2(addr) ((void *)(addr)) // Byteswap macros -#define BSWAP16(x) \ - ( (((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00) ) -#define BSWAP32(x) \ +#define BSWAP16(x) (((x) & 0xFF) << 8 | (((x) >> 8) & 0xFF)) +#define BSWAP32(x) \ ( (((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | \ (((x) << 8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) ) diff --git a/src/audio/data.c b/src/audio/data.c index 10bbe19c..711ee847 100644 --- a/src/audio/data.c +++ b/src/audio/data.c @@ -175,9 +175,9 @@ s8 gVibratoCurve[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, #endif struct AdsrEnvelope gDefaultEnvelope[] = { - { BSWAP16(4), BSWAP16(32000) }, // go from 0 to 32000 over the course of 16ms - { BSWAP16(1000), BSWAP16(32000) }, // stay there for 4.16 seconds - { BSWAP16(ADSR_HANG), 0 } // then continue staying there + { BE_TO_HOST16(4), BE_TO_HOST16(32000) }, // go from 0 to 32000 over the course of 16ms + { BE_TO_HOST16(1000), BE_TO_HOST16(32000) }, // stay there for 4.16 seconds + { BE_TO_HOST16(ADSR_HANG), 0 } // then continue staying there }; #ifdef VERSION_EU diff --git a/src/audio/effects.c b/src/audio/effects.c index 29446094..2218fba7 100644 --- a/src/audio/effects.c +++ b/src/audio/effects.c @@ -391,7 +391,7 @@ s32 adsr_update(struct AdsrState *adsr) { // fallthrough case ADSR_STATE_LOOP: - adsr->delay = BSWAP16(adsr->envelope[adsr->envIndex].delay); + adsr->delay = BE_TO_HOST16(adsr->envelope[adsr->envIndex].delay); switch (adsr->delay) { case ADSR_DISABLE: adsr->state = ADSR_STATE_DISABLED; @@ -400,7 +400,7 @@ s32 adsr_update(struct AdsrState *adsr) { adsr->state = ADSR_STATE_HANG; break; case ADSR_GOTO: - adsr->envIndex = BSWAP16(adsr->envelope[adsr->envIndex].arg); + adsr->envIndex = BE_TO_HOST16(adsr->envelope[adsr->envIndex].arg); break; case ADSR_RESTART: adsr->state = ADSR_STATE_INITIAL; @@ -411,11 +411,11 @@ s32 adsr_update(struct AdsrState *adsr) { if (adsr->delay >= 4) { adsr->delay = adsr->delay * gAudioBufferParameters.updatesPerFrame / 4; } - adsr->target = (f32) BSWAP16(adsr->envelope[adsr->envIndex].arg) / 32767.0; + adsr->target = (f32) BE_TO_HOST16(adsr->envelope[adsr->envIndex].arg) / 32767.0; adsr->target = adsr->target * adsr->target; adsr->velocity = (adsr->target - adsr->current) / adsr->delay; #else - adsr->target = BSWAP16(adsr->envelope[adsr->envIndex].arg); + adsr->target = BE_TO_HOST16(adsr->envelope[adsr->envIndex].arg); adsr->velocity = ((adsr->target - adsr->current) << 0x10) / adsr->delay; #endif adsr->state = ADSR_STATE_FADE; diff --git a/src/audio/effects.h b/src/audio/effects.h index bb842c77..425eff57 100644 --- a/src/audio/effects.h +++ b/src/audio/effects.h @@ -3,6 +3,7 @@ #include "internal.h" #include "platform_info.h" +#include "macros.h" #define ADSR_STATE_DISABLED 0 #define ADSR_STATE_INITIAL 1 @@ -24,12 +25,9 @@ #define ADSR_RESTART -3 // Envelopes are always stored as big endian, to match sequence files which are -// byte blobs and can embed envelopes. Hence this byteswapping macro. -#if IS_BIG_ENDIAN -#define BSWAP16(x) (x) -#else -#define BSWAP16(x) (((x) & 0xff) << 8 | (((x) >> 8) & 0xff)) -#endif +// byte blobs and can embed envelopes. +// BSWAP16() definition has been moved to macros.h. Use BE_TO_HOST16() for the +// same effect in the future. void sequence_player_process_sound(struct SequencePlayer *seqPlayer); void note_vibrato_update(struct Note *note); diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 8661568e..d7de9d4e 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -130,11 +130,11 @@ s32 gDialogResponse = 0; #if defined(VERSION_JP) || defined(VERSION_SH) || defined(VERSION_EU) #ifdef VERSION_EU -#define CHCACHE_BUFLEN (8 * 8) // EU only converts 8x8 characters +#define CHCACHE_BUFLEN (8 * 8) // EU only converts 8x8 #else #define CHCACHE_BUFLEN (8 * 16) // JP only converts 8x16 or 16x8 characters #endif -// stores char data unpacked from ia1 to ia8 or ia1 to ia4 +// stores char data unpacked from ia1 to ia8 or ia4 // so that it won't be reconverted every time a character is rendered static struct CachedChar { u8 used; u8 data[CHCACHE_BUFLEN]; } charCache[256]; #endif // VERSION @@ -279,7 +279,7 @@ void render_generic_char(u8 c) { } #ifdef VERSION_EU -static inline void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) { +static void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) { u32 size = (u32) width * (u32) height; s32 inPos; s16 outPos = 0; @@ -297,7 +297,7 @@ static inline void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) } } -static inline u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { +static u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { if (!charCache[c].used) { charCache[c].used = 1; alloc_ia4_tex_from_i1(charCache[c].data, tex, w, h); From 686ea5be7b805498088fe0131837a62bb6298906 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 22 May 2020 01:36:39 +0300 Subject: [PATCH 06/24] separate options menu strings and add JP strings --- Makefile | 4 + include/text_options_strings.h.in | 138 ++++++++++++++++++++++++++++++ include/text_strings.h.in | 62 ++------------ src/game/options_menu.c | 2 +- 4 files changed, 148 insertions(+), 58 deletions(-) create mode 100644 include/text_options_strings.h.in diff --git a/Makefile b/Makefile index 9356281c..4acdb9de 100644 --- a/Makefile +++ b/Makefile @@ -639,6 +639,9 @@ $(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in $(BUILD_DIR)/include/text_menu_strings.h: include/text_menu_strings.h.in $(TEXTCONV) charmap_menu.txt $< $@ +$(BUILD_DIR)/include/text_options_strings.h: include/text_options_strings.h.in + $(TEXTCONV) charmap.txt $< $@ + ifeq ($(VERSION),eu) TEXT_DIRS := text/de text/us text/fr @@ -678,6 +681,7 @@ ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GOD DUMMY != mkdir -p $(ALL_DIRS) $(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_menu_strings.h +$(BUILD_DIR)/include/text_strings.h: $(BUILD_DIR)/include/text_options_strings.h ifeq ($(VERSION),eu) $(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in new file mode 100644 index 00000000..7580ec9e --- /dev/null +++ b/include/text_options_strings.h.in @@ -0,0 +1,138 @@ +#ifndef TEXT_OPTIONS_STRINGS_H +#define TEXT_OPTIONS_STRINGS_H + +/* Extended options menu text */ + +// Menu title strings + +#define TEXT_OPT_OPTIONS _("OPTIONS") +#define TEXT_OPT_CAMERA _("CAMERA") +#define TEXT_OPT_CONTROLS _("CONTROLS") +#define TEXT_OPT_VIDEO _("DISPLAY") +#define TEXT_OPT_AUDIO _("SOUND") +#define TEXT_OPT_CHEATS _("CHEATS") + +// Markers + +#define TEXT_OPT_HIGHLIGHT _("O") +#define TEXT_OPT_UNBOUND _("NONE") + +// Language specific strings + +#if defined(VERSION_JP) || defined(VERSION_SH) + +// TODO: Actually translate this to JP + +// No . in JP + +#define TEXT_OPT_PRESSKEY _("・・・") + +// Option strings + +#define TEXT_OPT_BUTTON1 _("R OPTIONS") +#define TEXT_OPT_BUTTON2 _("R RETURN") +#define TEXT_OPT_ENABLED _("ENABLED") +#define TEXT_OPT_DISABLED _("DISABLED") +#define TEXT_OPT_CAMX _("CAMERA X SENSITIVITY") +#define TEXT_OPT_CAMY _("CAMERA Y SENSITIVITY") +#define TEXT_OPT_INVERTX _("INVERT X AXIS") +#define TEXT_OPT_INVERTY _("INVERT Y AXIS") +#define TEXT_OPT_CAMC _("CAMERA CENTRE AGGRESSION") +#define TEXT_OPT_CAMP _("CAMERA PAN LEVEL") +#define TEXT_OPT_CAMD _("CAMERA DECELERATION") +#define TEXT_OPT_ANALOGUE _("ANALOGUE CAMERA") +#define TEXT_OPT_MOUSE _("MOUSE LOOK") +#define TEXT_OPT_TEXFILTER _("TEXTURE FILTERING") +#define TEXT_OPT_FSCREEN _("FULLSCREEN") +#define TEXT_OPT_NEAREST _("NEAREST") +#define TEXT_OPT_LINEAR _("LINEAR") +#define TEXT_OPT_MVOLUME _("MASTER VOLUME") +#define TEXT_OPT_VSYNC _("VERTICAL SYNC") +#define TEXT_OPT_DOUBLE _("DOUBLE") +#define TEXT_RESET_WINDOW _("RESET WINDOW") +#define TEXT_OPT_HUD _("HUD") + +#define TEXT_BIND_A _("A BUTTON") +#define TEXT_BIND_B _("B BUTTON") +#define TEXT_BIND_START _("START BUTTON") +#define TEXT_BIND_L _("L TRIGGER") +#define TEXT_BIND_R _("R TRIGGER") +#define TEXT_BIND_Z _("Z TRIGGER") +#define TEXT_BIND_C_UP _("C-UP") +#define TEXT_BIND_C_DOWN _("C-DOWN") +#define TEXT_BIND_C_LEFT _("C-LEFT") +#define TEXT_BIND_C_RIGHT _("C-RIGHT") +#define TEXT_BIND_UP _("STICK UP") +#define TEXT_BIND_DOWN _("STICK DOWN") +#define TEXT_BIND_LEFT _("STICK LEFT") +#define TEXT_BIND_RIGHT _("STICK RIGHT") + +#define TEXT_OPT_CHEAT1 _("ENABLE CHEATS") +#define TEXT_OPT_CHEAT2 _("MOONJUMP (PRESS L)") +#define TEXT_OPT_CHEAT3 _("INVINCIBLE MARIO") +#define TEXT_OPT_CHEAT4 _("INFINITE LIVES") +#define TEXT_OPT_CHEAT5 _("SUPER SPEED") +#define TEXT_OPT_CHEAT6 _("SUPER RESPONSIVE CONTROLS") +#define TEXT_OPT_CHEAT7 _("EXIT COURSE AT ANY TIME") +#define TEXT_OPT_CHEAT8 _("HUGE MARIO") +#define TEXT_OPT_CHEAT9 _("TINY MARIO") + +#else // VERSION + +// Markers + +#define TEXT_OPT_PRESSKEY _("...") + +// Option strings + +#define TEXT_OPT_BUTTON1 _("[R] Options") +#define TEXT_OPT_BUTTON2 _("[R] Return") +#define TEXT_OPT_ENABLED _("Enabled") +#define TEXT_OPT_DISABLED _("Disabled") +#define TEXT_OPT_CAMX _("Camera X Sensitivity") +#define TEXT_OPT_CAMY _("Camera Y Sensitivity") +#define TEXT_OPT_INVERTX _("Invert X Axis") +#define TEXT_OPT_INVERTY _("Invert Y Axis") +#define TEXT_OPT_CAMC _("Camera Centre Aggression") +#define TEXT_OPT_CAMP _("Camera Pan Level") +#define TEXT_OPT_CAMD _("Camera Deceleration") +#define TEXT_OPT_ANALOGUE _("Analogue Camera") +#define TEXT_OPT_MOUSE _("Mouse Look") +#define TEXT_OPT_TEXFILTER _("Texture Filtering") +#define TEXT_OPT_FSCREEN _("Fullscreen") +#define TEXT_OPT_NEAREST _("Nearest") +#define TEXT_OPT_LINEAR _("Linear") +#define TEXT_OPT_MVOLUME _("Master Volume") +#define TEXT_OPT_VSYNC _("Vertical Sync") +#define TEXT_OPT_DOUBLE _("Double") +#define TEXT_RESET_WINDOW _("Reset Window") +#define TEXT_OPT_HUD _("HUD") + +#define TEXT_BIND_A _("A Button") +#define TEXT_BIND_B _("B Button") +#define TEXT_BIND_START _("Start Button") +#define TEXT_BIND_L _("L Trigger") +#define TEXT_BIND_R _("R Trigger") +#define TEXT_BIND_Z _("Z Trigger") +#define TEXT_BIND_C_UP _("C-Up") +#define TEXT_BIND_C_DOWN _("C-Down") +#define TEXT_BIND_C_LEFT _("C-Left") +#define TEXT_BIND_C_RIGHT _("C-Right") +#define TEXT_BIND_UP _("Stick Up") +#define TEXT_BIND_DOWN _("Stick Down") +#define TEXT_BIND_LEFT _("Stick Left") +#define TEXT_BIND_RIGHT _("Stick Right") + +#define TEXT_OPT_CHEAT1 _("Enable cheats") +#define TEXT_OPT_CHEAT2 _("Moonjump (Press L)") +#define TEXT_OPT_CHEAT3 _("Invincible Mario") +#define TEXT_OPT_CHEAT4 _("Infinite lives") +#define TEXT_OPT_CHEAT5 _("Super speed") +#define TEXT_OPT_CHEAT6 _("Super responsive controls") +#define TEXT_OPT_CHEAT7 _("Exit course at any time") +#define TEXT_OPT_CHEAT8 _("Huge Mario") +#define TEXT_OPT_CHEAT9 _("Tiny Mario") + +#endif // VERSION + +#endif // TEXT_OPTIONS_STRINGS_H diff --git a/include/text_strings.h.in b/include/text_strings.h.in index d4ec173a..786e3a36 100644 --- a/include/text_strings.h.in +++ b/include/text_strings.h.in @@ -1,64 +1,12 @@ - #ifndef TEXT_STRINGS_H +#ifndef TEXT_STRINGS_H #define TEXT_STRINGS_H #include "text_menu_strings.h" -#define TEXT_OPT_CAMX _("Camera X Sensitivity") -#define TEXT_OPT_CAMY _("Camera Y Sensitivity") -#define TEXT_OPT_INVERTX _("Invert X Axis") -#define TEXT_OPT_INVERTY _("Invert Y Axis") -#define TEXT_OPT_CAMC _("Camera Centre Aggression") -#define TEXT_OPT_CAMP _("Camera Pan Level") -#define TEXT_OPT_CAMD _("Camera Deceleration") -#define TEXT_OPT_ENABLED _("Enabled") -#define TEXT_OPT_DISABLED _("Disabled") -#define TEXT_OPT_BUTTON1 _("[R]: Options") -#define TEXT_OPT_BUTTON2 _("[R]: Return") -#define TEXT_OPT_OPTIONS _("OPTIONS") -#define TEXT_OPT_CAMERA _("CAMERA") -#define TEXT_OPT_CONTROLS _("CONTROLS") -#define TEXT_OPT_VIDEO _("DISPLAY") -#define TEXT_OPT_AUDIO _("SOUND") -#define TEXT_OPT_HIGHLIGHT _("O") -#define TEXT_OPT_ANALOGUE _("Analogue Camera") -#define TEXT_OPT_MOUSE _("Mouse Look") -#define TEXT_OPT_TEXFILTER _("Texture Filtering") -#define TEXT_OPT_FSCREEN _("Fullscreen") -#define TEXT_OPT_NEAREST _("Nearest") -#define TEXT_OPT_LINEAR _("Linear") -#define TEXT_OPT_MVOLUME _("Master Volume") -#define TEXT_OPT_VSYNC _("Vertical Sync") -#define TEXT_OPT_DOUBLE _("Double") -#define TEXT_RESET_WINDOW _("Reset Window") -#define TEXT_OPT_HUD _("HUD") +#ifdef EXT_OPTIONS_MENU +#include "text_options_strings.h" +#endif -#define TEXT_OPT_UNBOUND _("NONE") -#define TEXT_OPT_PRESSKEY _("...") -#define TEXT_BIND_A _("A Button") -#define TEXT_BIND_B _("B Button") -#define TEXT_BIND_START _("Start Button") -#define TEXT_BIND_L _("L Trigger") -#define TEXT_BIND_R _("R Trigger") -#define TEXT_BIND_Z _("Z Trigger") -#define TEXT_BIND_C_UP _("C-Up") -#define TEXT_BIND_C_DOWN _("C-Down") -#define TEXT_BIND_C_LEFT _("C-Left") -#define TEXT_BIND_C_RIGHT _("C-Right") -#define TEXT_BIND_UP _("Stick Up") -#define TEXT_BIND_DOWN _("Stick Down") -#define TEXT_BIND_LEFT _("Stick Left") -#define TEXT_BIND_RIGHT _("Stick Right") - -#define TEXT_OPT_CHEATS _("CHEATS") -#define TEXT_OPT_CHEAT1 _("Enable cheats") -#define TEXT_OPT_CHEAT2 _("Moonjump (Press L)") -#define TEXT_OPT_CHEAT3 _("Invincible Mario") -#define TEXT_OPT_CHEAT4 _("Infinite lives") -#define TEXT_OPT_CHEAT5 _("Super speed") -#define TEXT_OPT_CHEAT6 _("Super responsive controls") -#define TEXT_OPT_CHEAT7 _("Exit course at any time") -#define TEXT_OPT_CHEAT8 _("Huge Mario") -#define TEXT_OPT_CHEAT9 _("Tiny Mario") /** * Global Symbols */ @@ -146,7 +94,7 @@ #define TEXT_COURSE _("コース") #define TEXT_MYSCORE _("マイスコア") #define TEXT_CONTINUE _("つづけて マリオする?") -#define TEXT_EXIT_GAME _("ゲームをしゅうりょうする?") +#define TEXT_EXIT_GAME _("ゲームをしゅうりょうする") #define TEXT_EXIT_COURSE _("コースからでる?") #define TEXT_CAMERA_ANGLE_R _("Rボタンのカメラきりかえ") diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 6c9c1a1c..8d1661bf 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -462,7 +462,7 @@ void optmenu_draw(void) { //This has been separated for interesting reasons. Don't question it. void optmenu_draw_prompt(void) { gSPDisplayList(gDisplayListHead++, dl_ia_text_begin); - optmenu_draw_text(278, 212, menuStr[1 + optmenu_open], 0); + optmenu_draw_text(264, 212, menuStr[1 + optmenu_open], 0); gSPDisplayList(gDisplayListHead++, dl_ia_text_end); } From 4bbde37464e736e38ba526a3edfd7c47986d00d8 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 22 May 2020 01:42:07 +0300 Subject: [PATCH 07/24] this ain't const anymore --- src/pc/gfx/gfx_sdl2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 19ef621f..58ef09af 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -156,7 +156,7 @@ static void gfx_sdl_init(void) { else if (gCLIOpts.FullScreen == 2) configWindow.fullscreen = false; - const char window_title[96] = + char window_title[96] = #ifndef USE_GLES "Super Mario 64 PC port (OpenGL)"; #else @@ -164,8 +164,7 @@ static void gfx_sdl_init(void) { #endif #ifdef NIGHTLY - strcat(window_title, " nightly "); - strcat(window_title, GIT_HASH); + strcat(window_title, " nightly " GIT_HASH); #endif wnd = SDL_CreateWindow( From eeca3b0ec0e895d9f50f2a55b33021cc75b86c59 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 25 May 2020 00:58:43 +0300 Subject: [PATCH 08/24] remove debug print in Makefile --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 4acdb9de..2444468c 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,6 @@ endif # Stuff for showing the git hash in the intro on nightly builds # From https://stackoverflow.com/questions/44038428/include-git-commit-hash-and-or-branch-name-in-c-c-source ifeq ($(shell git rev-parse --abbrev-ref HEAD),nightly) - $(info Hello Caldera!!! I'm here all week!) GIT_HASH=`git rev-parse --short HEAD` COMPILE_TIME=`date -u +'%Y-%m-%d %H:%M:%S UTC'` VERSION_CFLAGS += -DNIGHTLY -DGIT_HASH="\"$(GIT_HASH)\"" -DCOMPILE_TIME="\"$(COMPILE_TIME)\"" From 87d6f30a08a501ac348242df3bd6af77f1bdfa6c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 25 May 2020 02:25:13 +0300 Subject: [PATCH 09/24] fix skyconv --write-tiles --type sky --- tools/skyconv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/skyconv.c b/tools/skyconv.c index 2dcdf33a..4fb0523e 100644 --- a/tools/skyconv.c +++ b/tools/skyconv.c @@ -216,7 +216,6 @@ static void assign_tile_positions() { void write_tiles() { const ImageProps props = IMAGE_PROPERTIES[type][true]; char buffer[PATH_MAX]; - char skyboxName[PATH_MAX]; if (realpath(writeDir, buffer) == NULL) { fprintf(stderr, "err: Could not find find img dir %s", writeDir); From 9825b02f505e3b17d53a2d28effaae5561a6e84f Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 25 May 2020 04:21:36 +0300 Subject: [PATCH 10/24] add option to load textures from external files this stores the null terminated texture name instead of the texture data activated with EXTERNAL_TEXTURES=1 --- Makefile | 29 +++++++++++++++- Makefile.split | 8 ++--- {tools => include}/stb/stb_image.h | 0 {tools => include}/stb/stb_image_write.h | 0 src/pc/configfile.h | 1 + src/pc/gfx/gfx_pc.c | 24 ++++++++++++++ tools/Makefile | 2 +- tools/n64graphics_ci_dir/n64graphics_ci.c | 4 +-- tools/skyconv.c | 40 ++++++++++++++++++----- 9 files changed, 91 insertions(+), 17 deletions(-) rename {tools => include}/stb/stb_image.h (100%) rename {tools => include}/stb/stb_image_write.h (100%) diff --git a/Makefile b/Makefile index 2444468c..e9ebc5d0 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,8 @@ TEXTURE_FIX ?= 0 EXT_OPTIONS_MENU ?= 1 # Disable text-based save-files by default TEXTSAVES ?= 0 +# Load textures from external PNG files +EXTERNAL_TEXTURES ?= 0 # Various workarounds for weird toolchains @@ -552,6 +554,14 @@ ifeq ($(LEGACY_GL),1) CFLAGS += -DLEGACY_GL endif +# Load external textures +ifeq ($(EXTERNAL_TEXTURES),1) + CC_CHECK += -DEXTERNAL_TEXTURES + CFLAGS += -DEXTERNAL_TEXTURES + # tell skyconv to write names instead of actual texture data and save the split tiles so we can use them later + SKYCONV_ARGS := --store-names --write-tiles "$(BUILD_DIR)/textures/skybox_tiles" +endif + ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) ifeq ($(TARGET_WEB),1) @@ -606,6 +616,16 @@ SHA1SUM = sha1sum all: $(EXE) +ifeq ($(EXTERNAL_TEXTURES),1) +# prepares the resource folder for external data +res: $(EXE) + @mkdir -p $(BUILD_DIR)/res + @cp -r -f textures/ $(BUILD_DIR)/res/ + @cp -r -f $(BUILD_DIR)/textures/skybox_tiles/ $(BUILD_DIR)/res/textures/ + @find actors -name \*.png -exec cp --parents {} $(BUILD_DIR)/res/ \; + @find levels -name \*.png -exec cp --parents {} $(BUILD_DIR)/res/ \; +endif + clean: $(RM) -r $(BUILD_DIR_BASE) @@ -700,13 +720,19 @@ endif ################################################################ # RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4 +ifeq ($(EXTERNAL_TEXTURES),1) +$(BUILD_DIR)/%: %.png + printf "%s%b" "$(patsubst %.png,%,$^)" '\x00' > $@ +else $(BUILD_DIR)/%: %.png $(N64GRAPHICS) -i $@ -g $< -f $(lastword $(subst ., ,$@)) +endif $(BUILD_DIR)/%.inc.c: $(BUILD_DIR)/% %.png hexdump -v -e '1/1 "0x%X,"' $< > $@ echo >> $@ +ifeq ($(EXTERNAL_TEXTURES),0) # Color Index CI8 $(BUILD_DIR)/%.ci8: %.ci8.png $(N64GRAPHICS_CI) -i $@ -g $< -f ci8 @@ -714,6 +740,7 @@ $(BUILD_DIR)/%.ci8: %.ci8.png # Color Index CI4 $(BUILD_DIR)/%.ci4: %.ci4.png $(N64GRAPHICS_CI) -i $@ -g $< -f ci4 +endif ################################################################ @@ -857,7 +884,7 @@ $(BUILD_DIR)/%.o: %.s $(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS) -.PHONY: all clean distclean default diff test load libultra +.PHONY: all clean distclean default diff test load libultra res .PRECIOUS: $(BUILD_DIR)/bin/%.elf $(SOUND_BIN_DIR)/%.ctl $(SOUND_BIN_DIR)/%.tbl $(SOUND_SAMPLE_TABLES) $(SOUND_BIN_DIR)/%.s $(BUILD_DIR)/% .DELETE_ON_ERROR: diff --git a/Makefile.split b/Makefile.split index 9619c603..c7bdaa2e 100644 --- a/Makefile.split +++ b/Makefile.split @@ -5,7 +5,7 @@ # obtain a list of segments from the *.c files in bin directory SEGMENTS := $(notdir $(basename $(wildcard bin/*.c))) $(addprefix $(VERSION)/,$(notdir $(basename $(wildcard bin/$(VERSION)/*.c)))) $(addsuffix _skybox,$(notdir $(basename $(wildcard textures/skyboxes/*.png)))) ACTORS := $(filter %/,$(wildcard actors/*/)) -TEXTURE_DIRS := $(addprefix textures/,$(SEGMENTS)) $(ACTORS) textures/intro_raw +TEXTURE_DIRS := $(addprefix textures/,$(SEGMENTS)) $(ACTORS) textures/intro_raw textures/skybox_tiles # NOTE: textures assume naming convention "texture..png" generates "texture." @@ -165,9 +165,9 @@ $(eval $(call level_rules,menu,generic)) # Menu (File Select) # Ending cake textures are generated in a special way $(BUILD_DIR)/levels/ending/cake_eu.inc.c: levels/ending/cake_eu.png - $(SKYCONV) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending + $(SKYCONV) $(SKYCONV_ARGS) --type cake-eu --split $^ $(BUILD_DIR)/levels/ending $(BUILD_DIR)/levels/ending/cake.inc.c: levels/ending/cake.png - $(SKYCONV) --type cake --split $^ $(BUILD_DIR)/levels/ending + $(SKYCONV) $(SKYCONV_ARGS) --type cake --split $^ $(BUILD_DIR)/levels/ending # -------------------------------------- # Texture Bin Rules @@ -235,7 +235,7 @@ $(BUILD_DIR)/bin/eu/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000 # -------------------------------------- $(BUILD_DIR)/bin/%_skybox.c: textures/skyboxes/%.png - $(SKYCONV) --type sky --split $^ $(BUILD_DIR)/bin + $(SKYCONV) $(SKYCONV_ARGS) --type sky --split $^ $(BUILD_DIR)/bin $(BUILD_DIR)/bin/%_skybox.elf: SEGMENT_ADDRESS := 0x0A000000 diff --git a/tools/stb/stb_image.h b/include/stb/stb_image.h similarity index 100% rename from tools/stb/stb_image.h rename to include/stb/stb_image.h diff --git a/tools/stb/stb_image_write.h b/include/stb/stb_image_write.h similarity index 100% rename from tools/stb/stb_image_write.h rename to include/stb/stb_image_write.h diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 17a7e25d..6f2c4a25 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -4,6 +4,7 @@ #include #define CONFIGFILE_DEFAULT "sm64config.txt" +#define DATAPATH_DEFAULT "res" #define MAX_BINDS 3 #define MAX_VOLUME 127 diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index e2aadfa1..210c34ff 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -5,6 +5,11 @@ #include #include +#ifdef EXTERNAL_TEXTURES +#define STB_IMAGE_IMPLEMENTATION +#include +#endif + #ifndef _LANGUAGE_C #define _LANGUAGE_C #endif @@ -315,6 +320,7 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co return false; } +#ifndef EXTERNAL_TEXTURES static void import_texture_rgba32(int tile) { uint32_t width = rdp.texture_tile.line_size_bytes / 2; uint32_t height = (rdp.loaded_texture[tile].size_bytes / 2) / rdp.texture_tile.line_size_bytes; @@ -486,6 +492,7 @@ static void import_texture_ci8(int tile) { gfx_rapi->upload_texture(rgba32_buf, width, height); } +#endif // EXTERNAL_TEXTURES static void import_texture(int tile) { uint8_t fmt = rdp.texture_tile.fmt; @@ -495,6 +502,22 @@ static void import_texture(int tile) { return; } +#ifdef EXTERNAL_TEXTURES + // the "texture data" is actually a C string with the path to our texture in it + // load it from an external image in our data path + static char fpath[1024]; + int w, h; + const char *texname = (const char*)rdp.loaded_texture[tile].addr; + snprintf(fpath, sizeof(fpath), "%s/%s.png", DATAPATH_DEFAULT, texname); + u8 *data = stbi_load(fpath, &w, &h, NULL, 4); + if (!data) { + fprintf(stderr, "texture not found: `%s`\n", fpath); + abort(); + } + gfx_rapi->upload_texture(data, w, h); + stbi_image_free(data); // don't need this anymore +#else + // the texture data is actual texture data int t0 = get_time(); if (fmt == G_IM_FMT_RGBA) { if (siz == G_IM_SIZ_32b) { @@ -536,6 +559,7 @@ static void import_texture(int tile) { } int t1 = get_time(); //printf("Time diff: %d\n", t1 - t0); +#endif } static void gfx_normalize_vector(float v[3]) { diff --git a/tools/Makefile b/tools/Makefile index 0d8e6dd7..d81f5f9a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -4,7 +4,7 @@ ifeq ($(UNAME),Darwin) endif CC := gcc -CFLAGS := -Llib -Iinclude -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 -O3 -s +CFLAGS := -Llib -I../include -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 -O3 -s PROGRAMS := n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math iplfontutil aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv n64graphics_SOURCES := n64graphics.c utils.c diff --git a/tools/n64graphics_ci_dir/n64graphics_ci.c b/tools/n64graphics_ci_dir/n64graphics_ci.c index 6ec4476a..05fe88aa 100644 --- a/tools/n64graphics_ci_dir/n64graphics_ci.c +++ b/tools/n64graphics_ci_dir/n64graphics_ci.c @@ -6,9 +6,9 @@ #define STBI_NO_HDR #define STBI_NO_TGA #define STB_IMAGE_IMPLEMENTATION -#include "../stb/stb_image.h" +#include #define STB_IMAGE_WRITE_IMPLEMENTATION -#include "../stb/stb_image_write.h" +#include #include "exoquant/exoquant.h" diff --git a/tools/skyconv.c b/tools/skyconv.c index 4fb0523e..a66c5c1b 100644 --- a/tools/skyconv.c +++ b/tools/skyconv.c @@ -75,6 +75,7 @@ char *writeDir; char skyboxName[256]; bool expanded = false; bool writeTiles; +bool storeNamesOnly = false; static void allocate_tiles() { const ImageProps props = IMAGE_PROPERTIES[type][true]; @@ -291,11 +292,18 @@ static void write_skybox_c() { /* write c data to disc */ for (int i = 0; i < props.numRows * props.numCols; i++) { if (!tiles[i].useless) { - fprintf(cFile, "ALIGNED8 static const u8 %s_skybox_texture_%05X[] = {\n", skyboxName, tiles[i].pos); - - print_raw_data(cFile, &tiles[i]); - - fputs("};\n\n", cFile); + if (storeNamesOnly) { + fprintf( + cFile, + "ALIGNED8 static const u8 %s_skybox_texture_%05X[] = " + "\"textures/skybox_tiles/%s.%d.rgba16\";\n\n", + skyboxName, tiles[i].pos, skyboxName, tiles[i].pos + ); + } else { + fprintf(cFile, "ALIGNED8 static const u8 %s_skybox_texture_%05X[] = {\n", skyboxName, tiles[i].pos); + print_raw_data(cFile, &tiles[i]); + fputs("};\n\n", cFile); + } } } @@ -334,9 +342,18 @@ static void write_cake_c() { int numTiles = TABLE_DIMENSIONS[type].cols * TABLE_DIMENSIONS[type].rows; for (int i = 0; i < numTiles; ++i) { - fprintf(cFile, "ALIGNED8 static const u8 cake_end_texture_%s%d[] = {\n", euSuffx, i); - print_raw_data(cFile, &tiles[i]); - fputs("};\n\n", cFile); + if (storeNamesOnly) { + fprintf( + cFile, + "ALIGNED8 static const u8 cake_end_texture_%s%d[] = " + "\"textures/skybox_tiles/cake%s.%d.rgba16\";\n\n", + euSuffx, i, *euSuffx ? "_eu" : "", tiles[i].pos + ); + } else { + fprintf(cFile, "ALIGNED8 static const u8 cake_end_texture_%s%d[] = {\n", euSuffx, i); + print_raw_data(cFile, &tiles[i]); + fputs("};\n\n", cFile); + } } fclose(cFile); } @@ -473,7 +490,8 @@ static void usage() { "Usage: %s --type sky|cake|cake_eu {--combine INPUT OUTPUT | --split INPUT OUTPUT}\n" "\n" "Optional arguments:\n" - " --write-tiles OUTDIR Also create the individual tiles' PNG files\n", programName); + " --write-tiles OUTDIR Also create the individual tiles' PNG files\n" + " --store-names Store texture file names instead of actual data\n", programName); } // Modified from n64split @@ -529,6 +547,10 @@ static int parse_arguments(int argc, char *argv[]) { writeTiles = true; writeDir = argv[i]; } + + if (strcmp(argv[i], "--store-names") == 0) { + storeNamesOnly = true; + } } return 1; From 1873f7aba57513d6ea5cb2577e827be2cd4b4397 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 25 May 2020 07:17:10 +0300 Subject: [PATCH 11/24] game now uses non-working directory paths by default saves by default go into XDG_DATA_HOME/sm64pc external data is read from the executable directory, if it's not found there on Unix systems the game will attempt to read it from some paths like /usr/local/share/sm64pc both save data and readonly data fall back to other options in case of a problem behavior can be overridden by specifying --datapath and --savepath on the CLI both of those will expand the exclamation point ('!') to the executable path, e. g. --savepath '!/save' --- Makefile | 8 +- src/game/options_menu.c | 2 +- src/pc/cliopts.c | 39 ++++---- src/pc/cliopts.h | 6 +- src/pc/configfile.c | 14 +++ src/pc/configfile.h | 2 +- src/pc/gfx/gfx_pc.c | 5 +- src/pc/pc_main.c | 4 +- src/pc/platform.c | 158 ++++++++++++++++++++++++++++++++ src/pc/platform.h | 16 ++++ src/pc/ultra_reimplementation.c | 9 +- 11 files changed, 234 insertions(+), 29 deletions(-) create mode 100644 src/pc/platform.c create mode 100644 src/pc/platform.h diff --git a/Makefile b/Makefile index e9ebc5d0..17b93a55 100644 --- a/Makefile +++ b/Makefile @@ -491,8 +491,8 @@ PYTHON := python3 SDLCONFIG := $(CROSS)sdl2-config ifeq ($(WINDOWS_BUILD),1) -CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` +CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -DUSE_SDL=2 +CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` -DUSE_SDL=2 else ifeq ($(TARGET_WEB),1) CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2 @@ -500,8 +500,8 @@ CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fn # Linux / Other builds below else -CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` +CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(SDLCONFIG) --cflags` -DUSE_SDL=2 +CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(SDLCONFIG) --cflags` -DUSE_SDL=2 endif # Check for enhancement options diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 8d1661bf..4e08dbdb 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -496,7 +496,7 @@ void optmenu_toggle(void) { newcam_init_settings(); // load bettercam settings from config vars #endif controller_reconfigure(); // rebind using new config values - configfile_save(gCLIOpts.ConfigFile); + configfile_save(configfile_name()); } } diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index 0a0e6a55..bff335a2 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -2,6 +2,7 @@ #include "configfile.h" #include "cheats.h" #include "pc_main.h" +#include "platform.h" #include #include @@ -15,15 +16,27 @@ static void print_help(void) { printf("Super Mario 64 PC Port\n"); printf("%-20s\tEnables the cheat menu.\n", "--cheats"); printf("%-20s\tSaves the configuration file as CONFIGNAME.\n", "--configfile CONFIGNAME"); + printf("%-20s\tOverrides the default read-only data path ('!' expands to executable path).\n", "--datapath DATAPATH"); + printf("%-20s\tOverrides the default save/config path ('!' expands to executable path).\n", "--savepath SAVEPATH"); printf("%-20s\tStarts the game in full screen mode.\n", "--fullscreen"); printf("%-20s\tSkips the Peach and Castle intro when starting a new game.\n", "--skip-intro"); printf("%-20s\tStarts the game in windowed mode.\n", "--windowed"); } +static inline int arg_string(const char *name, const char *value, char *target) { + const unsigned int arglen = strlen(value); + if (arglen >= SYS_MAX_PATH) { + fprintf(stderr, "Supplied value for `%s` is too long.\n", name); + return 0; + } + strncpy(target, value, arglen); + target[arglen] = '\0'; + return 1; +} + void parse_cli_opts(int argc, char* argv[]) { // Initialize options with false values. memset(&gCLIOpts, 0, sizeof(gCLIOpts)); - strncpy(gCLIOpts.ConfigFile, CONFIGFILE_DEFAULT, sizeof(gCLIOpts.ConfigFile)); for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--skip-intro") == 0) // Skip Peach Intro @@ -38,25 +51,19 @@ void parse_cli_opts(int argc, char* argv[]) { else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu Cheats.EnableCheats = true; + else if (strcmp(argv[i], "--configfile") == 0 && (i + 1) < argc) + arg_string("--configfile", argv[++i], gCLIOpts.ConfigFile); + + else if (strcmp(argv[i], "--datapath") == 0 && (i + 1) < argc) + arg_string("--datapath", argv[++i], gCLIOpts.DataPath); + + else if (strcmp(argv[i], "--savepath") == 0 && (i + 1) < argc) + arg_string("--savepath", argv[++i], gCLIOpts.SavePath); + // Print help else if (strcmp(argv[i], "--help") == 0) { print_help(); game_exit(); } - - else if (strcmp(argv[i], "--configfile") == 0) { - if (i+1 < argc) { - const unsigned int arglen = strlen(argv[i+1]); - if (arglen >= sizeof(gCLIOpts.ConfigFile)) { - fprintf(stderr, "Configuration file supplied has a name too long.\n"); - } else { - strncpy(gCLIOpts.ConfigFile, argv[i+1], arglen); - gCLIOpts.ConfigFile[arglen] = '\0'; - } - } - - // Skip the next string since it's the configuration file name. - i++; - } } } diff --git a/src/pc/cliopts.h b/src/pc/cliopts.h index d20dcb4f..2d084eda 100644 --- a/src/pc/cliopts.h +++ b/src/pc/cliopts.h @@ -1,10 +1,14 @@ #ifndef _CLIOPTS_H #define _CLIOPTS_H +#include "platform.h" + struct PCCLIOptions { unsigned int SkipIntro; unsigned int FullScreen; - char ConfigFile[1024]; + char ConfigFile[SYS_MAX_PATH]; + char SavePath[SYS_MAX_PATH]; + char DataPath[SYS_MAX_PATH]; }; extern struct PCCLIOptions gCLIOpts; diff --git a/src/pc/configfile.c b/src/pc/configfile.c index c1983855..588d075a 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -7,7 +7,9 @@ #include #include +#include "platform.h" #include "configfile.h" +#include "cliopts.h" #include "gfx/gfx_screen_config.h" #include "controller/controller_api.h" @@ -192,6 +194,18 @@ static unsigned int tokenize_string(char *str, int maxTokens, char **tokens) { return count; } +// Gets the config file path and caches it +const char *configfile_name(void) { + static char cfgpath[SYS_MAX_PATH] = { 0 }; + if (!cfgpath[0]) { + if (gCLIOpts.ConfigFile[0]) + snprintf(cfgpath, sizeof(cfgpath), "%s", gCLIOpts.ConfigFile); + else + snprintf(cfgpath, sizeof(cfgpath), "%s/%s", sys_save_path(), CONFIGFILE_DEFAULT); + } + return cfgpath; +} + // Loads the config file specified by 'filename' void configfile_load(const char *filename) { FILE *file; diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 6f2c4a25..263d3907 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -4,7 +4,6 @@ #include #define CONFIGFILE_DEFAULT "sm64config.txt" -#define DATAPATH_DEFAULT "res" #define MAX_BINDS 3 #define MAX_VOLUME 127 @@ -51,5 +50,6 @@ extern bool configHUD; void configfile_load(const char *filename); void configfile_save(const char *filename); +const char *configfile_name(void); #endif diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 210c34ff..5abe91e3 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -23,6 +23,7 @@ #include "gfx_rendering_api.h" #include "gfx_screen_config.h" +#include "../platform.h" #include "../configfile.h" #define SUPPORT_CHECK(x) assert(x) @@ -505,10 +506,10 @@ static void import_texture(int tile) { #ifdef EXTERNAL_TEXTURES // the "texture data" is actually a C string with the path to our texture in it // load it from an external image in our data path - static char fpath[1024]; + static char fpath[SYS_MAX_PATH]; int w, h; const char *texname = (const char*)rdp.loaded_texture[tile].addr; - snprintf(fpath, sizeof(fpath), "%s/%s.png", DATAPATH_DEFAULT, texname); + snprintf(fpath, sizeof(fpath), "%s/%s.png", sys_data_path(), texname); u8 *data = stbi_load(fpath, &w, &h, NULL, 4); if (!data) { fprintf(stderr, "texture not found: `%s`\n", fpath); diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index c4162c32..ddb83ce4 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -92,7 +92,7 @@ void audio_shutdown(void) { } void game_deinit(void) { - configfile_save(gCLIOpts.ConfigFile);; + configfile_save(configfile_name()); controller_shutdown(); audio_shutdown(); gfx_shutdown(); @@ -145,7 +145,7 @@ void main_func(void) { main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0])); gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); - configfile_load(gCLIOpts.ConfigFile); + configfile_load(configfile_name()); wm_api = &gfx_sdl; rendering_api = &gfx_opengl_api; diff --git a/src/pc/platform.c b/src/pc/platform.c new file mode 100644 index 00000000..720c91c1 --- /dev/null +++ b/src/pc/platform.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#include "cliopts.h" + +static inline bool dir_exists(const char *path) { + struct stat st; + return (stat(path, &st) == 0 && S_ISDIR(st.st_mode)); +} + +bool sys_mkdir(const char *name) { + #ifdef _WIN32 + return _mkdir(name) == 0; + #else + return mkdir(name, 0777) == 0; + #endif +} + +#if USE_SDL + +// we can just ask SDL for most of this shit if we have it +#include + +const char *sys_data_path(void) { + static char path[SYS_MAX_PATH] = { 0 }; + + if (!path[0]) { + // prefer the override, if it is set + // "!" expands to executable path + if (gCLIOpts.DataPath[0]) { + if (gCLIOpts.DataPath[0] == '!') + snprintf(path, sizeof(path), "%s%s", sys_exe_path(), gCLIOpts.DataPath + 1); + else + snprintf(path, sizeof(path), "%s", gCLIOpts.DataPath); + if (dir_exists(path)) return path; + printf("Warning: Specified data path ('%s') doesn't exist\n", path); + } + + // then the executable directory + snprintf(path, sizeof(path), "%s/" DATADIR, sys_exe_path()); + if (dir_exists(path)) return path; + + // then the save path + snprintf(path, sizeof(path), "%s/" DATADIR, sys_save_path()); + if (dir_exists(path)) return path; + + #if defined(__linux__) || defined(__unix__) + // on Linux/BSD try some common paths for read-only data + const char *try[] = { + "/usr/local/share/sm64pc/" DATADIR, + "/usr/share/sm64pc/" DATADIR, + "/opt/sm64pc/" DATADIR, + }; + for (unsigned i = 0; i < sizeof(try) / sizeof(try[0]); ++i) { + if (dir_exists(try[i])) { + strcpy(path, try[i]); + return path; + } + } + #endif + + // hope for the best + strcpy(path, "./" DATADIR); + } + + return path; +} + +const char *sys_save_path(void) { + static char path[SYS_MAX_PATH] = { 0 }; + + if (!path[0]) { + // if the override is set, use that + // "!" expands to executable path + if (gCLIOpts.SavePath[0]) { + if (gCLIOpts.SavePath[0] == '!') + snprintf(path, sizeof(path), "%s%s", sys_exe_path(), gCLIOpts.SavePath + 1); + else + snprintf(path, sizeof(path), "%s", gCLIOpts.SavePath); + if (!dir_exists(path) && !sys_mkdir(path)) { + printf("Warning: Specified save path ('%s') doesn't exist and can't be created\n", path); + path[0] = 0; // doesn't exist and no write access + } + } + + // didn't work? get it from SDL + if (!path[0]) { + char *sdlpath = SDL_GetPrefPath("", "sm64pc"); + if (sdlpath) { + const unsigned int len = strlen(sdlpath); + strncpy(path, sdlpath, sizeof(path)); + path[sizeof(path)-1] = 0; + SDL_free(sdlpath); + if (path[len-1] == '/' || path[len-1] == '\\') + path[len-1] = 0; // strip the trailing separator + if (!dir_exists(path) && !sys_mkdir(path)) + path[0] = 0; + } + } + + // if all else fails, just store near the EXE + if (!path[0]) + strcpy(path, sys_exe_path()); + + printf("Save path set to '%s'\n", path); + } + + return path; +} + +const char *sys_exe_path(void) { + static char path[SYS_MAX_PATH] = { 0 }; + + if (!path[0]) { + char *sdlpath = SDL_GetBasePath(); + if (sdlpath) { + // use the SDL path if it exists + const unsigned int len = strlen(sdlpath); + strncpy(path, sdlpath, sizeof(path)); + path[sizeof(path)-1] = 0; + SDL_free(sdlpath); + if (path[len-1] == '/' || path[len-1] == '\\') + path[len-1] = 0; // strip the trailing separator + } else { + // hope for the best + strcpy(path, "."); + } + printf("Executable path set to '%s'\n", path); + } + + return path; +} + +#else + +#warning "You might want to implement these functions for your platform" + +const char *sys_data_path(void) { + return "."; +} + +const char *sys_save_path(void) { + return "."; +} + +const char *sys_exe_path(void) { + return "."; +} + +#endif // platform switch diff --git a/src/pc/platform.h b/src/pc/platform.h new file mode 100644 index 00000000..dae51bf9 --- /dev/null +++ b/src/pc/platform.h @@ -0,0 +1,16 @@ +#ifndef _SM64_PLATFORM_H_ +#define _SM64_PLATFORM_H_ + +#include + +/* Platform-specific functions and whatnot */ + +#define DATADIR "res" +#define SYS_MAX_PATH 1024 // FIXME: define this on different platforms + +bool sys_mkdir(const char *name); // creates with 0777 by default +const char *sys_data_path(void); +const char *sys_save_path(void); +const char *sys_exe_path(void); + +#endif // _SM64_PLATFORM_H_ diff --git a/src/pc/ultra_reimplementation.c b/src/pc/ultra_reimplementation.c index 476e3590..c28894f6 100644 --- a/src/pc/ultra_reimplementation.c +++ b/src/pc/ultra_reimplementation.c @@ -2,6 +2,7 @@ #include #include "lib/src/libultra_internal.h" #include "macros.h" +#include "platform.h" #ifdef TARGET_WEB #include @@ -119,7 +120,9 @@ s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) ret = 0; } #else - FILE *fp = fopen("sm64_save_file.bin", "rb"); + char save_path[SYS_MAX_PATH] = { 0 }; + snprintf(save_path, sizeof(save_path), "%s/sm64_save_file.bin", sys_save_path()); + FILE *fp = fopen(save_path, "rb"); if (fp == NULL) { return -1; } @@ -149,7 +152,9 @@ s32 osEepromLongWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes }, content); s32 ret = 0; #else - FILE* fp = fopen("sm64_save_file.bin", "wb"); + char save_path[SYS_MAX_PATH] = { 0 }; + snprintf(save_path, sizeof(save_path), "%s/sm64_save_file.bin", sys_save_path()); + FILE *fp = fopen(save_path, "wb"); if (fp == NULL) { return -1; } From f8139cce6da5a25657ac45f3ba24f20f9585adaf Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 26 May 2020 00:47:08 +0300 Subject: [PATCH 12/24] fix tools Makefile --- tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index d81f5f9a..28ff49bf 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -4,7 +4,7 @@ ifeq ($(UNAME),Darwin) endif CC := gcc -CFLAGS := -Llib -I../include -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 -O3 -s +CFLAGS := -Llib -Iinclude -I../include -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 -O3 -s PROGRAMS := n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math iplfontutil aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv n64graphics_SOURCES := n64graphics.c utils.c From 655c381d6fa48a044f4aa2ec70d32e9a024ff259 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 26 May 2020 00:54:51 +0300 Subject: [PATCH 13/24] add texture preloading when EXTERNAL_TEXTURES is defined, the texture hashmap in gfx_pc.c uses texture names as keys all textures are precached on startup if EXTERNAL_TEXTURES is defined and 'precache' is true in the config --- src/pc/configfile.c | 7 +- src/pc/configfile.h | 3 + src/pc/gfx/gfx_pc.c | 163 +++++++++++++++++++++++++++++++++----------- src/pc/platform.c | 86 ++++++++++++++++++++--- src/pc/platform.h | 18 +++++ 5 files changed, 230 insertions(+), 47 deletions(-) diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 588d075a..2baf96cf 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -66,7 +66,9 @@ unsigned int configKeyStickUp[MAX_BINDS] = { 0x0011, VK_INVALID, VK_INVALID unsigned int configKeyStickDown[MAX_BINDS] = { 0x001F, VK_INVALID, VK_INVALID }; unsigned int configKeyStickLeft[MAX_BINDS] = { 0x001E, VK_INVALID, VK_INVALID }; unsigned int configKeyStickRight[MAX_BINDS] = { 0x0020, VK_INVALID, VK_INVALID }; - +#ifdef EXTERNAL_TEXTURES +bool configPrecacheRes = false; +#endif #ifdef BETTERCAMERA // BetterCamera settings unsigned int configCameraXSens = 50; @@ -105,6 +107,9 @@ static const struct ConfigOption options[] = { {.name = "key_stickdown", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickDown}, {.name = "key_stickleft", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickLeft}, {.name = "key_stickright", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickRight}, + #ifdef EXTERNAL_TEXTURES + {.name = "precache", .type = CONFIG_TYPE_BOOL, .boolValue = &configPrecacheRes}, + #endif #ifdef BETTERCAMERA {.name = "bettercam_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configEnableCamera}, {.name = "bettercam_mouse_look", .type = CONFIG_TYPE_BOOL, .boolValue = &configCameraMouse}, diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 263d3907..1ae38f84 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -35,6 +35,9 @@ extern unsigned int configKeyStickUp[]; extern unsigned int configKeyStickDown[]; extern unsigned int configKeyStickLeft[]; extern unsigned int configKeyStickRight[]; +#ifdef EXTERNAL_TEXTURES +extern bool configPrecacheRes; +#endif #ifdef BETTERCAMERA extern unsigned int configCameraXSens; extern unsigned int configCameraYSens; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 5abe91e3..c0900831 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -46,6 +46,17 @@ #define MAX_LIGHTS 2 #define MAX_VERTICES 64 +#ifdef EXTERNAL_TEXTURES +# define MAX_CACHED_TEXTURES 4096 // for preloading purposes +# define HASH_SHIFT 0 +#else +# define MAX_CACHED_TEXTURES 512 +# define HASH_SHIFT 5 +#endif + +#define HASHMAP_LEN (MAX_CACHED_TEXTURES * 2) +#define HASH_MASK (HASHMAP_LEN - 1) + struct RGBA { uint8_t r, g, b, a; }; @@ -72,8 +83,8 @@ struct TextureHashmapNode { bool linear_filter; }; static struct { - struct TextureHashmapNode *hashmap[1024]; - struct TextureHashmapNode pool[512]; + struct TextureHashmapNode *hashmap[HASHMAP_LEN]; + struct TextureHashmapNode pool[MAX_CACHED_TEXTURES]; uint32_t pool_pos; } gfx_texture_cache; @@ -161,41 +172,17 @@ static size_t buf_vbo_num_tris; static struct GfxWindowManagerAPI *gfx_wapi; static struct GfxRenderingAPI *gfx_rapi; -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && !defined(__APPLE__) -// old mingw -# include <_mingw.h> -# define NO_CLOCK_GETTIME +#ifdef EXTERNAL_TEXTURES +static inline size_t string_hash(const uint8_t *str) { + size_t h = 0; + for (const uint8_t *p = str; *p; p++) + h = 31 * h + *p; + return h; +} #endif -#ifdef NO_CLOCK_GETTIME - -#if defined(_WIN32) -#include -#define CLOCK_MONOTONIC 0 -// https://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows -struct timespec { long tv_sec; long tv_nsec; }; -int clock_gettime(int arg, struct timespec *spec) { - __int64 wintime; - GetSystemTimeAsFileTime((FILETIME*)&wintime); - wintime -= 116444736000000000LL; //1jan1601 to 1jan1970 - spec->tv_sec = wintime / 10000000LL; //seconds - spec->tv_nsec = wintime % 10000000LL*100; //nano-seconds - return 0; -} -#else // _WIN32 -#error "Add a clock_gettime() impl for your platform!" -#endif // _WIN32 - -#else // NO_CLOCK_GETTIME - -#include - -#endif // NO_CLOCK_GETTIME - static unsigned long get_time(void) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (unsigned long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + return 0; } static void gfx_flush(void) { @@ -287,11 +274,19 @@ static struct ColorCombiner *gfx_lookup_or_create_color_combiner(uint32_t cc_id) } static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, const uint8_t *orig_addr, uint32_t fmt, uint32_t siz) { + #ifdef EXTERNAL_TEXTURES // hash and compare the data (i.e. the texture name) itself + size_t hash = string_hash(orig_addr); + #define CMPADDR(x, y) (x && !sys_strcasecmp(x, y)) + #else // hash and compare the address size_t hash = (uintptr_t)orig_addr; - hash = (hash >> 5) & 0x3ff; + #define CMPADDR(x, y) x == y + #endif + + hash = (hash >> HASH_SHIFT) & HASH_MASK; + struct TextureHashmapNode **node = &gfx_texture_cache.hashmap[hash]; while (*node != NULL && *node - gfx_texture_cache.pool < gfx_texture_cache.pool_pos) { - if ((*node)->texture_addr == orig_addr && (*node)->fmt == fmt && (*node)->siz == siz) { + if (CMPADDR((*node)->texture_addr, orig_addr) && (*node)->fmt == fmt && (*node)->siz == siz) { gfx_rapi->select_texture(tile, (*node)->texture_id); *n = *node; return true; @@ -302,7 +297,7 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co // Pool is full. We just invalidate everything and start over. gfx_texture_cache.pool_pos = 0; node = &gfx_texture_cache.hashmap[hash]; - //puts("Clearing texture cache"); + // puts("Clearing texture cache"); } *node = &gfx_texture_cache.pool[gfx_texture_cache.pool_pos++]; if ((*node)->texture_addr == NULL) { @@ -319,9 +314,11 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co (*node)->siz = siz; *n = *node; return false; + #undef CMPADDR } #ifndef EXTERNAL_TEXTURES + static void import_texture_rgba32(int tile) { uint32_t width = rdp.texture_tile.line_size_bytes / 2; uint32_t height = (rdp.loaded_texture[tile].size_bytes / 2) / rdp.texture_tile.line_size_bytes; @@ -493,6 +490,89 @@ static void import_texture_ci8(int tile) { gfx_rapi->upload_texture(rgba32_buf, width, height); } + +#else // EXTERNAL_TEXTURES + +// this is taken straight from n64graphics +static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) { + static const struct { + const char *name; + const u8 format; + const u8 size; + } fmt_table[] = { + { "rgba16", G_IM_FMT_RGBA, G_IM_SIZ_16b }, + { "rgba32", G_IM_FMT_RGBA, G_IM_SIZ_32b }, + { "ia1", G_IM_FMT_IA, G_IM_SIZ_8b }, // uhh + { "ia4", G_IM_FMT_IA, G_IM_SIZ_4b }, + { "ia8", G_IM_FMT_IA, G_IM_SIZ_8b }, + { "ia16", G_IM_FMT_IA, G_IM_SIZ_16b }, + { "i4", G_IM_FMT_I, G_IM_SIZ_4b }, + { "i8", G_IM_FMT_I, G_IM_SIZ_8b }, + { "ci8", G_IM_FMT_I, G_IM_SIZ_8b }, + { "ci16", G_IM_FMT_I, G_IM_SIZ_16b }, + }; + + char *fstr = strrchr(name, '.'); + if (!fstr) return false; // no format string? + fstr++; + + for (unsigned i = 0; i < sizeof(fmt_table) / sizeof(fmt_table[0]); ++i) { + if (!sys_strcasecmp(fstr, fmt_table[i].name)) { + *fmt = fmt_table[i].format; + *siz = fmt_table[i].size; + return true; + } + } + + return false; +} + +// calls import_texture() on every texture in the res folder +// we can get the format and size from the texture files +// and then cache them using gfx_texture_cache_lookup +static bool preload_texture(const char *path) { + // strip off the extension + char texname[SYS_MAX_PATH]; + strncpy(texname, path, sizeof(texname)); + texname[sizeof(texname)-1] = 0; + char *dot = strrchr(texname, '.'); + if (dot) *dot = 0; + + // get the format and size from filename + u8 fmt, siz; + if (!texname_to_texformat(texname, &fmt, &siz)) { + fprintf(stderr, "unknown texture format: `%s`, skipping\n", texname); + return true; // just skip it, might be a stray skybox or something + } + + // strip off the data path + const char *datapath = sys_data_path(); + const unsigned int datalen = strlen(datapath); + const char *actualname = (!strncmp(texname, datapath, datalen)) ? + texname + datalen + 1 : texname; + // skip any separators + while (*actualname == '/' || *actualname == '\\') ++actualname; + // this will be stored in the hashtable, so make a copy + actualname = sys_strdup(actualname); + assert(actualname); + + struct TextureHashmapNode *n; + if (!gfx_texture_cache_lookup(0, &n, actualname, fmt, siz)) { + // new texture, load it + int w, h; + u8 *data = stbi_load(path, &w, &h, NULL, 4); + if (!data) { + fprintf(stderr, "could not load texture: `%s`\n", path); + return false; + } + // upload it + gfx_rapi->upload_texture(data, w, h); + stbi_image_free(data); + } + + return true; +} + #endif // EXTERNAL_TEXTURES static void import_texture(int tile) { @@ -512,7 +592,7 @@ static void import_texture(int tile) { snprintf(fpath, sizeof(fpath), "%s/%s.png", sys_data_path(), texname); u8 *data = stbi_load(fpath, &w, &h, NULL, 4); if (!data) { - fprintf(stderr, "texture not found: `%s`\n", fpath); + fprintf(stderr, "could not load texture: `%s`\n", fpath); abort(); } gfx_rapi->upload_texture(data, w, h); @@ -1663,6 +1743,13 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi) { for (size_t i = 0; i < sizeof(precomp_shaders) / sizeof(uint32_t); i++) { gfx_lookup_or_create_shader_program(precomp_shaders[i]); } + #ifdef EXTERNAL_TEXTURES + // preload all textures if needed + if (configPrecacheRes) { + printf("Precaching textures from `%s`\n", sys_data_path()); + sys_dir_walk(sys_data_path(), preload_texture, true); + } + #endif } void gfx_start_frame(void) { diff --git a/src/pc/platform.c b/src/pc/platform.c index 720c91c1..00cfa289 100644 --- a/src/pc/platform.c +++ b/src/pc/platform.c @@ -5,15 +5,85 @@ #include #include #include +#include +#include #ifdef _WIN32 #include #endif #include "cliopts.h" -static inline bool dir_exists(const char *path) { +/* these are not available on some platforms, so might as well */ + +char *sys_strlwr(char *src) { + for (unsigned char *p = (unsigned char *)src; *p; p++) + *p = tolower(*p); + return src; +} + +char *sys_strdup(const char *src) { + const unsigned len = strlen(src) + 1; + char *newstr = malloc(len); + if (newstr) memcpy(newstr, src, len); + return newstr; +} + +int sys_strcasecmp(const char *s1, const char *s2) { + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + int result; + if (p1 == p2) + return 0; + while ((result = tolower(*p1) - tolower(*p2++)) == 0) + if (*p1++ == '\0') + break; + return result; +} + +/* file system stuff */ + +bool sys_file_exists(const char *name) { struct stat st; - return (stat(path, &st) == 0 && S_ISDIR(st.st_mode)); + return (stat(name, &st) == 0 && S_ISREG(st.st_mode)); +} + +bool sys_dir_exists(const char *name) { + struct stat st; + return (stat(name, &st) == 0 && S_ISDIR(st.st_mode)); +} + +bool sys_dir_walk(const char *base, walk_fn_t walk, const bool recur) { + char fullpath[SYS_MAX_PATH]; + DIR *dir; + struct dirent *ent; + + if (!(dir = opendir(base))) { + fprintf(stderr, "sys_dir_walk(): could not open `%s`\n", base); + return false; + } + + bool ret = true; + + while ((ent = readdir(dir)) != NULL) { + if (ent->d_name[0] == 0 || ent->d_name[0] == '.') continue; // skip ./.. and hidden files + snprintf(fullpath, sizeof(fullpath), "%s/%s", base, ent->d_name); + if (sys_dir_exists(fullpath)) { + if (recur) { + if (!sys_dir_walk(fullpath, walk, recur)) { + ret = false; + break; + } + } + } else { + if (!walk(fullpath)) { + ret = false; + break; + } + } + } + + closedir(dir); + return ret; } bool sys_mkdir(const char *name) { @@ -40,17 +110,17 @@ const char *sys_data_path(void) { snprintf(path, sizeof(path), "%s%s", sys_exe_path(), gCLIOpts.DataPath + 1); else snprintf(path, sizeof(path), "%s", gCLIOpts.DataPath); - if (dir_exists(path)) return path; + if (sys_dir_exists(path)) return path; printf("Warning: Specified data path ('%s') doesn't exist\n", path); } // then the executable directory snprintf(path, sizeof(path), "%s/" DATADIR, sys_exe_path()); - if (dir_exists(path)) return path; + if (sys_dir_exists(path)) return path; // then the save path snprintf(path, sizeof(path), "%s/" DATADIR, sys_save_path()); - if (dir_exists(path)) return path; + if (sys_dir_exists(path)) return path; #if defined(__linux__) || defined(__unix__) // on Linux/BSD try some common paths for read-only data @@ -60,7 +130,7 @@ const char *sys_data_path(void) { "/opt/sm64pc/" DATADIR, }; for (unsigned i = 0; i < sizeof(try) / sizeof(try[0]); ++i) { - if (dir_exists(try[i])) { + if (sys_dir_exists(try[i])) { strcpy(path, try[i]); return path; } @@ -85,7 +155,7 @@ const char *sys_save_path(void) { snprintf(path, sizeof(path), "%s%s", sys_exe_path(), gCLIOpts.SavePath + 1); else snprintf(path, sizeof(path), "%s", gCLIOpts.SavePath); - if (!dir_exists(path) && !sys_mkdir(path)) { + if (!sys_dir_exists(path) && !sys_mkdir(path)) { printf("Warning: Specified save path ('%s') doesn't exist and can't be created\n", path); path[0] = 0; // doesn't exist and no write access } @@ -101,7 +171,7 @@ const char *sys_save_path(void) { SDL_free(sdlpath); if (path[len-1] == '/' || path[len-1] == '\\') path[len-1] = 0; // strip the trailing separator - if (!dir_exists(path) && !sys_mkdir(path)) + if (!sys_dir_exists(path) && !sys_mkdir(path)) path[0] = 0; } } diff --git a/src/pc/platform.h b/src/pc/platform.h index dae51bf9..9b498470 100644 --- a/src/pc/platform.h +++ b/src/pc/platform.h @@ -2,13 +2,31 @@ #define _SM64_PLATFORM_H_ #include +#include +#include /* Platform-specific functions and whatnot */ #define DATADIR "res" #define SYS_MAX_PATH 1024 // FIXME: define this on different platforms +// crossplatform impls of misc stuff +char *sys_strdup(const char *src); +char *sys_strlwr(char *src); +int sys_strcasecmp(const char *s1, const char *s2); + +// filesystem stuff bool sys_mkdir(const char *name); // creates with 0777 by default +bool sys_file_exists(const char *name); +bool sys_dir_exists(const char *name); + +// receives the full path +// should return `true` if traversal should continue +typedef bool (*walk_fn_t)(const char *); +// returns `true` if the directory was successfully opened and walk() didn't ever return false +bool sys_dir_walk(const char *base, walk_fn_t walk, const bool recur); + +// path stuff const char *sys_data_path(void); const char *sys_save_path(void); const char *sys_exe_path(void); From 9f9e79ed9d972e34f73342e6f20e8de84dae1b74 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 26 May 2020 02:18:09 +0300 Subject: [PATCH 14/24] build the res target by default when EXTERNAL_TEXTURES is enabled --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 17b93a55..c862101d 100644 --- a/Makefile +++ b/Makefile @@ -617,6 +617,9 @@ SHA1SUM = sha1sum all: $(EXE) ifeq ($(EXTERNAL_TEXTURES),1) +# depend on resources as well +all: res + # prepares the resource folder for external data res: $(EXE) @mkdir -p $(BUILD_DIR)/res From e3401f15472c62274f2e3baf0d9de5452206cbdf Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 26 May 2020 02:59:38 +0300 Subject: [PATCH 15/24] use a script to output zero-terminated strings instead of bash printf --- Makefile | 3 ++- tools/zeroterm.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tools/zeroterm.py diff --git a/Makefile b/Makefile index c862101d..56404185 100644 --- a/Makefile +++ b/Makefile @@ -607,6 +607,7 @@ EMU_FLAGS = --noosd LOADER = loader64 LOADER_FLAGS = -vwf SHA1SUM = sha1sum +ZEROTERM = $(PYTHON) $(TOOLS_DIR)/zeroterm.py ###################### Dependency Check ##################### @@ -725,7 +726,7 @@ endif # RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4 ifeq ($(EXTERNAL_TEXTURES),1) $(BUILD_DIR)/%: %.png - printf "%s%b" "$(patsubst %.png,%,$^)" '\x00' > $@ + $(ZEROTERM) "$(patsubst %.png,%,$^)" > $@ else $(BUILD_DIR)/%: %.png $(N64GRAPHICS) -i $@ -g $< -f $(lastword $(subst ., ,$@)) diff --git a/tools/zeroterm.py b/tools/zeroterm.py new file mode 100644 index 00000000..7675017a --- /dev/null +++ b/tools/zeroterm.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 +import sys +if len(sys.argv) < 2: + print("usage: zeroterm ") +else: + sys.stdout.buffer.write(bytes(sys.argv[1], 'ascii') + b'\x00') From b5b5aab076b0b35005335a67cc0a368be8470474 Mon Sep 17 00:00:00 2001 From: "Colton G. Rushton" Date: Tue, 26 May 2020 15:28:36 -0300 Subject: [PATCH 16/24] Fix a minor error with bettercamera The bettercamera code set when the player goes to THI is actually supposed to be set when the player goes to TTM. This small PR fixes this minor bug. --- src/game/bettercamera.inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/bettercamera.inc.h b/src/game/bettercamera.inc.h index e6d3bf6f..c2003347 100644 --- a/src/game/bettercamera.inc.h +++ b/src/game/bettercamera.inc.h @@ -129,7 +129,7 @@ void newcam_init(struct Camera *c, u8 dv) case LEVEL_CCM: if (gCurrAreaIndex == 1) {newcam_yaw = -0x4000; newcam_tilt = 2000; newcam_distance_target = newcam_distance_values[1];} else newcam_mode = NC_MODE_SLIDE; break; case LEVEL_WDW: newcam_yaw = 0x2000; newcam_tilt = 3000; newcam_distance_target = newcam_distance_values[1]; break; case 27: newcam_mode = NC_MODE_SLIDE; break; - case LEVEL_THI: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break; + case LEVEL_TTM: if (gCurrAreaIndex == 2) newcam_mode = NC_MODE_SLIDE; break; } newcam_distance = newcam_distance_target; From 62e78a74c0b3379e951c069cf8ba113e7338659d Mon Sep 17 00:00:00 2001 From: fgsfds Date: Wed, 27 May 2020 02:51:05 +0300 Subject: [PATCH 17/24] fix crashes with EXTERNAL_TEXTURES on JP/EU and Bowser related to two huge textures and fonts --- actors/bowser_flame/model.inc.c | 51 ++++++++++++--------------------- actors/impact_smoke/model.inc.c | 20 ++++++------- src/game/ingame_menu.c | 10 ++++++- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/actors/bowser_flame/model.inc.c b/actors/bowser_flame/model.inc.c index e5c1beeb..2551342e 100644 --- a/actors/bowser_flame/model.inc.c +++ b/actors/bowser_flame/model.inc.c @@ -78,10 +78,10 @@ static const Vtx flame_seg6_vertex_0601C000[] = { {{{ 150, 150, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}}, {{{ 150, 300, 0}, 0, { 2016, 0}, {0xff, 0xff, 0xff, 0xff}}}, {{{ -150, 300, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ -150, 0, 0}, 0, { 0, 992}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ 150, 0, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ 150, 150, 0}, 0, { 2016, 0}, {0xff, 0xff, 0xff, 0xff}}}, - {{{ -150, 150, 0}, 0, { 0, 0}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ -150, 0, 0}, 0, { 0, 2016}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ 150, 0, 0}, 0, { 2016, 2016}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ 150, 150, 0}, 0, { 2016, 992}, {0xff, 0xff, 0xff, 0xff}}}, + {{{ -150, 150, 0}, 0, { 0, 992}, {0xff, 0xff, 0xff, 0xff}}}, }; // 0x0601C080 - 0x0601C0B0 @@ -117,10 +117,9 @@ const Gfx flame_seg6_dl_0601C0E0[] = { // 0x0601C108 - 0x0601C1A8 const Gfx flame_seg6_dl_0601C108[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06000000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06000000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06000000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -129,10 +128,9 @@ const Gfx flame_seg6_dl_0601C108[] = { // 0x0601C1A8 - 0x0601C248 const Gfx flame_seg6_dl_0601C1A8[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06002000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06002000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06002000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -141,10 +139,9 @@ const Gfx flame_seg6_dl_0601C1A8[] = { // 0x0601C248 - 0x0601C2E8 const Gfx flame_seg6_dl_0601C248[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06004000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06004000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06004000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -153,10 +150,9 @@ const Gfx flame_seg6_dl_0601C248[] = { // 0x0601C2E8 - 0x0601C388 const Gfx flame_seg6_dl_0601C2E8[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06006000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06006000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06006000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -165,10 +161,9 @@ const Gfx flame_seg6_dl_0601C2E8[] = { // 0x0601C388 - 0x0601C428 const Gfx flame_seg6_dl_0601C388[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06008000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06008000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06008000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -177,10 +172,9 @@ const Gfx flame_seg6_dl_0601C388[] = { // 0x0601C428 - 0x0601C4C8 const Gfx flame_seg6_dl_0601C428[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_0600A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_0600A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_0600A000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -189,10 +183,8 @@ const Gfx flame_seg6_dl_0601C428[] = { // 0x0601C4C8 - 0x0601C568 const Gfx flame_seg6_dl_0601C4C8[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_0600C000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_0600C000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), - gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_0600C000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -201,10 +193,9 @@ const Gfx flame_seg6_dl_0601C4C8[] = { // 0x0601C568 - 0x0601C608 const Gfx flame_seg6_dl_0601C568[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_0600E000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_0600E000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_0600E000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -213,10 +204,9 @@ const Gfx flame_seg6_dl_0601C568[] = { // 0x0601C608 - 0x0601C6A8 const Gfx flame_seg6_dl_0601C608[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06010000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06010000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06010000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -225,10 +215,9 @@ const Gfx flame_seg6_dl_0601C608[] = { // 0x0601C6A8 - 0x0601C748 const Gfx flame_seg6_dl_0601C6A8[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06012000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06012000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06012000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -237,10 +226,9 @@ const Gfx flame_seg6_dl_0601C6A8[] = { // 0x0601C748 - 0x0601C7E8 const Gfx flame_seg6_dl_0601C748[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06014000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06014000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06014000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -249,10 +237,9 @@ const Gfx flame_seg6_dl_0601C748[] = { // 0x0601C7E8 - 0x0601C888 const Gfx flame_seg6_dl_0601C7E8[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06016000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06016000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06016000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -261,10 +248,9 @@ const Gfx flame_seg6_dl_0601C7E8[] = { // 0x0601C888 - 0x0601C928 const Gfx flame_seg6_dl_0601C888[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_06018000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_06018000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_06018000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), @@ -273,10 +259,9 @@ const Gfx flame_seg6_dl_0601C888[] = { // 0x0601C928 - 0x0601C9C8 const Gfx flame_seg6_dl_0601C928[] = { gsSPDisplayList(flame_seg6_dl_0601C080), - gsDPLoadTextureBlock(flame_seg6_texture_0601A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(flame_seg6_texture_0601A000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(flame_seg6_vertex_0601C000, 8, 0), gsSPDisplayList(flame_seg6_dl_0601C0B0), - gsDPLoadTextureBlock(flame_seg6_texture_0601A000 + 0x1000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(flame_seg6_dl_0601C0C8), gsSPDisplayList(flame_seg6_dl_0601C0E0), gsSPEndDisplayList(), diff --git a/actors/impact_smoke/model.inc.c b/actors/impact_smoke/model.inc.c index 48aeb602..012cf6f6 100644 --- a/actors/impact_smoke/model.inc.c +++ b/actors/impact_smoke/model.inc.c @@ -28,10 +28,10 @@ static const Vtx impact_smoke_seg6_vertex_06062A28[] = { {{{ 150, 150, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}}, {{{ 150, 300, 0}, 0, { 2016, 0}, {0x28, 0x19, 0x14, 0xff}}}, {{{ -150, 300, 0}, 0, { 0, 0}, {0x28, 0x19, 0x14, 0xff}}}, - {{{ -150, 0, 0}, 0, { 0, 992}, {0x28, 0x19, 0x14, 0xff}}}, - {{{ 150, 0, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}}, - {{{ 150, 150, 0}, 0, { 2016, 0}, {0x28, 0x19, 0x14, 0xff}}}, - {{{ -150, 150, 0}, 0, { 0, 0}, {0x28, 0x19, 0x14, 0xff}}}, + {{{ -150, 0, 0}, 0, { 0, 2016}, {0x28, 0x19, 0x14, 0xff}}}, + {{{ 150, 0, 0}, 0, { 2016, 2016}, {0x28, 0x19, 0x14, 0xff}}}, + {{{ 150, 150, 0}, 0, { 2016, 992}, {0x28, 0x19, 0x14, 0xff}}}, + {{{ -150, 150, 0}, 0, { 0, 992}, {0x28, 0x19, 0x14, 0xff}}}, }; // 0x06062AA8 - 0x06062AD8 @@ -68,10 +68,9 @@ const Gfx impact_smoke_seg6_dl_06062B08[] = { // 0x06062B38 - 0x06062BD8 const Gfx impact_smoke_seg6_dl_06062B38[] = { gsSPDisplayList(impact_smoke_seg6_dl_06062AA8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0), gsSPDisplayList(impact_smoke_seg6_dl_06062AD8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605AA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(impact_smoke_seg6_dl_06062AF0), gsSPDisplayList(impact_smoke_seg6_dl_06062B08), gsSPEndDisplayList(), @@ -80,10 +79,9 @@ const Gfx impact_smoke_seg6_dl_06062B38[] = { // 0x06062BD8 - 0x06062C78 const Gfx impact_smoke_seg6_dl_06062BD8[] = { gsSPDisplayList(impact_smoke_seg6_dl_06062AA8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0), gsSPDisplayList(impact_smoke_seg6_dl_06062AD8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605CA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(impact_smoke_seg6_dl_06062AF0), gsSPDisplayList(impact_smoke_seg6_dl_06062B08), gsSPEndDisplayList(), @@ -92,10 +90,9 @@ const Gfx impact_smoke_seg6_dl_06062BD8[] = { // 0x06062C78 - 0x06062D18 const Gfx impact_smoke_seg6_dl_06062C78[] = { gsSPDisplayList(impact_smoke_seg6_dl_06062AA8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0), gsSPDisplayList(impact_smoke_seg6_dl_06062AD8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_0605EA28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(impact_smoke_seg6_dl_06062AF0), gsSPDisplayList(impact_smoke_seg6_dl_06062B08), gsSPEndDisplayList(), @@ -104,10 +101,9 @@ const Gfx impact_smoke_seg6_dl_06062C78[] = { // 0x06062D18 - 0x06062DB8 const Gfx impact_smoke_seg6_dl_06062D18[] = { gsSPDisplayList(impact_smoke_seg6_dl_06062AA8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), + gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 64, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD), gsSPVertex(impact_smoke_seg6_vertex_06062A28, 8, 0), gsSPDisplayList(impact_smoke_seg6_dl_06062AD8), - gsDPLoadTextureBlock(impact_smoke_seg6_texture_06060A28 + 0x1000, G_IM_FMT_IA, G_IM_SIZ_16b, 64, 32, 0, G_TX_CLAMP, G_TX_CLAMP, 6, 5, G_TX_NOLOD, G_TX_NOLOD), gsSPDisplayList(impact_smoke_seg6_dl_06062AF0), gsSPDisplayList(impact_smoke_seg6_dl_06062B08), gsSPEndDisplayList(), diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index d7de9d4e..6f3d84b9 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -128,7 +128,7 @@ u8 gMenuHoldKeyIndex = 0; u8 gMenuHoldKeyTimer = 0; s32 gDialogResponse = 0; -#if defined(VERSION_JP) || defined(VERSION_SH) || defined(VERSION_EU) +#if !defined(EXTERNAL_TEXTURES) && (defined(VERSION_JP) || defined(VERSION_SH) || defined(VERSION_EU)) #ifdef VERSION_EU #define CHCACHE_BUFLEN (8 * 8) // EU only converts 8x8 #else @@ -242,11 +242,15 @@ static inline void alloc_ia8_text_from_i1(u8 *out, u16 *in, s16 width, s16 heigh } static inline u8 *convert_ia8_char(u8 c, u16 *tex, s16 w, s16 h) { +#ifdef EXTERNAL_TEXTURES + return (u8 *)tex; // the data's just a name +#else if (!charCache[c].used) { charCache[c].used = 1; alloc_ia8_text_from_i1(charCache[c].data, tex, w, h); } return charCache[c].data; +#endif } #endif @@ -298,11 +302,15 @@ static void alloc_ia4_tex_from_i1(u8 *out, u8 *in, s16 width, s16 height) { } static u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { +#ifdef EXTERNAL_TEXTURES + return tex; // the data's just a name +#else if (!charCache[c].used) { charCache[c].used = 1; alloc_ia4_tex_from_i1(charCache[c].data, tex, w, h); } return charCache[c].data; +#endif } void render_generic_char_at_pos(s16 xPos, s16 yPos, u8 c) { From 8013b9a32509ebc7bf2bc96fbbc4f7343590b184 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Wed, 27 May 2020 02:56:12 +0300 Subject: [PATCH 18/24] add scripts to rename CRC-named HD textures as used by @originalgrego's fork --- tools/cleancrcmap.py | 42 ++ tools/default_crcmap.txt | 1237 ++++++++++++++++++++++++++++++++++++++ tools/texrename.py | 71 +++ 3 files changed, 1350 insertions(+) create mode 100644 tools/cleancrcmap.py create mode 100644 tools/default_crcmap.txt create mode 100644 tools/texrename.py diff --git a/tools/cleancrcmap.py b/tools/cleancrcmap.py new file mode 100644 index 00000000..a5f343c2 --- /dev/null +++ b/tools/cleancrcmap.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +import sys +import os +import glob + +if len(sys.argv) < 4: + print("usage: cleancrcmap ") + sys.exit(1) + +# load and check the old map +searchpath = sys.argv[3] +inmap = list() +with open(sys.argv[1], 'r') as f: + for line in f: + line = line.strip() + if line == '' or line[0] == '#': + continue + tok = line.split(',') + crcstr = tok[0].strip() + if crcstr.startswith('0x'): + crc = int(crcstr[2:], 16) + else: + crc = int(crcstr) + tok[1] = tok[1].strip() + [fname, fext] = os.path.splitext(tok[1]) + [fname, ffmt] = os.path.splitext(fname) + fname = fname + ffmt[:-1] + '*' + matches = glob.glob(os.path.join(searchpath, fname)) + if len(matches) == 0: + print("warning: texture '{0}' does not match anything in '{1}'".format(fname, searchpath)) + else: + for s in matches: + tup = (crc, os.path.relpath(s, searchpath)) + if not (tup in inmap): + inmap.append(tup) + +# save cleaned up version to the new one +with open(sys.argv[2], 'w') as f: + for (crc, fpath) in inmap: + f.write("0x{0:08x}, {1}\n".format(crc, fpath)) + diff --git a/tools/default_crcmap.txt b/tools/default_crcmap.txt new file mode 100644 index 00000000..96d18d0e --- /dev/null +++ b/tools/default_crcmap.txt @@ -0,0 +1,1237 @@ +0x6ce78789, actors/amp/amp_body.rgba16.png +0x5b9c3f42, actors/amp/amp_electricity.rgba16.png +0x5e27d08d, actors/amp/amp_eyes.rgba16.png +0x9e3c9a4f, actors/amp/amp_mouth.rgba16.png +0x48dde054, actors/blue_coin_switch/blue_coin_switch_side.rgba16.png +0x8850ff36, actors/blue_coin_switch/blue_coin_switch_top.rgba16.png +0xc3996a4f, actors/blue_fish/blue_fish.rgba16.png +0xbdfeb7e9, actors/bobomb/bob-omb_buddy_left_side.rgba16.png +0x0b1833a6, actors/bobomb/bob-omb_buddy_right_side.rgba16.png +0xae5a9812, actors/bobomb/bob-omb_eyes.rgba16.png +0x6cf0fe65, actors/bobomb/bob-omb_eyes_blink.rgba16.png +0xd5ef42fe, actors/bobomb/bob-omb_left_side.rgba16.png +0xc9a10845, actors/bobomb/bob-omb_right_side.rgba16.png +0x6348045f, actors/bomb/bomb_left_side.rgba16.png +0x83895fa8, actors/bomb/bomb_right_side.rgba16.png +0x6edb77dd, actors/bomb/bomb_spike.rgba16.png +0xdbd94196, actors/boo/boo_eyes.rgba16.png +0xe4e9207b, actors/boo/boo_mouth.rgba16.png +0x873a803d, actors/book/book_cover.rgba16.png +0x873a803d, actors/bookend/bookend_cover.rgba16.png +0xf16beef9, actors/bookend/bookend_mouth.rgba16.png +0xf20999a3, actors/bookend/bookend_pages.rgba16.png +0x1b67dd5e, actors/bookend/bookend_spine.rgba16.png +0x86fb718b, actors/bookend/bookend_tooth.rgba16.png +0xdbd94196, actors/boo_castle/bbh_boo_eyes.rgba16.png +0xe4e9207b, actors/boo_castle/bbh_boo_mouth.rgba16.png +0x1216b12c, actors/bowser/bowser_armband.rgba16.png +0x5373f495, actors/bowser/bowser_armband_spike.rgba16.png +0xa91fab36, actors/bowser/bowser_blue_eye_unused.rgba16.png +0xadcde34c, actors/bowser/bowser_body.rgba16.png +0x77d3e700, actors/bowser/bowser_chest.rgba16.png +0xe954c2e1, actors/bowser/bowser_claw_edge.rgba16.png +0x992a5f26, actors/bowser/bowser_claw_horn_angle.rgba16.png +0x42fe6ddf, actors/bowser/bowser_claw_horn_tooth.rgba16.png +0x5c85a49b, actors/bowser/bowser_eyebrow.rgba16.png +0x6d829b70, actors/bowser/bowser_eye_center_0.rgba16.png +0x6d829b70, actors/bowser/bowser_eye_center_1.rgba16.png +0xabc1926e, actors/bowser/bowser_eye_closed_0.rgba16.png +0xabc1926e, actors/bowser/bowser_eye_closed_1.rgba16.png +0xc7cba4bb, actors/bowser/bowser_eye_far_left_0.rgba16.png +0xc7cba4bb, actors/bowser/bowser_eye_far_left_1.rgba16.png +0x960f22ad, actors/bowser/bowser_eye_half_closed_0.rgba16.png +0x960f22ad, actors/bowser/bowser_eye_half_closed_1.rgba16.png +0xa3228592, actors/bowser/bowser_eye_left_0.rgba16.png +0xa3228592, actors/bowser/bowser_eye_left_1.rgba16.png +0x8276c6db, actors/bowser/bowser_eye_right_0.rgba16.png +0x8276c6db, actors/bowser/bowser_eye_right_1.rgba16.png +0x06d96598, actors/bowser/bowser_hair.rgba16.png +0x7517b30d, actors/bowser/bowser_mouth_unused.rgba16.png +0xeb652400, actors/bowser/bowser_muzzle.rgba16.png +0xf0835c8b, actors/bowser/bowser_nostrils.rgba16.png +0xf88cd2e7, actors/bowser/bowser_shell.rgba16.png +0xd3b6356a, actors/bowser/bowser_shell_edge.rgba16.png +0x5a9a602f, actors/bowser/bowser_tongue.rgba16.png +0x549de5f1, actors/bowser/bowser_upper_face.rgba16.png +0x6727a3b0, actors/bowser_flame/bowser_flame_0.rgba16.png +0x9a6e1a6d, actors/bowser_flame/bowser_flame_1.rgba16.png +0xecd82c74, actors/bowser_flame/bowser_flame_10.rgba16.png +0xc7de1268, actors/bowser_flame/bowser_flame_11.rgba16.png +0xc00cbf87, actors/bowser_flame/bowser_flame_12.rgba16.png +0xa9812b21, actors/bowser_flame/bowser_flame_13.rgba16.png +0xd03c08db, actors/bowser_flame/bowser_flame_2.rgba16.png +0xefbd7dde, actors/bowser_flame/bowser_flame_3.rgba16.png +0x90bbbf55, actors/bowser_flame/bowser_flame_4.rgba16.png +0xf8f11fd3, actors/bowser_flame/bowser_flame_5.rgba16.png +0xb8e0116c, actors/bowser_flame/bowser_flame_6.rgba16.png +0x07b2ffca, actors/bowser_flame/bowser_flame_7.rgba16.png +0x0c44fe85, actors/bowser_flame/bowser_flame_8.rgba16.png +0xd6ffbba9, actors/bowser_flame/bowser_flame_9.rgba16.png +0x7ed45348, actors/breakable_box/cork_box_surface.rgba16.png +0xbb9bfd9b, actors/breakable_box/crazy_box_surface.rgba16.png +0xcf7a737c, actors/bub/bub_eyes.rgba16.png +0x2781ee31, actors/bub/bub_eye_border.rgba16.png +0xda65418a, actors/bub/bub_fins.rgba16.png +0x8ac2ce9e, actors/bub/bub_scales.rgba16.png +0xcf7a737c, actors/bubba/bubba_eyes_unused.rgba16.png +0x2781ee31, actors/bubba/bubba_eye_border.rgba16.png +0xda65418a, actors/bubba/bubba_fins.rgba16.png +0x8f294c48, actors/bubba/bubba_scales.rgba16.png +0x0c8d30ca, actors/bubba/bubba_sunglasses.rgba16.png +0x332edb92, actors/bubble/bubble.rgba16.png +0xcdf0fa68, actors/bubble/mr_i_bubble.rgba16.png +0x21fe5d40, actors/bullet_bill/bullet_bill_eye.rgba16.png +0xb1b85895, actors/bullet_bill/bullet_bill_mouth.rgba16.png +0x5a12c79d, actors/bully/bully_eye.rgba16.png +0xec266038, actors/bully/bully_horn.rgba16.png +0x49520b07, actors/bully/bully_left_side.rgba16.png +0xb5c23e47, actors/bully/bully_right_side.rgba16.png +0xdbd6053f, actors/burn_smoke/burn_smoke.ia16.png +0x2e2ad98c, actors/butterfly/butterfly_wing.rgba16.png +0x0e4dd4fc, actors/cannon_barrel/cannon_barrel.rgba16.png +0x5f030348, actors/cannon_base/cannon_base.rgba16.png +0x158b08e7, actors/cannon_lid/cannon_lid.rgba16.png +0x71d10611, actors/capswitch/cap_switch_base.rgba16.png +0xf4aef8c8, actors/capswitch/cap_switch_head.ia16.png +0x1dc03e3e, actors/chain_ball/chain_ball.rgba16.png +0xfd062ba1, actors/chain_chomp/chain_chomp_bright_shine.rgba16.png +0xf7a6e017, actors/chain_chomp/chain_chomp_dull_shine.rgba16.png +0x8bd0db01, actors/chain_chomp/chain_chomp_eye.rgba16.png +0x2cc7d027, actors/chain_chomp/chain_chomp_tongue.rgba16.png +0x241e32b1, actors/chain_chomp/chain_chomp_tooth.rgba16.png +0x1258699c, actors/chair/chair_bottom.rgba16.png +0x6aeb7431, actors/chair/chair_front.rgba16.png +0xb1699f08, actors/chair/chair_leg.rgba16.png +0xf1ce5071, actors/chair/chair_surface_unused.rgba16.png +0x0d4f911f, actors/checkerboard_platform/checkerboard_platform.rgba16.png +0xb78d39ae, actors/checkerboard_platform/checkerboard_platform_side.rgba16.png +0x5a12c79d, actors/chillychief/chill_bully_eye.rgba16.png +0x7ef18bc0, actors/chillychief/chill_bully_left_side.rgba16.png +0x51899ea2, actors/chillychief/chill_bully_right_side.rgba16.png +0xb1168bb8, actors/chuckya/chuckya_body_arm_left_side.rgba16.png +0x3a87fdcb, actors/chuckya/chuckya_body_arm_right_side.rgba16.png +0x64f4c24d, actors/chuckya/chuckya_eyes.rgba16.png +0xb8520d0e, actors/chuckya/chuckya_hand_antenna.rgba16.png +0xe9f30ab8, actors/clam_shell/clam_shell.rgba16.png +0x9226c89b, actors/clam_shell/clam_shell_mouth.rgba16.png +0xf917b481, actors/coin/coin_front.ia16.png +0xf3efe791, actors/coin/coin_side.ia16.png +0x398f8275, actors/coin/coin_tilt_left.ia16.png +0x285437f2, actors/coin/coin_tilt_right.ia16.png +0xcfa59ad1, actors/cyan_fish/cyan_fish.rgba16.png +0xdcfc2924, actors/dirt/dirt_particle.rgba16.png +0x30e837d4, actors/door/bbh_door.rgba16.png +0x43fb37a9, actors/door/bbh_door_overlay.rgba16.png +0x48cb5ae9, actors/door/door_lock.rgba16.png +0x8e8a0021, actors/door/hmc_mural_door.rgba16.png +0x1c2f63d1, actors/door/hmc_mural_door_overlay.rgba16.png +0x15880e25, actors/door/metal_door.rgba16.png +0x0b2e6255, actors/door/metal_door_overlay.rgba16.png +0xabff97b7, actors/door/one_star_door_sign.rgba16.png +0xac08e08f, actors/door/polished_wooden_door.rgba16.png +0x0a018421, actors/door/polished_wooden_door_overlay.rgba16.png +0xbee60bab, actors/door/rough_wooden_door.rgba16.png +0xfc028d47, actors/door/rough_wooden_door_overlay.rgba16.png +0x5b2d3a75, actors/door/three_star_door_sign.rgba16.png +0x7cdbd009, actors/door/zero_star_door_sign.rgba16.png +0x84ae4f62, actors/dorrie/dorrie_eye.rgba16.png +0x566ceea7, actors/dorrie/dorrie_skin.rgba16.png +0x2cc7d027, actors/dorrie/dorrie_tongue.rgba16.png +0x48e8dc18, actors/exclamation_box/exclamation_box_front.rgba16.png +0x4ea62323, actors/exclamation_box/exclamation_box_side.rgba16.png +0x33aa18f1, actors/exclamation_box/metal_cap_box_front.rgba16.png +0x01295855, actors/exclamation_box/metal_cap_box_side.rgba16.png +0x4868d6f8, actors/exclamation_box/vanish_cap_box_front.rgba16.png +0x25fa6e30, actors/exclamation_box/vanish_cap_box_sides.rgba16.png +0x109a876c, actors/exclamation_box/wing_cap_box_front.rgba16.png +0x49dc8276, actors/exclamation_box/wing_cap_box_sides.rgba16.png +0x86c1470d, actors/exclamation_box_outline/exclamation_box_outline.rgba16.png +0x380f4109, actors/exclamation_box_outline/exclamation_point.rgba16.png +0x33181fa0, actors/explosion/explosion_0.rgba16.png +0xf9b0adc0, actors/explosion/explosion_1.rgba16.png +0x60ed7b14, actors/explosion/explosion_2.rgba16.png +0xf6bc5ca6, actors/explosion/explosion_3.rgba16.png +0x02f615dd, actors/explosion/explosion_4.rgba16.png +0x6456136f, actors/explosion/explosion_5.rgba16.png +0xb58eb1ef, actors/explosion/explosion_6.rgba16.png +0xbfb0c0c1, actors/eyerok/eyerok_bricks.rgba16.png +0x5e4df953, actors/eyerok/eyerok_eye_closed.rgba16.png +0xee91056d, actors/eyerok/eyerok_eye_mostly_closed.rgba16.png +0xa955f8c5, actors/eyerok/eyerok_eye_mostly_open.rgba16.png +0x8b76add0, actors/eyerok/eyerok_eye_open.rgba16.png +0x9ce4f269, actors/flame/flame_0.ia16.png +0x20d5be86, actors/flame/flame_1.ia16.png +0x73a7a005, actors/flame/flame_2.ia16.png +0x2c6d7d31, actors/flame/flame_3.ia16.png +0xfa3914af, actors/flame/flame_4.ia16.png +0x41eb9aab, actors/flame/flame_5.ia16.png +0xc3f536f0, actors/flame/flame_6.ia16.png +0xcc3acab3, actors/flame/flame_7.ia16.png +0xd265b139, actors/flyguy/flyguy_cloth_wrinkle.rgba16.png +0x519d3d8a, actors/flyguy/flyguy_face.rgba16.png +0x1058cfe1, actors/flyguy/flyguy_propeller.ia16.png +0x49f51e07, actors/fwoosh/fwoosh_face.ia16.png +0xff8aa0d7, actors/goomba/goomba_body.rgba16.png +0xa0f28d98, actors/goomba/goomba_face.rgba16.png +0x029304d9, actors/goomba/goomba_face_blink.rgba16.png +0xd1559bcc, actors/haunted_cage/bbh_cage_bars.rgba16.png +0xa630c9ea, actors/haunted_cage/bbh_cage_double_ornament.rgba16.png +0xab6318d0, actors/haunted_cage/bbh_cage_floor.rgba16.png +0xf6e0fd6c, actors/haunted_cage/bbh_cage_garbage.rgba16.png +0x8db79b54, actors/haunted_cage/bbh_cage_ornament.rgba16.png +0x29698152, actors/haunted_cage/bbh_cage_wooden_base.rgba16.png +0xaa2b7d4d, actors/heart/spinning_heart.rgba16.png +0xedcc13fa, actors/heave_ho/heave-ho_arm_ornament.rgba16.png +0x5966641f, actors/heave_ho/heave-ho_face.rgba16.png +0xb6f72a6e, actors/heave_ho/heave-ho_logo.rgba16.png +0x638933f8, actors/heave_ho/heave-ho_platform.rgba16.png +0x857a40d7, actors/heave_ho/heave-ho_roller.rgba16.png +0xcdc7a027, actors/heave_ho/heave-ho_turnkey.rgba16.png +0x7ac462c0, actors/hoot/hoot_eyes.rgba16.png +0x7826c81a, actors/hoot/hoot_wing.rgba16.png +0x4461a545, actors/hoot/hoot_wing_tip.rgba16.png +0x9486ce85, actors/impact_ring/impact_ring_left_side.ia16.png +0x2d6b7a90, actors/impact_ring/impact_ring_right_side.ia16.png +0x920a4830, actors/impact_smoke/impact_smoke_0.ia16.png +0xe658e7ec, actors/impact_smoke/impact_smoke_1.ia16.png +0x5e4d860f, actors/impact_smoke/impact_smoke_2.ia16.png +0x66afde95, actors/impact_smoke/impact_smoke_3.ia16.png +0x09f2a7d9, actors/king_bobomb/bob-omb_buddy_body_unused.rgba16.png +0xbdfeb7e9, actors/king_bobomb/bob-omb_buddy_left_side_unused.rgba16.png +0x0b1833a6, actors/king_bobomb/bob-omb_buddy_right_side_unused.rgba16.png +0x13947d02, actors/king_bobomb/king_bob-omb_arm.rgba16.png +0xbcb092cb, actors/king_bobomb/king_bob-omb_body_unused.rgba16.png +0x9cb3f8a1, actors/king_bobomb/king_bob-omb_crown_rim.rgba16.png +0xf9084721, actors/king_bobomb/king_bob-omb_eyes.rgba16.png +0x89f3f5a0, actors/king_bobomb/king_bob-omb_hand.rgba16.png +0x5741b6a5, actors/king_bobomb/king_bob-omb_left_side.rgba16.png +0x625018c9, actors/king_bobomb/king_bob-omb_right_side.rgba16.png +0xa5f8d058, actors/klepto/klepto_beak.rgba16.png +0x7ccef531, actors/klepto/klepto_chest_tuft.rgba16.png +0xab4f6226, actors/klepto/klepto_eye.rgba16.png +0x39695931, actors/klepto/klepto_wing.rgba16.png +0x1e03d762, actors/klepto/klepto_wing_flap.rgba16.png +0x3d9b7dd6, actors/koopa/koopa_eyes_closed.rgba16.png +0x7409fc94, actors/koopa/koopa_eyes_open.rgba16.png +0xcf8c4236, actors/koopa/koopa_eye_border.rgba16.png +0x3650b971, actors/koopa/koopa_nostrils.rgba16.png +0x69fbaa13, actors/koopa/koopa_shell_back.rgba16.png +0x449e0eec, actors/koopa/koopa_shell_front.rgba16.png +0x34adb0d7, actors/koopa/koopa_shell_front_top.rgba16.png +0x4b0b84c0, actors/koopa/koopa_shoe.rgba16.png +0x83279720, actors/koopa_flag/koopa_flag_banner.rgba16.png +0x69fbaa13, actors/koopa_shell/koopa_shell_back.rgba16.png +0x449e0eec, actors/koopa_shell/koopa_shell_front.rgba16.png +0x0a7cdd78, actors/lakitu_cameraman/lakitu_cameraman_cloud_face_unused.rgba16.png +0x34132ec9, actors/lakitu_cameraman/lakitu_cameraman_eyes_closed.rgba16.png +0xb1a8de05, actors/lakitu_cameraman/lakitu_cameraman_eyes_open.rgba16.png +0xf6568aa1, actors/lakitu_cameraman/lakitu_cameraman_frown.rgba16.png +0xb4d174d5, actors/lakitu_cameraman/lakitu_cameraman_shell.rgba16.png +0x52984569, actors/lakitu_cameraman/lakitu_camera_lens.rgba16.png +0x0a7cdd78, actors/lakitu_enemy/lakitu_enemy_cloud_face_unused.rgba16.png +0x34132ec9, actors/lakitu_enemy/lakitu_enemy_eyes_closed.rgba16.png +0xb1a8de05, actors/lakitu_enemy/lakitu_enemy_eyes_open.rgba16.png +0xf6568aa1, actors/lakitu_enemy/lakitu_enemy_frown.rgba16.png +0xb4d174d5, actors/lakitu_enemy/lakitu_enemy_shell.rgba16.png +0x491f98d7, actors/leaves/leaf.rgba16.png +0xada51580, actors/mad_piano/mad_piano_body.rgba16.png +0x857a6a85, actors/mad_piano/mad_piano_keys.rgba16.png +0x39cdf80e, actors/mad_piano/mad_piano_keys_corner.rgba16.png +0x4c5c141a, actors/mad_piano/mad_piano_keys_edge.rgba16.png +0x2e36badc, actors/mad_piano/mad_piano_mouth.rgba16.png +0x241e32b1, actors/mad_piano/mad_piano_tooth.rgba16.png +0x1e94913c, actors/manta/manta_eye.rgba16.png +0x66703e44, actors/manta/manta_fin_corner.rgba16.png +0x2783aa5c, actors/manta/manta_fin_edge.rgba16.png +0xfd83a1ff, actors/manta/manta_gills.rgba16.png +0x390b6600, actors/mario/mario_eyes_center.rgba16.png +0x99c5d462, actors/mario/mario_eyes_closed.rgba16.png +0x99c5d462, actors/mario/mario_eyes_closed_unused_0.rgba16.png +0x99c5d462, actors/mario/mario_eyes_closed_unused_1.rgba16.png +0xe35bf3c5, actors/mario/mario_eyes_dead.rgba16.png +0x93c8da3e, actors/mario/mario_eyes_down_unused.rgba16.png +0xf1a15c9c, actors/mario/mario_eyes_half_closed.rgba16.png +0xd2d084ab, actors/mario/mario_eyes_left_unused.rgba16.png +0x8bf71d85, actors/mario/mario_eyes_right_unused.rgba16.png +0x38880faa, actors/mario/mario_eyes_up_unused.rgba16.png +0x0f25af6f, actors/mario/mario_logo.rgba16.png +0x088c7205, actors/mario/mario_metal.rgba16.png +0xf35da883, actors/mario/mario_metal_wing_tip_unused.rgba16.png +0x5efff350, actors/mario/mario_metal_wing_unused.rgba16.png +0xc09ebd12, actors/mario/mario_mustache.rgba16.png +0x63d38a3a, actors/mario/mario_overalls_button.rgba16.png +0xc300ba83, actors/mario/mario_sideburn.rgba16.png +0x944d654f, actors/mario/mario_wing.rgba16.png +0x8723ab77, actors/mario/mario_wing_tip.rgba16.png +0x0f25af6f, actors/mario_cap/mario_cap_logo.rgba16.png +0x088c7205, actors/mario_cap/mario_cap_metal.rgba16.png +0xf35da883, actors/mario_cap/mario_cap_metal_wing_tip_unused.rgba16.png +0x5efff350, actors/mario_cap/mario_cap_metal_wing_unused.rgba16.png +0x944d654f, actors/mario_cap/mario_cap_wing.rgba16.png +0x8723ab77, actors/mario_cap/mario_cap_wing_tip.rgba16.png +0xd3bf1790, actors/metal_box/metal_box_side.rgba16.png +0xaa35ca84, actors/mips/mips_eyes.rgba16.png +0xaf1faaba, actors/mist/mist.ia16.png +0x56094a62, actors/moneybag/moneybag_eyes.rgba16.png +0x3dd1312a, actors/moneybag/moneybag_mouth.rgba16.png +0xa69a12ef, actors/monty_mole/monty_mole_cheek.rgba16.png +0x69644253, actors/monty_mole/monty_mole_claw.rgba16.png +0xd9c71d69, actors/monty_mole/monty_mole_eye.rgba16.png +0xc1f6c926, actors/monty_mole/monty_mole_nose.rgba16.png +0xd20c1c79, actors/monty_mole/monty_mole_tooth.rgba16.png +0xe10f36d8, actors/monty_mole_hole/monty_mole_hole.ia16.png +0x4c2fcf44, actors/mr_i_eyeball/mr_i_eyeball_left_side.rgba16.png +0xd849accc, actors/mr_i_eyeball/mr_i_eyeball_right_side.rgba16.png +0x8b9be6ab, actors/mr_i_iris/mr_i_iris_closed.rgba16.png +0xdd4329a2, actors/mr_i_iris/mr_i_iris_mostly_closed.rgba16.png +0x75a83827, actors/mr_i_iris/mr_i_iris_mostly_open.rgba16.png +0xe41a72a4, actors/mr_i_iris/mr_i_iris_open.rgba16.png +0xacfdc2be, actors/mushroom_1up/1-up_mushroom.rgba16.png +0x6172af0c, actors/peach/peach_chest_jewel.rgba16.png +0xf354bc7d, actors/peach/peach_crown_jewel.rgba16.png +0x1ceda1e4, actors/peach/peach_dress.rgba16.png +0xc0c368e5, actors/peach/peach_eye_closed.rgba16.png +0xee2d4448, actors/peach/peach_eye_mostly_closed.rgba16.png +0x72ddc9b3, actors/peach/peach_eye_mostly_open.rgba16.png +0x560c8875, actors/peach/peach_eye_open.rgba16.png +0xf2559dae, actors/peach/peach_lips.rgba16.png +0x549c25be, actors/peach/peach_lips_scrunched.rgba16.png +0x4e9ed4d1, actors/peach/peach_nostril.rgba16.png +0xd0b817a0, actors/pebble/pebble.rgba16.png +0xefa35c23, actors/penguin/penguin_beak.rgba16.png +0x3c4eb858, actors/penguin/penguin_eye_angry.rgba16.png +0x07f3fbbc, actors/penguin/penguin_eye_angry_unused.rgba16.png +0x21ce109b, actors/penguin/penguin_eye_closed.rgba16.png +0x25562c85, actors/penguin/penguin_eye_half_closed.rgba16.png +0x1d74c023, actors/penguin/penguin_eye_open.rgba16.png +0x9db9def2, actors/piranha_plant/piranha_plant_bottom_lip.rgba16.png +0x329e5c61, actors/piranha_plant/piranha_plant_leaf.rgba16.png +0x6888b5f7, actors/piranha_plant/piranha_plant_skin.rgba16.png +0x1eac9092, actors/piranha_plant/piranha_plant_stem.rgba16.png +0x5a9a602f, actors/piranha_plant/piranha_plant_tongue.rgba16.png +0x68af8823, actors/piranha_plant/piranha_plant_tooth.rgba16.png +0xd30fa85a, actors/pokey/pokey_body.rgba16.png +0x273debaa, actors/pokey/pokey_face.rgba16.png +0x6a13b542, actors/pokey/pokey_face_blink.rgba16.png +0x61169028, actors/poundable_pole/poundable_pole_side.rgba16.png +0xd6411a11, actors/poundable_pole/poundable_pole_top.rgba16.png +0xa74393f4, actors/power_meter/power_meter_five_segments.rgba16.png +0x157109aa, actors/power_meter/power_meter_four_segments.rgba16.png +0x33f410c0, actors/power_meter/power_meter_full.rgba16.png +0x6197365b, actors/power_meter/power_meter_left_side.rgba16.png +0xeed76ec2, actors/power_meter/power_meter_one_segment.rgba16.png +0x13d766df, actors/power_meter/power_meter_right_side.rgba16.png +0x2a2ea06e, actors/power_meter/power_meter_seven_segments.rgba16.png +0xd836de6b, actors/power_meter/power_meter_six_segments.rgba16.png +0x5ae71e0c, actors/power_meter/power_meter_three_segments.rgba16.png +0xb7a9ee70, actors/power_meter/power_meter_two_segments.rgba16.png +0x998b4dba, actors/purple_switch/purple_switch_base.rgba16.png +0xea1f2eda, actors/purple_switch/purple_switch_exclamation_point.rgba16.png +0x0f99a13e, actors/sand/sand_particle.rgba16.png +0x89d3117c, actors/scuttlebug/scuttlebug_eye.rgba16.png +0x24542211, actors/scuttlebug/scuttlebug_iris.rgba16.png +0x8b920b74, actors/scuttlebug/scuttlebug_left_side.rgba16.png +0x66d33146, actors/scuttlebug/scuttlebug_leg.rgba16.png +0xdc33bd67, actors/scuttlebug/scuttlebug_right_side.rgba16.png +0x50d823e3, actors/seaweed/seaweed_base.rgba16.png +0x807cea9e, actors/seaweed/seaweed_lower_center.rgba16.png +0x1273f5d1, actors/seaweed/seaweed_tip.rgba16.png +0x2f3b03f7, actors/seaweed/seaweed_upper_center.rgba16.png +0x2ced4bc1, actors/skeeter/skeeter_eye.rgba16.png +0x0a253de9, actors/skeeter/skeeter_iris.rgba16.png +0x136a65ce, actors/smoke/smoke.ia16.png +0x7049fa4b, actors/snowman/mr_blizzard_eye.rgba16.png +0x3cfde407, actors/snowman/mr_blizzard_left_side.rgba16.png +0x08ebc9b4, actors/snowman/mr_blizzard_mitten.rgba16.png +0x1b0c6388, actors/snowman/mr_blizzard_mouth.rgba16.png +0x795fa575, actors/snowman/mr_blizzard_right_side.rgba16.png +0x2bbcb936, actors/snufit/snufit_body.rgba16.png +0x1c3980b3, actors/snufit/snufit_eye.rgba16.png +0x87e77672, actors/snufit/snufit_mask_strap.rgba16.png +0xb8f2454c, actors/snufit/snufit_mouth.rgba16.png +0xbbf6e56d, actors/sparkle/sparkle_0.rgba16.png +0x49fd1350, actors/sparkle/sparkle_1.rgba16.png +0x0694a394, actors/sparkle/sparkle_2.rgba16.png +0xc81c3e98, actors/sparkle/sparkle_3.rgba16.png +0xe08a7a20, actors/sparkle/sparkle_4.rgba16.png +0x98d62174, actors/sparkle/sparkle_5.rgba16.png +0x6d5f2ac7, actors/sparkle_animation/sparkle_animation_0.ia16.png +0xb2160b76, actors/sparkle_animation/sparkle_animation_1.ia16.png +0x7ba93370, actors/sparkle_animation/sparkle_animation_2.ia16.png +0x6a102c8b, actors/sparkle_animation/sparkle_animation_3.ia16.png +0xecfd928c, actors/sparkle_animation/sparkle_animation_4.ia16.png +0x7cfea0f6, actors/spindrift/spindrift_face.rgba16.png +0x74943f2a, actors/spindrift/spindrift_head.rgba16.png +0xe6307aa4, actors/spindrift/spindrift_leaf.rgba16.png +0x30da7207, actors/spindrift/spindrift_petal.rgba16.png +0x912d74b1, actors/springboard/springboard_base_unused.rgba16.png +0x9303578c, actors/springboard/springboard_top_unused.rgba16.png +0xe343a70a, actors/star/star_eye.rgba16.png +0x2379d1f3, actors/star/star_surface.rgba16.png +0x7bc16686, actors/stomp_smoke/stomp_smoke_0.ia16.png +0x0f2deec7, actors/stomp_smoke/stomp_smoke_1.ia16.png +0x952c47c7, actors/stomp_smoke/stomp_smoke_2.ia16.png +0xc2e2f406, actors/stomp_smoke/stomp_smoke_3.ia16.png +0xcdee92fc, actors/stomp_smoke/stomp_smoke_4.ia16.png +0x6888b25f, actors/stomp_smoke/stomp_smoke_5.ia16.png +0x819c8ee0, actors/sushi/sushi_eye.rgba16.png +0xa76449c5, actors/sushi/sushi_snout.rgba16.png +0x28b67cbf, actors/sushi/sushi_tooth.rgba16.png +0x633218da, actors/swoop/swoop_body.rgba16.png +0xe2b7624d, actors/swoop/swoop_eye.rgba16.png +0xf2e3f3ae, actors/swoop/swoop_nose.rgba16.png +0x111d5500, actors/swoop/swoop_wing.rgba16.png +0x09403c76, actors/thwomp/thwomp_face.rgba16.png +0x7b9b0f38, actors/thwomp/thwomp_surface.rgba16.png +0xfe36303d, actors/toad/toad_face.rgba16.png +0x1011b465, actors/toad/toad_head.rgba16.png +0x43c09930, actors/tornado/tornado.ia16.png +0x95cd8673, actors/treasure_chest/treasure_chest_front.rgba16.png +0xfd64803f, actors/treasure_chest/treasure_chest_lock.rgba16.png +0x3b9ab086, actors/treasure_chest/treasure_chest_lock_top.rgba16.png +0xa002ac4e, actors/treasure_chest/treasure_chest_side.rgba16.png +0x6f406bac, actors/tree/palm_tree.rgba16.png +0x86a4406c, actors/tree/pine_tree.rgba16.png +0xcaaf6a50, actors/tree/snowy_pine_tree.rgba16.png +0x7b4ce4e0, actors/tree/tree_left_side.rgba16.png +0xba697dbe, actors/tree/tree_right_side.rgba16.png +0xe9132646, actors/ukiki/ukiki_butt.rgba16.png +0x3fbbd9a5, actors/ukiki/ukiki_face.rgba16.png +0xa3534f24, actors/ukiki/ukiki_face_blink.rgba16.png +0x85436a0d, actors/ukiki/ukiki_fur.rgba16.png +0x53798e34, actors/unagi/unagi_body.rgba16.png +0x6a2b9929, actors/unagi/unagi_eye.rgba16.png +0xec75ddec, actors/unagi/unagi_head_base.rgba16.png +0x134c42e0, actors/unagi/unagi_mouth.rgba16.png +0x91c6cbcb, actors/unagi/unagi_tail.rgba16.png +0xa9aaed3d, actors/unagi/unagi_tooth.rgba16.png +0x9f28a579, actors/walk_smoke/walk_smoke_0.ia16.png +0xf2864cd5, actors/walk_smoke/walk_smoke_1.ia16.png +0xdedb492e, actors/walk_smoke/walk_smoke_2.ia16.png +0x81feb406, actors/walk_smoke/walk_smoke_3.ia16.png +0xdc375568, actors/walk_smoke/walk_smoke_4.ia16.png +0x453dbbbd, actors/walk_smoke/walk_smoke_5.ia16.png +0x0740e5f6, actors/walk_smoke/walk_smoke_6.ia16.png +0x9595cfab, actors/warp_pipe/warp_pipe_side.rgba16.png +0xe599f4b8, actors/warp_pipe/warp_pipe_top.rgba16.png +0x264ee37c, actors/water_bubble/water_bubble.rgba16.png +0x6348045f, actors/water_mine/water_mine_left_side_unused.rgba16.png +0x83895fa8, actors/water_mine/water_mine_right_side_unused.rgba16.png +0x6edb77dd, actors/water_mine/water_mine_spike_unused.rgba16.png +0xb59ea4c2, actors/water_ring/water_ring.rgba16.png +0x334f97f8, actors/water_splash/water_splash_0.rgba16.png +0xd2d9d04b, actors/water_splash/water_splash_1.rgba16.png +0xe0e38759, actors/water_splash/water_splash_2.rgba16.png +0x62b77b76, actors/water_splash/water_splash_3.rgba16.png +0xef1328a3, actors/water_splash/water_splash_4.rgba16.png +0x84fffbbc, actors/water_splash/water_splash_5.rgba16.png +0x3f218927, actors/water_splash/water_splash_6.rgba16.png +0x6237f906, actors/water_splash/water_splash_7.rgba16.png +0x43c09930, actors/whirlpool/whirlpool.ia16.png +0x053b1cf1, actors/white_particle/snow_particle.rgba16.png +0xf0bb14a0, actors/white_particle_small/small_snow_particle.rgba16.png +0x28eb23a5, actors/whomp/whomp_back.rgba16.png +0xb29261b3, actors/whomp/whomp_face.rgba16.png +0x18602905, actors/whomp/whomp_hand.rgba16.png +0x7bb8fef7, actors/whomp/whomp_surface.rgba16.png +0xe343a70a, actors/wiggler/wiggler_eye.rgba16.png +0x1f3f7866, actors/wiggler/wiggler_flower.rgba16.png +0x5abb875f, actors/wiggler/wiggler_frown.rgba16.png +0x970bbf97, actors/wiggler/wiggler_nose_left_side.rgba16.png +0x02d3aa6c, actors/wiggler/wiggler_nose_right_side.rgba16.png +0xf337fa3f, actors/wiggler/wiggler_segment_left_side.rgba16.png +0x45eb8dd5, actors/wiggler/wiggler_segment_right_side.rgba16.png +0x0eaf1606, actors/wooden_signpost/wooden_signpost_back.rgba16.png +0x9fa93f54, actors/wooden_signpost/wooden_signpost_front.rgba16.png +0x89f3f5a0, actors/yellow_sphere/yellow_sphere.rgba16.png +0x89f3f5a0, actors/yellow_sphere_small/small_yellow_sphere.rgba16.png +0x8c68c203, actors/yoshi/yoshi_eye.rgba16.png +0xf56d22e8, actors/yoshi/yoshi_eye_blink.rgba16.png +0xaeaecdf2, actors/yoshi/yoshi_nostril.rgba16.png +0xdbc97799, actors/yoshi_egg/yoshi_egg_0_unused.rgba16.png +0x65d071c5, actors/yoshi_egg/yoshi_egg_1_unused.rgba16.png +0x05e4c57d, actors/yoshi_egg/yoshi_egg_2_unused.rgba16.png +0xc3dedd5a, actors/yoshi_egg/yoshi_egg_3_unused.rgba16.png +0xa3e2af46, actors/yoshi_egg/yoshi_egg_4_unused.rgba16.png +0xb74e542d, actors/yoshi_egg/yoshi_egg_5_unused.rgba16.png +0x432f62ec, actors/yoshi_egg/yoshi_egg_6_unused.rgba16.png +0x77a02e4d, actors/yoshi_egg/yoshi_egg_7_unused.rgba16.png +0x5c5145b1, levels/bbh/0.rgba16.png +0x944c43cd, levels/bbh/1.rgba16.png +0xe05685d7, levels/bbh/2.rgba16.png +0x61ed9ac7, levels/bbh/3.rgba16.png +0xc0601a31, levels/bbh/4.rgba16.png +0xd84ab30a, levels/bbh/5.rgba16.png +0x3444bf90, levels/bbh/6.rgba16.png +0x83cb5a9e, levels/bitdw/0.rgba16.png +0x5d04dbaf, levels/bitdw/1.rgba16.png +0x3e6e4959, levels/bitdw/2.rgba16.png +0xacccd295, levels/bitdw/3.rgba16.png +0x09b8a53d, levels/bitfs/0.rgba16.png +0xee52a0fe, levels/bitfs/1.rgba16.png +0xa1c532ae, levels/bitfs/2.rgba16.png +0xb23a9652, levels/bits/0.rgba16.png +0xbcc1cac5, levels/bits/1.rgba16.png +0x040da45d, levels/bits/2.rgba16.png +0xab7cc8f7, levels/bob/0.rgba16.png +0x04fda79c, levels/bob/1.rgba16.png +0xdbf53dbc, levels/bob/2.rgba16.png +0x9c5be999, levels/bob/3.rgba16.png +0xf1b9b3ad, levels/bob/4.rgba16.png +0xd57b7c36, levels/bowser_1/0.rgba16.png +0x5a7d2683, levels/bowser_1/1.rgba16.png +0x9115bf02, levels/bowser_1/2.rgba16.png +0x1b6a23a2, levels/bowser_2/0.rgba16.png +0x817c83e8, levels/bowser_3/0.rgba16.png +0x5e8126b3, levels/bowser_3/1.rgba16.png +0xa389ce0d, levels/bowser_3/2.rgba16.png +0xec2a0090, levels/castle_grounds/0.rgba16.png +0xd65056c7, levels/castle_grounds/1.rgba16.png +0x483afe79, levels/castle_grounds/2.rgba16.png +0xda226d02, levels/castle_grounds/3.rgba16.png +0xa31f114a, levels/castle_grounds/4.rgba16.png +0x425e6092, levels/castle_grounds/5.ia8.png +0xfa3f6f74, levels/castle_inside/1.rgba16.png +0x388593be, levels/castle_inside/10.rgba16.png +0x44d65143, levels/castle_inside/11.rgba16.png +0xf08495fe, levels/castle_inside/12.rgba16.png +0x51502b7b, levels/castle_inside/13.rgba16.png +0xb53c3c04, levels/castle_inside/14.rgba16.png +0x4b9432f3, levels/castle_inside/15.rgba16.png +0x99015431, levels/castle_inside/16.ia16.png +0xe2ae61f0, levels/castle_inside/17.rgba16.png +0x35903c25, levels/castle_inside/18.rgba16.png +0x943652c9, levels/castle_inside/19.rgba16.png +0x99eeb704, levels/castle_inside/2.ia16.png +0x99181ee6, levels/castle_inside/20.rgba16.png +0x6cac020a, levels/castle_inside/21.rgba16.png +0x166253af, levels/castle_inside/22.rgba16.png +0x0461b2ef, levels/castle_inside/23_us.rgba16.png +0xf46a25f1, levels/castle_inside/24_us.rgba16.png +0xd6f07968, levels/castle_inside/25.rgba16.png +0x483e0839, levels/castle_inside/26.rgba16.png +0xad3a9b8e, levels/castle_inside/27.rgba16.png +0x192995f1, levels/castle_inside/28.rgba16.png +0xccfe01ba, levels/castle_inside/29.rgba16.png +0xa613ad29, levels/castle_inside/3.rgba16.png +0xa1feefa1, levels/castle_inside/30.rgba16.png +0x271ae292, levels/castle_inside/31.rgba16.png +0xb4b9385a, levels/castle_inside/32.rgba16.png +0x5771f505, levels/castle_inside/33.rgba16.png +0x1787e161, levels/castle_inside/34.rgba16.png +0x1c63e539, levels/castle_inside/35.rgba16.png +0xe61cc3d6, levels/castle_inside/36.rgba16.png +0x75e62f4a, levels/castle_inside/37.rgba16.png +0xbcac9db6, levels/castle_inside/38.rgba16.png +0x340ffbe1, levels/castle_inside/39.rgba16.png +0xe6920e39, levels/castle_inside/4.rgba16.png +0xe2ac5e67, levels/castle_inside/40.rgba16.png +0xff7de579, levels/castle_inside/5.rgba16.png +0x2404ae69, levels/castle_inside/6.rgba16.png +0x8f8c9db6, levels/castle_inside/7.rgba16.png +0x951da9ea, levels/castle_inside/8.rgba16.png +0xffb8cee5, levels/castle_inside/9.rgba16.png +0x4ad539e9, levels/castle_inside/castle_light.ia16.png +0xf26399d3, levels/ccm/0.rgba16.png +0xe20286cf, levels/ccm/1.rgba16.png +0xa035eec1, levels/ccm/10.rgba16.png +0x4d71f1ab, levels/ccm/11.rgba16.png +0x0086fd9f, levels/ccm/12.rgba16.png +0x03023b7a, levels/ccm/2.rgba16.png +0x61dc28cc, levels/ccm/3.rgba16.png +0xfccba0ba, levels/ccm/4.rgba16.png +0x1b0c6388, levels/ccm/5.rgba16.png +0x7049fa4b, levels/ccm/6.rgba16.png +0x17e335d2, levels/ccm/7.rgba16.png +0xa7adb5a2, levels/ccm/8.ia16.png +0x8327df20, levels/ccm/9.ia16.png +0xa784a5fe, levels/cotmc/0.rgba16.png +0xbdcdfb4c, levels/cotmc/1.rgba16.png +0xbb187a52, levels/cotmc/2.rgba16.png +0xe8555a11, levels/cotmc/3.rgba16.png +0xe135f21b, levels/cotmc/4.rgba16.png +0xea0349b4, levels/ddd/0.rgba16.png +0x71d6258e, levels/ddd/1.rgba16.png +0xe8ee2c1a, levels/ddd/2.rgba16.png +0x2fd07664, levels/ddd/3.rgba16.png +0x50e55520, levels/ddd/4.rgba16.png +0x4c7513c6, levels/hmc/0.rgba16.png +0x42e50b41, levels/hmc/1.rgba16.png +0xdef49e6a, levels/hmc/2.rgba16.png +0x8a9f7877, levels/hmc/3.rgba16.png +0x4a6df6b5, levels/hmc/4.rgba16.png +0xd4fa8789, levels/hmc/5.rgba16.png +0x6d5b3127, levels/hmc/6.rgba16.png +0xccfe01ba, levels/hmc/7.rgba16.png +0xa37ed248, levels/intro/0.rgba16.png +0xd01d2c8c, levels/intro/1.rgba16.png +0xcf3ab52b, levels/intro/2_copyright.rgba16.png +0x34f68b34, levels/intro/3_tm.rgba16.png +0x71d6258e, levels/jrb/0.rgba16.png +0x619f7672, levels/jrb/1.rgba16.png +0x9efada2a, levels/jrb/2.rgba16.png +0xfedee222, levels/jrb/3.rgba16.png +0x858a739f, levels/lll/0.rgba16.png +0x8e39e767, levels/lll/1.rgba16.png +0x0d612534, levels/lll/10.rgba16.png +0xff672816, levels/lll/11.rgba16.png +0x54813b65, levels/lll/12.rgba16.png +0x65633450, levels/lll/13.rgba16.png +0xf3360668, levels/lll/14.rgba16.png +0xb8bd5c30, levels/lll/15.rgba16.png +0x4f24c618, levels/lll/16.rgba16.png +0x4b34b8b6, levels/lll/17.rgba16.png +0xb46d0b27, levels/lll/18.rgba16.png +0x81dadd7c, levels/lll/19.rgba16.png +0xc555fb1c, levels/lll/2.rgba16.png +0xecfe27b5, levels/lll/20.rgba16.png +0xa60061ea, levels/lll/21.rgba16.png +0xd6ca289a, levels/lll/22.rgba16.png +0x85f98cbd, levels/lll/23.rgba16.png +0x099f118d, levels/lll/24.rgba16.png +0x6e68c10b, levels/lll/25.rgba16.png +0x7181dbcf, levels/lll/26.rgba16.png +0xa7adb5a2, levels/lll/27.ia16.png +0x06d93b1e, levels/lll/28.rgba16.png +0x6e523fee, levels/lll/29.rgba16.png +0x3766a306, levels/lll/3.rgba16.png +0x129b69cc, levels/lll/30.rgba16.png +0xf3648041, levels/lll/31.rgba16.png +0xfb4c90a4, levels/lll/32.rgba16.png +0xb29b3c1d, levels/lll/4.rgba16.png +0x24c6d141, levels/lll/5.rgba16.png +0xe7268cdd, levels/lll/6.rgba16.png +0xdce9bb52, levels/lll/7.rgba16.png +0x3af9a723, levels/lll/8.rgba16.png +0xad98a046, levels/lll/9.rgba16.png +0x1da84c4d, levels/menu/main_menu_seg7.00018.rgba16.png +0xb83d32a6, levels/menu/main_menu_seg7.00818.rgba16.png +0x514fd3e7, levels/menu/main_menu_seg7.01018.rgba16.png +0xe6daa7fd, levels/menu/main_menu_seg7.02018.rgba16.png +0x2c874bfe, levels/menu/main_menu_seg7.03468.rgba16.png +0x794c2e6d, levels/menu/main_menu_seg7.03C68.rgba16.png +0xe6a23bbc, levels/menu/main_menu_seg7.04468.rgba16.png +0x55d63b31, levels/menu/main_menu_seg7.04C68.rgba16.png +0x4cdbeb28, levels/menu/main_menu_seg7.05468.rgba16.png +0xf684b56a, levels/menu/main_menu_seg7.06328.rgba16.png +0x5366bcf7, levels/menu/main_menu_seg7.06B28.rgba16.png +0xf5c6117d, levels/menu/main_menu_seg7.073D0.rgba16.png +0xf5033d3c, levels/menu/main_menu_seg7.075D0.rgba16.png +0x8ce1067e, levels/menu/main_menu_seg7.077D0.rgba16.png +0x81338dc9, levels/menu/main_menu_seg7.079D0.rgba16.png +0x10d7118c, levels/menu/main_menu_seg7.07BD0.rgba16.png +0x5e2803e1, levels/menu/main_menu_seg7.07DD0.rgba16.png +0x672cbb6d, levels/menu/main_menu_seg7.07FD0.rgba16.png +0x199eb6f2, levels/menu/main_menu_seg7.081D0.rgba16.png +0x2e3534a5, levels/menu/main_menu_seg7.083D0.rgba16.png +0x4b094d62, levels/menu/main_menu_seg7.085D0.rgba16.png +0x3526ec73, levels/menu/main_menu_seg7.087D0.rgba16.png +0x148aa944, levels/menu/main_menu_seg7.089D0.rgba16.png +0xe6b70a56, levels/menu/main_menu_seg7.08BD0.rgba16.png +0xdc8e1e4b, levels/menu/main_menu_seg7.08DD0.rgba16.png +0x4581a549, levels/menu/main_menu_seg7.08FD0.rgba16.png +0x64fe6413, levels/menu/main_menu_seg7.091D0.rgba16.png +0xdb73b45b, levels/menu/main_menu_seg7.093D0.rgba16.png +0x8dacc224, levels/menu/main_menu_seg7.095D0.rgba16.png +0x91b05c17, levels/menu/main_menu_seg7.097D0.rgba16.png +0xe2e16e94, levels/menu/main_menu_seg7.099D0.rgba16.png +0xe6b1e0fd, levels/menu/main_menu_seg7.09BD0.rgba16.png +0xb543a988, levels/menu/main_menu_seg7.09DD0.rgba16.png +0xdca27f0a, levels/menu/main_menu_seg7.09FD0.rgba16.png +0xeaef8ec7, levels/menu/main_menu_seg7.0A1D0.rgba16.png +0x84ac97af, levels/menu/main_menu_seg7.0A3D0.rgba16.png +0x07203782, levels/menu/main_menu_seg7.0A5D0.rgba16.png +0x1f8aa229, levels/menu/main_menu_seg7.0A7D0.rgba16.png +0x83add63b, levels/menu/main_menu_seg7.0A9D0.rgba16.png +0x6f3f423f, levels/menu/main_menu_seg7.0D1A8.rgba16.png +0xbca6968b, levels/menu/main_menu_seg7.0E1A8.rgba16.png +0x162e39a6, levels/menu/main_menu_seg7_us.0AC40.ia8.png +0xf10460c9, levels/menu/main_menu_seg7_us.0AC80.ia8.png +0xf228a45d, levels/menu/main_menu_seg7_us.0ACC0.ia8.png +0x8bdb6559, levels/menu/main_menu_seg7_us.0AD00.ia8.png +0xa3525146, levels/menu/main_menu_seg7_us.0AD40.ia8.png +0x14545347, levels/menu/main_menu_seg7_us.0AD80.ia8.png +0xaa6d8f7e, levels/menu/main_menu_seg7_us.0ADC0.ia8.png +0xf5d61ae9, levels/menu/main_menu_seg7_us.0AE00.ia8.png +0xaed4bc77, levels/menu/main_menu_seg7_us.0AE40.ia8.png +0x192afe7c, levels/menu/main_menu_seg7_us.0AE80.ia8.png +0xc547e63a, levels/menu/main_menu_seg7_us.0AEC0.ia8.png +0x0f00e7e1, levels/menu/main_menu_seg7_us.0AF00.ia8.png +0xe400fd4b, levels/menu/main_menu_seg7_us.0AF40.ia8.png +0x6825594f, levels/menu/main_menu_seg7_us.0AF80.ia8.png +0xe4037e30, levels/menu/main_menu_seg7_us.0AFC0.ia8.png +0xda9edc44, levels/menu/main_menu_seg7_us.0B000.ia8.png +0xa76687fb, levels/menu/main_menu_seg7_us.0B040.ia8.png +0x0f97d07d, levels/menu/main_menu_seg7_us.0B080.ia8.png +0x619bee29, levels/menu/main_menu_seg7_us.0B0C0.ia8.png +0x509b1b0c, levels/menu/main_menu_seg7_us.0B100.ia8.png +0x30a21493, levels/menu/main_menu_seg7_us.0B140.ia8.png +0x0e503bd8, levels/menu/main_menu_seg7_us.0B180.ia8.png +0x5b6f4412, levels/menu/main_menu_seg7_us.0B1C0.ia8.png +0xe88ff4dc, levels/menu/main_menu_seg7_us.0B200.ia8.png +0x2198da61, levels/menu/main_menu_seg7_us.0B240.ia8.png +0x544a08c3, levels/menu/main_menu_seg7_us.0B280.ia8.png +0x11a39572, levels/menu/main_menu_seg7_us.0B2C0.ia8.png +0x1bef1652, levels/menu/main_menu_seg7_us.0B300.ia8.png +0x1cd73c42, levels/menu/main_menu_seg7_us.0B340.ia8.png +0xf206a679, levels/menu/main_menu_seg7_us.0B380.ia8.png +0x02d31d25, levels/menu/main_menu_seg7_us.0B3C0.ia8.png +0x9f07b343, levels/menu/main_menu_seg7_us.0B400.ia8.png +0x836b21f9, levels/menu/main_menu_seg7_us.0B440.ia8.png +0x56efd458, levels/menu/main_menu_seg7_us.0B480.ia8.png +0x326f58e9, levels/menu/main_menu_seg7_us.0B4C0.ia8.png +0x8de17184, levels/menu/main_menu_seg7_us.0B500.ia8.png +0x34e5627e, levels/menu/main_menu_seg7_us.0B540.ia8.png +0x66746f69, levels/menu/main_menu_seg7_us.0B580.ia8.png +0x662a6d1b, levels/menu/main_menu_seg7_us.0B5C0.ia8.png +0x31fb3ea8, levels/menu/main_menu_seg7_us.0B600.ia8.png +0x863c411f, levels/menu/main_menu_seg7_us.0B640.ia8.png +0x395ceae6, levels/menu/main_menu_seg7_us.0B680.ia8.png +0xf64de414, levels/menu/main_menu_seg7_us.0B6C0.ia8.png +0x5f7d7cfc, levels/menu/main_menu_seg7_us.0B700.ia8.png +0x1914b3e0, levels/menu/main_menu_seg7_us.0B740.ia8.png +0x2432c484, levels/menu/main_menu_seg7_us.0B780.ia8.png +0x23fea78c, levels/menu/main_menu_seg7_us.0B7C0.ia8.png +0x03398fab, levels/menu/main_menu_seg7_us.0B800.ia8.png +0xc4672c2c, levels/pss/0.rgba16.png +0x24245dda, levels/pss/1.ia16.png +0xbcecff47, levels/pss/2.rgba16.png +0x84a18b1a, levels/rr/1.rgba16.png +0x3c608334, levels/rr/2.rgba16.png +0x0527cea8, levels/rr/quarter_flying_carpet.rgba16.png +0x0adc550e, levels/sl/0.rgba16.png +0xaca4e108, levels/sl/1.rgba16.png +0xebfbd0ff, levels/sl/2.rgba16.png +0xbc5a142c, levels/sl/3.rgba16.png +0xffc64b0d, levels/sl/4.rgba16.png +0x0b974921, levels/ssl/0.rgba16.png +0xcc338863, levels/ssl/1.ia16.png +0x9ba3742c, levels/ssl/10.rgba16.png +0xe0238780, levels/ssl/11.rgba16.png +0x72dd8350, levels/ssl/2.rgba16.png +0x464c110a, levels/ssl/3.rgba16.png +0x8b6b8087, levels/ssl/4.rgba16.png +0x0924e963, levels/ssl/5.rgba16.png +0x7d0e309d, levels/ssl/6.rgba16.png +0xd0dcc5a8, levels/ssl/7.rgba16.png +0x747d5ad1, levels/ssl/8.rgba16.png +0xc05d4301, levels/ssl/9.rgba16.png +0xa738ab70, levels/thi/0.rgba16.png +0x00789a1f, levels/thi/1.rgba16.png +0x7a7cc25b, levels/totwc/0.rgba16.png +0x50a5b2ab, levels/totwc/1.rgba16.png +0x85db5e7b, levels/totwc/2.rgba16.png +0x9c35ed91, levels/totwc/3.ia16.png +0xd5d7efab, levels/ttc/0.rgba16.png +0xf915a262, levels/ttc/1.rgba16.png +0x92d9c64f, levels/ttc/2.rgba16.png +0xbc1a2d49, levels/ttm/0.ia16.png +0x437a2fa4, levels/ttm/1.rgba16.png +0xbec34aa9, levels/ttm/2.rgba16.png +0x66f12d05, levels/ttm/3.rgba16.png +0x340e48e3, levels/ttm/4.rgba16.png +0x811b7718, levels/ttm/5.rgba16.png +0x875b1a7b, levels/ttm/6.rgba16.png +0xc3c215ab, levels/ttm/7.rgba16.png +0x6128b338, levels/ttm/8.rgba16.png +0xf755b95f, levels/vcutm/0.rgba16.png +0x2bda3bfa, levels/vcutm/1.rgba16.png +0x9fc44b41, levels/vcutm/2.rgba16.png +0xba8c6c67, levels/vcutm/3.rgba16.png +0xc7229a30, levels/wdw/0.rgba16.png +0x241f463f, levels/wdw/1.rgba16.png +0xc5e4658c, levels/wdw/2.rgba16.png +0xfe7d0d8a, levels/wdw/3.rgba16.png +0xef715196, levels/wdw/4.rgba16.png +0x0bc6f01d, levels/wf/0.rgba16.png +0xa2a8c04f, levels/wf/1.rgba16.png +0xfd37e14e, levels/wf/2.rgba16.png +0x7e168bbb, levels/wf/3.rgba16.png +0xe77d22d7, levels/wf/4.rgba16.png +0x0fea0598, levels/wf/5.ia8.png +0x6e29fa4b, levels/wmotr/0.rgba16.png +0xe57c9fc5, levels/wmotr/1.rgba16.png +0x0f459e52, levels/wmotr/2.rgba16.png +0xd025cebb, levels/wmotr/3.rgba16.png +0x1b9faea4, levels/wmotr/4.rgba16.png +0xb53e35a9, textures/cave/hmc_textures.00000.rgba16.png +0x71d6258e, textures/cave/hmc_textures.01000.rgba16.png +0x4716c9a3, textures/cave/hmc_textures.01800.rgba16.png +0x41dc652c, textures/cave/hmc_textures.02800.rgba16.png +0x7f050a18, textures/cave/hmc_textures.03000.rgba16.png +0x1fb47ed1, textures/cave/hmc_textures.03800.rgba16.png +0xfdcac8c9, textures/cave/hmc_textures.04800.rgba16.png +0x6fb425db, textures/cave/hmc_textures.05800.rgba16.png +0xe15bca32, textures/cave/hmc_textures.06800.rgba16.png +0xcbd76f04, textures/cave/hmc_textures.07000.rgba16.png +0x19a880e7, textures/cave/hmc_textures.07800.rgba16.png +0x17af0fbc, textures/cave/hmc_textures.08800.rgba16.png +0x292be7cc, textures/cave/hmc_textures.09800.rgba16.png +0xe35b6b5c, textures/cave/hmc_textures.0A000.rgba16.png +0xa500d1f7, textures/cave/hmc_textures.0A800.rgba16.png +0x4ad539e9, textures/cave/hmc_textures.0B800.ia16.png +0x56cc824d, textures/cave/hmc_textures.0C000.ia16.png +0xbba387b7, textures/effect/bubble.06048.rgba16.png +0x96d3f934, textures/effect/flower.00008.rgba16.png +0xb93fd448, textures/effect/flower.00808.rgba16.png +0x38f8a4e7, textures/effect/flower.01008.rgba16.png +0xa268e8e7, textures/effect/flower.01808.rgba16.png +0xe50ac330, textures/effect/lava_bubble.02020.rgba16.png +0x5e9c57c9, textures/effect/lava_bubble.02820.rgba16.png +0x9c66e986, textures/effect/lava_bubble.03020.rgba16.png +0xd197e10c, textures/effect/lava_bubble.03820.rgba16.png +0x4111e3b8, textures/effect/lava_bubble.04020.rgba16.png +0xca0a2523, textures/effect/lava_bubble.04820.rgba16.png +0xcbff0cc0, textures/effect/lava_bubble.05020.rgba16.png +0x0a5807c0, textures/effect/lava_bubble.05820.rgba16.png +0x38a3aae7, textures/effect/tiny_bubble.0684C.rgba16.png +0xe3a28667, textures/effect/tiny_bubble.06AD8.rgba16.png +0x4dc116b5, textures/fire/lll_textures.00000.rgba16.png +0x58a09e6a, textures/fire/lll_textures.00800.rgba16.png +0x92bdabd2, textures/fire/lll_textures.01000.rgba16.png +0xdce9bb52, textures/fire/lll_textures.01800.rgba16.png +0x5f787109, textures/fire/lll_textures.02000.rgba16.png +0x822cd739, textures/fire/lll_textures.02800.rgba16.png +0x29eae5c6, textures/fire/lll_textures.03000.rgba16.png +0x0bce35bd, textures/fire/lll_textures.03800.rgba16.png +0x4cba0464, textures/fire/lll_textures.04000.rgba16.png +0x08d3734e, textures/fire/lll_textures.04800.rgba16.png +0x544d2f6e, textures/fire/lll_textures.05000.rgba16.png +0x87f5517a, textures/fire/lll_textures.05800.rgba16.png +0x5c797ba2, textures/fire/lll_textures.06000.rgba16.png +0xfc886eee, textures/fire/lll_textures.06800.rgba16.png +0x8385b066, textures/fire/lll_textures.07000.rgba16.png +0xec50358f, textures/fire/lll_textures.07800.rgba16.png +0x7a4ad1c4, textures/fire/lll_textures.08000.rgba16.png +0x3d4950f7, textures/fire/lll_textures.08800.rgba16.png +0xf088177d, textures/fire/lll_textures.09000.rgba16.png +0xb81cf987, textures/fire/lll_textures.09800.rgba16.png +0x8662e645, textures/fire/lll_textures.0A000.rgba16.png +0x5e4660ac, textures/fire/lll_textures.0A800.rgba16.png +0x9368fefd, textures/fire/lll_textures.0B000.rgba16.png +0xb707fcd7, textures/fire/lll_textures.0B800.rgba16.png +0x87f00ecb, textures/generic/bob_textures.00000.rgba16.png +0xbfb0c0c1, textures/generic/bob_textures.00800.rgba16.png +0xcf6e4951, textures/generic/bob_textures.01000.rgba16.png +0xd063fb8c, textures/generic/bob_textures.01800.rgba16.png +0x1769f780, textures/generic/bob_textures.02000.rgba16.png +0x8e97fb4d, textures/generic/bob_textures.02800.rgba16.png +0x2b4d294f, textures/generic/bob_textures.03000.rgba16.png +0x4e77ac6e, textures/generic/bob_textures.03800.rgba16.png +0xa2be0843, textures/generic/bob_textures.04000.rgba16.png +0xb1a8c5c3, textures/generic/bob_textures.04800.rgba16.png +0x9e647908, textures/generic/bob_textures.05000.rgba16.png +0x91e11f4e, textures/generic/bob_textures.05800.rgba16.png +0x6f780f03, textures/generic/bob_textures.06000.rgba16.png +0x634ac9cd, textures/generic/bob_textures.07000.rgba16.png +0x37507a71, textures/generic/bob_textures.07800.rgba16.png +0xd0dcc5a8, textures/generic/bob_textures.08000.rgba16.png +0xa1bf3406, textures/generic/bob_textures.08800.rgba16.png +0xe98dac45, textures/generic/bob_textures.09000.rgba16.png +0x5a1108d8, textures/generic/bob_textures.09800.rgba16.png +0x20792e3c, textures/generic/bob_textures.0A000.rgba16.png +0x690a7f2c, textures/generic/bob_textures.0A800.rgba16.png +0x971b9a46, textures/generic/bob_textures.0B000.ia16.png +0xf6c15bcd, textures/grass/wf_textures.00000.rgba16.png +0xe321208d, textures/grass/wf_textures.00800.rgba16.png +0x6b4457b2, textures/grass/wf_textures.01000.rgba16.png +0x24199eca, textures/grass/wf_textures.01800.rgba16.png +0x4da8a3cc, textures/grass/wf_textures.02000.rgba16.png +0x764530b6, textures/grass/wf_textures.02800.rgba16.png +0x78310e1a, textures/grass/wf_textures.03000.rgba16.png +0xaab68db0, textures/grass/wf_textures.03800.rgba16.png +0x3de336df, textures/grass/wf_textures.04000.rgba16.png +0x6e3106d2, textures/grass/wf_textures.04800.rgba16.png +0x2b8425ab, textures/grass/wf_textures.05000.rgba16.png +0x97a3d063, textures/grass/wf_textures.05800.rgba16.png +0x34353e2a, textures/grass/wf_textures.06000.rgba16.png +0x89891fe2, textures/grass/wf_textures.06800.rgba16.png +0xc65b7d80, textures/grass/wf_textures.07000.rgba16.png +0x4b934fe7, textures/grass/wf_textures.07800.rgba16.png +0x65a283de, textures/grass/wf_textures.08000.rgba16.png +0xd9574d8e, textures/grass/wf_textures.08800.rgba16.png +0x2a6ccadc, textures/grass/wf_textures.09000.rgba16.png +0x2c102ab5, textures/grass/wf_textures.09800.rgba16.png +0x2ebc856e, textures/grass/wf_textures.0A000.rgba16.png +0xd9a9c915, textures/grass/wf_textures.0A800.rgba16.png +0x971b9a46, textures/grass/wf_textures.0B000.ia16.png +0xa49fa282, textures/grass/wf_textures.0B800.ia16.png +0x628c427f, textures/inside/inside_castle_textures.00000.rgba16.png +0xc2868738, textures/inside/inside_castle_textures.01000.rgba16.png +0x47fdb7eb, textures/inside/inside_castle_textures.02000.rgba16.png +0x2d736f1d, textures/inside/inside_castle_textures.03000.rgba16.png +0xc089ead9, textures/inside/inside_castle_textures.03800.rgba16.png +0xcef46d6c, textures/inside/inside_castle_textures.04000.rgba16.png +0x6d43e7c6, textures/inside/inside_castle_textures.04800.rgba16.png +0x05954f72, textures/inside/inside_castle_textures.05000.rgba16.png +0x13c0139d, textures/inside/inside_castle_textures.05800.rgba16.png +0x01ea96b5, textures/inside/inside_castle_textures.06000.rgba16.png +0x1db20ce1, textures/inside/inside_castle_textures.07000.rgba16.png +0x09653817, textures/inside/inside_castle_textures.08000.rgba16.png +0x0b8a2663, textures/inside/inside_castle_textures.08800.rgba16.png +0x0371d531, textures/inside/inside_castle_textures.09000.rgba16.png +0xd2205732, textures/inside/inside_castle_textures.0A000.rgba16.png +0xc89b23f9, textures/inside/inside_castle_textures.0B000.rgba16.png +0x7040247a, textures/inside/inside_castle_textures.0B800.rgba16.png +0x70ddcaba, textures/intro_raw/hand_closed.rgba16.png +0xd27fdcd1, textures/intro_raw/hand_open.rgba16.png +0xf0e6ba5d, textures/intro_raw/mario_face_shine.ia8.png +0x6ef97862, textures/intro_raw/red_star_0.rgba16.png +0xf320228e, textures/intro_raw/red_star_1.rgba16.png +0x72fc9260, textures/intro_raw/red_star_2.rgba16.png +0x997e3200, textures/intro_raw/red_star_3.rgba16.png +0x18857b4f, textures/intro_raw/red_star_4.rgba16.png +0x887020ac, textures/intro_raw/red_star_5.rgba16.png +0x3119dc11, textures/intro_raw/red_star_6.rgba16.png +0x3c6ec18c, textures/intro_raw/red_star_7.rgba16.png +0x3c7895de, textures/intro_raw/sparkle_0.rgba16.png +0xb6431ae1, textures/intro_raw/sparkle_1.rgba16.png +0xc5d5652e, textures/intro_raw/sparkle_2.rgba16.png +0xbc3c428f, textures/intro_raw/sparkle_3.rgba16.png +0xb4cb71eb, textures/intro_raw/sparkle_4.rgba16.png +0x5100bf97, textures/intro_raw/sparkle_5.rgba16.png +0xdd7c86b8, textures/intro_raw/white_star_0.rgba16.png +0xba802a03, textures/intro_raw/white_star_1.rgba16.png +0x149a9b81, textures/intro_raw/white_star_2.rgba16.png +0x4f5a41e8, textures/intro_raw/white_star_3.rgba16.png +0x4a3e2c85, textures/intro_raw/white_star_4.rgba16.png +0x3178664a, textures/intro_raw/white_star_5.rgba16.png +0x3e672903, textures/intro_raw/white_star_6.rgba16.png +0xf2f7945a, textures/intro_raw/white_star_7.rgba16.png +0x46116522, textures/machine/ttc_textures.00000.rgba16.png +0x6d43e7c6, textures/machine/ttc_textures.00800.rgba16.png +0xa1f85408, textures/machine/ttc_textures.01000.rgba16.png +0x62e6d009, textures/machine/ttc_textures.01800.rgba16.png +0xf334ddfb, textures/machine/ttc_textures.02000.rgba16.png +0x8c56517c, textures/machine/ttc_textures.02800.rgba16.png +0x356dfe13, textures/machine/ttc_textures.03000.rgba16.png +0xc573883e, textures/machine/ttc_textures.03800.rgba16.png +0xd4308a0e, textures/machine/ttc_textures.04000.rgba16.png +0xdba71c6e, textures/machine/ttc_textures.05000.rgba16.png +0x0b6370af, textures/machine/ttc_textures.05800.rgba16.png +0x6e1a0405, textures/machine/ttc_textures.06000.rgba16.png +0xbbb65ff3, textures/machine/ttc_textures.06800.rgba16.png +0x1ae05253, textures/machine/ttc_textures.07000.rgba16.png +0xd275624b, textures/machine/ttc_textures.07800.rgba16.png +0xc8f2dd9c, textures/machine/ttc_textures.08000.rgba16.png +0x92c1c319, textures/machine/ttc_textures.08400.rgba16.png +0xe4ca5265, textures/mountain/ttm_textures.00000.rgba16.png +0x488a70aa, textures/mountain/ttm_textures.00800.rgba16.png +0x4832f88f, textures/mountain/ttm_textures.01800.rgba16.png +0xcecfc1e5, textures/mountain/ttm_textures.02800.rgba16.png +0xe9ffbe26, textures/mountain/ttm_textures.03000.rgba16.png +0xab35c95e, textures/mountain/ttm_textures.03800.rgba16.png +0x511b3cd3, textures/mountain/ttm_textures.04000.rgba16.png +0xdc695e31, textures/mountain/ttm_textures.04800.rgba16.png +0x210e8f00, textures/mountain/ttm_textures.05000.rgba16.png +0xe18ecf36, textures/mountain/ttm_textures.05800.rgba16.png +0x273dcb72, textures/mountain/ttm_textures.06800.rgba16.png +0x5ee6e213, textures/mountain/ttm_textures.07000.rgba16.png +0x0ad2decd, textures/mountain/ttm_textures.07800.rgba16.png +0x2a789f5e, textures/mountain/ttm_textures.08000.rgba16.png +0x5bcea656, textures/mountain/ttm_textures.08800.rgba16.png +0x4153345f, textures/mountain/ttm_textures.09800.rgba16.png +0x213c5711, textures/mountain/ttm_textures.0A000.rgba16.png +0x6128b338, textures/mountain/ttm_textures.0A800.rgba16.png +0x667b7cd0, textures/mountain/ttm_textures.0B000.rgba16.png +0x235d693f, textures/mountain/ttm_textures.0B800.rgba16.png +0xd8a136b8, textures/mountain/ttm_textures.0C000.rgba16.png +0xc66dcd09, textures/outside/castle_grounds_textures.00000.rgba16.png +0x0f121216, textures/outside/castle_grounds_textures.00800.rgba16.png +0xcfec5f97, textures/outside/castle_grounds_textures.01000.rgba16.png +0xcdd47bdb, textures/outside/castle_grounds_textures.02000.rgba16.png +0xae8607c0, textures/outside/castle_grounds_textures.03000.rgba16.png +0x5eadd3be, textures/outside/castle_grounds_textures.03800.rgba16.png +0xa181c1f9, textures/outside/castle_grounds_textures.04000.rgba16.png +0xde9fb91a, textures/outside/castle_grounds_textures.04800.rgba16.png +0xfefd090b, textures/outside/castle_grounds_textures.05800.rgba16.png +0x82af551f, textures/outside/castle_grounds_textures.06000.rgba16.png +0xb38f1745, textures/outside/castle_grounds_textures.06800.rgba16.png +0xeee4f4be, textures/outside/castle_grounds_textures.07800.rgba16.png +0x4cc3235f, textures/outside/castle_grounds_textures.08000.rgba16.png +0xa0655572, textures/outside/castle_grounds_textures.08800.rgba16.png +0x30648738, textures/outside/castle_grounds_textures.09000.rgba16.png +0x58f04853, textures/outside/castle_grounds_textures.09800.rgba16.png +0xc4ed8afd, textures/outside/castle_grounds_textures.0A000.rgba16.png +0xacb13417, textures/outside/castle_grounds_textures.0A800.rgba16.png +0x0a59209b, textures/outside/castle_grounds_textures.0B000.rgba16.png +0xf41c8766, textures/outside/castle_grounds_textures.0B400.rgba16.png +0x971b9a46, textures/outside/castle_grounds_textures.0BC00.ia16.png +0x2b21b934, textures/segment2/font_graphics.05900.ia4.png +0x765fbf8c, textures/segment2/font_graphics.05940.ia4.png +0x08c6481a, textures/segment2/font_graphics.05980.ia4.png +0xda797890, textures/segment2/font_graphics.059C0.ia4.png +0x983e7bdd, textures/segment2/font_graphics.05A00.ia4.png +0xd0c98125, textures/segment2/font_graphics.05A40.ia4.png +0x29d925ee, textures/segment2/font_graphics.05A80.ia4.png +0x06099ce6, textures/segment2/font_graphics.05AC0.ia4.png +0xa966e2e3, textures/segment2/font_graphics.05B00.ia4.png +0xda612d70, textures/segment2/font_graphics.05B40.ia4.png +0x82c4684b, textures/segment2/font_graphics.05B80.ia4.png +0x8b9822cb, textures/segment2/font_graphics.05BC0.ia4.png +0xabf92139, textures/segment2/font_graphics.05C00.ia4.png +0xd977640c, textures/segment2/font_graphics.05C40.ia4.png +0x89fac515, textures/segment2/font_graphics.05C80.ia4.png +0x753225a5, textures/segment2/font_graphics.05CC0.ia4.png +0x3a9efdff, textures/segment2/font_graphics.05D00.ia4.png +0x9b01a8de, textures/segment2/font_graphics.05D40.ia4.png +0x99fa7ad4, textures/segment2/font_graphics.05D80.ia4.png +0x54c4b7e3, textures/segment2/font_graphics.05DC0.ia4.png +0x2f11ed57, textures/segment2/font_graphics.05E00.ia4.png +0x0eb65e8a, textures/segment2/font_graphics.05E40.ia4.png +0x3c00926d, textures/segment2/font_graphics.05E80.ia4.png +0xbeb5686e, textures/segment2/font_graphics.05EC0.ia4.png +0x4b3330f8, textures/segment2/font_graphics.05F00.ia1.png +0x4b3330f8, textures/segment2/font_graphics.05F00.ia4.png +0x21a0d845, textures/segment2/font_graphics.05F40.ia1.png +0x21a0d845, textures/segment2/font_graphics.05F40.ia4.png +0xf3e57b1b, textures/segment2/font_graphics.05F80.ia1.png +0xf3e57b1b, textures/segment2/font_graphics.05F80.ia4.png +0x3bdbe695, textures/segment2/font_graphics.05FC0.ia1.png +0x3bdbe695, textures/segment2/font_graphics.05FC0.ia4.png +0x73b8dc0c, textures/segment2/font_graphics.06000.ia1.png +0x73b8dc0c, textures/segment2/font_graphics.06000.ia4.png +0x127c5adf, textures/segment2/font_graphics.06040.ia1.png +0x127c5adf, textures/segment2/font_graphics.06040.ia4.png +0xa19f9c6f, textures/segment2/font_graphics.06080.ia1.png +0xa19f9c6f, textures/segment2/font_graphics.06080.ia4.png +0x1c13b722, textures/segment2/font_graphics.060C0.ia1.png +0x1c13b722, textures/segment2/font_graphics.060C0.ia4.png +0x8de0c55a, textures/segment2/font_graphics.06100.ia1.png +0x8de0c55a, textures/segment2/font_graphics.06100.ia4.png +0x2f99158e, textures/segment2/font_graphics.06140.ia1.png +0x2f99158e, textures/segment2/font_graphics.06140.ia4.png +0xa205efa8, textures/segment2/font_graphics.06180.ia1.png +0xa205efa8, textures/segment2/font_graphics.06180.ia4.png +0xa4e6855b, textures/segment2/font_graphics.061C0.ia1.png +0xa4e6855b, textures/segment2/font_graphics.061C0.ia4.png +0x6e8db5f0, textures/segment2/font_graphics.06200.ia1.png +0x6e8db5f0, textures/segment2/font_graphics.06200.ia4.png +0x06282fb2, textures/segment2/font_graphics.06240.ia1.png +0x06282fb2, textures/segment2/font_graphics.06240.ia4.png +0xda97d693, textures/segment2/font_graphics.06280.ia1.png +0xda97d693, textures/segment2/font_graphics.06280.ia4.png +0xd66044bd, textures/segment2/font_graphics.062C0.ia1.png +0xd66044bd, textures/segment2/font_graphics.062C0.ia4.png +0x721a2fe6, textures/segment2/font_graphics.06300.ia1.png +0x721a2fe6, textures/segment2/font_graphics.06300.ia4.png +0x8cc6d915, textures/segment2/font_graphics.06340.ia1.png +0x8cc6d915, textures/segment2/font_graphics.06340.ia4.png +0x83e97844, textures/segment2/font_graphics.06380.ia1.png +0x83e97844, textures/segment2/font_graphics.06380.ia4.png +0x30680b75, textures/segment2/font_graphics.063C0.ia1.png +0x30680b75, textures/segment2/font_graphics.063C0.ia4.png +0xdb251749, textures/segment2/font_graphics.06400.ia1.png +0xdb251749, textures/segment2/font_graphics.06400.ia4.png +0xb90d56a2, textures/segment2/font_graphics.06410.ia1.png +0x171832d2, textures/segment2/font_graphics.06420.ia1.png +0xff0f8bf2, textures/segment2/font_graphics.06440.ia1.png +0xff0f8bf2, textures/segment2/font_graphics.06440.ia4.png +0xa880db9e, textures/segment2/font_graphics.06480.ia1.png +0xa880db9e, textures/segment2/font_graphics.06480.ia4.png +0x3a18167e, textures/segment2/font_graphics.064C0.ia1.png +0x3a18167e, textures/segment2/font_graphics.064C0.ia4.png +0xe6d07b70, textures/segment2/font_graphics.06500.ia1.png +0xe6d07b70, textures/segment2/font_graphics.06500.ia4.png +0x68ef89de, textures/segment2/font_graphics.06540.ia4.png +0x98aae3db, textures/segment2/font_graphics.06580.ia4.png +0xefe377b2, textures/segment2/font_graphics.065C0.ia4.png +0xd12dfd4d, textures/segment2/font_graphics.06600.ia4.png +0x8833a12d, textures/segment2/font_graphics.06640.ia4.png +0xed681fc9, textures/segment2/font_graphics.06680.ia4.png +0x0f60bf81, textures/segment2/font_graphics.066C0.ia4.png +0x874360ae, textures/segment2/font_graphics.06700.ia4.png +0x38380d33, textures/segment2/font_graphics.06740.ia4.png +0xfba6103a, textures/segment2/font_graphics.06780.ia4.png +0x44901970, textures/segment2/font_graphics.067C0.ia4.png +0x656d4d26, textures/segment2/font_graphics.06800.ia4.png +0x4e908389, textures/segment2/font_graphics.06840.ia4.png +0x61711d35, textures/segment2/font_graphics.06880.ia4.png +0xe6d96bbd, textures/segment2/font_graphics.068C0.ia4.png +0xa4d5bda3, textures/segment2/font_graphics.06900.ia4.png +0xb78885a6, textures/segment2/font_graphics.06940.ia4.png +0xe2d6c874, textures/segment2/font_graphics.06980.ia4.png +0xff837f05, textures/segment2/font_graphics.069C0.ia4.png +0x28a6df13, textures/segment2/font_graphics.06A00.ia4.png +0xd4430e72, textures/segment2/font_graphics.06A40.ia4.png +0x8e761727, textures/segment2/font_graphics.06A80.ia4.png +0x3d3fb5dc, textures/segment2/font_graphics.06AC0.ia4.png +0x01fec34d, textures/segment2/font_graphics.06B00.ia4.png +0x56f01700, textures/segment2/font_graphics.06B40.ia4.png +0x818bf892, textures/segment2/font_graphics.06B80.ia4.png +0x6a83d046, textures/segment2/font_graphics.06BC0.ia4.png +0xb18ae980, textures/segment2/font_graphics.06C00.ia4.png +0xfec0b7bf, textures/segment2/font_graphics.06C40.ia4.png +0x05c60d5c, textures/segment2/font_graphics.06C80.ia4.png +0x181addca, textures/segment2/font_graphics.06CC0.ia4.png +0xab697b20, textures/segment2/font_graphics.06D00.ia4.png +0x7d6c3af4, textures/segment2/font_graphics.06D40.ia4.png +0x7c533062, textures/segment2/font_graphics.06D80.ia4.png +0x50769e3d, textures/segment2/font_graphics.06DC0.ia4.png +0xd3485c56, textures/segment2/font_graphics.06E00.ia4.png +0x14a1622c, textures/segment2/font_graphics.06E40.ia4.png +0x3fb1a251, textures/segment2/font_graphics.06E80.ia4.png +0x93a5982f, textures/segment2/font_graphics.06EC0.ia4.png +0x330e5327, textures/segment2/font_graphics.06F00.ia4.png +0x37db6cf9, textures/segment2/font_graphics.06F40.ia4.png +0x89813602, textures/segment2/font_graphics.06F80.ia4.png +0x55595e27, textures/segment2/font_graphics.06FC0.ia4.png +0xcf341250, textures/segment2/segment2.00000.rgba16.png +0x39f1d028, textures/segment2/segment2.00200.rgba16.png +0xca380082, textures/segment2/segment2.00400.rgba16.png +0xeb41b2c9, textures/segment2/segment2.00600.rgba16.png +0x03a5f3b2, textures/segment2/segment2.00800.rgba16.png +0x2cbaf6de, textures/segment2/segment2.00A00.rgba16.png +0x6e925f0b, textures/segment2/segment2.00C00.rgba16.png +0x7b160b36, textures/segment2/segment2.00E00.rgba16.png +0x377ab51e, textures/segment2/segment2.01000.rgba16.png +0xe204fbf6, textures/segment2/segment2.01200.rgba16.png +0x9e0865f1, textures/segment2/segment2.01400.rgba16.png +0xccf5a18a, textures/segment2/segment2.01600.rgba16.png +0x3c6e303c, textures/segment2/segment2.01800.rgba16.png +0x817a6e74, textures/segment2/segment2.01A00.rgba16.png +0x79c5d587, textures/segment2/segment2.01C00.rgba16.png +0x210c4aaf, textures/segment2/segment2.01E00.rgba16.png +0x4324fca9, textures/segment2/segment2.02000.rgba16.png +0xec9fa838, textures/segment2/segment2.02200.rgba16.png +0x150cdac9, textures/segment2/segment2.02400.rgba16.png +0xd03ea4ce, textures/segment2/segment2.02800.rgba16.png +0x0fdcec5a, textures/segment2/segment2.02A00.rgba16.png +0x78a1a365, textures/segment2/segment2.02C00.rgba16.png +0xe43ae816, textures/segment2/segment2.02E00.rgba16.png +0x23925acf, textures/segment2/segment2.03000.rgba16.png +0x92a12559, textures/segment2/segment2.03200.rgba16.png +0x251a6d5e, textures/segment2/segment2.03600.rgba16.png +0xf55c37c5, textures/segment2/segment2.03800.rgba16.png +0xdb07300e, textures/segment2/segment2.03A00.rgba16.png +0x02fb0145, textures/segment2/segment2.03C00.rgba16.png +0xbde1ffd1, textures/segment2/segment2.04000.rgba16.png +0x21a3669e, textures/segment2/segment2.04400.rgba16.png +0x347bb5c1, textures/segment2/segment2.04800.rgba16.png +0xe4ae946f, textures/segment2/segment2.04A00.rgba16.png +0xeaef8ec7, textures/segment2/segment2.05000.rgba16.png +0xf3554378, textures/segment2/segment2.05600.rgba16.png +0x7efec761, textures/segment2/segment2.05800.rgba16.png +0x207e74f1, textures/segment2/segment2.05A00.rgba16.png +0x9cc450c0, textures/segment2/segment2.05C00.rgba16.png +0x6df02dac, textures/segment2/segment2.06200.rgba16.png +0x400ac163, textures/segment2/segment2.06280.rgba16.png +0x83e67e30, textures/segment2/segment2.06300.rgba16.png +0xb17b06da, textures/segment2/segment2.06380.rgba16.png +0xc8282ec6, textures/segment2/segment2.06400.rgba16.png +0xd5d54ca2, textures/segment2/segment2.06480.rgba16.png +0x91f9a359, textures/segment2/segment2.06500.rgba16.png +0xf7d84d57, textures/segment2/segment2.06580.rgba16.png +0xfe439057, textures/segment2/segment2.06600.rgba16.png +0xfe7ff6f9, textures/segment2/segment2.06680.rgba16.png +0x52435413, textures/segment2/segment2.06700.rgba16.png +0x99b11f3f, textures/segment2/segment2.06780.rgba16.png +0x3f362558, textures/segment2/segment2.06800.rgba16.png +0x065e4fd0, textures/segment2/segment2.06880.rgba16.png +0x90320242, textures/segment2/segment2.06900.rgba16.png +0x07557259, textures/segment2/segment2.06980.rgba16.png +0x2d313791, textures/segment2/segment2.06A00.rgba16.png +0x9c5fa376, textures/segment2/segment2.06A80.rgba16.png +0x58036014, textures/segment2/segment2.06B00.rgba16.png +0x79209be0, textures/segment2/segment2.06B80.rgba16.png +0xe2dac354, textures/segment2/segment2.06C00.rgba16.png +0xa6476afc, textures/segment2/segment2.06C80.rgba16.png +0x0849c4e9, textures/segment2/segment2.06D00.rgba16.png +0x2ed9feaf, textures/segment2/segment2.06D80.rgba16.png +0x2b9584a9, textures/segment2/segment2.06E00.rgba16.png +0x04c60f5a, textures/segment2/segment2.06E80.rgba16.png +0xed28daef, textures/segment2/segment2.06F00.rgba16.png +0xf98b2e9b, textures/segment2/segment2.06F80.rgba16.png +0xf513768d, textures/segment2/segment2.07000.rgba16.png +0x51874ba9, textures/segment2/segment2.07080.rgba16.png +0xb65924dd, textures/segment2/segment2.07340.ia1.png +0xd9ce10d3, textures/segment2/segment2.07B50.rgba16.png +0x20c1e685, textures/segment2/segment2.07D50.rgba16.png +0x6328bdd7, textures/segment2/segment2.07F50.rgba16.png +0x28231083, textures/segment2/segment2.08150.rgba16.png +0xfa68ab28, textures/segment2/segment2.081D0.rgba16.png +0xd2092ad4, textures/segment2/segment2.0F458.ia8.png +0x57d32732, textures/segment2/segment2.0FC58.ia8.png +0x147fe400, textures/segment2/segment2.10458.ia8.png +0x384cdcb7, textures/segment2/segment2.11458.ia8.png +0x403a1649, textures/segment2/segment2.11C58.rgba16.png +0xf6adc736, textures/segment2/segment2.12458.rgba16.png +0xb554471b, textures/segment2/segment2.12C58.rgba16.png +0xcaa570b7, textures/segment2/segment2.13458.ia16.png +0xf088177d, textures/segment2/segment2.13C58.rgba16.png +0x0913f835, textures/segment2/segment2.14838.ia8.png +0x2f349533, textures/segment2/shadow_quarter_circle.ia8.png +0x0fea0598, textures/segment2/shadow_quarter_square.ia8.png +0xc7189179, textures/sky/metal_hole.rgba16.png +0x52d580bd, textures/sky/rr_textures.00000.rgba16.png +0xe7bcf2bd, textures/sky/rr_textures.00800.rgba16.png +0xac07afea, textures/sky/rr_textures.01000.rgba16.png +0x4eeddde4, textures/sky/rr_textures.01800.rgba16.png +0xd3dd1e91, textures/sky/rr_textures.02000.rgba16.png +0x2f929b35, textures/sky/rr_textures.03000.rgba16.png +0xb99e8366, textures/sky/rr_textures.03800.rgba16.png +0xbcb6c303, textures/sky/rr_textures.04800.rgba16.png +0x34353e2a, textures/sky/rr_textures.05000.rgba16.png +0xe75ad632, textures/sky/rr_textures.05800.rgba16.png +0x213c5711, textures/sky/rr_textures.06000.rgba16.png +0xbcb8ad0f, textures/sky/rr_textures.07000.rgba16.png +0xa7368d36, textures/sky/rr_textures.07800.rgba16.png +0x8cfbe9af, textures/sky/rr_textures.08000.rgba16.png +0xe37b5e19, textures/snow/ccm_textures.00000.rgba16.png +0x59afeec0, textures/snow/ccm_textures.00800.rgba16.png +0x98aa302b, textures/snow/ccm_textures.01000.rgba16.png +0xc989acca, textures/snow/ccm_textures.02000.rgba16.png +0xedbf938f, textures/snow/ccm_textures.02800.rgba16.png +0x3762b58f, textures/snow/ccm_textures.03000.rgba16.png +0xae12405c, textures/snow/ccm_textures.03800.rgba16.png +0xfba4b6be, textures/snow/ccm_textures.04000.rgba16.png +0xa89d818c, textures/snow/ccm_textures.04800.rgba16.png +0xdf6d09df, textures/snow/ccm_textures.05000.rgba16.png +0x3ed61016, textures/snow/ccm_textures.05800.rgba16.png +0xa5cde39c, textures/snow/ccm_textures.06000.rgba16.png +0x247b9862, textures/snow/ccm_textures.06800.rgba16.png +0x5d26657a, textures/snow/ccm_textures.07000.rgba16.png +0x190aa01a, textures/snow/ccm_textures.08000.rgba16.png +0x123ff0b2, textures/snow/ccm_textures.08800.rgba16.png +0xea4456cb, textures/snow/ccm_textures.09000.ia16.png +0xb21d1349, textures/snow/ccm_textures.09800.ia16.png +0x962e26e7, textures/spooky/bbh_textures.00000.rgba16.png +0x4e3e51b0, textures/spooky/bbh_textures.00800.rgba16.png +0xb1587f41, textures/spooky/bbh_textures.01800.rgba16.png +0x2c722543, textures/spooky/bbh_textures.02800.rgba16.png +0x0aaa943b, textures/spooky/bbh_textures.03800.rgba16.png +0x13de896a, textures/spooky/bbh_textures.04800.rgba16.png +0xdadaf940, textures/spooky/bbh_textures.05000.rgba16.png +0x7e7f9c91, textures/spooky/bbh_textures.06000.rgba16.png +0x3831c28f, textures/spooky/bbh_textures.06800.rgba16.png +0x8a362a23, textures/spooky/bbh_textures.07000.rgba16.png +0x70229e8d, textures/spooky/bbh_textures.08000.rgba16.png +0x03fddfb0, textures/spooky/bbh_textures.08800.rgba16.png +0xa913399b, textures/spooky/bbh_textures.09000.rgba16.png +0xab6318d0, textures/spooky/bbh_textures.0A000.rgba16.png +0x56cc824d, textures/spooky/bbh_textures.0A800.ia16.png +0x5bdd0813, textures/spooky/bbh_textures.0B000.ia16.png +0x99eeb704, textures/spooky/bbh_textures.0B800.ia16.png +0x8225ba70, textures/title_screen_bg/title_screen_bg.001C0.rgba16.png +0x8bf7a728, textures/title_screen_bg/title_screen_bg.00E40.rgba16.png +0xa5ab0bf0, textures/title_screen_bg/title_screen_bg.01AC0.rgba16.png +0x53af13cf, textures/title_screen_bg/title_screen_bg.02740.rgba16.png +0xeab50b79, textures/title_screen_bg/title_screen_bg.033C0.rgba16.png +0xd3e3772c, textures/title_screen_bg/title_screen_bg.04040.rgba16.png +0xbe7e3218, textures/title_screen_bg/title_screen_bg.04CC0.rgba16.png +0xb35dbc9d, textures/title_screen_bg/title_screen_bg.05940.rgba16.png +0xa02d5dfe, textures/water/jrb_textures.00000.rgba16.png +0x37fec9d4, textures/water/jrb_textures.00800.rgba16.png +0xbe46e587, textures/water/jrb_textures.01800.rgba16.png +0xf29de32f, textures/water/jrb_textures.02800.rgba16.png +0xb46e7714, textures/water/jrb_textures.03800.rgba16.png +0x6357adf7, textures/water/jrb_textures.04800.rgba16.png +0xce277ff7, textures/water/jrb_textures.05800.rgba16.png +0xf1c7863b, textures/water/jrb_textures.06000.rgba16.png +0x444b7785, textures/water/jrb_textures.06800.rgba16.png +0x7a5a6efd, textures/water/jrb_textures.07800.rgba16.png +0x5d749b6c, textures/water/jrb_textures.08800.rgba16.png +0x3ba85443, textures/water/jrb_textures.09000.rgba16.png +0x359500dd, textures/water/jrb_textures.0A000.rgba16.png +0xd4e87a88, textures/water/jrb_textures.0A800.rgba16.png +0x742e8b1b, textures/water/jrb_textures.0B800.rgba16.png diff --git a/tools/texrename.py b/tools/texrename.py new file mode 100644 index 00000000..541a0a09 --- /dev/null +++ b/tools/texrename.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +import sys +import os +import shutil + +if len(sys.argv) < 3: + print("usage: texrename []") + sys.exit(1) + +inpath = sys.argv[1] +outpath = sys.argv[2] +mapfname = "crcmap.txt" +if len(sys.argv) > 3: + mapfname = sys.argv[3] + +# catalog the original texture pack +texmap = dict() +imgexts = frozenset(['.png', '.bmp', '.jpg', '.tga', '.gif']) +try: + for root, dirs, files in os.walk(inpath): + for f in files: + ffull = os.path.join(root, f) + [fpath, fname] = os.path.split(f) + ext = os.path.splitext(fname)[1].lower() + if fname[0] == '.' or not (ext in imgexts): + continue + crc = 0 + try: + if '#' in fname: # rice pack format: "GAME NAME#hash#whatever" + crc = int(fname.split('#')[1], 16) + else: # just the crc probably + crc = int(os.path.splitext(fname)[0], 16) + except ValueError: + print('unknown filename format: {0}'.format(ffull)) + continue + texmap[crc] = ffull +except OSError as e: + print('error opening {0}: {1}'.format(inpath, e)) + sys.exit(2) + +# load the CRC map +crcmap = dict() +try: + with open(mapfname, 'r') as f: + for line in f: + line = line.strip() + if line == '' or line[0] == '#': + continue + tok = line.split(',') + crcstr = tok[0].strip() + if crcstr.startswith('0x'): + crc = int(crcstr[2:], 16) + else: + crc = int(crcstr) + crcmap[crc] = os.path.join(outpath, tok[1].strip()) +except OSError as e: + print('could not open {0}: {1}'.format(mapfname, e)) +except ValueError as e: + print('invalid integer in {0}: {1}'.format(mapfname, e)) + sys.exit(3) + +# copy the files to the correct locations +for crc, path in crcmap.items(): + if not (crc in texmap): + print('unmatched CRC: {0} ({1})'.format(crc, path)) + else: + [fpath, fname] = os.path.split(path) + if not os.path.exists(fpath): + os.makedirs(fpath) + shutil.copy2(texmap[crc], path) From 85a1d8842234a1e27cc5871e80207cb4a500ee0c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Thu, 28 May 2020 23:08:32 +0300 Subject: [PATCH 19/24] texrename: handle multiple files with the same CRC too --- tools/texrename.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/texrename.py b/tools/texrename.py index 541a0a09..e8ac24e0 100644 --- a/tools/texrename.py +++ b/tools/texrename.py @@ -40,7 +40,7 @@ except OSError as e: sys.exit(2) # load the CRC map -crcmap = dict() +crcmap = list() try: with open(mapfname, 'r') as f: for line in f: @@ -53,7 +53,7 @@ try: crc = int(crcstr[2:], 16) else: crc = int(crcstr) - crcmap[crc] = os.path.join(outpath, tok[1].strip()) + crcmap.append((crc, os.path.join(outpath, tok[1].strip()))) except OSError as e: print('could not open {0}: {1}'.format(mapfname, e)) except ValueError as e: @@ -61,7 +61,7 @@ except ValueError as e: sys.exit(3) # copy the files to the correct locations -for crc, path in crcmap.items(): +for (crc, path) in crcmap: if not (crc in texmap): print('unmatched CRC: {0} ({1})'.format(crc, path)) else: From 875d7a9b3c7acdd8b7e6f02674159359fee1e501 Mon Sep 17 00:00:00 2001 From: GateGuy <57763469+GateGuy@users.noreply.github.com> Date: Thu, 28 May 2020 18:40:36 -0400 Subject: [PATCH 20/24] Added deadzone option --- include/text_options_strings.h.in | 2 ++ src/game/options_menu.c | 4 ++++ src/pc/configfile.c | 2 ++ src/pc/configfile.h | 1 + src/pc/controller/controller_api.h | 2 +- src/pc/controller/controller_entry_point.c | 3 ++- src/pc/controller/controller_sdl.c | 3 ++- 7 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/text_options_strings.h.in b/include/text_options_strings.h.in index 7580ec9e..13faf3dd 100644 --- a/include/text_options_strings.h.in +++ b/include/text_options_strings.h.in @@ -66,6 +66,7 @@ #define TEXT_BIND_DOWN _("STICK DOWN") #define TEXT_BIND_LEFT _("STICK LEFT") #define TEXT_BIND_RIGHT _("STICK RIGHT") +#define TEXT_OPT_DEADZONE _("STICK DEADZONE") #define TEXT_OPT_CHEAT1 _("ENABLE CHEATS") #define TEXT_OPT_CHEAT2 _("MOONJUMP (PRESS L)") @@ -122,6 +123,7 @@ #define TEXT_BIND_DOWN _("Stick Down") #define TEXT_BIND_LEFT _("Stick Left") #define TEXT_BIND_RIGHT _("Stick Right") +#define TEXT_OPT_DEADZONE _("Stick Deadzone") #define TEXT_OPT_CHEAT1 _("Enable cheats") #define TEXT_OPT_CHEAT2 _("Moonjump (Press L)") diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 4e08dbdb..3b0ed9fa 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -115,6 +115,7 @@ static const u8 bindStr[][32] = { { TEXT_BIND_DOWN }, { TEXT_BIND_LEFT }, { TEXT_BIND_RIGHT }, + { TEXT_OPT_DEADZONE }, }; static const u8 *filterChoices[] = { @@ -233,6 +234,9 @@ static struct Option optsControls[] = { DEF_OPT_BIND( bindStr[13], configKeyStickDown ), DEF_OPT_BIND( bindStr[14], configKeyStickLeft ), DEF_OPT_BIND( bindStr[15], configKeyStickRight ), + // max deadzone is 31000; this is less than the max range of 32768, but this + // way, the player can't accidentally lock themselves out of using the stick + DEF_OPT_SCROLL( bindStr[16], &configStickDeadzone, 0, 100, 1 ), }; static struct Option optsVideo[] = { diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 2baf96cf..25eb1146 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -66,6 +66,7 @@ unsigned int configKeyStickUp[MAX_BINDS] = { 0x0011, VK_INVALID, VK_INVALID unsigned int configKeyStickDown[MAX_BINDS] = { 0x001F, VK_INVALID, VK_INVALID }; unsigned int configKeyStickLeft[MAX_BINDS] = { 0x001E, VK_INVALID, VK_INVALID }; unsigned int configKeyStickRight[MAX_BINDS] = { 0x0020, VK_INVALID, VK_INVALID }; +unsigned int configStickDeadzone = 16; // 16*DEADZONE_STEP=4960 (the original default deadzone) #ifdef EXTERNAL_TEXTURES bool configPrecacheRes = false; #endif @@ -107,6 +108,7 @@ static const struct ConfigOption options[] = { {.name = "key_stickdown", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickDown}, {.name = "key_stickleft", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickLeft}, {.name = "key_stickright", .type = CONFIG_TYPE_BIND, .uintValue = configKeyStickRight}, + {.name = "stick_deadzone", .type = CONFIG_TYPE_UINT, .uintValue = &configStickDeadzone}, #ifdef EXTERNAL_TEXTURES {.name = "precache", .type = CONFIG_TYPE_BOOL, .boolValue = &configPrecacheRes}, #endif diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 1ae38f84..d6087612 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -35,6 +35,7 @@ extern unsigned int configKeyStickUp[]; extern unsigned int configKeyStickDown[]; extern unsigned int configKeyStickLeft[]; extern unsigned int configKeyStickRight[]; +extern unsigned int configStickDeadzone; #ifdef EXTERNAL_TEXTURES extern bool configPrecacheRes; #endif diff --git a/src/pc/controller/controller_api.h b/src/pc/controller/controller_api.h index 2f9c1d16..74db6552 100644 --- a/src/pc/controller/controller_api.h +++ b/src/pc/controller/controller_api.h @@ -1,7 +1,7 @@ #ifndef CONTROLLER_API #define CONTROLLER_API -#define DEADZONE 4960 +#define DEADZONE_STEP 310 // original deadzone is 4960 #define VK_INVALID 0xFFFF #define VK_SIZE 0x1000 diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index 90c10c1d..2b264b29 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -40,7 +40,8 @@ void osContGetReadData(OSContPad *pad) { #ifdef BETTERCAMERA uint32_t magnitude_sq = (uint32_t)(rightx * rightx) + (uint32_t)(righty * righty); - if (magnitude_sq > (uint32_t)(DEADZONE * DEADZONE)) { + uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; + if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { c_rightx = rightx / 0x100; int stick_y = -righty / 0x100; c_righty = stick_y == 128 ? 127 : stick_y; diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index cbdd6178..b28e3f7b 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -182,7 +182,8 @@ static void controller_sdl_read(OSContPad *pad) { if (rtrig > 30 * 256) pad->button |= R_TRIG; uint32_t magnitude_sq = (uint32_t)(leftx * leftx) + (uint32_t)(lefty * lefty); - if (magnitude_sq > (uint32_t)(DEADZONE * DEADZONE)) { + uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; + if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { pad->stick_x = leftx / 0x100; int stick_y = -lefty / 0x100; pad->stick_y = stick_y == 128 ? 127 : stick_y; From 2e332c9316d0461e8bcf8a6ac9f5caffc07ac388 Mon Sep 17 00:00:00 2001 From: GateGuy <57763469+GateGuy@users.noreply.github.com> Date: Thu, 28 May 2020 18:42:45 -0400 Subject: [PATCH 21/24] Fixed typo in comment --- src/game/options_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/options_menu.c b/src/game/options_menu.c index 3b0ed9fa..68cd98f0 100644 --- a/src/game/options_menu.c +++ b/src/game/options_menu.c @@ -234,7 +234,7 @@ static struct Option optsControls[] = { DEF_OPT_BIND( bindStr[13], configKeyStickDown ), DEF_OPT_BIND( bindStr[14], configKeyStickLeft ), DEF_OPT_BIND( bindStr[15], configKeyStickRight ), - // max deadzone is 31000; this is less than the max range of 32768, but this + // max deadzone is 31000; this is less than the max range of ~32768, but this // way, the player can't accidentally lock themselves out of using the stick DEF_OPT_SCROLL( bindStr[16], &configStickDeadzone, 0, 100, 1 ), }; From 540a0387c9fc107fcefd64e36cdbbec2930ed461 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 29 May 2020 18:08:00 +0300 Subject: [PATCH 22/24] fix build --- src/pc/controller/controller_entry_point.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index 2b264b29..65b88023 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -1,6 +1,8 @@ #include "lib/src/libultra_internal.h" #include "lib/src/osContInternal.h" +#include "../configfile.h" + #include "controller_recorded_tas.h" #include "controller_keyboard.h" From 93030b02a3451f95c97103bec3f114e448c6ed7f Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 29 May 2020 19:35:35 +0300 Subject: [PATCH 23/24] don't die after encountering a NULL texture --- src/game/ingame_menu.c | 2 ++ src/pc/gfx/gfx_pc.c | 44 +++++++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 6f3d84b9..9711ec7e 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -245,6 +245,7 @@ static inline u8 *convert_ia8_char(u8 c, u16 *tex, s16 w, s16 h) { #ifdef EXTERNAL_TEXTURES return (u8 *)tex; // the data's just a name #else + if (!tex) return NULL; if (!charCache[c].used) { charCache[c].used = 1; alloc_ia8_text_from_i1(charCache[c].data, tex, w, h); @@ -305,6 +306,7 @@ static u8 *convert_ia4_char(u8 c, u8 *tex, s16 w, s16 h) { #ifdef EXTERNAL_TEXTURES return tex; // the data's just a name #else + if (!tex) return NULL; if (!charCache[c].used) { charCache[c].used = 1; alloc_ia4_tex_from_i1(charCache[c].data, tex, w, h); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index c0900831..6bd2fca4 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -573,30 +574,47 @@ static bool preload_texture(const char *path) { return true; } +static inline void load_texture(const char *name) { + static char fpath[SYS_MAX_PATH]; + int w, h; + const char *texname = name; + + if (!texname[0]) { + fprintf(stderr, "empty texture name at %p\n", texname); + return; + } + + snprintf(fpath, sizeof(fpath), "%s/%s.png", sys_data_path(), texname); + u8 *data = stbi_load(fpath, &w, &h, NULL, 4); + if (!data) { + fprintf(stderr, "could not load texture: `%s`\n", fpath); + return; + } + + gfx_rapi->upload_texture(data, w, h); + stbi_image_free(data); // don't need this anymore +} + #endif // EXTERNAL_TEXTURES static void import_texture(int tile) { uint8_t fmt = rdp.texture_tile.fmt; uint8_t siz = rdp.texture_tile.siz; - + + if (!rdp.loaded_texture[tile].addr) { + fprintf(stderr, "NULL texture: tile %d, format %d/%d, size %d\n", + tile, (int)fmt, (int)siz, (int)rdp.loaded_texture[tile].size_bytes); + return; + } + if (gfx_texture_cache_lookup(tile, &rendering_state.textures[tile], rdp.loaded_texture[tile].addr, fmt, siz)) { return; } - + #ifdef EXTERNAL_TEXTURES // the "texture data" is actually a C string with the path to our texture in it // load it from an external image in our data path - static char fpath[SYS_MAX_PATH]; - int w, h; - const char *texname = (const char*)rdp.loaded_texture[tile].addr; - snprintf(fpath, sizeof(fpath), "%s/%s.png", sys_data_path(), texname); - u8 *data = stbi_load(fpath, &w, &h, NULL, 4); - if (!data) { - fprintf(stderr, "could not load texture: `%s`\n", fpath); - abort(); - } - gfx_rapi->upload_texture(data, w, h); - stbi_image_free(data); // don't need this anymore + load_texture((const char*)rdp.loaded_texture[tile].addr); #else // the texture data is actual texture data int t0 = get_time(); From f6c54e95b239e991253b730c62a068baf1c6a3b5 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 29 May 2020 20:10:38 +0300 Subject: [PATCH 24/24] read in all config line tokens (fixes the binds not saving) --- src/pc/configfile.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 25eb1146..9c9038a4 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -231,7 +231,7 @@ void configfile_load(const char *filename) { // Go through each line in the file while ((line = read_file_line(file)) != NULL) { char *p = line; - char *tokens[2]; + char *tokens[1 + MAX_BINDS]; int numTokens; while (isspace(*p)) @@ -240,7 +240,7 @@ void configfile_load(const char *filename) { if (!*p || *p == '#') // comment or empty line continue; - numTokens = tokenize_string(p, 2, tokens); + numTokens = tokenize_string(p, sizeof(tokens) / sizeof(tokens[0]), tokens); if (numTokens != 0) { if (numTokens >= 2) { const struct ConfigOption *option = NULL; @@ -274,7 +274,9 @@ void configfile_load(const char *filename) { default: assert(0); // bad type } - printf("option: '%s', value: '%s'\n", tokens[0], tokens[1]); + printf("option: '%s', value:", tokens[0]); + for (int i = 1; i < numTokens; ++i) printf(" '%s'", tokens[i]); + printf("\n"); } } else puts("error: expected value");