From eeca3b0ec0e895d9f50f2a55b33021cc75b86c59 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 25 May 2020 00:58:43 +0300 Subject: [PATCH 01/14] 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 02/14] 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 03/14] 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 04/14] 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 05/14] 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 06/14] 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 07/14] 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 08/14] 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 09/14] 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 10/14] 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 11/14] 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 12/14] 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 13/14] 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 14/14] 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 ), };