From bd68d6cb67b8aac3b605db0741008feddaadf1af Mon Sep 17 00:00:00 2001 From: fgsfds Date: Thu, 4 Jun 2020 23:39:57 +0300 Subject: [PATCH 01/29] move rumble functions to controller API --- src/pc/controller/controller_api.h | 18 ++++-- src/pc/controller/controller_entry_point.c | 23 ++++++- src/pc/controller/controller_recorded_tas.c | 2 + src/pc/controller/controller_sdl.c | 66 +++++++++++---------- src/pc/controller/controller_sdl.h | 4 -- 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/src/pc/controller/controller_api.h b/src/pc/controller/controller_api.h index 6e55c846..d4a9d86c 100644 --- a/src/pc/controller/controller_api.h +++ b/src/pc/controller/controller_api.h @@ -16,18 +16,24 @@ #include struct ControllerAPI { - const u32 vkbase; // base number in the virtual keyspace (e.g. keyboard is 0x0000-0x1000) - void (*init)(void); // call once, also calls reconfig() - void (*read)(OSContPad *pad); // read controller and update N64 pad values - u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none - void (*reconfig)(void); // (optional) call when bindings have changed - void (*shutdown)(void); // (optional) call in osContReset + const u32 vkbase; // base number in the virtual keyspace (e.g. keyboard is 0x0000-0x1000) + void (*init)(void); // call once, also calls reconfig() + void (*read)(OSContPad *pad); // read controller and update N64 pad values + u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none + void (*rumble_play)(float str, float time); // (optional) rumble with intensity `str` (0 - 1) for `time` seconds + void (*rumble_stop)(void); // (optional) stop any ongoing haptic feedback + void (*reconfig)(void); // (optional) call when bindings have changed + void (*shutdown)(void); // (optional) call in osContReset }; // used for binding keys u32 controller_get_raw_key(void); void controller_reconfigure(void); +// rumbles all controllers with rumble support +void controller_rumble_play(float str, float time); +void controller_rumble_stop(void); + // calls the shutdown() function of all controller subsystems void controller_shutdown(void); diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index b8b54ad3..fae9d657 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -31,15 +31,18 @@ s32 osContInit(OSMesgQueue *mq, u8 *controllerBits, OSContStatus *status) { s32 osMotorStart(void *pfs) { // Since rumble stops by osMotorStop, its duration is not nessecary. - return controller_rumble_play(configRumbleStrength / 100.0, 50); + // Set it to 5 seconds and hope osMotorStop() is called in time. + controller_rumble_play(configRumbleStrength / 100.0f, 5.0f); + return 0; } s32 osMotorStop(void *pfs) { - return controller_rumble_stop(); + controller_rumble_stop(); + return 0; } u32 osMotorInit(OSMesgQueue *mq, void *pfs, s32 port) { - return controller_rumble_init(); + return 0; // rumble is initialized in the specific backend's init function } s32 osContStartReadData(OSMesgQueue *mesg) { @@ -93,3 +96,17 @@ void controller_reconfigure(void) { controller_implementations[i]->reconfig(); } } + +void controller_rumble_play(float str, float time) { + for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { + if (controller_implementations[i]->rumble_play) + controller_implementations[i]->rumble_play(str, time); + } +} + +void controller_rumble_stop(void) { + for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { + if (controller_implementations[i]->rumble_stop) + controller_implementations[i]->rumble_stop(); + } +} diff --git a/src/pc/controller/controller_recorded_tas.c b/src/pc/controller/controller_recorded_tas.c index 2fcd5b54..73b507dc 100644 --- a/src/pc/controller/controller_recorded_tas.c +++ b/src/pc/controller/controller_recorded_tas.c @@ -39,6 +39,8 @@ struct ControllerAPI controller_recorded_tas = { tas_init, tas_read, tas_rawkey, + NULL, // no rumble_play + NULL, // no rumble_stop NULL, // no rebinding tas_shutdown }; diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index 683eefbb..368179f3 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -113,6 +113,24 @@ static void controller_sdl_init(void) { init_ok = true; } +static SDL_Haptic *controller_sdl_init_haptics(const int joy) { + SDL_Haptic *hap = SDL_HapticOpen(joy); + if (!hap) return NULL; + + if (SDL_HapticRumbleSupported(hap) != SDL_TRUE) { + SDL_HapticClose(hap); + return NULL; + } + + if (SDL_HapticRumbleInit(hap) != 0) { + SDL_HapticClose(hap); + return NULL; + } + + printf("controller %s has haptics support, rumble enabled\n", SDL_JoystickNameForIndex(joy)); + return hap; +} + static void controller_sdl_read(OSContPad *pad) { if (!init_ok) { return; @@ -138,15 +156,18 @@ static void controller_sdl_read(OSContPad *pad) { SDL_GameControllerUpdate(); if (sdl_cntrl != NULL && !SDL_GameControllerGetAttached(sdl_cntrl)) { + SDL_HapticClose(sdl_haptic); SDL_GameControllerClose(sdl_cntrl); sdl_cntrl = NULL; + sdl_haptic = NULL; } + if (sdl_cntrl == NULL) { for (int i = 0; i < SDL_NumJoysticks(); i++) { if (SDL_IsGameController(i)) { sdl_cntrl = SDL_GameControllerOpen(i); - sdl_haptic = SDL_HapticOpen(i); if (sdl_cntrl != NULL) { + sdl_haptic = controller_sdl_init_haptics(i); break; } } @@ -220,6 +241,16 @@ static void controller_sdl_read(OSContPad *pad) { } } +static void controller_sdl_rumble_play(f32 strength, u32 length) { + if (sdl_haptic) + SDL_HapticRumblePlay(sdl_haptic, strength, length); +} + +static void controller_sdl_rumble_stop(void) { + if (sdl_haptic) + SDL_HapticRumbleStop(sdl_haptic); +} + static u32 controller_sdl_rawkey(void) { if (last_joybutton != VK_INVALID) { const u32 ret = last_joybutton; @@ -252,42 +283,13 @@ static void controller_sdl_shutdown(void) { init_ok = false; } -u32 controller_rumble_init(void) { - if (SDL_HapticRumbleSupported(sdl_haptic) != SDL_TRUE) { - // printf("Controller does not support haptics! %s\n", SDL_GetError()); - return 1; - } - if (SDL_HapticRumbleInit(sdl_haptic) != 0) { - printf("Unable to initialize rumble! %s\n", SDL_GetError()); - return 1; - } - return 0; -} - - -s32 controller_rumble_play(f32 strength, u32 length) { - if (SDL_HapticRumblePlay(sdl_haptic, strength, length) != 0) { - printf("Unable to start rumble! %s\n", SDL_GetError()); - return -1; - } else { - return 0; - } -} - -s32 controller_rumble_stop(void) { - if (SDL_HapticRumbleStop(sdl_haptic) != 0) { - printf("Unable to stop rumble! %s\n", SDL_GetError()); - return -1; - } else { - return 0; - } -} - struct ControllerAPI controller_sdl = { VK_BASE_SDL_GAMEPAD, controller_sdl_init, controller_sdl_read, controller_sdl_rawkey, + controller_sdl_rumble_play, + controller_sdl_rumble_stop, controller_sdl_bind, controller_sdl_shutdown }; diff --git a/src/pc/controller/controller_sdl.h b/src/pc/controller/controller_sdl.h index c1a43cec..bbe8a62c 100644 --- a/src/pc/controller/controller_sdl.h +++ b/src/pc/controller/controller_sdl.h @@ -7,8 +7,4 @@ extern struct ControllerAPI controller_sdl; -u32 controller_rumble_init(void); -s32 controller_rumble_play(f32 strength, u32 length); -s32 controller_rumble_stop(void); - #endif From 3954f7d1d3080858e5fdb635d77ceb3e5a59fa8a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Thu, 4 Jun 2020 23:42:19 +0300 Subject: [PATCH 02/29] nuke some leftover MIPS assembly and binary blobs --- lib/PR/audio/aspMain.bin | Bin 3616 -> 0 bytes lib/PR/audio/aspMain_data.bin | Bin 704 -> 0 bytes lib/PR/boot/F3D_boot.bin | Bin 208 -> 0 bytes lib/PR/boot/F3D_boot_eu.bin | Bin 204 -> 0 bytes lib/PR/f3d/new/F3D.bin | Bin 5120 -> 0 bytes lib/PR/f3d/new/F3D_data.bin | Bin 2048 -> 0 bytes lib/PR/f3d/new/F3D_data_EU.bin | Bin 2048 -> 0 bytes lib/PR/f3d/old/F3D.bin | Bin 5128 -> 0 bytes lib/PR/f3d/old/F3D_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/F3DEX.bin | Bin 5168 -> 0 bytes lib/PR/f3dex/F3DEX_NoN.bin | Bin 5168 -> 0 bytes lib/PR/f3dex/F3DEX_NoN_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/F3DEX_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/F3DLX.bin | Bin 5168 -> 0 bytes lib/PR/f3dex/F3DLX_NoN.bin | Bin 5168 -> 0 bytes lib/PR/f3dex/F3DLX_NoN_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/F3DLX_Rej.bin | Bin 5072 -> 0 bytes lib/PR/f3dex/F3DLX_Rej_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/F3DLX_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex/L3DEX.bin | Bin 4080 -> 0 bytes lib/PR/f3dex/L3DEX_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex2/F3DEX2.bin | Bin 5008 -> 0 bytes lib/PR/f3dex2/F3DEX2_NoN.bin | Bin 5008 -> 0 bytes lib/PR/f3dex2/F3DEX2_NoN_data.bin | Bin 1056 -> 0 bytes lib/PR/f3dex2/F3DEX2_data.bin | Bin 1056 -> 0 bytes lib/PR/f3dex2/F3DLX2_Rej.bin | Bin 4496 -> 0 bytes lib/PR/f3dex2/F3DLX2_Rej_data.bin | Bin 1040 -> 0 bytes lib/PR/f3dex2/F3DZEX.bin | Bin 6336 -> 0 bytes lib/PR/f3dex2/F3DZEX_data.bin | Bin 2048 -> 0 bytes lib/PR/f3dex2/L3DEX2.bin | Bin 4496 -> 0 bytes lib/PR/f3dex2/L3DEX2_data.bin | Bin 1008 -> 0 bytes lib/PR/s2dex/S2DEX.bin | Bin 6128 -> 0 bytes lib/PR/s2dex/S2DEX_data.bin | Bin 960 -> 0 bytes lib/asm/__osDisableInt.s | 18 - lib/asm/__osExceptionPreamble.s | 1123 ----------------------------- lib/asm/__osGetCause.s | 15 - lib/asm/__osGetSR.s | 15 - lib/asm/__osProbeTLB.s | 64 -- lib/asm/__osRestoreInt.s | 19 - lib/asm/__osSetCompare.s | 15 - lib/asm/__osSetFpcCsr.s | 14 - lib/asm/__osSetSR.s | 14 - lib/asm/__os_eu_802ef550.s | 22 - lib/asm/bcopy.s | 232 ------ lib/asm/bzero.s | 53 -- lib/asm/llmuldiv_gcc.s | 100 --- lib/asm/osGetCount.s | 15 - lib/asm/osInvalDCache.s | 59 -- lib/asm/osInvalICache.s | 44 -- lib/asm/osMapTLB.s | 63 -- lib/asm/osMapTLBRdb.s | 36 - lib/asm/osSetIntMask.s | 138 ---- lib/asm/osUnmapTLBAll.s | 32 - lib/asm/osWritebackDCache.s | 39 - lib/asm/osWritebackDCacheAll.s | 24 - lib/asm/parameters.s | 18 - lib/rsp.s | 252 ------- 57 files changed, 2424 deletions(-) delete mode 100644 lib/PR/audio/aspMain.bin delete mode 100644 lib/PR/audio/aspMain_data.bin delete mode 100644 lib/PR/boot/F3D_boot.bin delete mode 100644 lib/PR/boot/F3D_boot_eu.bin delete mode 100644 lib/PR/f3d/new/F3D.bin delete mode 100644 lib/PR/f3d/new/F3D_data.bin delete mode 100644 lib/PR/f3d/new/F3D_data_EU.bin delete mode 100644 lib/PR/f3d/old/F3D.bin delete mode 100644 lib/PR/f3d/old/F3D_data.bin delete mode 100644 lib/PR/f3dex/F3DEX.bin delete mode 100644 lib/PR/f3dex/F3DEX_NoN.bin delete mode 100644 lib/PR/f3dex/F3DEX_NoN_data.bin delete mode 100644 lib/PR/f3dex/F3DEX_data.bin delete mode 100644 lib/PR/f3dex/F3DLX.bin delete mode 100644 lib/PR/f3dex/F3DLX_NoN.bin delete mode 100644 lib/PR/f3dex/F3DLX_NoN_data.bin delete mode 100644 lib/PR/f3dex/F3DLX_Rej.bin delete mode 100644 lib/PR/f3dex/F3DLX_Rej_data.bin delete mode 100644 lib/PR/f3dex/F3DLX_data.bin delete mode 100644 lib/PR/f3dex/L3DEX.bin delete mode 100644 lib/PR/f3dex/L3DEX_data.bin delete mode 100644 lib/PR/f3dex2/F3DEX2.bin delete mode 100644 lib/PR/f3dex2/F3DEX2_NoN.bin delete mode 100644 lib/PR/f3dex2/F3DEX2_NoN_data.bin delete mode 100644 lib/PR/f3dex2/F3DEX2_data.bin delete mode 100644 lib/PR/f3dex2/F3DLX2_Rej.bin delete mode 100644 lib/PR/f3dex2/F3DLX2_Rej_data.bin delete mode 100644 lib/PR/f3dex2/F3DZEX.bin delete mode 100644 lib/PR/f3dex2/F3DZEX_data.bin delete mode 100644 lib/PR/f3dex2/L3DEX2.bin delete mode 100644 lib/PR/f3dex2/L3DEX2_data.bin delete mode 100644 lib/PR/s2dex/S2DEX.bin delete mode 100644 lib/PR/s2dex/S2DEX_data.bin delete mode 100644 lib/asm/__osDisableInt.s delete mode 100644 lib/asm/__osExceptionPreamble.s delete mode 100644 lib/asm/__osGetCause.s delete mode 100644 lib/asm/__osGetSR.s delete mode 100644 lib/asm/__osProbeTLB.s delete mode 100644 lib/asm/__osRestoreInt.s delete mode 100644 lib/asm/__osSetCompare.s delete mode 100644 lib/asm/__osSetFpcCsr.s delete mode 100644 lib/asm/__osSetSR.s delete mode 100644 lib/asm/__os_eu_802ef550.s delete mode 100644 lib/asm/bcopy.s delete mode 100644 lib/asm/bzero.s delete mode 100644 lib/asm/llmuldiv_gcc.s delete mode 100644 lib/asm/osGetCount.s delete mode 100644 lib/asm/osInvalDCache.s delete mode 100644 lib/asm/osInvalICache.s delete mode 100644 lib/asm/osMapTLB.s delete mode 100644 lib/asm/osMapTLBRdb.s delete mode 100644 lib/asm/osSetIntMask.s delete mode 100644 lib/asm/osUnmapTLBAll.s delete mode 100644 lib/asm/osWritebackDCache.s delete mode 100644 lib/asm/osWritebackDCacheAll.s delete mode 100644 lib/asm/parameters.s delete mode 100644 lib/rsp.s diff --git a/lib/PR/audio/aspMain.bin b/lib/PR/audio/aspMain.bin deleted file mode 100644 index 6fe732ddbdf455756911828c6d772381f735eeda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3616 zcma)9eQZKQlpg) zX+on7b_jNgLL6vN&_sZ#;X_-(M@Kd~6);uk{2n9iq^;_-Hl4;k8{uO{O<35g!!Z{tM1`yQjX|~+9H8BdM^j$8+wAfNe{RSZQ2F?>Gek&S+>BxR? zN4DA%k+Wz=?Fo#=+Lwb08n|gr{1sQG?VI$mpb1<~LoQwc$X}=W5Rr0 zm>{QXR@gTBIvhUSHvk|75c7NyL{yK+7~vY&F0n|xD-Hfqku66Xs1l>?;10&X6^Xdg zM=__P=s{zT`awP_ffw66PF;i|2$YJ^dT^@@WVG_p00eVmE3hpe+eEYy@#nM$ATMXh z#|8c(5q(sgvn1zNiuL(e_vPvVehc{EtAhV7^HtvROn_I}n3&d<& zfs~DVCxw-S_sw@M#cw=YpsgKi{HzHxKld zfUGN9Z`2B4>uUSLC5TI()7c`0I;!-No&j20eeV7nw7#7yBql~Wn6;Gw76Af9BJOd- zMr-DLi>d%(IE-h22x_=Fr(FpuH5Y34P;TF$ZkY;ErpRg2?*r2p1hdR1m}No1#CgM; zft6_RLo@D!JwF48ehm~T{ISL{m>W?t8w zBHVm!M~blX)>w-0^8?!y%7LHTl;WcsQ~dl`ir3cl@!*r?{NTF@e(s)8I6{my{FL?-OQR);XZv9(3S~*jAi*gaQM&GMbZ+ct^&K8gFiRt9@XyKPHVY8Ch&6~R><>pX(z$4ZqE zN5}sH8qQM*fm$(Yfl!{itLZKv9zTB<X>Le!6c)W$;L9~G9G7nPWw`pAHIXSyA4s&10SEd$oE{{#Ve*p`0A;ZeC<#p zfBns;_<_!q{6~|GG@pffwsvC~FKkboLY%K)83cD?2bPl{COWVTfG5$8PnGGj(8h+qDGH)|5?=Zo<$wc!OlgtSwC-JqJ+cTcz94Jbv;7xk* zb*6yYFz*61ln%qiR+ev^!g*iDvJBS^&#X(Oip19( zzQ~szPH~tT(dV80qh30+n~&ca=AYde!M0ue&eXT~?J1?=5Xe|>M5jAMQWO912HIeMu?k@=au7x})uGx6qPypjjv z-I~12Z%(Ev@cqwWa)fW`c@5(|>crd9)6d`U!FaD?ysLom+}wOGhVeQqjALP((1<-2 z8pLx5wGdtns<^0wiAs#|HG{*L>t()la0K&JC>PAhL!3}f{7m04V!O=u^^Fimd|ywB zc*5AvIXEcSFBs$WBM%m?8*yRb+RgGo`4cA&2gnQNRY2TOUWAD_x*r$Dd%@wEa(zg@ z(}x^Tp2P#?NnB8##0TYmKPSWiy$gsNoV%X5uuxYP>dHc0<+T3H{rAu8IZgK>y~#>6 z@Du+vHMSkzOmEYEe2d`!7OU`1+&u>PP6D$J%TG|V`!V;AM$>dB^NN3D@J?{vX#Au1 dVl;+V{Jn$5SU483GxEi|`WE@lz7;9fe*nBkQSAT# diff --git a/lib/PR/audio/aspMain_data.bin b/lib/PR/audio/aspMain_data.bin deleted file mode 100644 index 1e74134e94fbb57390d684a0487f6831c7a414c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 704 zcmb7+T`22u7{{Ogf3uBk_V$8VDdgSy2Dz_x~ir z`{e1*^k@Fw|7=uX04IEdA8-N>fGE)UwuL5)@pV3b`XJt<8GXZ|S&XLk`3l7c80JlT zFC=ex%nf)QGA)KUPo7(50fU@kPeaBFuBS}67c;HsXI~9P#rPrODH0T)!}vef2}clvLx%!Lh!;cv&1NxhVqg+*U|@#` wLdT85PKaO@Vf`-2WF6d0DHk9jsO4v diff --git a/lib/PR/boot/F3D_boot_eu.bin b/lib/PR/boot/F3D_boot_eu.bin deleted file mode 100644 index 6eb44776299c793a87e5dba32323874a7c7993ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204 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 diff --git a/lib/PR/f3d/new/F3D_data.bin b/lib/PR/f3d/new/F3D_data.bin deleted file mode 100644 index 194598c9eabd9b47cafc3a23dc825022ef6d0704..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmZQzU|`_)7ia*I0SxT|Al?lodGQPe2EiYU(?PWG1cr3+4E|pq*y{fSr5P9)8JPb6 zcVJ*(VKZi8sQ>@}2LlI#1A{^X1LK)9XBZg&{|Bl7LMY9|fC?F*W`N8AVK5)47R(3J zKo*Quc75Lh96Ltuqyh-iwy3ULF0 z6(A^FBitZd0;FSveS~#{E(o0vS|ZdV6d)`h#3Q~({D6dngpOp2c#HS~fe4`8NC0B@ zdk!9mZ;@mgz;;6f96-*X184x+0m5+50AvAiJzM|>gP;ObeGeGr|1+>KFn~Ob;c--@ z6!C(B0~CV86~a=BiZk=`tQ3s&3_Nrc42*OQjdU%|8G_wC6++ES6x`h+K*~Z~9eu47 zf)yO|Qh*xr^K^i0=ft8S9R&{s=Zw_6bR7k61)tL5l2o8jkb-Z1eo?B9f}cV_etu4B zrH+E5LU2)LUS?Thabg}9*xk$uj2jp)Fn(YXU@~9|U@Bmmz_fws0;2`<2Nnhv0pNfK$0t(;3#)A1V%$(Gz5lV2mk;|bacW1 diff --git a/lib/PR/f3d/new/F3D_data_EU.bin b/lib/PR/f3d/new/F3D_data_EU.bin deleted file mode 100644 index 4e7db003fb7e50d336df06bc63f182a2b5a15093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmZQzU|`_)7ia*I0SxT|Al?lodGQPe2EiYU(?PWG1cr3+4E|pq*y{fSr5P9)8JPb6 zcVJ*(VKZi8sQ>@}2LlI#1A{^X1LK)9XBZg&{|Bl7LMY9|fC?F*W`N8AVK5)47R(3J zKo*Quc75Lh96Ltuqyh-iwy3ULF0 z6(A^FBitZd0;FSveS~#{E(o0vS|ZdV6d)`h#3Q~({D6dngpOp2c#HS~fe4`8NC0B@ zdk!9mZ;@mgz;;6f96-*X184x+0m5+50AvAiJzM|>gP;ObeGeGr|1+>KFn~Ob;c--@ z6!C(B0~CV86~a=BiZk=`tQ3s&3|w>+3`}$l40SEd7=qnB6++ES6x`h+K*~Z~9eu47 zf)yO|Qh*xr^K^i0=ft8S9R&{s=Zw_6bR7k61)tL5l2o8jkb-Z1eo?B9f}cV_etu4B zrH+E5LU2)LUS?Thabg}9*xk$uj2jp)Fn(YXU@~9|U@Bmmz_fws0;2`<2Nnhv0pNfK$0t(;3#)A1V%$(Gz5lV2mk;t5_G)) diff --git a/lib/PR/f3d/old/F3D.bin b/lib/PR/f3d/old/F3D.bin deleted file mode 100644 index 90eafc23edf07689ecb7bb2a25e7d9d4882feab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5128 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 diff --git a/lib/PR/f3d/old/F3D_data.bin b/lib/PR/f3d/old/F3D_data.bin deleted file mode 100644 index 56a28db14cea78f2a8fb3609d69550d4fa48a92c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 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 diff --git a/lib/PR/f3dex/F3DEX_NoN.bin b/lib/PR/f3dex/F3DEX_NoN.bin deleted file mode 100644 index a55a33b0521ca5c82d31bb24e573a75f62fd1409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5168 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 Q-`K|-V)5}lz7D|u0`V!^F8}}l diff --git a/lib/PR/f3dex/F3DEX_NoN_data.bin b/lib/PR/f3dex/F3DEX_NoN_data.bin deleted file mode 100644 index e1570d983a3ff0ee4011b435d93ed10ade6d7350..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHGF>KR76#aKS+ZU-)FFwJw1B%BERTRi#F?lGEDT)AzbW22wT2X3CO{H$WjSd~W z!QdeS17ijT#*PdbGBPl9%!bDZRWkqVC{l_L3xXy8-@pI<_xJt#U-tn3He#W1*YH-L zB{;1qAHdxv?~ImL5GsG;M`p)4eg+^w^E?1xc9TM!=QH3CfTw|s$73LQjuFUnO<|eI z{0wuBk;2Bt(eIKY%WB zmyW<(;~$X597YzT5uwBj$8W$N1D5~0Cbb+GfGPTy!k0t;tM&9*$9wYX+&g<2?jLxM zo4b#?^>*0y4Bf9kXnK3$>EY3!|GMw(^-s^WVZbO(0L9)i3I#xD9)39qx4K!5!`9M^ycM!C OR~=Y&VAX-Y(t)4b`gHyP diff --git a/lib/PR/f3dex/F3DEX_data.bin b/lib/PR/f3dex/F3DEX_data.bin deleted file mode 100644 index 212139c886ac97479dab621dd226b2187f7b9534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHGJ#5oJ6n=L-+ZU-)FSg3L1Ii5y9jYo2hNzPVpcxRdU?ANR(V|wA+EP=gn{T57 zLpB&ZWME*-z|gT{h71`ybm+*2#|j}G&vqLrMTiB#lK1Z2`|U5lRkjENkK)2Y`I5>z5oz_47m9TGsYvgPyaDd#BF(w> z-p#5P-kR6)0+D*Y$K8qBbNAhrTd)3bht)4~U&eAIFIIf{P==z7)u&X}{>B%}Zl`eo zUDPfEL4J*YKpJc0G9`@`N-_=n#`t5x?0=V}W`F_YP5;vPZ0djYp1%my=Idj1^eWok zQBN9=9=FvE-CuvuP+QUA?q09^rmMEPhevOtUZkGw9rSh%wxe~t`GO`xG9eiiv`#}B z(>@*232CyJY1U^QvIa5fEc8jn21Kv{8?nstt-#u~`qrs+X>+@7w{2~IwkP(Lqnwr# zJ0G1h=PMVy$vgan5BYfoDyx;Sa*RX5fKi+Pir6v=g@I=N@XJZKg=RSpE6rQsxjRQ- Lj=&s&zmC99>`-z> diff --git a/lib/PR/f3dex/F3DLX.bin b/lib/PR/f3dex/F3DLX.bin deleted file mode 100644 index e94f2de612a082ed0280c23f4e66144a51bb4a6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5168 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 B@_+yU diff --git a/lib/PR/f3dex/F3DLX_NoN.bin b/lib/PR/f3dex/F3DLX_NoN.bin deleted file mode 100644 index 6c9814ac7966a5f64467bae9b59c605e50da4c40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5168 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 diff --git a/lib/PR/f3dex/F3DLX_NoN_data.bin b/lib/PR/f3dex/F3DLX_NoN_data.bin deleted file mode 100644 index 722968dad9ef752ce97821cd08ede5a0d154ba4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHGA#B@F5WWBV{rw|V>W|&YDVXv>K)@7r3yFpdrnR7oq75u%j+RcT*42@kN(Ght z*$TrJU{F|45KvH9SP&2}Fj!c&fPre{?|zbIN~dXL(@5_A{d;#l-}z2H0DzT5YP>ak zlxRso^FajQ70D;7{VRxrXyyBeCk7t_5TM3{0F0L@B*xr z$ux(}V`Xe(?ARV_L{p6@*h|ct$Iq8Bj^e>W_5>}zC(~@|Z_4x$qF~kU<6V%c<-GQ8 zv!DHfANm!U`qBsQ+S~J*Ug#CG-@LQzd2kV2=47t076r#aPu8*ejIg!__$rns-Ol`A z-Qm3%{)G3gf1)*JwK5}(2ql?0egpm(F#p~S$s1q*w&`CQpAY@7)~nYwwejvq9lnj5 zJL+Zm#a6vkjjPJi)6%oD+KvxeyPd}ShT3i%9Day9v8wLwcXsxhaS6YCNs~Sqk`a}3 zoz`fZc4?muNrknUW?dGMC(tI*QkRU_DUs}yU9*vsb3&)(be&7*h6}#V>s<3QKIC_< zayQ+!+jFnnTOmb7MB+sB#g`0ZikVvG2$zHbqqqSSXUiyz0YdxZPd4GfG$-q@rXRQ$ P=3)Yi2`nb?*C+4;_&sx> diff --git a/lib/PR/f3dex/F3DLX_Rej.bin b/lib/PR/f3dex/F3DLX_Rej.bin deleted file mode 100644 index fad03ca502b30b9106f51112ae62f52fc752fe07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5072 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 Xu7j_`zVfbHdiW5V(vNX>et7;5s64w* diff --git a/lib/PR/f3dex/F3DLX_Rej_data.bin b/lib/PR/f3dex/F3DLX_Rej_data.bin deleted file mode 100644 index fd66da740fe98b8eb12c6a8bea29e0992a36a74a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHGze~eF6n=LNQl!vpA`(RD{Q**{br5mLP}D)B)WLSM*h;I|6xu?!WDr~(1eg2? z4&CgS!LdUJ2S@(^!HlB9`7ZrsD4fe3*L^Z`B+B(eYQ=WwLo?WZFfu+M=RV+ynI<__~? zjM!uTdnSv>H8L9+E^CzdhWsd)eD0CN1t{1(roS{kDgDzZyPx6P$1UDGGK(d?l}hjC z64}xTm$s5vP4T>0FIO6c(*n;I>diB=Ve-97wNa`T%>;gVh?6$y5sxyOq#0VHm$XfL pWL;qjSCR^lWvG$EP?C6xLFDf+W&P_ql?=jQ0>K1=3H-wed;sC-We)%V diff --git a/lib/PR/f3dex/F3DLX_data.bin b/lib/PR/f3dex/F3DLX_data.bin deleted file mode 100644 index 5a2ea93beafb6f1eeacf6fb8b79ce6945406c9b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHGD{LD<5S`uZ-L0iaS>Gzz1XNy7U{FPAO{}5?RbmiTRtxG#1-9x`iQ48Y#gWWz zSqcpz)!;y2K!9OkV1R)^L1AE64+KOd*I7Gu3Fi6o!Mib$3_B3ZeSeUT_862}D_ zUgy8ahtkNhNTiSuUWV_(W@y4<{w6%jpQ{tqQ|T&OGwQYKh#GdE685$L-}vHq+G!kI z*i2mW)0~9}&v+rGzLIw=L4gJgDv#I~pd-1ZWx88R2(VM8b zt2ax}wrhGqkJq1+^iFiRx8H8OYv`TE;n9bv9qH%$2kqU1X0(o9zFf*fegHW%a_0a5 diff --git a/lib/PR/f3dex/L3DEX.bin b/lib/PR/f3dex/L3DEX.bin deleted file mode 100644 index 7b84fb77ce5c3e07b36ea435210fd5284f41701e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4080 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 diff --git a/lib/PR/f3dex/L3DEX_data.bin b/lib/PR/f3dex/L3DEX_data.bin deleted file mode 100644 index 1b9ca5c6bd46cd2addcee7194339bb6106ae84ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmeHFJxIeq6n=MJk}DKU$ORP?Z*&k*yA*NApy(h{6j8Spe^5jdumuMpH##_EbZ~HV z?C9X&;NaN7!O_9N&5lKc^De1ksp2Gx^u4?H`{m`m#{mFzN48K>KwvBHbLxJsn~_X% z2(Xks05NkIA}Jd{!3HkCT2gr=B_PdBjiHrMvxY)ybRt1v6F<>u4Gl}Okz5{_$SNDF z13u^j;2k-!OT2z3?wNJs-fQnn$y+DZJb275-AUH)n3r`KdtkThl=&>rnET@1utQhq z3Muv3eN)cdo2PZ!!xPP>(|$;a=D&5wPuuvA{TWlJviiQ0P?oyUd*BP>TR`h~_h?W8 zQPZn%+u*IxU-cFi3w&ntfLGRn^$k9ko0?wXZ!|VCp5v>*{?>N6v{T}%rTxloP!9O~ z_Fj2oZ#@`Mop%*c71dB3+jtZgaEN1E#Wj>C1yUp-@zF4ZsMr;vIuXbwf}E2YX&Bs? zHA3UWxH2A1+svCq^T@24cNSPfR>3;3&a4}&PJ5|Ow`fc+=zWG}Ml&nzt4f~#UtVx~ P%biGP1Dy^0(+#`=w}EE| diff --git a/lib/PR/f3dex2/F3DEX2.bin b/lib/PR/f3dex2/F3DEX2.bin deleted file mode 100644 index 7137569432d8ffe41cb8f971c7ef9dcdf5a5bea9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5008 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 diff --git a/lib/PR/f3dex2/F3DEX2_NoN.bin b/lib/PR/f3dex2/F3DEX2_NoN.bin deleted file mode 100644 index e9a3b4cb2c40561e906bf6f5a5a4acc775f812aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5008 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 diff --git a/lib/PR/f3dex2/F3DEX2_data.bin b/lib/PR/f3dex2/F3DEX2_data.bin deleted file mode 100644 index 70871391f5bcef78fa6a562f48bdfc84e48aecbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1056 zcmd^7J4gdT5S=~u?lvm8djw(;$dnc$r#1;#Y~d$Gkf2TM3~EU5bAl1lp zECekqEK*tuHb<(I7K$lT1lPSg1+lWQ5odUBe(W+cy8wS%Uc&Z^Bb`?^uD(yA6y(3> zek)#EFXBq2fyZ0k_6{!3FD{iZmP)PS;oOXyMcnX?say>AgBp!#v1B8&!BYleClP>XLKzas}0J@^Z8=@uJk#_hL zFNlEmc~)TNl7n~_ZSD#w7Wg!uc9I{;olpxJQUjtW&V6NcLQN(IX+JH~)zn?;CUqm) z6ltCw(lgqjPbN3B=B9aKUYUUf)|6GW8rHdWZ}sg-TiR8-W#8I8#+b`W%x4$ufejL< jRQ#+yxUQ5xe%Wv(sJ9Xu%~B&Iabnm`pub|t$T-0}0o7`5 diff --git a/lib/PR/f3dex2/F3DLX2_Rej.bin b/lib/PR/f3dex2/F3DLX2_Rej.bin deleted file mode 100644 index 559bbb6153314b69757c1f2bbbd8b4f915bdbc26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4496 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 diff --git a/lib/PR/f3dex2/F3DZEX.bin b/lib/PR/f3dex2/F3DZEX.bin deleted file mode 100644 index 86c0af4817aee352673acdd095b54fe247b6d59b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6336 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 diff --git a/lib/PR/f3dex2/F3DZEX_data.bin b/lib/PR/f3dex2/F3DZEX_data.bin deleted file mode 100644 index 65678669edbaaa2e39a363c5d396b78efae6e980..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 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 o{_DXfSWLc4GDEtR1sC4)JW?*y%Wi0qbBYHVl- za%g;`W6&Z_jt)g{bdX;6y_ZnVE%kkz@0{-(?&TgXz~9E3`~19Mz2jA9c@xKh>~in7 z{Lyiq9n`w4bE;RWEVrB4FESssMonisNj1e-Nx!T&+U2t{E0r%h=XzUb+v#+g9X49+ zYOA6rg8;~TQGlyk1$^&(_}P1joxq9-ZfGz;wlD<)jgbK}Gzl;?f-yBomzuQi(IRn@ zqa$LI6lGiY1n4X66P0Rok0eMU6#HT%;_r7a9W;ly4@HMvZ a6hKuqjsHCW<6HWPtH#3@2?WbEE~N)B16q?s( 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 b??~7RrV|@3HDV(xXFi!X;!zA}s9nDS4;Esv diff --git a/lib/asm/__osDisableInt.s b/lib/asm/__osDisableInt.s deleted file mode 100644 index 4c759b4c..00000000 --- a/lib/asm/__osDisableInt.s +++ /dev/null @@ -1,18 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - - -glabel __osDisableInt - mfc0 $t0, $12 - and $t1, $t0, -2 - mtc0 $t1, $12 - andi $v0, $t0, 1 - nop - jr $ra - nop - diff --git a/lib/asm/__osExceptionPreamble.s b/lib/asm/__osExceptionPreamble.s deleted file mode 100644 index c98608b0..00000000 --- a/lib/asm/__osExceptionPreamble.s +++ /dev/null @@ -1,1123 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - -.ifdef VERSION_SH -.set VERSION_EU, 1 # HACK, someone fix this file, its poorly diff'd! -.endif - -.section .text, "ax" - -.ifdef AVOID_UB -.set D_80334890, D_80334890_fix -.endif - -glabel __osExceptionPreamble - lui $k0, %hi(__osException) # $k0, 0x8032 - addiu $k0, %lo(__osException) # addiu $k0, $k0, 0x66d0 - jr $k0 - nop - - -glabel __osException -.ifndef VERSION_EU - lui $k0, %hi(gInterruptedThread) # $k0, 0x8036 - addiu $k0, %lo(gInterruptedThread) # addiu $k0, $k0, 0x5f40 - sd $at, 0x20($k0) - mfc0 $k1, $12 - sw $k1, 0x118($k0) - li $at, -4 - and $k1, $k1, $at - mtc0 $k1, $12 - sd $t0, 0x58($k0) - sd $t1, 0x60($k0) - sd $t2, 0x68($k0) - sw $zero, 0x18($k0) - mfc0 $t0, $13 - - andi $t1, $t0, 0x7c - li $t2, 0 - bne $t1, $t2, .L80326750 - nop - and $t1, $k1, $t0 - andi $t2, $t1, 0x4000 - beqz $t2, .L80326734 - nop - li $t1, 1 - lui $at, %hi(D_80334934) # $at, 0x8033 - b .L80326794 - sw $t1, %lo(D_80334934)($at) -.L80326734: - andi $t2, $t1, 0x2000 - beqz $t2, .L80326750 - nop - li $t1, 1 - lui $at, %hi(D_80334938) # $at, 0x8033 - b .L80326794 - sw $t1, %lo(D_80334938)($at) -.L80326750: - lui $at, %hi(D_80334934) # $at, 0x8033 - sw $zero, %lo(D_80334934)($at) - lui $at, %hi(D_80334938) # $at, 0x8033 - - move $t0, $k0 - sw $zero, %lo(D_80334938)($at) - lui $k0, %hi(D_80334890 + 0x10) # $k0, 0x8033 - lw $k0, %lo(D_80334890 + 0x10)($k0) - ld $t1, 0x20($t0) - sd $t1, 0x20($k0) - ld $t1, 0x118($t0) - sd $t1, 0x118($k0) - ld $t1, 0x58($t0) - sd $t1, 0x58($k0) - ld $t1, 0x60($t0) - sd $t1, 0x60($k0) - ld $t1, 0x68($t0) - sd $t1, 0x68($k0) -.L80326794: - mflo $t0 - sd $t0, 0x108($k0) - mfhi $t0 - sd $v0, 0x28($k0) - sd $v1, 0x30($k0) - sd $a0, 0x38($k0) - sd $a1, 0x40($k0) - sd $a2, 0x48($k0) - sd $a3, 0x50($k0) - sd $t3, 0x70($k0) - sd $t4, 0x78($k0) - sd $t5, 0x80($k0) - sd $t6, 0x88($k0) - sd $t7, 0x90($k0) - sd $s0, 0x98($k0) - sd $s1, 0xa0($k0) - sd $s2, 0xa8($k0) - sd $s3, 0xb0($k0) - sd $s4, 0xb8($k0) - sd $s5, 0xc0($k0) - sd $s6, 0xc8($k0) - sd $s7, 0xd0($k0) - sd $t8, 0xd8($k0) - sd $t9, 0xe0($k0) - sd $gp, 0xe8($k0) - sd $sp, 0xf0($k0) - sd $fp, 0xf8($k0) - sd $ra, 0x100($k0) -.ifndef VERSION_EU - sd $t0, 0x110($k0) -.else - beqz $t1, .L802F3A18 - sd $t0, 0x110($k0) - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t0, ($t0) - li $at, -1 - xor $t0, $t0, $at - lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff - andi $t0, $t0, 0xff00 - ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff - or $t1, $t1, $t0 - and $k1, $k1, $at - or $k1, $k1, $t1 - sw $k1, 0x118($k0) -.L802F3A18: - lui $t1, %hi(MI_INTR_MASK_REG) # $t1, 0xa430 - lw $t1, %lo(MI_INTR_MASK_REG)($t1) - beqz $t1, .L802F3A50 - nop - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t0, ($t0) - lw $t4, 0x128($k0) - li $at, -1 - srl $t0, $t0, 0x10 - xor $t0, $t0, $at - andi $t0, $t0, 0x3f - and $t0, $t0, $t4 - or $t1, $t1, $t0 -.L802F3A50: - sw $t1, 0x128($k0) -.endif - - - mfc0 $t0, $14 - sw $t0, 0x11c($k0) - lw $t0, 0x18($k0) - beqz $t0, .L80326868 - nop - cfc1 $t0, $31 - nop - sw $t0, 0x12c($k0) - sdc1 $f0, 0x130($k0) - sdc1 $f2, 0x138($k0) - sdc1 $f4, 0x140($k0) - sdc1 $f6, 0x148($k0) - sdc1 $f8, 0x150($k0) - sdc1 $f10, 0x158($k0) - sdc1 $f12, 0x160($k0) - sdc1 $f14, 0x168($k0) - sdc1 $f16, 0x170($k0) - sdc1 $f18, 0x178($k0) - sdc1 $f20, 0x180($k0) - sdc1 $f22, 0x188($k0) - sdc1 $f24, 0x190($k0) - sdc1 $f26, 0x198($k0) - sdc1 $f28, 0x1a0($k0) - sdc1 $f30, 0x1a8($k0) -.L80326868: - mfc0 $t0, $13 - sw $t0, 0x120($k0) - lui $t1, %hi(MI_INTR_MASK_REG) # $t1, 0xa430 - lw $t1, %lo(MI_INTR_MASK_REG)($t1) - sw $t1, 0x128($k0) - li $t1, 2 - sh $t1, 0x10($k0) - lui $t1, %hi(D_80334934) # $t1, 0x8033 - lw $t1, %lo(D_80334934)($t1) - beqz $t1, .L803268B4 - nop - lui $t2, %hi(D_C0000008) # $t2, 0xc000 - sw $zero, %lo(D_C0000008)($t2) - lui $a0, %hi(D_C0000000) - addiu $t2, %lo(D_C0000008) # addiu $t2, $t2, 8 - jal kdebugserver - lw $a0, %lo(D_C0000000)($a0) - b .L80326E08 - nop -.L803268B4: - lui $t1, %hi(D_80334938) # $t1, 0x8033 - lw $t1, %lo(D_80334938)($t1) - beqz $t1, .L80326900 - nop - lui $t2, %hi(D_C000000C) # $t2, 0xc000 - sw $zero, %lo(D_C000000C)($t2) - lui $t1, %hi(D_80334A40) # $t1, 0x8033 - lw $t1, %lo(D_80334A40)($t1) - addiu $t2, %lo(D_C000000C) # addiu $t2, $t2, 0xc - beqz $t1, .L803268E8 - nop - jal send_mesg - li $a0, 120 -.L803268E8: - lui $t1, %hi(D_80334A44) # $t1, 0x8033 - lw $t1, %lo(D_80334A44)($t1) - lui $at, %hi(D_80334A44) # $at, 0x8033 - addi $t1, $t1, 1 - b .L80326E08 - sw $t1, %lo(D_80334A44)($at) -.L80326900: - andi $t1, $t0, 0x7c - li $t2, 36 - beq $t1, $t2, .L80326B84 - nop - li $t2, 44 - beq $t1, $t2, .L80326CCC - nop - li $t2, 0 - bne $t1, $t2, .L80326BE8 - nop - and $s0, $k1, $t0 -.L8032692C: - andi $t1, $s0, 0xff00 - srl $t2, $t1, 0xc - bnez $t2, .L80326944 - nop - srl $t2, $t1, 8 - addi $t2, $t2, 0x10 -.L80326944: - lui $at, %hi(D_80338610) - addu $at, $at, $t2 - lbu $t2, %lo(D_80338610)($at) - lui $at, %hi(jtbl_80338630) - addu $at, $at, $t2 - lw $t2, %lo(jtbl_80338630)($at) - jr $t2 - nop -glabel L80326964 - mfc0 $t1, $11 - mtc0 $t1, $11 - jal send_mesg - li $a0, 24 - lui $at, (0xFFFF7FFF >> 16) # lui $at, 0xffff - ori $at, (0xFFFF7FFF & 0xFFFF) # ori $at, $at, 0x7fff - b .L8032692C - and $s0, $s0, $at -glabel L80326984 - li $t2, 4 - lui $at, %hi(D_80334920) - addu $at, $at, $t2 - lw $t2, %lo(D_80334920)($at) - beqz $t2, .L803269A4 - nop - jalr $t2 - nop -.L803269A4: - jal send_mesg - li $a0, 16 - li $at, -2049 - b .L8032692C - and $s0, $s0, $at -glabel L803269B8 - lui $s1, %hi(MI_INTR_REG) # $s1, 0xa430 - lw $s1, %lo(MI_INTR_REG)($s1) - andi $s1, $s1, 0x3f - andi $t1, $s1, 1 - beqz $t1, .L80326A18 - nop - lui $t4, %hi(SP_STATUS_REG) # $t4, 0xa404 - lw $t4, %lo(SP_STATUS_REG)($t4) - li $t1, 8 - lui $at, %hi(SP_STATUS_REG) # $at, 0xa404 - andi $t4, $t4, 0x300 - andi $s1, $s1, 0x3e - beqz $t4, .L80326A08 - sw $t1, %lo(SP_STATUS_REG)($at) - jal send_mesg - li $a0, 32 - beqz $s1, .L80326ADC - nop - b .L80326A18 - nop -.L80326A08: - jal send_mesg - li $a0, 88 - beqz $s1, .L80326ADC - nop -.L80326A18: - andi $t1, $s1, 8 - beqz $t1, .L80326A3C - lui $at, %hi(VI_CURRENT_REG) # $at, 0xa440 - andi $s1, $s1, 0x37 - sw $zero, %lo(VI_CURRENT_REG)($at) - jal send_mesg - li $a0, 56 - beqz $s1, .L80326ADC - nop -.L80326A3C: - andi $t1, $s1, 4 - beqz $t1, .L80326A68 - nop - li $t1, 1 - lui $at, %hi(AI_STATUS_REG) # $at, 0xa450 - andi $s1, $s1, 0x3b - sw $t1, %lo(AI_STATUS_REG)($at) - jal send_mesg - li $a0, 48 - beqz $s1, .L80326ADC - nop -.L80326A68: - andi $t1, $s1, 2 - beqz $t1, .L80326A8C - lui $at, %hi(SI_STATUS_REG) # $at, 0xa480 - andi $s1, $s1, 0x3d - sw $zero, %lo(SI_STATUS_REG)($at) - jal send_mesg - li $a0, 40 - beqz $s1, .L80326ADC - nop -.L80326A8C: - andi $t1, $s1, 0x10 - beqz $t1, .L80326AB8 - nop - li $t1, 2 - lui $at, %hi(PI_STATUS_REG) # $at, 0xa460 - andi $s1, $s1, 0x2f - sw $t1, %lo(PI_STATUS_REG)($at) - jal send_mesg - li $a0, 64 - beqz $s1, .L80326ADC - nop -.L80326AB8: - andi $t1, $s1, 0x20 - beqz $t1, .L80326ADC - nop - li $t1, 2048 - lui $at, %hi(MI_MODE_REG) - andi $s1, $s1, 0x1f - sw $t1, %lo(MI_MODE_REG)($at) - jal send_mesg - li $a0, 72 -.L80326ADC: - li $at, -1025 - b .L8032692C - and $s0, $s0, $at -glabel L80326AE8 - lw $k1, 0x118($k0) - li $at, -4097 - lui $t1, %hi(D_80334808) # $t1, 0x8033 - and $k1, $k1, $at - sw $k1, 0x118($k0) - addiu $t1, %lo(D_80334808) # addiu $t1, $t1, 0x4808 - lw $t2, ($t1) - beqz $t2, .L80326B14 - li $at, -4097 - b .L80326B9C - and $s0, $s0, $at -.L80326B14: - li $t2, 1 - sw $t2, ($t1) - jal send_mesg - li $a0, 112 - lui $t2, %hi(D_80334890 + 0x8) # $t2, 0x8033 - lw $t2, %lo(D_80334890 + 0x8)($t2) - li $at, -4097 - and $s0, $s0, $at - lw $k1, 0x118($t2) - and $k1, $k1, $at - b .L80326B9C - sw $k1, 0x118($t2) -glabel L80326B44 - li $at, -513 - and $t0, $t0, $at - mtc0 $t0, $13 - jal send_mesg - li $a0, 8 - li $at, -513 - b .L8032692C - and $s0, $s0, $at -glabel L80326B64 - li $at, -257 - and $t0, $t0, $at - mtc0 $t0, $13 - jal send_mesg - li $a0, 0 - li $at, -257 - b .L8032692C - and $s0, $s0, $at -.L80326B84: - li $t1, 1 - sh $t1, 0x12($k0) - jal send_mesg - li $a0, 80 - b .L80326B9C - nop -.L80326B9C: -glabel L80326B9C - lui $t2, %hi(D_80334890 + 0x8) # $t2, 0x8033 - lw $t2, %lo(D_80334890 + 0x8)($t2) - lw $t1, 4($k0) - lw $t3, 4($t2) - slt $at, $t1, $t3 - beqz $at, .L80326BD0 - nop - lui $a0, %hi(D_80334890 + 0x8) # $a0, 0x8033 - move $a1, $k0 - jal __osEnqueueThread - addiu $a0, %lo(D_80334890 + 0x8) # addiu $a0, $a0, 0x4898 - j __osDispatchThread - nop - -.L80326BD0: - lui $t1, %hi(D_80334890 + 0x8) # $t1, 0x8033 - addiu $t1, %lo(D_80334890 + 0x8) # addiu $t1, $t1, 0x4898 - lw $t2, ($t1) - sw $t2, ($k0) - j __osDispatchThread - sw $k0, ($t1) - -.L80326BE8: -glabel L80326BE8 - lui $at, %hi(D_80334890 + 0x14) # $at, 0x8033 - sw $k0, %lo(D_80334890 + 0x14)($at) - li $t1, 1 - sh $t1, 0x10($k0) - li $t1, 2 - sh $t1, 0x12($k0) - mfc0 $t2, $8 - sw $t2, 0x124($k0) - jal send_mesg - li $a0, 96 - j __osDispatchThread - nop -.else - lui $k0, %hi(gInterruptedThread) # $k0, 0x8033 - addiu $k0, %lo(gInterruptedThread) # addiu $k0, $k0, 0x6ce0 - sd $at, 0x20($k0) - mfc0 $k1, $12 - sw $k1, 0x118($k0) - li $at, -4 - and $k1, $k1, $at - mtc0 $k1, $12 - sd $t0, 0x58($k0) - sd $t1, 0x60($k0) - sd $t2, 0x68($k0) - sw $zero, 0x18($k0) - mfc0 $t0, $13 - move $t0, $k0 - lui $k0, %hi(D_80334890 + 0x10) # $k0, 0x8030 - lw $k0, %lo(D_80334890 + 0x10)($k0) - ld $t1, 0x20($t0) - sd $t1, 0x20($k0) - ld $t1, 0x118($t0) - sd $t1, 0x118($k0) - ld $t1, 0x58($t0) - sd $t1, 0x58($k0) - ld $t1, 0x60($t0) - sd $t1, 0x60($k0) - ld $t1, 0x68($t0) - sd $t1, 0x68($k0) - lw $k1, 0x118($k0) - mflo $t0 - sd $t0, 0x108($k0) - mfhi $t0 - andi $t1, $k1, 0xff00 - sd $v0, 0x28($k0) - sd $v1, 0x30($k0) - sd $a0, 0x38($k0) - sd $a1, 0x40($k0) - sd $a2, 0x48($k0) - sd $a3, 0x50($k0) - sd $t3, 0x70($k0) - sd $t4, 0x78($k0) - sd $t5, 0x80($k0) - sd $t6, 0x88($k0) - sd $t7, 0x90($k0) - sd $s0, 0x98($k0) - sd $s1, 0xa0($k0) - sd $s2, 0xa8($k0) - sd $s3, 0xb0($k0) - sd $s4, 0xb8($k0) - sd $s5, 0xc0($k0) - sd $s6, 0xc8($k0) - sd $s7, 0xd0($k0) - sd $t8, 0xd8($k0) - sd $t9, 0xe0($k0) - sd $gp, 0xe8($k0) - sd $sp, 0xf0($k0) - sd $fp, 0xf8($k0) - sd $ra, 0x100($k0) - beqz $t1, .L802F3A18 - sd $t0, 0x110($k0) - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t0, ($t0) - li $at, -1 - xor $t0, $t0, $at - lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff - andi $t0, $t0, 0xff00 - ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff - or $t1, $t1, $t0 - and $k1, $k1, $at - or $k1, $k1, $t1 - sw $k1, 0x118($k0) -.L802F3A18: - lui $t1, %hi(MI_INTR_MASK_REG) # $t1, 0xa430 - lw $t1, %lo(MI_INTR_MASK_REG)($t1) - beqz $t1, .L802F3A50 - nop - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t0, ($t0) - lw $t4, 0x128($k0) - li $at, -1 - srl $t0, $t0, 0x10 - xor $t0, $t0, $at - andi $t0, $t0, 0x3f - and $t0, $t0, $t4 - or $t1, $t1, $t0 -.L802F3A50: - sw $t1, 0x128($k0) - mfc0 $t0, $14 - sw $t0, 0x11c($k0) - lw $t0, 0x18($k0) - beqz $t0, .L802F3AB4 - nop - cfc1 $t0, $31 - nop - sw $t0, 0x12c($k0) - sdc1 $f0, 0x130($k0) - sdc1 $f2, 0x138($k0) - sdc1 $f4, 0x140($k0) - sdc1 $f6, 0x148($k0) - sdc1 $f8, 0x150($k0) - sdc1 $f10, 0x158($k0) - sdc1 $f12, 0x160($k0) - sdc1 $f14, 0x168($k0) - sdc1 $f16, 0x170($k0) - sdc1 $f18, 0x178($k0) - sdc1 $f20, 0x180($k0) - sdc1 $f22, 0x188($k0) - sdc1 $f24, 0x190($k0) - sdc1 $f26, 0x198($k0) - sdc1 $f28, 0x1a0($k0) - sdc1 $f30, 0x1a8($k0) -.L802F3AB4: - mfc0 $t0, $13 - sw $t0, 0x120($k0) - li $t1, 2 - sh $t1, 0x10($k0) - andi $t1, $t0, 0x7c - li $t2, 36 - beq $t1, $t2, .L802F3D90 - nop - li $t2, 44 - beq $t1, $t2, .L80326CCC - nop - li $t2, 0 - bne $t1, $t2, .L80326BE8 - nop - and $s0, $k1, $t0 -.L802F3AF0: - andi $t1, $s0, 0xff00 - srl $t2, $t1, 0xc - bnez $t2, .L802F3B08 - nop - srl $t2, $t1, 8 - addi $t2, $t2, 0x10 -.L802F3B08: - lui $at, %hi(D_80338610) - addu $at, $at, $t2 - lbu $t2, %lo(D_80338610)($at) - lui $at, %hi(jtbl_80338630) - addu $at, $at, $t2 - lw $t2, %lo(jtbl_80338630)($at) - jr $t2 - nop - li $at, -8193 - b .L802F3AF0 - and $s0, $s0, $at - li $at, -16385 - b .L802F3AF0 - and $s0, $s0, $at -glabel L80326964 #probably not right... - mfc0 $t1, $11 - mtc0 $t1, $11 - jal send_mesg - li $a0, 24 - lui $at, (0xFFFF7FFF >> 16) # lui $at, 0xffff - ori $at, (0xFFFF7FFF & 0xFFFF) # ori $at, $at, 0x7fff - b .L802F3AF0 - and $s0, $s0, $at -glabel L80326984 #possibly wrong - li $at, -2049 - and $s0, $s0, $at - li $t2, 4 - lui $at, %hi(D_80334920) - addu $at, $at, $t2 - lw $t2, %lo(D_80334920)($at) - lui $sp, %hi(D_80365E40) # $sp, 0x8033 #.bss stack for D_802F4380 - addiu $sp, %lo(D_80365E40) # addiu $sp, $sp, 0x5c20 - li $a0, 16 - beqz $t2, .L802F3BA4 - addiu $sp, $sp, 0xff0 - jalr $t2 - nop - beqz $v0, .L802F3BA4 - nop - b .L802F3DA8 - nop -.L802F3BA4: - jal send_mesg - nop - b .L802F3AF0 - nop -glabel L803269B8 - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t0, ($t0) - lui $s1, %hi(MI_INTR_REG) # $s1, 0xa430 - lw $s1, %lo(MI_INTR_REG)($s1) - srl $t0, $t0, 0x10 - and $s1, $s1, $t0 - andi $t1, $s1, 1 - beqz $t1, .L802F3C24 - nop - lui $t4, %hi(SP_STATUS_REG) # $t4, 0xa404 - lw $t4, %lo(SP_STATUS_REG)($t4) - li $t1, 8 - lui $at, %hi(SP_STATUS_REG) # $at, 0xa404 - andi $t4, $t4, 0x300 - andi $s1, $s1, 0x3e - beqz $t4, .L802F3C14 - sw $t1, %lo(SP_STATUS_REG)($at) - jal send_mesg - li $a0, 32 - beqz $s1, .L802F3CE8 - nop - b .L802F3C24 - nop -.L802F3C14: - jal send_mesg - li $a0, 88 - beqz $s1, .L802F3CE8 - nop -.L802F3C24: - andi $t1, $s1, 8 - beqz $t1, .L802F3C48 - lui $at, %hi(VI_CURRENT_REG) # $at, 0xa440 - andi $s1, $s1, 0x37 - sw $zero, %lo(VI_CURRENT_REG)($at) - jal send_mesg - li $a0, 56 - beqz $s1, .L802F3CE8 - nop -.L802F3C48: - andi $t1, $s1, 4 - beqz $t1, .L802F3C74 - nop - li $t1, 1 - lui $at, %hi(AI_STATUS_REG) # $at, 0xa450 - andi $s1, $s1, 0x3b - sw $t1, %lo(AI_STATUS_REG)($at) - jal send_mesg - li $a0, 48 - beqz $s1, .L802F3CE8 - nop -.L802F3C74: - andi $t1, $s1, 2 - beqz $t1, .L802F3C98 - lui $at, %hi(SI_STATUS_REG) # $at, 0xa480 - andi $s1, $s1, 0x3d - sw $zero, %lo(SI_STATUS_REG)($at) - jal send_mesg - li $a0, 40 - beqz $s1, .L802F3CE8 - nop -.L802F3C98: - andi $t1, $s1, 0x10 - beqz $t1, .L802F3CC4 - nop - li $t1, 2 - lui $at, %hi(PI_STATUS_REG) # $at, 0xa460 - andi $s1, $s1, 0x2f - sw $t1, %lo(PI_STATUS_REG)($at) - jal send_mesg - li $a0, 64 - beqz $s1, .L802F3CE8 - nop -.L802F3CC4: - andi $t1, $s1, 0x20 - beqz $t1, .L802F3CE8 - nop - li $t1, 2048 - lui $at, 0xa430 - andi $s1, $s1, 0x1f - sw $t1, ($at) - jal send_mesg - li $a0, 72 -.L802F3CE8: - li $at, -1025 - b .L802F3AF0 - and $s0, $s0, $at -glabel L80326AE8 - lw $k1, 0x118($k0) - li $at, -4097 - lui $t1, %hi(D_80334808) # $t1, 0x8030 - and $k1, $k1, $at - sw $k1, 0x118($k0) - addiu $t1, %lo(D_80334808) # addiu $t1, $t1, 0x2088 - lw $t2, ($t1) - beqz $t2, .L802F3D20 - li $at, -4097 - b .L802F3DA8 - and $s0, $s0, $at -.L802F3D20: - li $t2, 1 - sw $t2, ($t1) - jal send_mesg - li $a0, 112 - lui $t2, %hi(D_80334890 + 0x8) # $t2, 0x8030 - lw $t2, %lo(D_80334890 + 0x8)($t2) - li $at, -4097 - and $s0, $s0, $at - lw $k1, 0x118($t2) - and $k1, $k1, $at - b .L802F3DA8 - sw $k1, 0x118($t2) -glabel L80326B44 - li $at, -513 - and $t0, $t0, $at - mtc0 $t0, $13 - jal send_mesg - li $a0, 8 - li $at, -513 - b .L802F3AF0 - and $s0, $s0, $at -glabel L80326B64 - li $at, -257 - and $t0, $t0, $at - mtc0 $t0, $13 - jal send_mesg - li $a0, 0 - li $at, -257 - b .L802F3AF0 - and $s0, $s0, $at -.L802F3D90: - li $t1, 1 - sh $t1, 0x12($k0) - jal send_mesg - li $a0, 80 - b .L802F3DA8 - nop -.L802F3DA8: -glabel L80326B9C - lui $t2, %hi(D_80334890 + 0x8) # $t2, 0x8030 - lw $t2, %lo(D_80334890 + 0x8)($t2) - lw $t1, 4($k0) - lw $t3, 4($t2) - slt $at, $t1, $t3 - beqz $at, .L80326BD0 - nop - lui $a0, %hi(D_80334890 + 0x8) # $a0, 0x8030 - move $a1, $k0 - jal __osEnqueueThread - addiu $a0, %lo(D_80334890 + 0x8) # addiu $a0, $a0, 0x2ef8 - j __osDispatchThread - nop - -.L80326BD0: - lui $t1, %hi(D_80334890 + 0x8) # $t1, 0x8030 - addiu $t1, %lo(D_80334890 + 0x8) # addiu $t1, $t1, 0x2ef8 - lw $t2, ($t1) - sw $t2, ($k0) - j __osDispatchThread - sw $k0, ($t1) - -.L80326BE8: -glabel L80326BE8 - lui $at, %hi(D_80334890 + 0x14) # $at, 0x8030 - sw $k0, %lo(D_80334890 + 0x14)($at) - li $t1, 1 - sh $t1, 0x10($k0) - li $t1, 2 - sh $t1, 0x12($k0) - mfc0 $t2, $8 - sw $t2, 0x124($k0) - jal send_mesg - li $a0, 96 - j __osDispatchThread - nop -.endif - -glabel send_mesg - lui $t2, %hi(D_80363830) # $t2, 0x8036 - addiu $t2, %lo(D_80363830) # addiu $t2, $t2, 0x3830 - addu $t2, $t2, $a0 - lw $t1, ($t2) - move $s2, $ra - beqz $t1, .L80326CC4 - nop - lw $t3, 8($t1) - lw $t4, 0x10($t1) - slt $at, $t3, $t4 - beqz $at, .L80326CC4 - nop - lw $t5, 0xc($t1) - addu $t5, $t5, $t3 - div $zero, $t5, $t4 - bnez $t4, .L80326C60 - nop - break 7 -.L80326C60: - li $at, -1 - bne $t4, $at, .L80326C78 - lui $at, 0x8000 - bne $t5, $at, .L80326C78 - nop - break 6 -.L80326C78: - lw $t4, 0x14($t1) - mfhi $t5 - sll $t5, $t5, 2 - addu $t4, $t4, $t5 - lw $t5, 4($t2) - addiu $t2, $t3, 1 - sw $t5, ($t4) - sw $t2, 8($t1) - lw $t2, ($t1) - lw $t3, ($t2) - beqz $t3, .L80326CC4 - nop - jal __osPopThread - move $a0, $t1 - move $t2, $v0 - lui $a0, %hi(D_80334890 + 0x8) # $a0, 0x8033 - move $a1, $t2 - jal __osEnqueueThread - addiu $a0, %lo(D_80334890 + 0x8) # addiu $a0, $a0, 0x4898 -.L80326CC4: - jr $s2 - nop -.L80326CCC: - lui $at, 0x3000 - and $t1, $t0, $at - srl $t1, $t1, 0x1c - li $t2, 1 - bne $t1, $t2, .L80326BE8 - nop - lw $k1, 0x118($k0) - lui $at, 0x2000 - li $t1, 1 - or $k1, $k1, $at - sw $t1, 0x18($k0) - b .L80326BD0 - sw $k1, 0x118($k0) - - -glabel __osEnqueueAndYield - lui $a1, %hi(D_80334890 + 0x10) # $a1, 0x8033 - lw $a1, %lo(D_80334890 + 0x10)($a1) - mfc0 $t0, $12 - lw $k1, 0x18($a1) - ori $t0, $t0, 2 - sw $t0, 0x118($a1) - sd $s0, 0x98($a1) - sd $s1, 0xa0($a1) - sd $s2, 0xa8($a1) - sd $s3, 0xb0($a1) - sd $s4, 0xb8($a1) - sd $s5, 0xc0($a1) - sd $s6, 0xc8($a1) - sd $s7, 0xd0($a1) - sd $gp, 0xe8($a1) - sd $sp, 0xf0($a1) - sd $fp, 0xf8($a1) - sd $ra, 0x100($a1) -.ifdef VERSION_EU - beqz $k1, .L802F3F7C -.else - beqz $k1, .L80326D70 -.endif - sw $ra, 0x11c($a1) - cfc1 $k1, $31 - sdc1 $f20, 0x180($a1) - sdc1 $f22, 0x188($a1) - sdc1 $f24, 0x190($a1) - sdc1 $f26, 0x198($a1) - sdc1 $f28, 0x1a0($a1) - sdc1 $f30, 0x1a8($a1) - sw $k1, 0x12c($a1) - -.ifdef VERSION_EU -.L802F3F7C: -/* 0B377C 802F3F7C 8CBB0118 */ lw $k1, 0x118($a1) -/* 0B3780 802F3F80 3369FF00 */ andi $t1, $k1, 0xff00 -/* 0B3784 802F3F84 1120000D */ beqz $t1, .L802F3FBC -/* 0B3788 802F3F88 00000000 */ nop -/* 0B378C 802F3F8C 3C088030 */ lui $t0, %hi(D_8030208C) # $t0, 0x8030 -/* 0B3790 802F3F90 2508208C */ addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c -/* 0B3794 802F3F94 8D080000 */ lw $t0, ($t0) -/* 0B3798 802F3F98 2401FFFF */ li $at, -1 -/* 0B379C 802F3F9C 01014026 */ xor $t0, $t0, $at -/* 0B37A0 802F3FA0 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 0B37A4 802F3FA4 3108FF00 */ andi $t0, $t0, 0xff00 -/* 0B37A8 802F3FA8 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 0B37AC 802F3FAC 01284825 */ or $t1, $t1, $t0 -/* 0B37B0 802F3FB0 0361D824 */ and $k1, $k1, $at -/* 0B37B4 802F3FB4 0369D825 */ or $k1, $k1, $t1 -/* 0B37B8 802F3FB8 ACBB0118 */ sw $k1, 0x118($a1) -.L802F3FBC: -/* 0B37BC 802F3FBC 3C1BA430 */ lui $k1, %hi(MI_INTR_MASK_REG) # $k1, 0xa430 -/* 0B37C0 802F3FC0 8F7B000C */ lw $k1, %lo(MI_INTR_MASK_REG)($k1) -/* 0B37C4 802F3FC4 1360000B */ beqz $k1, .L802F3FF4 -/* 0B37C8 802F3FC8 00000000 */ nop -/* 0B37CC 802F3FCC 3C1A8030 */ lui $k0, %hi(D_8030208C) # $k0, 0x8030 -/* 0B37D0 802F3FD0 275A208C */ addiu $k0, %lo(D_8030208C) # addiu $k0, $k0, 0x208c -/* 0B37D4 802F3FD4 8F5A0000 */ lw $k0, ($k0) -/* 0B37D8 802F3FD8 8CA80128 */ lw $t0, 0x128($a1) -/* 0B37DC 802F3FDC 2401FFFF */ li $at, -1 -/* 0B37E0 802F3FE0 001AD402 */ srl $k0, $k0, 0x10 -/* 0B37E4 802F3FE4 0341D026 */ xor $k0, $k0, $at -/* 0B37E8 802F3FE8 335A003F */ andi $k0, $k0, 0x3f -/* 0B37EC 802F3FEC 0348D024 */ and $k0, $k0, $t0 -/* 0B37F0 802F3FF0 037AD825 */ or $k1, $k1, $k0 -.L802F3FF4: -.endif - - -.L80326D70: -.ifndef VERSION_EU - lui $k1, %hi(MI_INTR_MASK_REG) # $k1, 0xa430 - lw $k1, %lo(MI_INTR_MASK_REG)($k1) -.endif - beqz $a0, .L80326D88 - sw $k1, 0x128($a1) - jal __osEnqueueThread - nop -.L80326D88: - j __osDispatchThread - nop - - -#enqueue and pop look like compiled functions? but there's no easy way to extract them -glabel __osEnqueueThread - lw $t8, ($a0) - lw $t7, 4($a1) - move $t9, $a0 - lw $t6, 4($t8) - slt $at, $t6, $t7 - bnez $at, .L80326DC4 - nop -.L80326DAC: - move $t9, $t8 - lw $t8, ($t8) - lw $t6, 4($t8) - slt $at, $t6, $t7 - beqz $at, .L80326DAC - nop -.L80326DC4: - lw $t8, ($t9) - sw $t8, ($a1) - sw $a1, ($t9) - jr $ra - sw $a0, 8($a1) - -glabel __osPopThread - lw $v0, ($a0) - lw $t9, ($v0) - jr $ra - sw $t9, ($a0) - -glabel __osDispatchThread - lui $a0, %hi(D_80334890 + 0x8) # $a0, 0x8033 - jal __osPopThread - addiu $a0, %lo(D_80334890 + 0x8) # addiu $a0, $a0, 0x4898 - lui $at, %hi(D_80334890 + 0x10) # $at, 0x8033 - sw $v0, %lo(D_80334890 + 0x10)($at) - li $t0, 4 - sh $t0, 0x10($v0) - move $k0, $v0 - -.ifdef VERSION_EU - -/* 0B3884 802F4084 3C088030 */ lui $t0, %hi(D_8030208C) # $t0, 0x8030 -/* 0B3888 802F4088 8F5B0118 */ lw $k1, 0x118($k0) -/* 0B388C 802F408C 2508208C */ addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c -/* 0B3890 802F4090 8D080000 */ lw $t0, ($t0) -/* 0B3894 802F4094 3C01FFFF */ lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff -/* 0B3898 802F4098 3369FF00 */ andi $t1, $k1, 0xff00 -/* 0B389C 802F409C 342100FF */ ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -/* 0B38A0 802F40A0 3108FF00 */ andi $t0, $t0, 0xff00 -/* 0B38A4 802F40A4 01284824 */ and $t1, $t1, $t0 -/* 0B38A8 802F40A8 0361D824 */ and $k1, $k1, $at -/* 0B38AC 802F40AC 0369D825 */ or $k1, $k1, $t1 -/* 0B38B0 802F40B0 409B6000 */ mtc0 $k1, $12 -.endif -.L80326E08: - ld $k1, 0x108($k0) - ld $at, 0x20($k0) - ld $v0, 0x28($k0) - mtlo $k1 - ld $k1, 0x110($k0) - ld $v1, 0x30($k0) - ld $a0, 0x38($k0) - ld $a1, 0x40($k0) - ld $a2, 0x48($k0) - ld $a3, 0x50($k0) - ld $t0, 0x58($k0) - ld $t1, 0x60($k0) - ld $t2, 0x68($k0) - ld $t3, 0x70($k0) - ld $t4, 0x78($k0) - ld $t5, 0x80($k0) - ld $t6, 0x88($k0) - ld $t7, 0x90($k0) - ld $s0, 0x98($k0) - ld $s1, 0xa0($k0) - ld $s2, 0xa8($k0) - ld $s3, 0xb0($k0) - ld $s4, 0xb8($k0) - ld $s5, 0xc0($k0) - ld $s6, 0xc8($k0) - ld $s7, 0xd0($k0) - ld $t8, 0xd8($k0) - ld $t9, 0xe0($k0) - ld $gp, 0xe8($k0) - mthi $k1 - ld $sp, 0xf0($k0) - ld $fp, 0xf8($k0) - ld $ra, 0x100($k0) - lw $k1, 0x11c($k0) - mtc0 $k1, $14 -.ifndef VERSION_EU - lw $k1, 0x118($k0) - mtc0 $k1, $12 -.endif - lw $k1, 0x18($k0) - beqz $k1, .L80326EF0 - nop - lw $k1, 0x12c($k0) - ctc1 $k1, $31 - ldc1 $f0, 0x130($k0) - ldc1 $f2, 0x138($k0) - ldc1 $f4, 0x140($k0) - ldc1 $f6, 0x148($k0) - ldc1 $f8, 0x150($k0) - ldc1 $f10, 0x158($k0) - ldc1 $f12, 0x160($k0) - ldc1 $f14, 0x168($k0) - ldc1 $f16, 0x170($k0) - ldc1 $f18, 0x178($k0) - ldc1 $f20, 0x180($k0) - ldc1 $f22, 0x188($k0) - ldc1 $f24, 0x190($k0) - ldc1 $f26, 0x198($k0) - ldc1 $f28, 0x1a0($k0) - ldc1 $f30, 0x1a8($k0) -.L80326EF0: - lw $k1, 0x128($k0) -.ifdef VERSION_EU -/* 0B3998 802F4198 3C1A8030 */ lui $k0, %hi(D_8030208C) # $k0, 0x8030 -/* 0B399C 802F419C 275A208C */ addiu $k0, %lo(D_8030208C) # addiu $k0, $k0, 0x208c -/* 0B39A0 802F41A0 8F5A0000 */ lw $k0, ($k0) -/* 0B39A4 802F41A4 001AD402 */ srl $k0, $k0, 0x10 -/* 0B39A8 802F41A8 037AD824 */ and $k1, $k1, $k0 -.endif - sll $k1, $k1, 1 - lui $k0, %hi(D_803386D0) # $k0, 0x8034 - addiu $k0, %lo(D_803386D0) # addiu $k0, $k0, -0x7930 - addu $k1, $k1, $k0 - lhu $k1, ($k1) - lui $k0, %hi(MI_INTR_MASK_REG) # $k0, 0xa430 - addiu $k0, %lo(MI_INTR_MASK_REG) # addiu $k0, $k0, 0xc - sw $k1, ($k0) - nop - nop - nop - nop - eret -glabel __osCleanupThread - jal osDestroyThread - move $a0, $zero - -.section .data - -glabel D_80334920 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - -glabel D_80334934 - .word 0 - -glabel D_80334938 - .word 0 - .word 0 - -.section .rodata - -glabel D_80338610 - .byte 0x00,0x14,0x18,0x18,0x1C,0x1C,0x1C,0x1C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x04,0x08,0x08,0x0C,0x0C,0x0C,0x0C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 - -glabel jtbl_80338630 - .word L80326B9C - .word L80326B64 - .word L80326B44 - .word L803269B8 - .word L80326984 - .word L80326AE8 -.ifdef VERSION_EU - .word 0x802f3b28 - .word 0x802f3b34 -.else - .word L80326BE8 - .word L80326BE8 -.endif - .word L80326964 - .word 0 - .word 0 - .word 0 diff --git a/lib/asm/__osGetCause.s b/lib/asm/__osGetCause.s deleted file mode 100644 index 13fff167..00000000 --- a/lib/asm/__osGetCause.s +++ /dev/null @@ -1,15 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osGetCause - mfc0 $v0, $13 - jr $ra - nop - - nop - diff --git a/lib/asm/__osGetSR.s b/lib/asm/__osGetSR.s deleted file mode 100644 index e2f74c76..00000000 --- a/lib/asm/__osGetSR.s +++ /dev/null @@ -1,15 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osGetSR - mfc0 $v0, $12 - jr $ra - nop - - nop - diff --git a/lib/asm/__osProbeTLB.s b/lib/asm/__osProbeTLB.s deleted file mode 100644 index fe83ea16..00000000 --- a/lib/asm/__osProbeTLB.s +++ /dev/null @@ -1,64 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osProbeTLB - mfc0 $t0, $10 - andi $t1, $t0, 0xff - li $at, -8192 - and $t2, $a0, $at - or $t1, $t1, $t2 - mtc0 $t1, $10 - nop - nop - nop - tlbp - nop - nop - mfc0 $t3, $0 - lui $at, 0x8000 - and $t3, $t3, $at - bnez $t3, .L8032A0D8 - nop - tlbr - nop - nop - nop - mfc0 $t3, $5 - addi $t3, $t3, 0x2000 - srl $t3, $t3, 1 - and $t4, $t3, $a0 - bnez $t4, .L8032A0A8 - addi $t3, $t3, -1 - mfc0 $v0, $2 - b .L8032A0AC - nop -.L8032A0A8: - mfc0 $v0, $3 -.L8032A0AC: - andi $t5, $v0, 2 - beqz $t5, .L8032A0D8 - nop - lui $at, (0x3FFFFFC0 >> 16) # lui $at, 0x3fff - ori $at, (0x3FFFFFC0 & 0xFFFF) # ori $at, $at, 0xffc0 - and $v0, $v0, $at - sll $v0, $v0, 6 - and $t5, $a0, $t3 - add $v0, $v0, $t5 - b .L8032A0DC - nop -.L8032A0D8: - li $v0, -1 -.L8032A0DC: - mtc0 $t0, $10 - jr $ra - nop - - nop - nop - diff --git a/lib/asm/__osRestoreInt.s b/lib/asm/__osRestoreInt.s deleted file mode 100644 index f6ab98ef..00000000 --- a/lib/asm/__osRestoreInt.s +++ /dev/null @@ -1,19 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osRestoreInt - mfc0 $t0, $12 - or $t0, $t0, $a0 - mtc0 $t0, $12 - nop - nop - jr $ra - nop - - nop - diff --git a/lib/asm/__osSetCompare.s b/lib/asm/__osSetCompare.s deleted file mode 100644 index a1dab931..00000000 --- a/lib/asm/__osSetCompare.s +++ /dev/null @@ -1,15 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osSetCompare - mtc0 $a0, $11 - jr $ra - nop - - nop - diff --git a/lib/asm/__osSetFpcCsr.s b/lib/asm/__osSetFpcCsr.s deleted file mode 100644 index e644bc74..00000000 --- a/lib/asm/__osSetFpcCsr.s +++ /dev/null @@ -1,14 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osSetFpcCsr - cfc1 $v0, $31 - ctc1 $a0, $31 - jr $ra - nop - diff --git a/lib/asm/__osSetSR.s b/lib/asm/__osSetSR.s deleted file mode 100644 index 3fba3e66..00000000 --- a/lib/asm/__osSetSR.s +++ /dev/null @@ -1,14 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel __osSetSR - mtc0 $a0, $12 - nop - jr $ra - nop - diff --git a/lib/asm/__os_eu_802ef550.s b/lib/asm/__os_eu_802ef550.s deleted file mode 100644 index 99b328e2..00000000 --- a/lib/asm/__os_eu_802ef550.s +++ /dev/null @@ -1,22 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 -.set noat - -.include "macros.inc" - - -.section .text, "ax" -# cache related -glabel __os_eu_802ef550 - lui $t0,0x8000 - li $t2,0x2000 - addu $t1,$t0,$t2 - addiu $t1,$t1,-0x10 -.L: cache 0x1,0($t0) - sltu $at,$t0,$t1 - bnez $at,.L - addiu $t0,$t0,0x10 - jr $ra - nop - nop - nop diff --git a/lib/asm/bcopy.s b/lib/asm/bcopy.s deleted file mode 100644 index 953a3d3c..00000000 --- a/lib/asm/bcopy.s +++ /dev/null @@ -1,232 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel bcopy - beqz $a2, .L80323A4C - move $a3, $a1 - beq $a0, $a1, .L80323A4C - slt $at, $a1, $a0 - bnezl $at, .L80323A14 - slti $at, $a2, 0x10 - add $v0, $a0, $a2 - slt $at, $a1, $v0 - beql $at, $zero, .L80323A14 - slti $at, $a2, 0x10 - b .L80323B78 - slti $at, $a2, 0x10 - slti $at, $a2, 0x10 -.L80323A14: - bnez $at, .L80323A2C - nop - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, .L80323A54 - nop -.L80323A2C: - beqz $a2, .L80323A4C - nop - addu $v1, $a0, $a2 -.L80323A38: - lb $v0, ($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - bne $a0, $v1, .L80323A38 - sb $v0, -1($a1) -.L80323A4C: - jr $ra - move $v0, $a3 - -.L80323A54: - beqz $v0, .L80323AB8 - li $at, 1 - beq $v0, $at, .L80323A9C - li $at, 2 - beql $v0, $at, .L80323A88 - lh $v0, ($a0) - lb $v0, ($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 1 - addiu $a2, $a2, -1 - b .L80323AB8 - sb $v0, -1($a1) - lh $v0, ($a0) -.L80323A88: - addiu $a0, $a0, 2 - addiu $a1, $a1, 2 - addiu $a2, $a2, -2 - b .L80323AB8 - sh $v0, -2($a1) -.L80323A9C: - lb $v0, ($a0) - lh $v1, 1($a0) - addiu $a0, $a0, 3 - addiu $a1, $a1, 3 - addiu $a2, $a2, -3 - sb $v0, -3($a1) - sh $v1, -2($a1) -.L80323AB8: - slti $at, $a2, 0x20 - bnezl $at, .L80323B18 - slti $at, $a2, 0x10 - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xc($a0) - lw $t2, 0x10($a0) - lw $t3, 0x14($a0) - lw $t4, 0x18($a0) - lw $t5, 0x1c($a0) - addiu $a0, $a0, 0x20 - addiu $a1, $a1, 0x20 - addiu $a2, $a2, -0x20 - sw $v0, -0x20($a1) - sw $v1, -0x1c($a1) - sw $t0, -0x18($a1) - sw $t1, -0x14($a1) - sw $t2, -0x10($a1) - sw $t3, -0xc($a1) - sw $t4, -8($a1) - b .L80323AB8 - sw $t5, -4($a1) -.L80323B14: - slti $at, $a2, 0x10 -.L80323B18: - bnezl $at, .L80323B54 - slti $at, $a2, 4 - lw $v0, ($a0) - lw $v1, 4($a0) - lw $t0, 8($a0) - lw $t1, 0xc($a0) - addiu $a0, $a0, 0x10 - addiu $a1, $a1, 0x10 - addiu $a2, $a2, -0x10 - sw $v0, -0x10($a1) - sw $v1, -0xc($a1) - sw $t0, -8($a1) - b .L80323B14 - sw $t1, -4($a1) -.L80323B50: - slti $at, $a2, 4 -.L80323B54: - bnez $at, .L80323A2C - nop - lw $v0, ($a0) - addiu $a0, $a0, 4 - addiu $a1, $a1, 4 - addiu $a2, $a2, -4 - b .L80323B50 - sw $v0, -4($a1) - slti $at, $a2, 0x10 -.L80323B78: - add $a0, $a0, $a2 - bnez $at, .L80323B94 - add $a1, $a1, $a2 - andi $v0, $a0, 3 - andi $v1, $a1, 3 - beq $v0, $v1, .L80323BC4 - nop -.L80323B94: - beqz $a2, .L80323A4C - nop - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - subu $v1, $a0, $a2 -.L80323BA8: - lb $v0, ($a0) - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - bne $a0, $v1, .L80323BA8 - sb $v0, 1($a1) - jr $ra - move $v0, $a3 - -.L80323BC4: - beqz $v0, .L80323C28 - li $at, 3 - beq $v0, $at, .L80323C0C - li $at, 2 - beql $v0, $at, .L80323BF8 - lh $v0, -2($a0) - lb $v0, -1($a0) - addiu $a0, $a0, -1 - addiu $a1, $a1, -1 - addiu $a2, $a2, -1 - b .L80323C28 - sb $v0, ($a1) - lh $v0, -2($a0) -.L80323BF8: - addiu $a0, $a0, -2 - addiu $a1, $a1, -2 - addiu $a2, $a2, -2 - b .L80323C28 - sh $v0, ($a1) -.L80323C0C: - lb $v0, -1($a0) - lh $v1, -3($a0) - addiu $a0, $a0, -3 - addiu $a1, $a1, -3 - addiu $a2, $a2, -3 - sb $v0, 2($a1) - sh $v1, ($a1) -.L80323C28: - slti $at, $a2, 0x20 - bnezl $at, .L80323C88 - slti $at, $a2, 0x10 - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xc($a0) - lw $t1, -0x10($a0) - lw $t2, -0x14($a0) - lw $t3, -0x18($a0) - lw $t4, -0x1c($a0) - lw $t5, -0x20($a0) - addiu $a0, $a0, -0x20 - addiu $a1, $a1, -0x20 - addiu $a2, $a2, -0x20 - sw $v0, 0x1c($a1) - sw $v1, 0x18($a1) - sw $t0, 0x14($a1) - sw $t1, 0x10($a1) - sw $t2, 0xc($a1) - sw $t3, 8($a1) - sw $t4, 4($a1) - b .L80323C28 - sw $t5, ($a1) -.L80323C84: - slti $at, $a2, 0x10 -.L80323C88: - bnezl $at, .L80323CC4 - slti $at, $a2, 4 - lw $v0, -4($a0) - lw $v1, -8($a0) - lw $t0, -0xc($a0) - lw $t1, -0x10($a0) - addiu $a0, $a0, -0x10 - addiu $a1, $a1, -0x10 - addiu $a2, $a2, -0x10 - sw $v0, 0xc($a1) - sw $v1, 8($a1) - sw $t0, 4($a1) - b .L80323C84 - sw $t1, ($a1) -.L80323CC0: - slti $at, $a2, 4 -.L80323CC4: - bnez $at, .L80323B94 - nop - lw $v0, -4($a0) - addiu $a0, $a0, -4 - addiu $a1, $a1, -4 - addiu $a2, $a2, -4 - b .L80323CC0 - sw $v0, ($a1) - nop - nop - nop - diff --git a/lib/asm/bzero.s b/lib/asm/bzero.s deleted file mode 100644 index 37053b7e..00000000 --- a/lib/asm/bzero.s +++ /dev/null @@ -1,53 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - -#this file is probably handwritten - -.section .text, "ax" - -glabel bzero - blt $a1, 0xc, .L803236BC - negu $v1, $a0 - andi $v1, $v1, 3 - beqz $v1, .L80323660 - subu $a1, $a1, $v1 - swl $zero, ($a0) - addu $a0, $a0, $v1 -.L80323660: - and $a3, $a1, -32 - beqz $a3, .L8032369C - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L80323674: - addiu $a0, $a0, 0x20 - sw $zero, -0x20($a0) - sw $zero, -0x1c($a0) - sw $zero, -0x18($a0) - sw $zero, -0x14($a0) - sw $zero, -0x10($a0) - sw $zero, -0xc($a0) - sw $zero, -8($a0) - bne $a0, $a3, .L80323674 - sw $zero, -4($a0) -.L8032369C: - and $a3, $a1, -4 - beqz $a3, .L803236BC - subu $a1, $a1, $a3 - addu $a3, $a3, $a0 -.L803236B0: - addiu $a0, $a0, 4 - bne $a0, $a3, .L803236B0 - sw $zero, -4($a0) -.L803236BC: - blez $a1, .L803236D4 - nop - addu $a1, $a1, $a0 -.L803236C8: - addiu $a0, $a0, 1 - bne $a0, $a1, .L803236C8 - sb $zero, -1($a0) -.L803236D4: - jr $ra - diff --git a/lib/asm/llmuldiv_gcc.s b/lib/asm/llmuldiv_gcc.s deleted file mode 100644 index cf604929..00000000 --- a/lib/asm/llmuldiv_gcc.s +++ /dev/null @@ -1,100 +0,0 @@ -# assembler directives -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -/* -------------------------------------------------------------------------------------- */ -/* need to asm these functions because lib32gcc-7-dev-mips-cross does not exist so we */ -/* cannot naturally link a libgcc variant for this target given this architecture and */ -/* compiler. Until we have a good workaround with a gcc target that doesn't involve */ -/* assuming a 32-bit to 64-bit change, we have to encode these functions as raw assembly */ -/* for it to compile. */ -/* -------------------------------------------------------------------------------------- */ - -/* TODO: Is there a non-insane way to fix this hack that doesn't involve the user compiling */ -/* a library themselves? */ -glabel __umoddi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L80324144 - nop - break 7 -.L80324144: - mfhi $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __udivdi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L80324180 - nop - break 7 -.L80324180: - mflo $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __moddi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddivu $zero, $t6, $t7 - bnez $t7, .L803241E8 - nop - break 7 -.L803241E8: - mfhi $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 - -glabel __divdi3 - sw $a0, ($sp) - sw $a1, 4($sp) - sw $a2, 8($sp) - sw $a3, 0xc($sp) - ld $t7, 8($sp) - ld $t6, ($sp) - ddiv $zero, $t6, $t7 - nop - bnez $t7, .L80324228 - nop - break 7 -.L80324228: - daddiu $at, $zero, -1 - bne $t7, $at, .L80324244 - daddiu $at, $zero, 1 - dsll32 $at, $at, 0x1f - bne $t6, $at, .L80324244 - nop - break 6 -.L80324244: - mflo $v0 - dsll32 $v1, $v0, 0 - dsra32 $v1, $v1, 0 - jr $ra - dsra32 $v0, $v0, 0 diff --git a/lib/asm/osGetCount.s b/lib/asm/osGetCount.s deleted file mode 100644 index 58bd3629..00000000 --- a/lib/asm/osGetCount.s +++ /dev/null @@ -1,15 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osGetCount - mfc0 $v0, $9 - jr $ra - nop - - nop - diff --git a/lib/asm/osInvalDCache.s b/lib/asm/osInvalDCache.s deleted file mode 100644 index 452c4dd3..00000000 --- a/lib/asm/osInvalDCache.s +++ /dev/null @@ -1,59 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osInvalDCache - blez $a1, .L80323500 - nop - li $t3, 8192 - sltu $at, $a1, $t3 - beqz $at, .L80323508 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, .L80323500 - nop - andi $t2, $t0, 0xf - beqz $t2, .L803234D0 - addiu $t1, $t1, -0x10 - subu $t0, $t0, $t2 - cache 0x15, ($t0) - sltu $at, $t0, $t1 - beqz $at, .L80323500 - nop - addiu $t0, $t0, 0x10 -.L803234D0: - andi $t2, $t1, 0xf - beqz $t2, .L803234F0 - nop - subu $t1, $t1, $t2 - cache 0x15, 0x10($t1) - sltu $at, $t1, $t0 - bnez $at, .L80323500 - nop -.L803234F0: - cache 0x11, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L803234F0 - addiu $t0, $t0, 0x10 -.L80323500: - jr $ra - nop - -.L80323508: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x10 -.L80323514: - cache 1, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80323514 - addiu $t0, $t0, 0x10 - jr $ra - nop diff --git a/lib/asm/osInvalICache.s b/lib/asm/osInvalICache.s deleted file mode 100644 index 8b8a03f0..00000000 --- a/lib/asm/osInvalICache.s +++ /dev/null @@ -1,44 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osInvalICache - blez $a1, .L80323728 - nop - li $t3, 16384 - sltu $at, $a1, $t3 - beqz $at, .L80323730 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - sltu $at, $t0, $t1 - beqz $at, .L80323728 - nop - andi $t2, $t0, 0x1f - addiu $t1, $t1, -0x20 - subu $t0, $t0, $t2 -.L80323718: - cache 0x10, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80323718 - addiu $t0, $t0, 0x20 -.L80323728: - jr $ra - nop - -.L80323730: - li $t0, K0BASE - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x20 -.L8032373C: - cache 0, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L8032373C - addiu $t0, $t0, 0x20 - jr $ra - nop diff --git a/lib/asm/osMapTLB.s b/lib/asm/osMapTLB.s deleted file mode 100644 index b9ee4364..00000000 --- a/lib/asm/osMapTLB.s +++ /dev/null @@ -1,63 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -# This file is handwritten - -#void osMapTLB(s32 index, OSPageMask pm, void *vaddr, u32 evenpaddr, u32 oddpaddr, s32 asid); -glabel osMapTLB - mfc0 $t0, $10 - mtc0 $a0, $0 - mtc0 $a1, $5 - lw $t1, 0x14($sp) #asid - beq $t1, -1, .L803214D8 - li $t4, 1 - li $t2, 30 - b .L803214DC - or $a2, $a2, $t1 #vaddr -.L803214D8: - li $t2, 31 -.L803214DC: - mtc0 $a2, $10 #vaddr - beq $a3, -1, .L80321500 #even paddr - nop - srl $t3, $a3, 6 #evenpaddr - or $t3, $t3, $t2 - mtc0 $t3, $2 - b .L80321504 - nop -.L80321500: - mtc0 $t4, $2 -.L80321504: - lw $t3, 0x10($sp) #oddpaddr - beq $t3, -1, .L80321528 - nop - srl $t3, $t3, 6 - or $t3, $t3, $t2 - mtc0 $t3, $3 - b .L80321540 - nop -.L80321528: - mtc0 $t4, $3 - bne $a3, -1, .L80321540 #evenpaddr - nop - lui $t3, 0x8000 - mtc0 $t3, $10 -.L80321540: - nop - tlbwi - nop - nop - nop - nop - mtc0 $t0, $10 - jr $ra - nop #file gets padded but - nop - nop - nop - diff --git a/lib/asm/osMapTLBRdb.s b/lib/asm/osMapTLBRdb.s deleted file mode 100644 index 6753280d..00000000 --- a/lib/asm/osMapTLBRdb.s +++ /dev/null @@ -1,36 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osMapTLBRdb - mfc0 $t0, $10 - li $t1, 31 - mtc0 $t1, $0 - mtc0 $zero, $5 - li $t2, 23 - lui $t1, 0xc000 - mtc0 $t1, $10 - lui $t1, 0x8000 - srl $t3, $t1, 6 - or $t3, $t3, $t2 - mtc0 $t3, $2 - li $t1, 1 - mtc0 $t1, $3 - nop - tlbwi - nop - nop - nop - nop - mtc0 $t0, $10 - jr $ra - nop - - nop - nop - diff --git a/lib/asm/osSetIntMask.s b/lib/asm/osSetIntMask.s deleted file mode 100644 index ccce609c..00000000 --- a/lib/asm/osSetIntMask.s +++ /dev/null @@ -1,138 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - -.eqv MI_INTR_MASK_REG, 0xA430000C - -.section .text, "ax" - -glabel osSetIntMask -.ifndef VERSION_EU - mfc0 $t1, $12 - andi $v0, $t1, 0xff01 -.else - mfc0 $t4, $12 - andi $v0, $t4, 0xff01 - lui $t0, %hi(D_8030208C) # $t0, 0x8030 - addiu $t0, %lo(D_8030208C) # addiu $t0, $t0, 0x208c - lw $t3, ($t0) - li $at, -1 - xor $t0, $t3, $at - andi $t0, $t0, 0xff00 - or $v0, $v0, $t0 -.endif - lui $t2, %hi(MI_INTR_MASK_REG) # $t2, 0xa430 - lw $t2, %lo(MI_INTR_MASK_REG)($t2) -.ifdef VERSION_EU - beqz $t2, .L80200074 - srl $t1, $t3, 0x10 - li $at, -1 - xor $t1, $t1, $at - andi $t1, $t1, 0x3f - or $t2, $t2, $t1 -.L80200074: -.endif - sll $t2, $t2, 0x10 - or $v0, $v0, $t2 - lui $at, 0x3f - and $t0, $a0, $at -.ifdef VERSION_EU - and $t0, $t0, $t3 -.endif - srl $t0, $t0, 0xf - lui $t2, %hi(D_803386D0) - addu $t2, $t2, $t0 - lhu $t2, %lo(D_803386D0)($t2) - lui $at, %hi(MI_INTR_MASK_REG) # $at, 0xa430 - sw $t2, %lo(MI_INTR_MASK_REG)($at) - andi $t0, $a0, 0xff01 -.ifdef VERSION_EU - andi $t1, $t3, 0xff00 - and $t0, $t0, $t1 -.endif - lui $at, (0xFFFF00FF >> 16) # lui $at, 0xffff - ori $at, (0xFFFF00FF & 0xFFFF) # ori $at, $at, 0xff -.ifndef VERSION_EU - and $t1, $t1, $at - or $t1, $t1, $t0 - mtc0 $t1, $12 -.else - and $t4, $t4, $at - or $t4, $t4, $t0 - mtc0 $t4, $12 -.endif - nop - nop - jr $ra - nop - - -.section .rodata - -glabel D_803386D0 -.half 0x0555 -.half 0x0556 -.half 0x0559 -.half 0x055A -.half 0x0565 -.half 0x0566 -.half 0x0569 -.half 0x056A -.half 0x0595 -.half 0x0596 -.half 0x0599 -.half 0x059A -.half 0x05A5 -.half 0x05A6 -.half 0x05A9 -.half 0x05AA -.half 0x0655 -.half 0x0656 -.half 0x0659 -.half 0x065A -.half 0x0665 -.half 0x0666 -.half 0x0669 -.half 0x066A -.half 0x0695 -.half 0x0696 -.half 0x0699 -.half 0x069A -.half 0x06A5 -.half 0x06A6 -.half 0x06A9 -.half 0x06AA -.half 0x0955 -.half 0x0956 -.half 0x0959 -.half 0x095A -.half 0x0965 -.half 0x0966 -.half 0x0969 -.half 0x096A -.half 0x0995 -.half 0x0996 -.half 0x0999 -.half 0x099A -.half 0x09A5 -.half 0x09A6 -.half 0x09A9 -.half 0x09AA -.half 0x0A55 -.half 0x0A56 -.half 0x0A59 -.half 0x0A5A -.half 0x0A65 -.half 0x0A66 -.half 0x0A69 -.half 0x0A6A -.half 0x0A95 -.half 0x0A96 -.half 0x0A99 -.half 0x0A9A -.half 0x0AA5 -.half 0x0AA6 -.half 0x0AA9 -.half 0x0AAA diff --git a/lib/asm/osUnmapTLBAll.s b/lib/asm/osUnmapTLBAll.s deleted file mode 100644 index 0bd9ad27..00000000 --- a/lib/asm/osUnmapTLBAll.s +++ /dev/null @@ -1,32 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osUnmapTLBAll - mfc0 $t0, $10 - li $t1, 31 - lui $t2, 0x8000 - mtc0 $t2, $10 - mtc0 $zero, $2 - mtc0 $zero, $3 -.L80321588: - mtc0 $t1, $0 - nop - tlbwi - nop - nop - addi $t1, $t1, -1 - bnezl $t1, .L80321588 #bnezl, bnez but with likely hint - nop - mtc0 $t0, $10 - jr $ra - nop - - nop - nop - nop - diff --git a/lib/asm/osWritebackDCache.s b/lib/asm/osWritebackDCache.s deleted file mode 100644 index 8e870168..00000000 --- a/lib/asm/osWritebackDCache.s +++ /dev/null @@ -1,39 +0,0 @@ -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osWritebackDCache - blez $a1, .osWritebackDCacheReturn - nop - li $t3, 8192 - bgeu $a1, $t3, .L80324E40 - nop - move $t0, $a0 - addu $t1, $a0, $a1 - bgeu $t0, $t1, .osWritebackDCacheReturn - nop - andi $t2, $t0, 0xf - addiu $t1, $t1, -0x10 - subu $t0, $t0, $t2 -.L80324E28: - cache 0x19, ($t0) - bltu $t0, $t1, .L80324E28 - addiu $t0, $t0, 0x10 -.osWritebackDCacheReturn: - jr $ra - nop - -.L80324E40: - lui $t0, 0x8000 - addu $t1, $t0, $t3 - addiu $t1, $t1, -0x10 -.L80324E4C: - cache 1, ($t0) - bltu $t0, $t1, .L80324E4C - addiu $t0, 0x10 # addiu $t0, $t0, 0x10 - jr $ra - nop diff --git a/lib/asm/osWritebackDCacheAll.s b/lib/asm/osWritebackDCacheAll.s deleted file mode 100644 index 88707604..00000000 --- a/lib/asm/osWritebackDCacheAll.s +++ /dev/null @@ -1,24 +0,0 @@ -.set noat # allow manual use of $at -.set noreorder # don't insert nops after branches -.set gp=64 - -.include "macros.inc" - - -.section .text, "ax" - -glabel osWritebackDCacheAll - li $t0, K0BASE - li $t2, 8192 - addu $t1, $t0, $t2 - addiu $t1, $t1, -0x10 -.L80322020: - cache 1, ($t0) - sltu $at, $t0, $t1 - bnez $at, .L80322020 - addiu $t0, $t0, 0x10 - jr $ra - nop - - nop - nop diff --git a/lib/asm/parameters.s b/lib/asm/parameters.s deleted file mode 100644 index d5106bfe..00000000 --- a/lib/asm/parameters.s +++ /dev/null @@ -1,18 +0,0 @@ -.macro gsymbol sym addr -.global \sym -.set \sym, \addr -.ifndef VERSION_JP -nop -nop -.endif -.endm - -.text -gsymbol osTvType 0x80000300 -gsymbol osRomType 0x80000304 -gsymbol osRomBase 0x80000308 -gsymbol osResetType 0x8000030C -gsymbol osCiCId 0x80000310 -gsymbol osVersion 0x80000314 -gsymbol osMemSize 0x80000318 -gsymbol osAppNmiBuffer 0x8000031C diff --git a/lib/rsp.s b/lib/rsp.s deleted file mode 100644 index a1284e1e..00000000 --- a/lib/rsp.s +++ /dev/null @@ -1,252 +0,0 @@ -.include "macros.inc" -.set UCODE_SIZE, 0x800 - -.section .text - -.balign 16 -glabel rspF3DBootStart - .ifndef VERSION_EU - .incbin "lib/PR/boot/F3D_boot.bin" - .else - .incbin "lib/PR/boot/F3D_boot_eu.bin" - .half 0 - .endif -glabel rspF3DBootEnd - -.balign 16 -.ifndef F3DEX_GBI_SHARED -glabel rspF3DStart /* Use regular Fast3D bins (default) */ - .ifndef F3D_OLD - .incbin "lib/PR/f3d/new/F3D.bin" /* OS 2.0H (J2 and IQ) */ - .else - .incbin "lib/PR/f3d/old/F3D.bin" /* OS 2.0D (US and JP) */ - .endif -glabel rspF3DEnd - -.else /* Use one of the Fast3DEX series grucodes. */ -glabel rspF3DStart - .if F3DEX_GBI_2 == 1 - .incbin "lib/PR/f3dex2/F3DEX2.bin" - .elseif F3DEX_GBI == 1 - .incbin "lib/PR/f3dex/F3DEX.bin" - .else /* Fast3DZEX */ - .incbin "lib/PR/f3dex2/F3DZEX.bin" - .endif -glabel rspF3DEnd -.endif - -/* Audio Bins */ - -.balign 16 -glabel rspAspMainStart - .incbin "lib/PR/audio/aspMain.bin" -glabel rspAspMainEnd - -/* - * LESS COMMON MICROCODES - * These are setup to be loaded by G_LOAD_UCODE - */ - -/* Fast3DEX NoN Text */ -.ifdef F3DEX_NON_GBI -glabel rspF3DEXNoNStart - .balign 16 - .incbin "lib/PR/f3dex/F3DEX_NoN.bin" -glabel rspF3DEXNoNEnd -.endif - -/* Fast3DLX Text */ -.ifdef F3DLX_GBI -glabel rspF3DLXStart - .incbin "lib/PR/f3dex/F3DLX.bin" -glabel rspF3DLXEnd -.endif - -/* Fast3DLX NoN Text */ -.ifdef F3DLX_NON_GBI -glabel rspF3DLXNoNStart - .balign 16 - .incbin "lib/PR/f3dex/F3DLX_NoN.bin" -glabel rspF3DLXNoNEnd -.endif - -/* Fast3DLX Rej Text */ -.ifdef F3DLX_REJ_GBI -glabel rspF3DLXRejStart - .balign 16 - .incbin "lib/PR/f3dex/F3DLX_Rej.bin" -glabel rspF3DLXRejEnd -.endif - -/* Line3DEX Text */ -.ifdef L3DEX_GBI -glabel rspL3DEXStart - .balign 16 - .incbin "lib/PR/f3dex/L3DEX.bin" -glabel rspL3DEXEnd -.endif - -/* S2DEX Text */ -.ifdef S2DEX_GBI -glabel rspS2DEXStart - .balign 16 - .incbin "lib/PR/s2dex/S2DEX.bin" -glabel rspS2DEXEnd -.endif - -/* Fast3DEX2 series */ - -/* Fast3DEX2 NoN Text */ -.ifdef F3DEX2_NON_GBI -.balign 16 -glabel rspF3DEX2NoNStart - .incbin "lib/PR/f3dex2/F3DEX2_NoN.bin" -glabel rspF3DEX2NoNEnd -.endif - -/* Fast3DEX2 Rej Text */ -.ifdef F3DEX2_REJ_GBI -.balign 16 -glabel rspF3DEX2RejStart - .incbin "lib/PR/f3dex2/F3DEX2_Rej.bin" -glabel rspF3DEX2RejEnd -.endif - -/* Line3DEX2 Text */ -.ifdef L3DEX2_GBI -.balign 16 -glabel rspL3DEX2Start - .incbin "lib/PR/f3dex2/L3DEX2.bin" -glabel rspL3DEX2End -.endif - -/* S2DEX2 Text */ -.ifdef S2DEX_GBI_2 -.balign 16 -glabel rspS2DEXStart - .incbin "lib/PR/s2dex/S2DEX2.bin" -glabel rspS2DEXEnd -.endif - -/* DATA SECTION START */ - -.section .rodata - -.balign 16 -.ifndef F3DEX_GBI_SHARED /* Use regular Fast3D data (default) */ -glabel rspF3DDataStart - .ifndef F3D_OLD /* OS 2.0H (J2 and IQ) */ - .ifdef VERSION_EU - .incbin "lib/PR/f3d/new/F3D_data_EU.bin" - .else - .incbin "lib/PR/f3d/new/F3D_data.bin" - .endif - .else /* OS 2.0D (US and JP) */ - .incbin "lib/PR/f3d/old/F3D_data.bin" - .endif -glabel rspF3DDataEnd - -.else /* Using one of the Fast3DEX series grucodes */ -glabel rspF3DDataStart - .if F3DEX_GBI_2 == 1 - .incbin "lib/PR/f3dex2/F3DEX2_data.bin" - .elseif F3DEX_GBI == 1 - .incbin "lib/PR/f3dex/F3DEX_data.bin" - .else /* Fast3DZEX */ - .incbin "lib/PR/f3dex2/F3DZEX_data.bin" - .endif -glabel rspF3DDataEnd -.endif - -/* Audio Data */ - -.balign 16 -glabel rspAspMainDataStart - .incbin "lib/PR/audio/aspMain_data.bin" -glabel rspAspMainDataEnd - -/* LESS COMMON MICROCODES */ - -/* Fast3DEX Series */ - -/* Fast3DEX NoN Data */ -.ifdef F3DEX_NON_GBI -.balign 16 -glabel rspF3DEXNoNDataStart - .incbin "lib/PR/f3dex/F3DEX_NoN_data.bin" -glabel rspF3DEXNoNDataEnd -.endif - -/* Fast3DLX Data */ -.ifdef F3DLX_GBI -.balign 16 -glabel rspF3DLXDataStart - .incbin "lib/PR/f3dex/F3DLX_data.bin" -glabel rspF3DLXDataEnd -.endif - -/* Fast3DLX NoN Data */ -.ifdef F3DLX_NON_GBI -.balign 16 -glabel rspF3DLXNoNDataStart - .incbin "lib/PR/f3dex/F3DLX_NoN_data.bin" -glabel rspF3DLXNoNDataEnd -.endif - -/* Fast3DLX Rej Data */ -.ifdef F3DLX_REJ_GBI -.balign 16 -glabel rspF3DLXRejDataStart - .incbin "lib/PR/f3dex/F3DLX_Rej_data.bin" -glabel rspF3DLXRejDataEnd -.endif - -/* Line3DEX Data */ -.ifdef L3DEX_GBI -.balign 16 -glabel rspL3DEXDataStart - .incbin "lib/PR/f3dex/L3DEX_data.bin" -glabel rspL3DEXDataEnd -.endif - -/* S2DEX Data */ -.ifdef S2DEX_GBI -.balign 16 -glabel rspS2DEXDataStart - .incbin "lib/PR/s2dex/S2DEX_data.bin" -glabel rspS2DEXDataEnd -.endif - -/* Fast3DEX2 Series */ - -/* Fast3DEX2 NoN Data */ -.ifdef F3DEX2_NON_GBI -.balign 16 -glabel rspF3DEX2NoNStart - .incbin "lib/PR/f3dex2/F3DEX2_NoN_data.bin" -glabel rspF3DEX2NoNEnd -.endif - -/* Fast3DEX2 Rej Data */ -.ifdef F3DEX2_REJ_GBI -.balign 16 -glabel rspF3DEX2RejStart - .incbin "lib/PR/f3dex2/F3DEX2_Rej_data.bin" -glabel rspF3DEX2RejEnd -.endif - -/* Line3DEX2 Data */ -.ifdef L3DEX2_GBI -.balign 16 -glabel rspL3DEX2Start - .incbin "lib/PR/f3dex2/L3DEX2_data.bin" -glabel rspL3DEX2End -.endif - -/* S2DEX2 Data */ -.ifdef S2DEX_GBI_2 -.balign 16 -glabel rspS2DEXStart - .incbin "lib/PR/s2dex/S2DEX2_data.bin" -glabel rspS2DEXEnd -.endif From aff081080b0fe36a50b866787365e8c7c9a4e22a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Thu, 4 Jun 2020 23:58:18 +0300 Subject: [PATCH 03/29] unfuck keyboard API; actually use seconds for rumble time --- src/game/thread6.h | 3 ++- src/pc/controller/controller_entry_point.c | 11 ++++++----- src/pc/controller/controller_keyboard.c | 2 ++ src/pc/controller/controller_sdl.c | 4 ++-- src/pc/pc_main.c | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/game/thread6.h b/src/game/thread6.h index 06586e62..a13cb142 100644 --- a/src/game/thread6.h +++ b/src/game/thread6.h @@ -15,5 +15,6 @@ extern void func_sh_8024CA04(void); extern void cancel_rumble(void); extern void create_thread_6(void); extern void rumble_thread_update_vi(void); +extern void thread6_rumble_loop(void *a0); -#endif // _THREAD_6_H \ No newline at end of file +#endif // _THREAD_6_H diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index fae9d657..d5403f93 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -1,5 +1,6 @@ #include "lib/src/libultra_internal.h" #include "lib/src/osContInternal.h" +#include "macros.h" #include "../configfile.h" @@ -21,7 +22,7 @@ static struct ControllerAPI *controller_implementations[] = { &controller_keyboard, }; -s32 osContInit(OSMesgQueue *mq, u8 *controllerBits, OSContStatus *status) { +s32 osContInit(UNUSED OSMesgQueue *mq, u8 *controllerBits, UNUSED OSContStatus *status) { for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { controller_implementations[i]->init(); } @@ -29,23 +30,23 @@ s32 osContInit(OSMesgQueue *mq, u8 *controllerBits, OSContStatus *status) { return 0; } -s32 osMotorStart(void *pfs) { +s32 osMotorStart(UNUSED void *pfs) { // Since rumble stops by osMotorStop, its duration is not nessecary. // Set it to 5 seconds and hope osMotorStop() is called in time. controller_rumble_play(configRumbleStrength / 100.0f, 5.0f); return 0; } -s32 osMotorStop(void *pfs) { +s32 osMotorStop(UNUSED void *pfs) { controller_rumble_stop(); return 0; } -u32 osMotorInit(OSMesgQueue *mq, void *pfs, s32 port) { +u32 osMotorInit(UNUSED OSMesgQueue *mq, UNUSED void *pfs, UNUSED s32 port) { return 0; // rumble is initialized in the specific backend's init function } -s32 osContStartReadData(OSMesgQueue *mesg) { +s32 osContStartReadData(UNUSED OSMesgQueue *mesg) { return 0; } diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c index b38352dd..da597328 100644 --- a/src/pc/controller/controller_keyboard.c +++ b/src/pc/controller/controller_keyboard.c @@ -113,6 +113,8 @@ struct ControllerAPI controller_keyboard = { keyboard_init, keyboard_read, keyboard_rawkey, + NULL, + NULL, keyboard_bindkeys, keyboard_shutdown }; diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index 368179f3..9345daf1 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -241,9 +241,9 @@ static void controller_sdl_read(OSContPad *pad) { } } -static void controller_sdl_rumble_play(f32 strength, u32 length) { +static void controller_sdl_rumble_play(f32 strength, f32 length) { if (sdl_haptic) - SDL_HapticRumblePlay(sdl_haptic, strength, length); + SDL_HapticRumblePlay(sdl_haptic, strength, (u32)(length * 1000.0f)); } static void controller_sdl_rumble_stop(void) { diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 90f0b90b..da548635 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -67,7 +67,7 @@ void send_display_list(struct SPTask *spTask) { void produce_one_frame(void) { gfx_start_frame(); game_loop_one_iteration(); - thread6_rumble_loop(); + thread6_rumble_loop(NULL); int samples_left = audio_api->buffered(); u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? 544 : 528; From ad92b93b394f66f3e2ae7b04844594bb728aaaa6 Mon Sep 17 00:00:00 2001 From: Zerocker Date: Fri, 5 Jun 2020 15:15:40 +0900 Subject: [PATCH 04/29] Fix missed collected stars after gameover --- src/game/text_save.inc.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index a5a8f54f..0c34f1b8 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -153,7 +153,7 @@ static s32 write_text_save(s32 fileIndex) { if (i == 0) { stars = save_file_get_star_flags(fileIndex, -1); } else { - stars = save_file_get_star_flags(fileIndex, i+15); + stars = save_file_get_star_flags(fileIndex, i+14); } starFlags = int_to_bin(stars); @@ -191,6 +191,10 @@ static s32 write_text_save(s32 fileIndex) { } fprintf(file, "area = %d\n", savedata->capArea); + /* Update a backup */ + bcopy(&gSaveBuffer.files[fileIndex][0], &gSaveBuffer.files[fileIndex][1], + sizeof(gSaveBuffer.files[fileIndex][1])); + fclose(file); return 1; } @@ -240,7 +244,6 @@ static s32 read_text_save(s32 fileIndex) { return -1; } - /* Parse main flags */ for (i = 1; i < NUM_FLAGS; i++) { value = ini_get(savedata, "flags", sav_flags[i]); From caea5ec4cb60943659edc373f2bb06492b376669 Mon Sep 17 00:00:00 2001 From: Zerocker Date: Fri, 5 Jun 2020 20:40:08 +0900 Subject: [PATCH 05/29] Nuke old VERSION OPT_FLAGS and add DEBUG flag --- Makefile | 10 ++++------ build.sh | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 49b60620..bfe0f8dc 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,8 @@ default: all # These options can either be changed by modifying the makefile, or # by building with 'make SETTING=value'. 'make clean' may be required. +# Build debug version (default) +DEBUG ?= 1 # Version of the game to build VERSION ?= us # Graphics microcode used @@ -280,15 +282,11 @@ GODDARD_SRC_DIRS := src/goddard src/goddard/dynlists MIPSISET := -mips2 MIPSBIT := -32 -ifeq ($(VERSION),eu) - OPT_FLAGS := -O2 -else -ifeq ($(VERSION),sh) - OPT_FLAGS := -O2 +ifeq ($(DEBUG),1) + OPT_FLAGS := -g else OPT_FLAGS := -O2 endif -endif # Set BITS (32/64) to compile for OPT_FLAGS += $(BITS) diff --git a/build.sh b/build.sh index 87d3597b..040860be 100644 --- a/build.sh +++ b/build.sh @@ -7,8 +7,8 @@ LIBAFLA=libaudiofile.la AUDDIR=./tools/audiofile-0.3.6 # Command line options -OPTIONS=("Analog Camera" "No Draw Distance" "Text-saves" "Smoke Texture Fix" "Clean build") -EXTRA=("BETTERCAMERA=1" "NODRAWINGDISTANCE=1" "TEXTSAVES=1" "TEXTURE_FIX=1" "clean") +OPTIONS=("Analog Camera" "No Draw Distance" "Text-saves" "Smoke Texture Fix" "Release build" "Clean build") +EXTRA=("BETTERCAMERA=1" "NODRAWINGDISTANCE=1" "TEXTSAVES=1" "TEXTURE_FIX=1" "DEBUG=0" "clean") # Colors RED=$(tput setaf 1) From 2ae6e0fac017e7f532ad77eaa2b76ab22b632df2 Mon Sep 17 00:00:00 2001 From: Zerocker Date: Fri, 5 Jun 2020 21:12:44 +0900 Subject: [PATCH 06/29] Remove old -O2 flag --- Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile b/Makefile index bfe0f8dc..b2154dda 100644 --- a/Makefile +++ b/Makefile @@ -295,10 +295,6 @@ ifeq ($(TARGET_WEB),1) OPT_FLAGS := -O2 -g4 --source-map-base http://localhost:8080/ endif -# Use a default opt flag for gcc, then override if RPi - -# OPT_FLAGS := -O2 # "Whole-compile optimization flag" Breaks sound on x86. - ifeq ($(TARGET_RPI),1) machine = $(shell sh -c 'uname -m 2>/dev/null || echo unknown') # Raspberry Pi B+, Zero, etc From 708b6c6855f419fe319351700b4aa27ff6e626d5 Mon Sep 17 00:00:00 2001 From: luciferin <40036150+hunterzero99@users.noreply.github.com> Date: Fri, 5 Jun 2020 09:50:16 -0400 Subject: [PATCH 07/29] Note changed save & config file location --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f8b0d6a4..efe50eda 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Please contribute **first** to the [nightly branch](https://github.com/sm64pc/sm * Disabling the HUD. * Cheats menu in Options. (Activate with `--cheats`) Please note that if a cheat asks you to press "L" it's referring to the N64 button. Check your bindings and make sure you have the "L" button mapped to a button in your controller. * Text-based save support. (Activate with `make TEXTSAVES=1`.) + * Recent changes in Nightly have moved save and configuration files, and they will *not* be read from the same directory as the executable. They are now stored in %HOMEPATH%\AppData\Roaming\sm64pc ## Building For building instructions, please refer to the [wiki](https://github.com/sm64pc/sm64pc/wiki). From f1393a4431cb75892df6160291cd682edbc3ffda Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 5 Jun 2020 20:21:44 +0300 Subject: [PATCH 08/29] update xxhash map --- tools/default_crcmap.txt | 531 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 531 insertions(+) diff --git a/tools/default_crcmap.txt b/tools/default_crcmap.txt index 96d18d0e..46439ecc 100644 --- a/tools/default_crcmap.txt +++ b/tools/default_crcmap.txt @@ -1235,3 +1235,534 @@ 0x359500dd, textures/water/jrb_textures.0A000.rgba16.png 0xd4e87a88, textures/water/jrb_textures.0A800.rgba16.png 0x742e8b1b, textures/water/jrb_textures.0B800.rgba16.png +0x0c2a29d1, textures/skybox_tiles/bbh.10.rgba16.png +0x127129a3, textures/skybox_tiles/bbh.35.rgba16.png +0x20a848ef, textures/skybox_tiles/bbh.17.rgba16.png +0x27d1fd7b, textures/skybox_tiles/bbh.9.rgba16.png +0x284ca0c5, textures/skybox_tiles/bbh.18.rgba16.png +0x3696290e, textures/skybox_tiles/bbh.8.rgba16.png +0x3cfb08d4, textures/skybox_tiles/bbh.22.rgba16.png +0x46155549, textures/skybox_tiles/bbh.12.rgba16.png +0x4951ce15, textures/skybox_tiles/bbh.20.rgba16.png +0x4d7bb2d4, textures/skybox_tiles/bbh.26.rgba16.png +0x4dd2efbe, textures/skybox_tiles/bbh.34.rgba16.png +0x5363d67e, textures/skybox_tiles/bbh.5.rgba16.png +0x006b2ac4, textures/skybox_tiles/bbh.6.rgba16.png +0x8a53d88f, textures/skybox_tiles/bbh.7.rgba16.png +0x56a63453, textures/skybox_tiles/bbh.27.rgba16.png +0x6b0abf55, textures/skybox_tiles/bbh.38.rgba16.png +0x72ad931e, textures/skybox_tiles/bbh.39.rgba16.png +0x76a045ea, textures/skybox_tiles/bbh.21.rgba16.png +0x76f1d4a5, textures/skybox_tiles/bbh.29.rgba16.png +0x79c3d825, textures/skybox_tiles/bbh.33.rgba16.png +0x7b1f009f, textures/skybox_tiles/bbh.37.rgba16.png +0x810b81b8, textures/skybox_tiles/bbh.31.rgba16.png +0x83d66711, textures/skybox_tiles/bbh.19.rgba16.png +0x370b42dd, textures/skybox_tiles/bbh.3.rgba16.png +0xad4d5fd6, textures/skybox_tiles/bbh.4.rgba16.png +0xae64c178, textures/skybox_tiles/bbh.24.rgba16.png +0xc31cd553, textures/skybox_tiles/bbh.25.rgba16.png +0xcc6f4232, textures/skybox_tiles/bbh.14.rgba16.png +0xda13b24f, textures/skybox_tiles/bbh.36.rgba16.png +0xe6f9d8a1, textures/skybox_tiles/bbh.28.rgba16.png +0xe7f8bc17, textures/skybox_tiles/bbh.11.rgba16.png +0xe98970f2, textures/skybox_tiles/bbh.32.rgba16.png +0xede2ca8c, textures/skybox_tiles/bbh.40.rgba16.png +0xf5ecf7b1, textures/skybox_tiles/bbh.30.rgba16.png +0xf7e57129, textures/skybox_tiles/bbh.23.rgba16.png +0xf8ba6541, textures/skybox_tiles/bbh.13.rgba16.png +0xf8fda326, textures/skybox_tiles/bbh.16.rgba16.png +0xf97cb7a0, textures/skybox_tiles/bbh.15.rgba16.png +0xf2dec30f, textures/skybox_tiles/bbh.0.rgba16.png +0x043f32a3, textures/skybox_tiles/bidw.13.rgba16.png +0x05ace106, textures/skybox_tiles/bidw.53.rgba16.png +0x0ddbc44f, textures/skybox_tiles/bidw.28.rgba16.png +0x167558ec, textures/skybox_tiles/bidw.51.rgba16.png +0x1ce3eb88, textures/skybox_tiles/bidw.8.rgba16.png +0x2aaa4518, textures/skybox_tiles/bidw.50.rgba16.png +0x3063e9c2, textures/skybox_tiles/bidw.26.rgba16.png +0x318d4424, textures/skybox_tiles/bidw.19.rgba16.png +0x3a4b1e75, textures/skybox_tiles/bidw.42.rgba16.png +0x3a748e08, textures/skybox_tiles/bidw.12.rgba16.png +0x3cb88a7c, textures/skybox_tiles/bidw.18.rgba16.png +0x4741a3f3, textures/skybox_tiles/bidw.10.rgba16.png +0x49be9263, textures/skybox_tiles/bidw.40.rgba16.png +0x4e671fe7, textures/skybox_tiles/bidw.11.rgba16.png +0x5d0c512e, textures/skybox_tiles/bidw.24.rgba16.png +0x672333be, textures/skybox_tiles/bidw.32.rgba16.png +0x6764441d, textures/skybox_tiles/bidw.9.rgba16.png +0x6fd9fab0, textures/skybox_tiles/bidw.23.rgba16.png +0x7609e579, textures/skybox_tiles/bidw.20.rgba16.png +0x7a714bd5, textures/skybox_tiles/bidw.44.rgba16.png +0x7da6e5fc, textures/skybox_tiles/bidw.55.rgba16.png +0x802d3753, textures/skybox_tiles/bidw.27.rgba16.png +0x900d54e9, textures/skybox_tiles/bidw.46.rgba16.png +0x9f7d3512, textures/skybox_tiles/bidw.54.rgba16.png +0xb200de26, textures/skybox_tiles/bidw.34.rgba16.png +0xb867da06, textures/skybox_tiles/bidw.33.rgba16.png +0xc4a3952c, textures/skybox_tiles/bidw.14.rgba16.png +0xc75a4473, textures/skybox_tiles/bidw.22.rgba16.png +0xc9cd900f, textures/skybox_tiles/bidw.47.rgba16.png +0xca24b001, textures/skybox_tiles/bidw.29.rgba16.png +0xcdd80dd0, textures/skybox_tiles/bidw.21.rgba16.png +0xd09450f4, textures/skybox_tiles/bidw.45.rgba16.png +0xd4ae6278, textures/skybox_tiles/bidw.25.rgba16.png +0xd6ada2fc, textures/skybox_tiles/bidw.30.rgba16.png +0xdd5c0937, textures/skybox_tiles/bidw.31.rgba16.png +0xde97d2e7, textures/skybox_tiles/bidw.39.rgba16.png +0xe5ff061e, textures/skybox_tiles/bidw.17.rgba16.png +0xe9f5bc54, textures/skybox_tiles/bidw.49.rgba16.png +0xea4f97d6, textures/skybox_tiles/bidw.43.rgba16.png +0xeb07e789, textures/skybox_tiles/bidw.15.rgba16.png +0xf2fd9c92, textures/skybox_tiles/bidw.41.rgba16.png +0xf3c86fb5, textures/skybox_tiles/bidw.38.rgba16.png +0xf6cc133c, textures/skybox_tiles/bidw.35.rgba16.png +0xf72670a5, textures/skybox_tiles/bidw.48.rgba16.png +0xf852bb6a, textures/skybox_tiles/bidw.16.rgba16.png +0xf9e32a8a, textures/skybox_tiles/bidw.37.rgba16.png +0xfb944dd9, textures/skybox_tiles/bidw.52.rgba16.png +0xfc7d260b, textures/skybox_tiles/bidw.36.rgba16.png +0x066561d2, textures/skybox_tiles/bitfs.9.rgba16.png +0x09b2a8df, textures/skybox_tiles/bitfs.26.rgba16.png +0x0c27c245, textures/skybox_tiles/bitfs.10.rgba16.png +0x0e64a624, textures/skybox_tiles/bitfs.46.rgba16.png +0x12450331, textures/skybox_tiles/bitfs.23.rgba16.png +0x1797df80, textures/skybox_tiles/bitfs.22.rgba16.png +0x19cae2a3, textures/skybox_tiles/bitfs.13.rgba16.png +0x2075bfa7, textures/skybox_tiles/bitfs.27.rgba16.png +0x28043a91, textures/skybox_tiles/bitfs.25.rgba16.png +0x29fe97c9, textures/skybox_tiles/bitfs.40.rgba16.png +0x3fc1264a, textures/skybox_tiles/bitfs.42.rgba16.png +0x4bf7b907, textures/skybox_tiles/bitfs.19.rgba16.png +0x4c0be564, textures/skybox_tiles/bitfs.8.rgba16.png +0x60962f15, textures/skybox_tiles/bitfs.38.rgba16.png +0x6a32e308, textures/skybox_tiles/bitfs.47.rgba16.png +0x74d4dbc0, textures/skybox_tiles/bitfs.34.rgba16.png +0x74f316eb, textures/skybox_tiles/bitfs.37.rgba16.png +0x78005ae7, textures/skybox_tiles/bitfs.30.rgba16.png +0x7a2a0af3, textures/skybox_tiles/bitfs.14.rgba16.png +0x81be4a28, textures/skybox_tiles/bitfs.20.rgba16.png +0x834bcea3, textures/skybox_tiles/bitfs.36.rgba16.png +0x83ea86ce, textures/skybox_tiles/bitfs.31.rgba16.png +0x8bb1fff4, textures/skybox_tiles/bitfs.16.rgba16.png +0x90c37df4, textures/skybox_tiles/bitfs.33.rgba16.png +0xa90a0dcd, textures/skybox_tiles/bitfs.17.rgba16.png +0xac12907e, textures/skybox_tiles/bitfs.35.rgba16.png +0xb82fa554, textures/skybox_tiles/bitfs.24.rgba16.png +0xbe08284c, textures/skybox_tiles/bitfs.29.rgba16.png +0xc02e764f, textures/skybox_tiles/bitfs.44.rgba16.png +0xc676ba59, textures/skybox_tiles/bitfs.39.rgba16.png +0xc69dd89b, textures/skybox_tiles/bitfs.28.rgba16.png +0xce098128, textures/skybox_tiles/bitfs.15.rgba16.png +0xd9e73ad5, textures/skybox_tiles/bitfs.41.rgba16.png +0xe1a812a2, textures/skybox_tiles/bitfs.11.rgba16.png +0xe674aa35, textures/skybox_tiles/bitfs.45.rgba16.png +0xeb4f600c, textures/skybox_tiles/bitfs.43.rgba16.png +0xece60402, textures/skybox_tiles/bitfs.32.rgba16.png +0xede2ca8c, textures/skybox_tiles/bitfs.48.rgba16.png +0xf0253766, textures/skybox_tiles/bitfs.12.rgba16.png +0xfefbfdf7, textures/skybox_tiles/bitfs.21.rgba16.png +0xff7ec174, textures/skybox_tiles/bitfs.18.rgba16.png +0x03ea51ab, textures/skybox_tiles/bits.22.rgba16.png +0x098bdb85, textures/skybox_tiles/bits.42.rgba16.png +0x241e859e, textures/skybox_tiles/bits.55.rgba16.png +0x257fedb8, textures/skybox_tiles/bits.37.rgba16.png +0x2768a71a, textures/skybox_tiles/bits.9.rgba16.png +0x277de620, textures/skybox_tiles/bits.24.rgba16.png +0x2acfffac, textures/skybox_tiles/bits.13.rgba16.png +0x3e7f575b, textures/skybox_tiles/bits.19.rgba16.png +0x41ba5076, textures/skybox_tiles/bits.41.rgba16.png +0x448d1f89, textures/skybox_tiles/bits.54.rgba16.png +0x449f8333, textures/skybox_tiles/bits.16.rgba16.png +0x4d6b3cd7, textures/skybox_tiles/bits.23.rgba16.png +0x5fb1c383, textures/skybox_tiles/bits.49.rgba16.png +0x6011b5ce, textures/skybox_tiles/bits.35.rgba16.png +0x6119b10d, textures/skybox_tiles/bits.48.rgba16.png +0x62533808, textures/skybox_tiles/bits.14.rgba16.png +0x661d9503, textures/skybox_tiles/bits.52.rgba16.png +0x68049672, textures/skybox_tiles/bits.17.rgba16.png +0x688cceba, textures/skybox_tiles/bits.20.rgba16.png +0x7357d6ee, textures/skybox_tiles/bits.50.rgba16.png +0x76c54c50, textures/skybox_tiles/bits.34.rgba16.png +0x7a754f12, textures/skybox_tiles/bits.15.rgba16.png +0x7b2fd37b, textures/skybox_tiles/bits.44.rgba16.png +0x7bb53e7a, textures/skybox_tiles/bits.12.rgba16.png +0x83af50a7, textures/skybox_tiles/bits.11.rgba16.png +0x85b0081b, textures/skybox_tiles/bits.47.rgba16.png +0x93693dc5, textures/skybox_tiles/bits.40.rgba16.png +0x965a0f36, textures/skybox_tiles/bits.25.rgba16.png +0x968b4216, textures/skybox_tiles/bits.26.rgba16.png +0x9bdfce3c, textures/skybox_tiles/bits.31.rgba16.png +0x9de8c051, textures/skybox_tiles/bits.18.rgba16.png +0xa15ad0c6, textures/skybox_tiles/bits.32.rgba16.png +0xa174b0ea, textures/skybox_tiles/bits.33.rgba16.png +0xa4f6be99, textures/skybox_tiles/bits.8.rgba16.png +0xaae75253, textures/skybox_tiles/bits.27.rgba16.png +0xb20701aa, textures/skybox_tiles/bits.21.rgba16.png +0xb43807fd, textures/skybox_tiles/bits.51.rgba16.png +0xb91449bf, textures/skybox_tiles/bits.29.rgba16.png +0xc0348ee3, textures/skybox_tiles/bits.10.rgba16.png +0xc2422c9f, textures/skybox_tiles/bits.36.rgba16.png +0xc56ea37d, textures/skybox_tiles/bits.46.rgba16.png +0xc6caf08d, textures/skybox_tiles/bits.30.rgba16.png +0xd6487ede, textures/skybox_tiles/bits.28.rgba16.png +0xe0a91e79, textures/skybox_tiles/bits.43.rgba16.png +0xecf9eeb6, textures/skybox_tiles/bits.45.rgba16.png +0xf0b8ce1b, textures/skybox_tiles/bits.38.rgba16.png +0xf2ee53ee, textures/skybox_tiles/bits.53.rgba16.png +0xf811fd31, textures/skybox_tiles/bits.39.rgba16.png +0x01a3bc1a, textures/skybox_tiles/cake.30.rgba16.png +0x0aae8e95, textures/skybox_tiles/cake.5.rgba16.png +0x11001a4a, textures/skybox_tiles/cake.31.rgba16.png +0x1106c725, textures/skybox_tiles/cake.19.rgba16.png +0x21cb1a4e, textures/skybox_tiles/cake.15.rgba16.png +0x27c5fa3c, textures/skybox_tiles/cake.0.rgba16.png +0x2ff059ea, textures/skybox_tiles/cake.2.rgba16.png +0x32f30afe, textures/skybox_tiles/cake.4.rgba16.png +0x33a85e50, textures/skybox_tiles/cake.40.rgba16.png +0x3f7975e7, textures/skybox_tiles/cake.27.rgba16.png +0x4112f982, textures/skybox_tiles/cake.6.rgba16.png +0x4ffd88dc, textures/skybox_tiles/cake.10.rgba16.png +0x550a63af, textures/skybox_tiles/cake.26.rgba16.png +0x565f0a85, textures/skybox_tiles/cake.17.rgba16.png +0x5ebb63ae, textures/skybox_tiles/cake.20.rgba16.png +0x650c8963, textures/skybox_tiles/cake.42.rgba16.png +0x6584dbe9, textures/skybox_tiles/cake.38.rgba16.png +0x659d7fe1, textures/skybox_tiles/cake.29.rgba16.png +0x6741387d, textures/skybox_tiles/cake.12.rgba16.png +0x6b37da50, textures/skybox_tiles/cake.14.rgba16.png +0x70cb2193, textures/skybox_tiles/cake.45.rgba16.png +0x75952848, textures/skybox_tiles/cake.43.rgba16.png +0x775f1e4b, textures/skybox_tiles/cake.36.rgba16.png +0x7bcb5633, textures/skybox_tiles/cake.32.rgba16.png +0x7beb1bb0, textures/skybox_tiles/cake.41.rgba16.png +0x83ad1b6f, textures/skybox_tiles/cake.8.rgba16.png +0x866cfdfa, textures/skybox_tiles/cake.3.rgba16.png +0x8ca33ecb, textures/skybox_tiles/cake.46.rgba16.png +0x9118bb8e, textures/skybox_tiles/cake.24.rgba16.png +0xa282f3ab, textures/skybox_tiles/cake.37.rgba16.png +0xb878f75e, textures/skybox_tiles/cake.13.rgba16.png +0xbcbb2bed, textures/skybox_tiles/cake.9.rgba16.png +0xc5e3c848, textures/skybox_tiles/cake.22.rgba16.png +0xc856d784, textures/skybox_tiles/cake.7.rgba16.png +0xca3e4daa, textures/skybox_tiles/cake.16.rgba16.png +0xcda231cf, textures/skybox_tiles/cake.18.rgba16.png +0xd3cda257, textures/skybox_tiles/cake.21.rgba16.png +0xd6acd732, textures/skybox_tiles/cake.35.rgba16.png +0xda4dded5, textures/skybox_tiles/cake.34.rgba16.png +0xdb34e935, textures/skybox_tiles/cake.28.rgba16.png +0xe4659004, textures/skybox_tiles/cake.33.rgba16.png +0xe7fa94ea, textures/skybox_tiles/cake.39.rgba16.png +0xe9ad4123, textures/skybox_tiles/cake.25.rgba16.png +0xf6d7be9d, textures/skybox_tiles/cake.23.rgba16.png +0xff3e3d09, textures/skybox_tiles/cake.11.rgba16.png +0xffa98d17, textures/skybox_tiles/cake.47.rgba16.png +0x055e28ac, textures/skybox_tiles/ccm.2.rgba16.png +0x08383434, textures/skybox_tiles/ccm.51.rgba16.png +0x0b58f779, textures/skybox_tiles/ccm.11.rgba16.png +0x0cc5b13c, textures/skybox_tiles/ccm.22.rgba16.png +0x168d74ac, textures/skybox_tiles/ccm.32.rgba16.png +0x29ae84cd, textures/skybox_tiles/ccm.55.rgba16.png +0x30bd11c3, textures/skybox_tiles/ccm.19.rgba16.png +0x31b35122, textures/skybox_tiles/ccm.54.rgba16.png +0x357312e7, textures/skybox_tiles/ccm.17.rgba16.png +0x36c31293, textures/skybox_tiles/ccm.47.rgba16.png +0x3a0a5f41, textures/skybox_tiles/ccm.43.rgba16.png +0x3cb609ce, textures/skybox_tiles/ccm.14.rgba16.png +0x44e0cd6e, textures/skybox_tiles/ccm.33.rgba16.png +0x50e38d1d, textures/skybox_tiles/ccm.40.rgba16.png +0x578dd0c2, textures/skybox_tiles/ccm.29.rgba16.png +0x599ac9f6, textures/skybox_tiles/ccm.42.rgba16.png +0x59ba83bc, textures/skybox_tiles/ccm.24.rgba16.png +0x64636bec, textures/skybox_tiles/ccm.52.rgba16.png +0x6f828465, textures/skybox_tiles/ccm.28.rgba16.png +0x730366a4, textures/skybox_tiles/ccm.53.rgba16.png +0x78a3267b, textures/skybox_tiles/ccm.30.rgba16.png +0x7944c340, textures/skybox_tiles/ccm.35.rgba16.png +0x7e45011d, textures/skybox_tiles/ccm.49.rgba16.png +0x7ebb4a6e, textures/skybox_tiles/ccm.48.rgba16.png +0x8011bee2, textures/skybox_tiles/ccm.34.rgba16.png +0x8090c3cf, textures/skybox_tiles/ccm.39.rgba16.png +0x85cb24f9, textures/skybox_tiles/ccm.13.rgba16.png +0x92ab7f1d, textures/skybox_tiles/ccm.18.rgba16.png +0x93e1cb7d, textures/skybox_tiles/ccm.21.rgba16.png +0x942a429d, textures/skybox_tiles/ccm.16.rgba16.png +0x95399033, textures/skybox_tiles/ccm.26.rgba16.png +0xa3b76b7a, textures/skybox_tiles/ccm.38.rgba16.png +0xa4f39ec5, textures/skybox_tiles/ccm.12.rgba16.png +0xa799d0e9, textures/skybox_tiles/ccm.37.rgba16.png +0xaf1b0302, textures/skybox_tiles/ccm.3.rgba16.png +0xb4fa1977, textures/skybox_tiles/ccm.25.rgba16.png +0xb724fba4, textures/skybox_tiles/ccm.41.rgba16.png +0xc09f8f08, textures/skybox_tiles/ccm.27.rgba16.png +0xc2afe2ee, textures/skybox_tiles/ccm.44.rgba16.png +0xc9babf94, textures/skybox_tiles/ccm.10.rgba16.png +0xca599652, textures/skybox_tiles/ccm.20.rgba16.png +0xd91118e0, textures/skybox_tiles/ccm.15.rgba16.png +0xe68e0b89, textures/skybox_tiles/ccm.31.rgba16.png +0xe86658ce, textures/skybox_tiles/ccm.9.rgba16.png +0xeef719d5, textures/skybox_tiles/ccm.46.rgba16.png +0xf7f5501b, textures/skybox_tiles/ccm.4.rgba16.png +0xa4f8a848, textures/skybox_tiles/ccm.5.rgba16.png +0xfaad1902, textures/skybox_tiles/ccm.50.rgba16.png +0xfabbf62b, textures/skybox_tiles/ccm.23.rgba16.png +0xfdd2a734, textures/skybox_tiles/ccm.8.rgba16.png +0xfe3ebb6f, textures/skybox_tiles/ccm.45.rgba16.png +0xfe5d53be, textures/skybox_tiles/ccm.36.rgba16.png +0x08f08935, textures/skybox_tiles/clouds.14.rgba16.png +0x0e6243cb, textures/skybox_tiles/clouds.0.rgba16.png +0x141df5ab, textures/skybox_tiles/clouds.2.rgba16.png +0x1901cc3c, textures/skybox_tiles/clouds.34.rgba16.png +0x1b635fef, textures/skybox_tiles/clouds.23.rgba16.png +0x205dcfbc, textures/skybox_tiles/clouds.27.rgba16.png +0x2654ca98, textures/skybox_tiles/clouds.11.rgba16.png +0x31e58403, textures/skybox_tiles/clouds.9.rgba16.png +0x337f44cd, textures/skybox_tiles/clouds.4.rgba16.png +0x351f61ca, textures/skybox_tiles/clouds.20.rgba16.png +0x409b75a9, textures/skybox_tiles/clouds.16.rgba16.png +0x428df875, textures/skybox_tiles/clouds.7.rgba16.png +0x4620fe63, textures/skybox_tiles/clouds.35.rgba16.png +0x498518c8, textures/skybox_tiles/clouds.12.rgba16.png +0x69857ccd, textures/skybox_tiles/clouds.17.rgba16.png +0x742348b6, textures/skybox_tiles/clouds.10.rgba16.png +0x748b76df, textures/skybox_tiles/clouds.5.rgba16.png +0x77ea8d67, textures/skybox_tiles/clouds.32.rgba16.png +0x7ca8732d, textures/skybox_tiles/clouds.8.rgba16.png +0x82b44cf5, textures/skybox_tiles/clouds.28.rgba16.png +0x8425521b, textures/skybox_tiles/clouds.36.rgba16.png +0x850e8b93, textures/skybox_tiles/clouds.19.rgba16.png +0x9cf0dd58, textures/skybox_tiles/clouds.18.rgba16.png +0xa51f3a7f, textures/skybox_tiles/clouds.38.rgba16.png +0xa6f401d3, textures/skybox_tiles/clouds.21.rgba16.png +0xb416ef38, textures/skybox_tiles/clouds.22.rgba16.png +0xc3701e1f, textures/skybox_tiles/clouds.39.rgba16.png +0xc407c4ce, textures/skybox_tiles/clouds.1.rgba16.png +0xc7cbdfa9, textures/skybox_tiles/clouds.26.rgba16.png +0xca8dfd7d, textures/skybox_tiles/clouds.13.rgba16.png +0xd66bcf0e, textures/skybox_tiles/clouds.37.rgba16.png +0xdfa4ba1b, textures/skybox_tiles/clouds.30.rgba16.png +0xe4090da9, textures/skybox_tiles/clouds.6.rgba16.png +0xe52ec690, textures/skybox_tiles/clouds.29.rgba16.png +0xe6525598, textures/skybox_tiles/clouds.33.rgba16.png +0xed76d6f5, textures/skybox_tiles/clouds.31.rgba16.png +0xee5ef53b, textures/skybox_tiles/clouds.24.rgba16.png +0xefceb811, textures/skybox_tiles/clouds.15.rgba16.png +0xf4aaa9e9, textures/skybox_tiles/clouds.25.rgba16.png +0xf86ba27d, textures/skybox_tiles/clouds.40.rgba16.png +0x02170d3b, textures/skybox_tiles/cloud_floor.4.rgba16.png +0x03dceb01, textures/skybox_tiles/cloud_floor.50.rgba16.png +0x03ea3079, textures/skybox_tiles/cloud_floor.18.rgba16.png +0x1a14e17e, textures/skybox_tiles/cloud_floor.25.rgba16.png +0x244d5841, textures/skybox_tiles/cloud_floor.54.rgba16.png +0x28303f4e, textures/skybox_tiles/cloud_floor.3.rgba16.png +0x3171e773, textures/skybox_tiles/cloud_floor.21.rgba16.png +0x32fd7d7b, textures/skybox_tiles/cloud_floor.39.rgba16.png +0x37876087, textures/skybox_tiles/cloud_floor.33.rgba16.png +0x37d2ed5d, textures/skybox_tiles/cloud_floor.29.rgba16.png +0x3b42ebe0, textures/skybox_tiles/cloud_floor.22.rgba16.png +0x3c1887d9, textures/skybox_tiles/cloud_floor.32.rgba16.png +0x4ac6cbe7, textures/skybox_tiles/cloud_floor.53.rgba16.png +0x4acbd2fd, textures/skybox_tiles/cloud_floor.28.rgba16.png +0x4fa6d582, textures/skybox_tiles/cloud_floor.40.rgba16.png +0x5bcfce7a, textures/skybox_tiles/cloud_floor.9.rgba16.png +0x5d9fcb17, textures/skybox_tiles/cloud_floor.23.rgba16.png +0x6106ec02, textures/skybox_tiles/cloud_floor.45.rgba16.png +0x630a785d, textures/skybox_tiles/cloud_floor.15.rgba16.png +0x64bb3d5d, textures/skybox_tiles/cloud_floor.10.rgba16.png +0x66f77672, textures/skybox_tiles/cloud_floor.49.rgba16.png +0x69291043, textures/skybox_tiles/cloud_floor.37.rgba16.png +0x6e0b85e4, textures/skybox_tiles/cloud_floor.35.rgba16.png +0x6f4aa02c, textures/skybox_tiles/cloud_floor.16.rgba16.png +0x7086d27f, textures/skybox_tiles/cloud_floor.30.rgba16.png +0x70ac8f57, textures/skybox_tiles/cloud_floor.1.rgba16.png +0x7fd9be0f, textures/skybox_tiles/cloud_floor.14.rgba16.png +0x821268df, textures/skybox_tiles/cloud_floor.17.rgba16.png +0x83aead23, textures/skybox_tiles/cloud_floor.11.rgba16.png +0x8549ef4a, textures/skybox_tiles/cloud_floor.12.rgba16.png +0x873e1572, textures/skybox_tiles/cloud_floor.52.rgba16.png +0x88dddbd5, textures/skybox_tiles/cloud_floor.47.rgba16.png +0x8db179ed, textures/skybox_tiles/cloud_floor.31.rgba16.png +0x91920a81, textures/skybox_tiles/cloud_floor.26.rgba16.png +0x96c5ec13, textures/skybox_tiles/cloud_floor.5.rgba16.png +0x96e706ed, textures/skybox_tiles/cloud_floor.8.rgba16.png +0x9c8eb32f, textures/skybox_tiles/cloud_floor.46.rgba16.png +0xa17cd54d, textures/skybox_tiles/cloud_floor.6.rgba16.png +0xa5aaaafc, textures/skybox_tiles/cloud_floor.38.rgba16.png +0xb25aabb9, textures/skybox_tiles/cloud_floor.48.rgba16.png +0xb5f978a7, textures/skybox_tiles/cloud_floor.19.rgba16.png +0xba37aa0b, textures/skybox_tiles/cloud_floor.42.rgba16.png +0xc7e7c9e4, textures/skybox_tiles/cloud_floor.13.rgba16.png +0xc94a832f, textures/skybox_tiles/cloud_floor.27.rgba16.png +0xcb05d655, textures/skybox_tiles/cloud_floor.36.rgba16.png +0xd2fb14ef, textures/skybox_tiles/cloud_floor.51.rgba16.png +0xd35408ed, textures/skybox_tiles/cloud_floor.34.rgba16.png +0xdad5f068, textures/skybox_tiles/cloud_floor.44.rgba16.png +0xe4742281, textures/skybox_tiles/cloud_floor.20.rgba16.png +0xf23d736c, textures/skybox_tiles/cloud_floor.43.rgba16.png +0xf27d7297, textures/skybox_tiles/cloud_floor.2.rgba16.png +0xf3e70377, textures/skybox_tiles/cloud_floor.24.rgba16.png +0xf9522d0c, textures/skybox_tiles/cloud_floor.41.rgba16.png +0xfecd3a6e, textures/skybox_tiles/cloud_floor.55.rgba16.png +0x00c6ac78, textures/skybox_tiles/ssl.18.rgba16.png +0x0668c5ac, textures/skybox_tiles/ssl.22.rgba16.png +0x08de5518, textures/skybox_tiles/ssl.31.rgba16.png +0x138a4d7a, textures/skybox_tiles/ssl.12.rgba16.png +0x1e2a18d7, textures/skybox_tiles/ssl.0.rgba16.png +0x2587baea, textures/skybox_tiles/ssl.47.rgba16.png +0x2b9772a8, textures/skybox_tiles/ssl.46.rgba16.png +0x2d35b5e2, textures/skybox_tiles/ssl.24.rgba16.png +0x2f9648f3, textures/skybox_tiles/ssl.40.rgba16.png +0x307cb980, textures/skybox_tiles/ssl.52.rgba16.png +0x4160cce0, textures/skybox_tiles/ssl.23.rgba16.png +0x42069678, textures/skybox_tiles/ssl.13.rgba16.png +0x44e1e374, textures/skybox_tiles/ssl.26.rgba16.png +0x45fe5da4, textures/skybox_tiles/ssl.42.rgba16.png +0x4c315f58, textures/skybox_tiles/ssl.50.rgba16.png +0x4dc86b03, textures/skybox_tiles/ssl.48.rgba16.png +0x514c13e3, textures/skybox_tiles/ssl.49.rgba16.png +0x54f66e8c, textures/skybox_tiles/ssl.25.rgba16.png +0x628aec7f, textures/skybox_tiles/ssl.51.rgba16.png +0x642a4df8, textures/skybox_tiles/ssl.20.rgba16.png +0x6893e588, textures/skybox_tiles/ssl.17.rgba16.png +0x6e8f7556, textures/skybox_tiles/ssl.39.rgba16.png +0x765518a1, textures/skybox_tiles/ssl.38.rgba16.png +0x7d7fc52a, textures/skybox_tiles/ssl.8.rgba16.png +0x7e036561, textures/skybox_tiles/ssl.45.rgba16.png +0x8622dde8, textures/skybox_tiles/ssl.54.rgba16.png +0x87c3cd18, textures/skybox_tiles/ssl.16.rgba16.png +0x89ce2386, textures/skybox_tiles/ssl.27.rgba16.png +0x9273b37c, textures/skybox_tiles/ssl.44.rgba16.png +0x99c39562, textures/skybox_tiles/ssl.7.rgba16.png +0x9c329960, textures/skybox_tiles/ssl.34.rgba16.png +0x9c6384f2, textures/skybox_tiles/ssl.55.rgba16.png +0xaa8831f6, textures/skybox_tiles/ssl.10.rgba16.png +0xb1eb1dd2, textures/skybox_tiles/ssl.30.rgba16.png +0xb24a3c7f, textures/skybox_tiles/ssl.29.rgba16.png +0xb5c53f3b, textures/skybox_tiles/ssl.35.rgba16.png +0xb9d7eed9, textures/skybox_tiles/ssl.43.rgba16.png +0xbc9a5752, textures/skybox_tiles/ssl.14.rgba16.png +0xbd947cf5, textures/skybox_tiles/ssl.1.rgba16.png +0xbfd6d3d6, textures/skybox_tiles/ssl.32.rgba16.png +0xc3e8ef7d, textures/skybox_tiles/ssl.2.rgba16.png +0xcc108f3a, textures/skybox_tiles/ssl.19.rgba16.png +0xd125bb65, textures/skybox_tiles/ssl.37.rgba16.png +0xe24e24cb, textures/skybox_tiles/ssl.15.rgba16.png +0xe47f6782, textures/skybox_tiles/ssl.53.rgba16.png +0xe61795d5, textures/skybox_tiles/ssl.41.rgba16.png +0xe8a2effc, textures/skybox_tiles/ssl.9.rgba16.png +0xea44258d, textures/skybox_tiles/ssl.36.rgba16.png +0xedd3be31, textures/skybox_tiles/ssl.21.rgba16.png +0xee3a78b4, textures/skybox_tiles/ssl.28.rgba16.png +0xf6017084, textures/skybox_tiles/ssl.33.rgba16.png +0xfe0052b0, textures/skybox_tiles/ssl.11.rgba16.png +0x05fbe999, textures/skybox_tiles/water.9.rgba16.png +0x15384ca8, textures/skybox_tiles/water.29.rgba16.png +0x15e589af, textures/skybox_tiles/water.32.rgba16.png +0x19c98c91, textures/skybox_tiles/water.22.rgba16.png +0x2b27b879, textures/skybox_tiles/water.39.rgba16.png +0x2efc6316, textures/skybox_tiles/water.8.rgba16.png +0x3529a790, textures/skybox_tiles/water.40.rgba16.png +0x42b58453, textures/skybox_tiles/water.12.rgba16.png +0x43d0bcfd, textures/skybox_tiles/water.27.rgba16.png +0x455081bb, textures/skybox_tiles/water.38.rgba16.png +0x4d2998ed, textures/skybox_tiles/water.33.rgba16.png +0x4e6390f2, textures/skybox_tiles/water.42.rgba16.png +0x5396e075, textures/skybox_tiles/water.30.rgba16.png +0x55109629, textures/skybox_tiles/water.52.rgba16.png +0x56e0d9c2, textures/skybox_tiles/water.24.rgba16.png +0x57098f04, textures/skybox_tiles/water.55.rgba16.png +0x57a74c47, textures/skybox_tiles/water.51.rgba16.png +0x5fcc8e05, textures/skybox_tiles/water.46.rgba16.png +0x65da8d91, textures/skybox_tiles/water.53.rgba16.png +0x68a54a56, textures/skybox_tiles/water.44.rgba16.png +0x69cc1850, textures/skybox_tiles/water.4.rgba16.png +0x6baa4dfb, textures/skybox_tiles/water.54.rgba16.png +0x6e5dc962, textures/skybox_tiles/water.20.rgba16.png +0x6ff74194, textures/skybox_tiles/water.7.rgba16.png +0x721ba1d7, textures/skybox_tiles/water.13.rgba16.png +0x7484f94f, textures/skybox_tiles/water.26.rgba16.png +0x7e94ae66, textures/skybox_tiles/water.10.rgba16.png +0x8161c698, textures/skybox_tiles/water.0.rgba16.png +0x826ca923, textures/skybox_tiles/water.37.rgba16.png +0x8bd7f18f, textures/skybox_tiles/water.17.rgba16.png +0x996b1ac0, textures/skybox_tiles/water.16.rgba16.png +0x998ccb46, textures/skybox_tiles/water.18.rgba16.png +0x9b9c72dd, textures/skybox_tiles/water.21.rgba16.png +0x9d89ee1a, textures/skybox_tiles/water.14.rgba16.png +0xaa696520, textures/skybox_tiles/water.3.rgba16.png +0xac6b51e7, textures/skybox_tiles/water.1.rgba16.png +0xb42352f6, textures/skybox_tiles/water.19.rgba16.png +0xbc01ae82, textures/skybox_tiles/water.23.rgba16.png +0xbd02c9df, textures/skybox_tiles/water.15.rgba16.png +0xbdac0e79, textures/skybox_tiles/water.50.rgba16.png +0xc08c0b84, textures/skybox_tiles/water.2.rgba16.png +0xc51e6cda, textures/skybox_tiles/water.11.rgba16.png +0xc61b4b9d, textures/skybox_tiles/water.36.rgba16.png +0xc9566f19, textures/skybox_tiles/water.48.rgba16.png +0xce3eff27, textures/skybox_tiles/water.43.rgba16.png +0xd82b465d, textures/skybox_tiles/water.41.rgba16.png +0xd9a7fca5, textures/skybox_tiles/water.47.rgba16.png +0xe35888ec, textures/skybox_tiles/water.31.rgba16.png +0xe51733ce, textures/skybox_tiles/water.28.rgba16.png +0xe5813083, textures/skybox_tiles/water.35.rgba16.png +0x2459fc0d, textures/skybox_tiles/water.5.rgba16.png +0xeb8264d8, textures/skybox_tiles/water.6.rgba16.png +0xf12c7d18, textures/skybox_tiles/water.45.rgba16.png +0xf9cdcba9, textures/skybox_tiles/water.25.rgba16.png +0xfadd22b9, textures/skybox_tiles/water.49.rgba16.png +0xff7aa543, textures/skybox_tiles/water.34.rgba16.png +0x04398d1a, textures/skybox_tiles/wdw.39.rgba16.png +0x04f329d4, textures/skybox_tiles/wdw.20.rgba16.png +0x05785641, textures/skybox_tiles/wdw.19.rgba16.png +0x08e6bb94, textures/skybox_tiles/wdw.48.rgba16.png +0x09f747c7, textures/skybox_tiles/wdw.42.rgba16.png +0x0a612720, textures/skybox_tiles/wdw.53.rgba16.png +0x183c80fa, textures/skybox_tiles/wdw.11.rgba16.png +0x1adca2bd, textures/skybox_tiles/wdw.50.rgba16.png +0x20be7b7f, textures/skybox_tiles/wdw.30.rgba16.png +0x2149c1f6, textures/skybox_tiles/wdw.38.rgba16.png +0x23d9d57c, textures/skybox_tiles/wdw.18.rgba16.png +0x23e53b53, textures/skybox_tiles/wdw.21.rgba16.png +0x270c3681, textures/skybox_tiles/wdw.45.rgba16.png +0x29c249bb, textures/skybox_tiles/wdw.13.rgba16.png +0x2da97b90, textures/skybox_tiles/wdw.43.rgba16.png +0x395577cc, textures/skybox_tiles/wdw.4.rgba16.png +0x4588a1fa, textures/skybox_tiles/wdw.22.rgba16.png +0x45d13c50, textures/skybox_tiles/wdw.26.rgba16.png +0x46215c68, textures/skybox_tiles/wdw.23.rgba16.png +0x4a9c1f83, textures/skybox_tiles/wdw.37.rgba16.png +0x4fb40efe, textures/skybox_tiles/wdw.35.rgba16.png +0x516dd9d6, textures/skybox_tiles/wdw.41.rgba16.png +0x5ad88b52, textures/skybox_tiles/wdw.17.rgba16.png +0x5cd0e0e8, textures/skybox_tiles/wdw.10.rgba16.png +0x6c2d7234, textures/skybox_tiles/wdw.51.rgba16.png +0x729b23e6, textures/skybox_tiles/wdw.25.rgba16.png +0x73a1ddf7, textures/skybox_tiles/wdw.54.rgba16.png +0x75251318, textures/skybox_tiles/wdw.46.rgba16.png +0x85f64761, textures/skybox_tiles/wdw.44.rgba16.png +0x8b2ca649, textures/skybox_tiles/wdw.1.rgba16.png +0x95c7ec28, textures/skybox_tiles/wdw.16.rgba16.png +0x99faf781, textures/skybox_tiles/wdw.27.rgba16.png +0x9d9f818d, textures/skybox_tiles/wdw.14.rgba16.png +0x9f5b79c1, textures/skybox_tiles/wdw.9.rgba16.png +0xa01da5fc, textures/skybox_tiles/wdw.29.rgba16.png +0xa08f6cf7, textures/skybox_tiles/wdw.47.rgba16.png +0xa114940d, textures/skybox_tiles/wdw.2.rgba16.png +0xb59bc572, textures/skybox_tiles/wdw.36.rgba16.png +0xb5c189f8, textures/skybox_tiles/wdw.40.rgba16.png +0xb77c6504, textures/skybox_tiles/wdw.49.rgba16.png +0xb95f40a9, textures/skybox_tiles/wdw.55.rgba16.png +0xbf1724e6, textures/skybox_tiles/wdw.31.rgba16.png +0xc0d56e70, textures/skybox_tiles/wdw.52.rgba16.png +0x42b3e0b5, textures/skybox_tiles/wdw.5.rgba16.png +0x4c61073d, textures/skybox_tiles/wdw.6.rgba16.png +0x7e90bb9f, textures/skybox_tiles/wdw.7.rgba16.png +0xd6d33f3f, textures/skybox_tiles/wdw.8.rgba16.png +0xdc871416, textures/skybox_tiles/wdw.28.rgba16.png +0xdcf416d6, textures/skybox_tiles/wdw.3.rgba16.png +0xdeddb605, textures/skybox_tiles/wdw.24.rgba16.png +0xe4274af3, textures/skybox_tiles/wdw.15.rgba16.png +0xe503f102, textures/skybox_tiles/wdw.12.rgba16.png +0xed75bba0, textures/skybox_tiles/wdw.32.rgba16.png +0xee13a838, textures/skybox_tiles/wdw.33.rgba16.png +0xf1591c2a, textures/skybox_tiles/wdw.34.rgba16.png From e9f0519bc47a7a05e6efa7965ba568dc94ccc818 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 5 Jun 2020 20:23:18 +0300 Subject: [PATCH 09/29] text saves now utilize the save path --- src/game/text_save.inc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 0c34f1b8..39ad1fc4 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -4,7 +4,7 @@ #include "course_table.h" #include "pc/ini.h" -#define FILENAME_FORMAT "save_file_%d.sav" +#define FILENAME_FORMAT "%s/save_file_%d.sav" #define NUM_COURSES 15 #define NUM_BONUS_COURSES 10 #define NUM_FLAGS 21 @@ -87,7 +87,7 @@ static s32 write_text_save(s32 fileIndex) { u32 i, bit, flags, coins, stars, starFlags; /* Define savefile's name */ - if (sprintf(filename, FILENAME_FORMAT, fileIndex) < 0) + if (sprintf(filename, FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; file = fopen(filename, "wt"); @@ -212,7 +212,7 @@ static s32 read_text_save(s32 fileIndex) { u32 capArea; /* Define savefile's name */ - if (sprintf(filename, FILENAME_FORMAT, fileIndex) < 0) + if (sprintf(filename, FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; /* Try to open the file */ From 5d2f4e1ba5f4d3cb33622f74bc736ab774274a63 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 5 Jun 2020 20:26:43 +0300 Subject: [PATCH 10/29] 32 chars is too small for this shit --- src/game/text_save.inc.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 39ad1fc4..29b6851b 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -3,6 +3,7 @@ #include #include "course_table.h" #include "pc/ini.h" +#include "pc/platform.h" #define FILENAME_FORMAT "%s/save_file_%d.sav" #define NUM_COURSES 15 @@ -82,12 +83,12 @@ static s32 write_text_save(s32 fileIndex) { FILE* file; struct SaveFile *savedata; struct MainMenuSaveData *menudata; - char filename[32] = { 0 }; - char value[32] = { 0 }; + char filename[SYS_MAX_PATH] = { 0 }; + char value[SYS_MAX_PATH] = { 0 }; u32 i, bit, flags, coins, stars, starFlags; /* Define savefile's name */ - if (sprintf(filename, FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) + if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; file = fopen(filename, "wt"); @@ -203,8 +204,8 @@ static s32 write_text_save(s32 fileIndex) { * Read gSaveBuffer data from a text-based savefile. */ static s32 read_text_save(s32 fileIndex) { - char filename[32] = { 0 }; - char temp[32] = { 0 }; + char filename[SYS_MAX_PATH] = { 0 }; + char temp[SYS_MAX_PATH] = { 0 }; const char *value; ini_t *savedata; @@ -212,7 +213,7 @@ static s32 read_text_save(s32 fileIndex) { u32 capArea; /* Define savefile's name */ - if (sprintf(filename, FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) + if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; /* Try to open the file */ From bcdaf1338628b3735f1b88e78ecb8e72b5a76a6b Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 5 Jun 2020 20:27:54 +0300 Subject: [PATCH 11/29] add script to unpack .pak-formatted texture packs --- tools/unpak.py | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 tools/unpak.py diff --git a/tools/unpak.py b/tools/unpak.py new file mode 100644 index 00000000..7e515aba --- /dev/null +++ b/tools/unpak.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +# requires Pillow and zstandard for Python +# on msys, install Pillow with +# pacman -S mingw-w64-x86_64-python-pillow +# zstd needs to be compiled, because the one in pip3 fails to do so: +# pacman -S mingw-w64-x86_64-python-setuptools mingw-w64-x86_64-zstd +# git clone https://github.com/indygreg/python-zstandard.git --recursive && cd python-zstandard +# python setup.py build_ext --external clean +# run like this: +# ./unpak.py pakfile.pak outdir tools/default_crcmap.txt +# any files not found in crcmap will go to the "nonmatching" folder + +import os +import sys +import zstd +import struct +from PIL import Image + +PAK_MAGIC = b'\x11\xde\x37\x10\x68\x75\xb6\xe8' + +if len(sys.argv) < 3: + print('usage: unpak []') + sys.exit(1) + +pakfname = sys.argv[1] +outpath = sys.argv[2] +mapfname = "crcmap.txt" +if len(sys.argv) > 3: + mapfname = sys.argv[3] + +# 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) + path = os.path.join(outpath, tok[1].strip()) + if crc in crcmap: + crcmap[crc].append(path) + else: + crcmap[crc] = [path] +except OSError as e: + print('could not open {0}: {1}'.format(mapfname, e)) + sys.exit(2) +except ValueError as e: + print('invalid integer in {0}: {1}'.format(mapfname, e)) + sys.exit(2) + +unmatchdir = os.path.join(outpath, "nonmatching") +if not os.path.exists(unmatchdir): + os.makedirs(unmatchdir) + +# read the PAK +try: + texlist = [] + with open(pakfname, "rb") as f: + magic = f.read(len(PAK_MAGIC)) + if magic != PAK_MAGIC: + print('invalid magic in PAK ' + pakfname) + sys.exit(3) + texcount = int.from_bytes(f.read(8), byteorder='little') + print('reading {0} textures from {1}'.format(texcount, pakfname)) + for i in range(texcount): + crc = int.from_bytes(f.read(4), byteorder='little') + size = int.from_bytes(f.read(4), byteorder='little') + offset = int.from_bytes(f.read(8), byteorder='little') + width = int.from_bytes(f.read(8), byteorder='little') + height = int.from_bytes(f.read(8), byteorder='little') + texlist.append((crc, size, offset, width, height)) + for (crc, size, ofs, w, h) in texlist: + f.seek(ofs) + data = f.read(size) + img = Image.frombytes('RGBA', (w, h), zstd.decompress(data)) + if crc in crcmap: + for path in crcmap[crc]: + [fpath, fname] = os.path.split(path) + if not os.path.exists(fpath): + os.makedirs(fpath) + img.save(path) + else: + print('unknown crc: {0:08x}'.format(crc)) + path = os.path.join(unmatchdir, "{0:08x}.png".format(crc)) + img.save(path) +except OSError as e: + print('could not open {0}: {1}'.format(pakfname, e)) + sys.exit(3) From fa3b68b9c87524b58e52672e7f94336852715ff8 Mon Sep 17 00:00:00 2001 From: luciferin <40036150+hunterzero99@users.noreply.github.com> Date: Fri, 5 Jun 2020 14:07:16 -0400 Subject: [PATCH 12/29] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index efe50eda..7b23d0bc 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ Please contribute **first** to the [nightly branch](https://github.com/sm64pc/sm * Disabling the HUD. * Cheats menu in Options. (Activate with `--cheats`) Please note that if a cheat asks you to press "L" it's referring to the N64 button. Check your bindings and make sure you have the "L" button mapped to a button in your controller. * Text-based save support. (Activate with `make TEXTSAVES=1`.) - * Recent changes in Nightly have moved save and configuration files, and they will *not* be read from the same directory as the executable. They are now stored in %HOMEPATH%\AppData\Roaming\sm64pc + * Recent changes in Nightly have moved the save and configuration file path to %HOMEPATH%\AppData\Roaming\sm64pc + This behaviour can be changed with the `--savepath` CLI option. For example `--savepath .` will read saves from the current directory (which not always matches the exe directory, but most of the time it does); +`--savepath '!'` will read saves from the executable directory. ## Building For building instructions, please refer to the [wiki](https://github.com/sm64pc/sm64pc/wiki). From 55692aebf89404f4bd352aea27ce7ef3350d3c66 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Fri, 5 Jun 2020 21:19:44 +0300 Subject: [PATCH 13/29] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7b23d0bc..882ee891 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ Please contribute **first** to the [nightly branch](https://github.com/sm64pc/sm * Disabling the HUD. * Cheats menu in Options. (Activate with `--cheats`) Please note that if a cheat asks you to press "L" it's referring to the N64 button. Check your bindings and make sure you have the "L" button mapped to a button in your controller. * Text-based save support. (Activate with `make TEXTSAVES=1`.) - * Recent changes in Nightly have moved the save and configuration file path to %HOMEPATH%\AppData\Roaming\sm64pc - This behaviour can be changed with the `--savepath` CLI option. For example `--savepath .` will read saves from the current directory (which not always matches the exe directory, but most of the time it does); -`--savepath '!'` will read saves from the executable directory. + * Recent changes in Nightly have moved the save and configuration file path to `%HOMEPATH%\AppData\Roaming\sm64pc` on Windows and `$HOME/.local/share/sm64pc` on Linux. This behaviour can be changed with the `--savepath` CLI option. + For example `--savepath .` will read saves from the current directory (which not always matches the exe directory, but most of the time it does); + `--savepath '!'` will read saves from the executable directory. ## Building For building instructions, please refer to the [wiki](https://github.com/sm64pc/sm64pc/wiki). From b78997814adab1a3d11efd2208fa066cf4932b44 Mon Sep 17 00:00:00 2001 From: Jordy <33688327+jordy-u@users.noreply.github.com> Date: Sat, 6 Jun 2020 21:34:16 +0200 Subject: [PATCH 14/29] Remove description for the FPS counter The removed description is about applying a patch that does not exist anymore. It is removed from all branches on the 9th of may (commit 7a81769 , 094e570 & 5024cde). --- enhancements/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/enhancements/README.md b/enhancements/README.md index 241d82f3..1bc26dff 100644 --- a/enhancements/README.md +++ b/enhancements/README.md @@ -26,10 +26,6 @@ This allows you to draw 3D boxes for debugging purposes. Call the `debug_box` function whenever you want to draw one. `debug_box` by default takes two arguments: a center and bounds vec3f. This will draw a box starting from the point (center - bounds) to (center + bounds). Use `debug_box_rot` to draw a box rotated in the xz-plane. If you want to draw a box by specifying min and max points, use `debug_box_pos` instead. -## FPS Counter - `fps.patch` - -This patch provides an in-game FPS counter to measure the frame rate. - ## iQue Player Support - `ique_support.patch` This enhancement allows the same ROM to work on both the Nintendo 64 and the iQue Player. From e7218f043b1032ef5003c1fce39cf0399f3beb4e Mon Sep 17 00:00:00 2001 From: Zerocker Date: Sun, 7 Jun 2020 21:16:09 +0900 Subject: [PATCH 15/29] Add separate DEBUG flag for tools --- Makefile | 12 +++--------- tools/Makefile | 30 ++++++++++++++++++++++-------- tools/gen_asset_list.cpp | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index b2154dda..a111fe56 100644 --- a/Makefile +++ b/Makefile @@ -75,9 +75,9 @@ else endif ifeq ($(TARGET_WEB),0) -ifeq ($(HOST_OS),Windows) -WINDOWS_BUILD := 1 -endif + ifeq ($(HOST_OS),Windows) + WINDOWS_BUILD := 1 + endif endif # MXE overrides @@ -96,8 +96,6 @@ endif ifneq ($(TARGET_BITS),0) BITS := -m$(TARGET_BITS) -else - BITS := endif # Release (version) flag defs @@ -340,10 +338,6 @@ GODDARD_C_FILES := $(foreach dir,$(GODDARD_SRC_DIRS),$(wildcard $(dir)/*.c)) GENERATED_C_FILES := $(BUILD_DIR)/assets/mario_anim_data.c $(BUILD_DIR)/assets/demo_data.c \ $(addprefix $(BUILD_DIR)/bin/,$(addsuffix _skybox.c,$(notdir $(basename $(wildcard textures/skyboxes/*.png))))) -ifeq ($(WINDOWS_BUILD),0) - CXX_FILES := -endif - # We need to keep this for now # If we're not N64 use below diff --git a/tools/Makefile b/tools/Makefile index 28ff49bf..d143bb46 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,17 +1,26 @@ UNAME := $(shell uname) +DEBUG ?= 0 + ifeq ($(UNAME),Darwin) - OSX_BUILD := -DOSX_BUILD + OSX_BUILD := -DOSX_BUILD +endif + +ifeq ($(DEBUG),1) + OPT_FLAG := -g +else + OPT_FLAG := -O2 endif CC := gcc -CFLAGS := -Llib -Iinclude -I../include -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 -O3 -s +CXX := g++ +CFLAGS := -Llib -Iinclude -I../include -I . -Wall -Wextra -Wno-unused-parameter $(OSX_BUILD) -pedantic -std=c99 $(OPT_FLAG) -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 n64graphics_CFLAGS := -DN64GRAPHICS_STANDALONE n64graphics_ci_SOURCES := n64graphics_ci_dir/n64graphics_ci.c n64graphics_ci_dir/exoquant/exoquant.c n64graphics_ci_dir/utils.c -n64graphics_ci_CFLAGS := -O2 # 3s faster compile time +n64graphics_ci_CFLAGS := $(OPT_FLAG) mio0_SOURCES := libmio0.c mio0_CFLAGS := -DMIO0_STANDALONE @@ -22,10 +31,10 @@ textconv_SOURCES := textconv.c utf8.c hashtable.c patch_libultra_math_SOURCES := patch_libultra_math.c iplfontutil_SOURCES := iplfontutil.c -iplfontutil_CFLAGS := -O2 # faster compile time +iplfontutil_CFLAGS := $(OPT_FLAG) aifc_decode_SOURCES := aifc_decode.c -aifc_decode_CFLAGS := -O2 # both runs and compiles faster than -O3 +aifc_decode_CFLAGS := $(OPT_FLAG) aiff_extract_codebook_SOURCES := aiff_extract_codebook.c @@ -36,19 +45,24 @@ vadpcm_enc_SOURCES := sdk-tools/adpcm/vadpcm_enc.c sdk-tools/adpcm/vpredictor.c vadpcm_enc_CFLAGS := -Wno-unused-result -Wno-uninitialized -Wno-sign-compare -Wno-absolute-value extract_data_for_mio_SOURCES := extract_data_for_mio.c -extract_data_for_mio_CFLAGS := -O2 +extract_data_for_mio_CFLAGS := $(OPT_FLAG) skyconv_SOURCES := skyconv.c n64graphics.c utils.c -skyconv_CFLAGS := -O2 -lm +skyconv_CFLAGS := $(OPT_FLAG) -lm all: $(PROGRAMS) clean: $(RM) $(PROGRAMS) + $(RM) gen_asset_list define COMPILE $(1): $($1_SOURCES) $(CC) $(CFLAGS) $(OSX_BUILD) $$^ -lm -o $$@ $($1_CFLAGS) endef -$(foreach p,$(PROGRAMS),$(eval $(call COMPILE,$(p)))) +# Separate build for debugging gen_asset_list.cpp +gen_asset_list: + $(CXX) -std=c++17 gen_asset_list.cpp -lstdc++fs $(OPT_FLAG) -Wall -o gen_asset_list + +$(foreach p,$(PROGRAMS),$(eval $(call COMPILE,$(p)))) \ No newline at end of file diff --git a/tools/gen_asset_list.cpp b/tools/gen_asset_list.cpp index 050bd118..3096293e 100644 --- a/tools/gen_asset_list.cpp +++ b/tools/gen_asset_list.cpp @@ -222,7 +222,7 @@ tuple> compileSoundData(const string& lang) { } int main() { - intentional syntax error; // (see comment at top of file) + //intentional syntax error; // (see comment at top of file) map assets; map>> soundAssets; From 808bd99592887dab4d4c00fa492b9ae15ca2bcaa Mon Sep 17 00:00:00 2001 From: Zerocker Date: Sun, 7 Jun 2020 21:38:14 +0900 Subject: [PATCH 16/29] Remove some braindead comments --- src/game/text_save.inc.h | 75 ++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 29b6851b..55f6f85b 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -11,37 +11,32 @@ #define NUM_FLAGS 21 #define NUM_CAP_ON 4 -/* Flag keys */ const char *sav_flags[NUM_FLAGS] = { "file_exists", "wing_cap", "metal_cap", "vanish_cap", "key_1", "key_2", "basement_door", "upstairs_door", "ddd_moved_back", "moat_drained", "pps_door", "wf_door", "ccm_door", "jrb_door", "bitdw_door", - "bitfs_door", "", "", "", "", "50star_door" + "bitfs_door", "", "", "", "", "50star_door" // 4 Cap flags are processed in their own section }; -/* Main course keys */ const char *sav_courses[NUM_COURSES] = { "bob", "wf", "jrb", "ccm", "bbh", "hmc", "lll", "ssl", "ddd", "sl", "wdw", "ttm", "thi", "ttc", "rr" }; -/* Bonus courses keys (including Castle Course) */ const char *sav_bonus_courses[NUM_BONUS_COURSES] = { - "hub", "bitdw", "bitfs", "bits", "pss", "cotmc", - "totwc", "vcutm", "wmotr", "sa", + "bitdw", "bitfs", "bits", "pss", "cotmc", + "totwc", "vcutm", "wmotr", "sa", "hub" // hub is Castle Grounds }; -/* Mario's cap type keys */ const char *cap_on_types[NUM_CAP_ON] = { "ground", "klepto", "ukiki", "mrblizzard" }; -/* Sound modes */ const char *sound_modes[3] = { "stereo", "mono", "headset" }; -/* Get current timestamp */ +/* Get current timestamp string */ static void get_timestamp(char* buffer) { time_t timer; struct tm* tm_info; @@ -77,7 +72,7 @@ static u32 int_to_bin(u32 n) { } /** - * Write SaveFile and MainMenuSaveData structs to a text-based savefile. + * Write SaveFile and MainMenuSaveData structs to a text-based savefile */ static s32 write_text_save(s32 fileIndex) { FILE* file; @@ -87,7 +82,6 @@ static s32 write_text_save(s32 fileIndex) { char value[SYS_MAX_PATH] = { 0 }; u32 i, bit, flags, coins, stars, starFlags; - /* Define savefile's name */ if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; @@ -95,60 +89,53 @@ static s32 write_text_save(s32 fileIndex) { if (file == NULL) return -1; else - printf("Updating savefile in '%s'\n", filename); + printf("Saving updated progress to '%s'\n", filename); - /* Write header */ fprintf(file, "# Super Mario 64 save file\n"); fprintf(file, "# Comment starts with #\n"); fprintf(file, "# True = 1, False = 0\n"); - /* Write current timestamp */ get_timestamp(value); fprintf(file, "# %s\n", value); - /* Write MainMenuSaveData info */ menudata = &gSaveBuffer.menuData[0]; fprintf(file, "\n[menu]\n"); fprintf(file, "coin_score_age = %d\n", menudata->coinScoreAges[fileIndex]); - /* Sound mode */ if (menudata->soundMode == 0) { - fprintf(file, "sound_mode = %s\n", sound_modes[0]); // stereo + fprintf(file, "sound_mode = %s\n", sound_modes[0]); // stereo } else if (menudata->soundMode == 3) { - fprintf(file, "sound_mode = %s\n", sound_modes[1]); // mono + fprintf(file, "sound_mode = %s\n", sound_modes[1]); // mono } else if (menudata->soundMode == 1) { - fprintf(file, "sound_mode = %s\n", sound_modes[2]); // headset + fprintf(file, "sound_mode = %s\n", sound_modes[2]); // headset } else { printf("Undefined sound mode!"); return -1; } - /* Write all flags */ fprintf(file, "\n[flags]\n"); for (i = 1; i < NUM_FLAGS; i++) { if (strcmp(sav_flags[i], "")) { flags = save_file_get_flags(); - flags = (flags & (1 << i)); /* Get a specific bit */ - flags = (flags) ? 1 : 0; /* Determine if bit is set or not */ + flags = (flags & (1 << i)); // Get 'star' flag bit + flags = (flags) ? 1 : 0; fprintf(file, "%s = %d\n", sav_flags[i], flags); } } - /* Write coin count and star flags from each course (except Castle Grounds) */ fprintf(file, "\n[courses]\n"); for (i = 0; i < NUM_COURSES; i++) { stars = save_file_get_star_flags(fileIndex, i); coins = save_file_get_course_coin_score(fileIndex, i); - starFlags = int_to_bin(stars); /* 63 -> 111111 */ + starFlags = int_to_bin(stars); // 63 -> 111111 fprintf(file, "%s = \"%d, %07d\"\n", sav_courses[i], coins, starFlags); } - /* Write star flags from each bonus cource (including Castle Grounds) */ fprintf(file, "\n[bonus]\n"); for (i = 0; i < NUM_BONUS_COURSES; i++) { if (i == 0) { @@ -161,20 +148,18 @@ static s32 write_text_save(s32 fileIndex) { fprintf(file, "%s = %d\n", sav_bonus_courses[i], starFlags); } - /* Write who steal Mario's cap */ fprintf(file, "\n[cap]\n"); for (i = 0; i < NUM_CAP_ON; i++) { - flags = save_file_get_flags(); // Read all flags - bit = (1 << (i+16)); // Determine current flag - flags = (flags & bit); // Get `cap` flag - flags = (flags) ? 1 : 0; // Determine if bit is set or not + flags = save_file_get_flags(); + bit = (1 << (i+16)); // Determine current flag + flags = (flags & bit); // Get 'cap' flag bit + flags = (flags) ? 1 : 0; if (flags) { fprintf(file, "type = %s\n", cap_on_types[i]); break; } } - /* Write in what course and area Mario losted its cap, and cap's position */ savedata = &gSaveBuffer.files[fileIndex][0]; switch(savedata->capLevel) { case COURSE_SSL: @@ -192,7 +177,7 @@ static s32 write_text_save(s32 fileIndex) { } fprintf(file, "area = %d\n", savedata->capArea); - /* Update a backup */ + // Backup is nessecary for saving recent progress after gameover bcopy(&gSaveBuffer.files[fileIndex][0], &gSaveBuffer.files[fileIndex][1], sizeof(gSaveBuffer.files[fileIndex][1])); @@ -201,7 +186,7 @@ static s32 write_text_save(s32 fileIndex) { } /** - * Read gSaveBuffer data from a text-based savefile. + * Read gSaveBuffer data from a text-based savefile */ static s32 read_text_save(s32 fileIndex) { char filename[SYS_MAX_PATH] = { 0 }; @@ -212,11 +197,9 @@ static s32 read_text_save(s32 fileIndex) { u32 i, flag, coins, stars, starFlags; u32 capArea; - /* Define savefile's name */ if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) return -1; - /* Try to open the file */ savedata = ini_load(filename); if (savedata == NULL) { return -1; @@ -224,7 +207,6 @@ static s32 read_text_save(s32 fileIndex) { printf("Loading savefile from '%s'\n", filename); } - /* Read coin score age for selected file and sound mode */ ini_sget(savedata, "menu", "coin_score_age", "%d", &gSaveBuffer.menuData[0].coinScoreAges[fileIndex]); @@ -245,32 +227,29 @@ static s32 read_text_save(s32 fileIndex) { return -1; } - /* Parse main flags */ for (i = 1; i < NUM_FLAGS; i++) { value = ini_get(savedata, "flags", sav_flags[i]); if (value) { flag = strtol(value, &temp, 10); if (flag) { - flag = 1 << i; /* Look #define in header.. */ + flag = 1 << i; // Flags defined in 'save_file' header gSaveBuffer.files[fileIndex][0].flags |= flag; } } } - /* Parse coin and star values for each main course */ for (i = 0; i < NUM_COURSES; i++) { value = ini_get(savedata, "courses", sav_courses[i]); if (value) { sscanf(value, "%d, %d", &coins, &stars); - starFlags = bin_to_int(stars); /* 111111 -> 63 */ + starFlags = bin_to_int(stars); // 111111 -> 63 save_file_set_star_flags(fileIndex, i, starFlags); gSaveBuffer.files[fileIndex][0].courseCoinScores[i] = coins; } } - /* Parse star values for each bonus course */ for (i = 0; i < NUM_BONUS_COURSES; i++) { value = ini_get(savedata, "bonus", sav_bonus_courses[i]); if (value) { @@ -278,19 +257,18 @@ static s32 read_text_save(s32 fileIndex) { starFlags = bin_to_int(stars); if (strlen(value) == 5) { - /* Process Castle Grounds */ + // Process Castle Grounds save_file_set_star_flags(fileIndex, -1, starFlags); } else if (strlen(value) == 2) { - /* Process Princess's Secret Slide */ + // Process Princess's Secret Slide save_file_set_star_flags(fileIndex, COURSE_PSS, starFlags); } else { - /* Process another shitty bonus course */ + // Process bonus courses save_file_set_star_flags(fileIndex, i+15, starFlags); } } } - /* Find, who steal Mario's cap ... */ for (i = 0; i < NUM_CAP_ON; i++) { value = ini_get(savedata, "cap", "type"); if (value) { @@ -302,7 +280,6 @@ static s32 read_text_save(s32 fileIndex) { } } - /* ... it's level ... */ value = ini_get(savedata, "cap", "level"); if (value) { if (strcmp(value, "ssl") == 0) { @@ -323,7 +300,6 @@ static s32 read_text_save(s32 fileIndex) { } } - /* ... and it's area */ value = ini_get(savedata, "cap", "area"); if (value) { sscanf(value, "%d", &capArea); @@ -336,14 +312,13 @@ static s32 read_text_save(s32 fileIndex) { } } - /* Good, file exists for gSaveBuffer */ + // Good, file exists for gSaveBuffer gSaveBuffer.files[fileIndex][0].flags |= SAVE_FLAG_FILE_EXISTS; - /* Make a backup */ + // Backup is nessecary for saving recent progress after gameover bcopy(&gSaveBuffer.files[fileIndex][0], &gSaveBuffer.files[fileIndex][1], sizeof(gSaveBuffer.files[fileIndex][1])); - /* Cleaning up after ourselves */ ini_free(savedata); return 0; } From 6733bdb3ae9cd640e4cb5136b81ff8aee61b95c4 Mon Sep 17 00:00:00 2001 From: Zerocker Date: Sun, 7 Jun 2020 21:44:00 +0900 Subject: [PATCH 17/29] Fix parsing for bonus and cap data --- src/game/text_save.inc.h | 49 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 55f6f85b..8128711e 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -5,7 +5,7 @@ #include "pc/ini.h" #include "pc/platform.h" -#define FILENAME_FORMAT "%s/save_file_%d.sav" +#define FILENAME_FORMAT "%s\\sm64_save_file_%d.sav" #define NUM_COURSES 15 #define NUM_BONUS_COURSES 10 #define NUM_FLAGS 21 @@ -86,9 +86,10 @@ static s32 write_text_save(s32 fileIndex) { return -1; file = fopen(filename, "wt"); - if (file == NULL) + if (file == NULL) { + printf("Savefile '%s' not found!\n", path); return -1; - else + } else printf("Saving updated progress to '%s'\n", filename); fprintf(file, "# Super Mario 64 save file\n"); @@ -138,14 +139,26 @@ static s32 write_text_save(s32 fileIndex) { fprintf(file, "\n[bonus]\n"); for (i = 0; i < NUM_BONUS_COURSES; i++) { - if (i == 0) { - stars = save_file_get_star_flags(fileIndex, -1); - } else { - stars = save_file_get_star_flags(fileIndex, i+14); - } - starFlags = int_to_bin(stars); + char *format; - fprintf(file, "%s = %d\n", sav_bonus_courses[i], starFlags); + if (i == NUM_BONUS_COURSES-1) { + // Process Castle Grounds + stars = save_file_get_star_flags(fileIndex, -1); + format = "%05d"; + } else if (i == 3) { + // Process Princess's Secret Slide + stars = save_file_get_star_flags(fileIndex, 18); + format = "%02d"; + } else { + // Process bonus courses + stars = save_file_get_star_flags(fileIndex, i+15); + format = "%d"; + } + + starFlags = int_to_bin(stars); + if (sprintf(value, format, starFlags) < 0) + return -1; + fprintf(file, "%s = %s\n", sav_bonus_courses[i], value); } fprintf(file, "\n[cap]\n"); @@ -172,10 +185,11 @@ static s32 write_text_save(s32 fileIndex) { fprintf(file, "level = %s\n", "ttm"); break; default: - fprintf(file, "level = %s\n", "none"); break; } - fprintf(file, "area = %d\n", savedata->capArea); + if (savedata->capLevel) { + fprintf(file, "area = %d\n", savedata->capArea); + } // Backup is nessecary for saving recent progress after gameover bcopy(&gSaveBuffer.files[fileIndex][0], &gSaveBuffer.files[fileIndex][1], @@ -261,7 +275,7 @@ static s32 read_text_save(s32 fileIndex) { save_file_set_star_flags(fileIndex, -1, starFlags); } else if (strlen(value) == 2) { // Process Princess's Secret Slide - save_file_set_star_flags(fileIndex, COURSE_PSS, starFlags); + save_file_set_star_flags(fileIndex, 18, starFlags); } else { // Process bonus courses save_file_set_star_flags(fileIndex, i+15, starFlags); @@ -283,16 +297,13 @@ static s32 read_text_save(s32 fileIndex) { value = ini_get(savedata, "cap", "level"); if (value) { if (strcmp(value, "ssl") == 0) { - gSaveBuffer.files[fileIndex][0].capLevel = 8; // ssl + gSaveBuffer.files[fileIndex][0].capLevel = COURSE_SSL; // ssl } else if (strcmp(value, "sl") == 0) { - gSaveBuffer.files[fileIndex][0].capLevel = 10; // sl + gSaveBuffer.files[fileIndex][0].capLevel = COURSE_SL; // sl } else if (strcmp(value, "ttm") == 0) { - gSaveBuffer.files[fileIndex][0].capLevel = 12; // ttm - } - else if (strcmp(value, "none") == 0) { - gSaveBuffer.files[fileIndex][0].capLevel = 0; + gSaveBuffer.files[fileIndex][0].capLevel = COURSE_TTM; // ttm } else { printf("Invalid 'cap:level' flag!\n"); From f6ab82d144fe61ec29156068b54b744974065616 Mon Sep 17 00:00:00 2001 From: Zerocker Date: Sun, 7 Jun 2020 22:19:47 +0900 Subject: [PATCH 18/29] Fix a couple of warnings --- src/game/save_file.c | 2 +- src/game/text_save.inc.h | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/game/save_file.c b/src/game/save_file.c index a8db910b..934b122e 100644 --- a/src/game/save_file.c +++ b/src/game/save_file.c @@ -391,7 +391,6 @@ BAD_RETURN(s32) save_file_copy(s32 srcFileIndex, s32 destFileIndex) { void save_file_load_all(void) { s32 file; - s32 validSlots; gMainMenuDataModified = FALSE; gSaveFileModified = FALSE; @@ -405,6 +404,7 @@ void save_file_load_all(void) { gSaveFileModified = TRUE; gMainMenuDataModified = TRUE; #else + s32 validSlots; read_eeprom_data(&gSaveBuffer, sizeof(gSaveBuffer)); if (save_file_need_bswap(&gSaveBuffer)) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 8128711e..1325f0a5 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -79,7 +79,7 @@ static s32 write_text_save(s32 fileIndex) { struct SaveFile *savedata; struct MainMenuSaveData *menudata; char filename[SYS_MAX_PATH] = { 0 }; - char value[SYS_MAX_PATH] = { 0 }; + char *value; u32 i, bit, flags, coins, stars, starFlags; if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) @@ -87,7 +87,7 @@ static s32 write_text_save(s32 fileIndex) { file = fopen(filename, "wt"); if (file == NULL) { - printf("Savefile '%s' not found!\n", path); + printf("Savefile '%s' not found!\n", filename); return -1; } else printf("Saving updated progress to '%s'\n", filename); @@ -204,7 +204,6 @@ static s32 write_text_save(s32 fileIndex) { */ static s32 read_text_save(s32 fileIndex) { char filename[SYS_MAX_PATH] = { 0 }; - char temp[SYS_MAX_PATH] = { 0 }; const char *value; ini_t *savedata; @@ -243,9 +242,8 @@ static s32 read_text_save(s32 fileIndex) { for (i = 1; i < NUM_FLAGS; i++) { value = ini_get(savedata, "flags", sav_flags[i]); - if (value) { - flag = strtol(value, &temp, 10); + flag = value[0] - '0'; // Flag should be 0 or 1 if (flag) { flag = 1 << i; // Flags defined in 'save_file' header gSaveBuffer.files[fileIndex][0].flags |= flag; From 4feacc0065db65e7c9ef56663d3c481c595fb0b1 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jun 2020 21:05:26 +0300 Subject: [PATCH 19/29] add virtual filesystem thing w/ ZIP support similar to Quake 3: all the archives and folders get mounted to the same mountpoint in the VFS, read access to files in the VFS is transparent --- Makefile | 50 +- include/macros.h | 12 +- include/tinfl.h | 724 +++++++++++++++++++++++++++++ src/audio/load.c | 8 +- src/pc/configfile.c | 36 +- src/pc/controller/controller_sdl.c | 19 +- src/pc/fs/dirtree.c | 137 ++++++ src/pc/fs/dirtree.h | 32 ++ src/pc/fs/fs.c | 443 ++++++++++++++++++ src/pc/fs/fs.h | 136 ++++++ src/pc/fs/fs_packtype_dir.c | 117 +++++ src/pc/fs/fs_packtype_zip.c | 486 +++++++++++++++++++ src/pc/gfx/gfx_opengl.c | 4 +- src/pc/gfx/gfx_opengl_legacy.c | 9 +- src/pc/gfx/gfx_pc.c | 88 ++-- src/pc/pc_main.c | 3 + src/pc/platform.c | 247 +++------- src/pc/platform.h | 23 +- src/pc/ultra_reimplementation.c | 15 +- tools/mkzip.py | 22 + 20 files changed, 2294 insertions(+), 317 deletions(-) create mode 100644 include/tinfl.h create mode 100644 src/pc/fs/dirtree.c create mode 100644 src/pc/fs/dirtree.h create mode 100644 src/pc/fs/fs.c create mode 100644 src/pc/fs/fs.h create mode 100644 src/pc/fs/fs_packtype_dir.c create mode 100644 src/pc/fs/fs_packtype_zip.c create mode 100644 tools/mkzip.py diff --git a/Makefile b/Makefile index a111fe56..8ec64322 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,11 @@ NO_LDIV ?= 0 LEGACY_GL ?= 0 +# Misc settings for EXTERNAL_DATA + +BASEDIR ?= res +BASEPACK ?= base.zip + # Automatic settings for PC port(s) NON_MATCHING := 1 @@ -266,7 +271,7 @@ LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h))) # Directories containing source files # Hi, I'm a PC -SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller +SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes ASM_DIRS := BIN_DIRS := bin bin/$(VERSION) @@ -556,8 +561,8 @@ endif # Load external textures ifeq ($(EXTERNAL_DATA),1) - CC_CHECK += -DEXTERNAL_DATA - CFLAGS += -DEXTERNAL_DATA + CC_CHECK += -DEXTERNAL_DATA -DFS_BASEDIR="\"$(BASEDIR)\"" + CFLAGS += -DEXTERNAL_DATA -DFS_BASEDIR="\"$(BASEDIR)\"" # 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 @@ -619,27 +624,30 @@ all: $(EXE) ifeq ($(EXTERNAL_DATA),1) -# thank you apple very cool -ifeq ($(HOST_OS),Darwin) - CP := gcp -else - CP := cp -endif +BASEPACK_PATH := $(BUILD_DIR)/$(BASEDIR)/$(BASEPACK) +BASEPACK_LST := $(BUILD_DIR)/basepack.lst # depend on resources as well -all: res +all: $(BASEPACK_PATH) -# prepares the resource folder for external data -res: $(EXE) - @mkdir -p $(BUILD_DIR)/res/sound - @$(CP) -r -f textures/ $(BUILD_DIR)/res/ - @$(CP) -r -f $(BUILD_DIR)/textures/skybox_tiles/ $(BUILD_DIR)/res/textures/ - @$(CP) -f $(SOUND_BIN_DIR)/sound_data.ctl $(BUILD_DIR)/res/sound/ - @$(CP) -f $(SOUND_BIN_DIR)/sound_data.tbl $(BUILD_DIR)/res/sound/ - @$(CP) -f $(SOUND_BIN_DIR)/sequences.bin $(BUILD_DIR)/res/sound/ - @$(CP) -f $(SOUND_BIN_DIR)/bank_sets $(BUILD_DIR)/res/sound/ - @find actors -name \*.png -exec $(CP) --parents {} $(BUILD_DIR)/res/ \; - @find levels -name \*.png -exec $(CP) --parents {} $(BUILD_DIR)/res/ \; +# phony target for building resources +res: $(BASEPACK_PATH) + +# prepares the basepack.lst +$(BASEPACK_LST): $(EXE) + @mkdir -p $(BUILD_DIR)/$(BASEDIR) + @echo -n > $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/bank_sets sound/bank_sets" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sequences.bin sound/sequences.bin" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.ctl sound/sound_data.ctl" >> $(BASEPACK_LST) + @echo "$(BUILD_DIR)/sound/sound_data.tbl sound/sound_data.tbl" >> $(BASEPACK_LST) + @find actors -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; + @find levels -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; + @find textures -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; + +# prepares the resource ZIP with base data +$(BASEPACK_PATH): $(BASEPACK_LST) + @$(TOOLS_DIR)/mkzip.py $(BASEPACK_LST) $(BASEPACK_PATH) endif diff --git a/include/macros.h b/include/macros.h index f93642fb..85512d23 100644 --- a/include/macros.h +++ b/include/macros.h @@ -59,11 +59,15 @@ // Convenience macros for endian conversions #if IS_BIG_ENDIAN -#define BE_TO_HOST16(x) (x) -#define BE_TO_HOST32(x) (x) +# define BE_TO_HOST16(x) (x) +# define BE_TO_HOST32(x) (x) +# define LE_TO_HOST16(x) BSWAP16(x) +# define LE_TO_HOST32(x) BSWAP32(x) #else -#define BE_TO_HOST16(x) BSWAP16(x) -#define BE_TO_HOST32(x) BSWAP32(x) +# define BE_TO_HOST16(x) BSWAP16(x) +# define BE_TO_HOST32(x) BSWAP32(x) +# define LE_TO_HOST16(x) (x) +# define LE_TO_HOST32(x) (x) #endif #endif diff --git a/include/tinfl.h b/include/tinfl.h new file mode 100644 index 00000000..b6b31d0a --- /dev/null +++ b/include/tinfl.h @@ -0,0 +1,724 @@ +/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c) + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated May 20, 2011 + Implements RFC 1950: https://www.ietf.org/rfc/rfc1950.txt and RFC 1951: https://www.ietf.org/rfc/rfc1951.txt + + The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers. +*/ +#ifndef TINFL_HEADER_INCLUDED +#define TINFL_HEADER_INCLUDED + +#include + +typedef uint8_t mz_uint8; +typedef int16_t mz_int16; +typedef uint16_t mz_uint16; +typedef uint32_t mz_uint32; +typedef unsigned int mz_uint; +typedef uint64_t mz_uint64; + +/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. */ +typedef unsigned long mz_ulong; + +/* Heap allocation callbacks. */ +typedef void *(*mz_alloc_func)(void *opaque, unsigned int items, unsigned int size); +typedef void (*mz_free_func)(void *opaque, void *address); + +#if defined(_M_IX86) || defined(_M_X64) +/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). */ +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */ +#define MINIZ_LITTLE_ENDIAN 1 +#endif + +#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) +/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) */ +#define MINIZ_HAS_64BIT_REGISTERS 1 +#endif + +/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */ +#ifdef _MSC_VER +#define MZ_MACRO_END while (0, 0) +#else +#define MZ_MACRO_END while (0) +#endif + +/* Decompression flags. */ +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +/* Max size of LZ dictionary. */ +#define TINFL_LZ_DICT_SIZE 32768 + +/* Return status. */ +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +/* Initializes the decompressor to its initial state. */ +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */ +/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */ +static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +/* Internal/private bits follow. */ +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +#endif /* #ifdef TINFL_HEADER_INCLUDED */ + +/* ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) */ + +#ifndef TINFL_HEADER_FILE_ONLY + +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) malloc(x) + #define MZ_FREE(x) free(x) + #define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +/* TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never */ +/* reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. */ +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */ +/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ +/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */ +/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */ +/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */ +/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */ +/* The slow path is only executed at the very end of the input buffer. */ +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +static void tinfl_def_free_func(void *opaque, void *address) { + (void)opaque, (void)address; + MZ_FREE(address); +} + +static void *tinfl_def_alloc_func(void *opaque, unsigned int items, unsigned int size) { + (void)opaque, (void)items, (void)size; + return MZ_MALLOC(items * size); +} + +static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; + static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */ + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other stuff is for advanced use. */ +enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; + +/* Return status codes. MZ_PARAM_ERROR is non-standard. */ +enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; + +/* Compression levels. */ +enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_DEFAULT_COMPRESSION = -1 }; + +/* Window bits */ +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +/* Compression/decompression stream struct. */ +typedef struct mz_stream_s +{ + const unsigned char *next_in; /* pointer to next byte to read */ + unsigned int avail_in; /* number of bytes available at next_in */ + mz_ulong total_in; /* total number of bytes consumed so far */ + + unsigned char *next_out; /* pointer to next byte to write */ + unsigned int avail_out; /* number of bytes that can be written to next_out */ + mz_ulong total_out; /* total number of bytes produced so far */ + + char *msg; /* error msg (unused) */ + struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */ + + mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */ + mz_free_func zfree; /* optional heap free function (defaults to free) */ + void *opaque; /* heap alloc function user pointer */ + + int data_type; /* data_type (unused) */ + mz_ulong adler; /* adler32 of the source or uncompressed data */ + mz_ulong reserved; /* not used */ +} mz_stream; + +typedef mz_stream *mz_streamp; + + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +static int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = tinfl_def_alloc_func; + if (!pStream->zfree) pStream->zfree = tinfl_def_free_func; + + pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +static int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state* pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + + pState = (inflate_state*)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */ + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + /* flush != MZ_FINISH then we must assume there's more input. */ + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for ( ; ; ) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */ + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */ + else if (flush == MZ_FINISH) + { + /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */ + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */ + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +static int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +/* make this a drop-in replacement for zlib... */ + #define voidpf void* + #define uInt unsigned int + #define z_stream mz_stream + #define inflateInit2 mz_inflateInit2 + #define inflate mz_inflate + #define inflateEnd mz_inflateEnd + #define Z_SYNC_FLUSH MZ_SYNC_FLUSH + #define Z_FINISH MZ_FINISH + #define Z_OK MZ_OK + #define Z_STREAM_END MZ_STREAM_END + #define Z_NEED_DICT MZ_NEED_DICT + #define Z_ERRNO MZ_ERRNO + #define Z_STREAM_ERROR MZ_STREAM_ERROR + #define Z_DATA_ERROR MZ_DATA_ERROR + #define Z_MEM_ERROR MZ_MEM_ERROR + #define Z_BUF_ERROR MZ_BUF_ERROR + #define Z_VERSION_ERROR MZ_VERSION_ERROR + #define MAX_WBITS 15 + +#endif /* #ifndef TINFL_HEADER_FILE_ONLY */ + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +*/ + diff --git a/src/audio/load.c b/src/audio/load.c index affc6081..e85fcdf5 100644 --- a/src/audio/load.c +++ b/src/audio/load.c @@ -7,6 +7,7 @@ #include "seqplayer.h" #include "../pc/platform.h" +#include "../pc/fs/fs.h" #define ALIGN16(val) (((val) + 0xF) & ~0xF) @@ -875,11 +876,8 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { # include # include static inline void *load_sound_res(const char *path) { - void *data = sys_load_res(path); - if (!data) { - fprintf(stderr, "could not load sound data from '%s'\n", path); - abort(); - } + void *data = fs_load_file(path, NULL); + if (!data) sys_fatal("could not load sound data from '%s'", path); // FIXME: figure out where it is safe to free this shit // can't free it immediately after in audio_init() return data; diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 79deadb6..ab0f166f 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -5,13 +5,20 @@ #include #include #include -#include + +#if USE_SDL == 2 +# include +# define WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED +#else +# define WINDOWPOS_CENTERED 0 +#endif #include "platform.h" #include "configfile.h" #include "cliopts.h" #include "gfx/gfx_screen_config.h" #include "controller/controller_api.h" +#include "fs/fs.h" #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) @@ -38,8 +45,8 @@ struct ConfigOption { // Video/audio stuff ConfigWindow configWindow = { - .x = SDL_WINDOWPOS_CENTERED, - .y = SDL_WINDOWPOS_CENTERED, + .x = WINDOWPOS_CENTERED, + .y = WINDOWPOS_CENTERED, .w = DESIRED_SCREEN_WIDTH, .h = DESIRED_SCREEN_HEIGHT, .vsync = 1, @@ -130,7 +137,7 @@ static const struct ConfigOption options[] = { // Reads an entire line from a file (excluding the newline character) and returns an allocated string // Returns NULL if no lines could be read from the file -static char *read_file_line(FILE *file) { +static char *read_file_line(fs_file_t *file) { char *buffer; size_t bufferSize = 8; size_t offset = 0; // offset in buffer to write @@ -138,7 +145,7 @@ static char *read_file_line(FILE *file) { buffer = malloc(bufferSize); while (1) { // Read a line from the file - if (fgets(buffer + offset, bufferSize - offset, file) == NULL) { + if (fs_readline(file, buffer + offset, bufferSize - offset) == NULL) { free(buffer); return NULL; // Nothing could be read. } @@ -151,7 +158,7 @@ static char *read_file_line(FILE *file) { break; } - if (feof(file)) // EOF was reached + if (fs_eof(file)) // EOF was reached break; // If no newline or EOF was reached, then the whole line wasn't read. @@ -205,24 +212,17 @@ static unsigned int tokenize_string(char *str, int maxTokens, char **tokens) { // 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; + return (gCLIOpts.ConfigFile[0]) ? gCLIOpts.ConfigFile : CONFIGFILE_DEFAULT; } // Loads the config file specified by 'filename' void configfile_load(const char *filename) { - FILE *file; + fs_file_t *file; char *line; printf("Loading configuration from '%s'\n", filename); - file = fopen(filename, "r"); + file = fs_open(filename); if (file == NULL) { // Create a new config file and save defaults printf("Config file '%s' not found. Creating it.\n", filename); @@ -286,7 +286,7 @@ void configfile_load(const char *filename) { free(line); } - fclose(file); + fs_close(file); } // Writes the config file to 'filename' @@ -295,7 +295,7 @@ void configfile_save(const char *filename) { printf("Saving configuration to '%s'\n", filename); - file = fopen(filename, "w"); + file = fopen(fs_get_write_path(filename), "w"); if (file == NULL) { // error return; diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index 9345daf1..10fe9d71 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -14,6 +14,7 @@ #include "controller_sdl.h" #include "../configfile.h" #include "../platform.h" +#include "../fs/fs.h" #include "game/level_update.h" @@ -92,15 +93,17 @@ static void controller_sdl_init(void) { } // try loading an external gamecontroller mapping file - char gcpath[SYS_MAX_PATH]; - snprintf(gcpath, sizeof(gcpath), "%s/gamecontrollerdb.txt", sys_save_path()); - int nummaps = SDL_GameControllerAddMappingsFromFile(gcpath); - if (nummaps < 0) { - snprintf(gcpath, sizeof(gcpath), "%s/gamecontrollerdb.txt", sys_data_path()); - nummaps = SDL_GameControllerAddMappingsFromFile(gcpath); + uint64_t gcsize = 0; + void *gcdata = fs_load_file("gamecontrollerdb.txt", &gcsize); + if (gcdata && gcsize) { + SDL_RWops *rw = SDL_RWFromConstMem(gcdata, gcsize); + if (rw) { + int nummaps = SDL_GameControllerAddMappingsFromRW(rw, SDL_TRUE); + if (nummaps >= 0) + printf("loaded %d controller mappings from 'gamecontrollerdb.txt'\n", nummaps); + } + free(gcdata); } - if (nummaps >= 0) - printf("loaded %d controller mappings from '%s'\n", nummaps, gcpath); #ifdef BETTERCAMERA if (newcam_mouse == 1) diff --git a/src/pc/fs/dirtree.c b/src/pc/fs/dirtree.c new file mode 100644 index 00000000..3ebdc5fe --- /dev/null +++ b/src/pc/fs/dirtree.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include + +#include "../platform.h" +#include "fs.h" +#include "dirtree.h" + +static inline uint32_t dirtree_hash(const char *s, size_t len) { + // djb hash + uint32_t hash = 5381; + while (len--) hash = ((hash << 5) + hash) ^ *(s++); + return hash & (FS_NUMBUCKETS - 1); +} + +bool fs_dirtree_init(fs_dirtree_t *tree, const size_t entry_len) { + memset(tree, 0, sizeof(*tree)); + + tree->root = malloc(entry_len); + if (!tree->root) return false; + + tree->root->name = ""; // root + tree->root->is_dir = true; + tree->entry_len = entry_len; + + return true; +} + +void fs_dirtree_free(fs_dirtree_t *tree) { + if (!tree) return; + if (tree->root) free(tree->root); + for (int i = 0; i < FS_NUMBUCKETS; ++i) { + fs_dirtree_entry_t *ent, *next; + for (ent = tree->buckets[i]; ent; ent = next) { + next = ent->next_hash; + free(ent); + } + } +} + +static inline fs_dirtree_entry_t *dirtree_add_ancestors(fs_dirtree_t *tree, char *name) { + fs_dirtree_entry_t *ent = tree->root; + + // look for parent directory + char *last_sep = strrchr(name, '/'); + if (!last_sep) return ent; + *last_sep = 0; + ent = fs_dirtree_find(tree, name); + + if (ent) { + *last_sep = '/'; // put the separator back + return ent; // parent directory already in tree + } + + // add the parent directory + ent = fs_dirtree_add(tree, name, true); + *last_sep = '/'; + + return ent; +} + +fs_dirtree_entry_t *fs_dirtree_add(fs_dirtree_t *tree, char *name, const bool is_dir) { + fs_dirtree_entry_t *ent = fs_dirtree_find(tree, name); + if (ent) return ent; + + // add the parent directory into the tree first + fs_dirtree_entry_t *parent = dirtree_add_ancestors(tree, name); + if (!parent) return NULL; + + // we'll plaster the name at the end of the allocated chunk, after the actual entry + const size_t name_len = strlen(name); + const size_t allocsize = tree->entry_len + name_len + 1; + ent = calloc(1, allocsize); + if (!ent) return NULL; + + ent->name = (const char *)ent + tree->entry_len; + strcpy((char *)ent->name, name); + + const uint32_t hash = dirtree_hash(name, name_len); + ent->next_hash = tree->buckets[hash]; + tree->buckets[hash] = ent; + ent->next_sibling = parent->next_child; + ent->is_dir = is_dir; + parent->next_child = ent; + + return ent; +} + +fs_dirtree_entry_t *fs_dirtree_find(fs_dirtree_t *tree, const char *name) { + if (!name) return NULL; + if (!*name) return tree->root; + + const uint32_t hash = dirtree_hash(name, strlen(name)); + + fs_dirtree_entry_t *ent, *prev = NULL; + for (ent = tree->buckets[hash]; ent; ent = ent->next_hash) { + if (!strcmp(ent->name, name)) { + // if this path is not in front of the hash list, move it to the front + // in case of reccurring searches + if (prev) { + prev->next_hash = ent->next_hash; + ent->next_hash = tree->buckets[hash]; + tree->buckets[hash] = ent; + } + return ent; + } + prev = ent; + } + + return NULL; +} + +static fs_walk_result_t dirtree_walk_impl(fs_dirtree_entry_t *ent, walk_fn_t walkfn, void *user, const bool recur) { + fs_walk_result_t res = FS_WALK_SUCCESS;; + ent = ent->next_child; + while (ent && (res == FS_WALK_SUCCESS)) { + if (ent->is_dir) { + if (recur && ent->next_child) + res = dirtree_walk_impl(ent, walkfn, user, recur); + } else if (!walkfn(user, ent->name)) { + res = FS_WALK_INTERRUPTED; + break; + } + ent = ent->next_sibling; + } + return res; +} + +fs_walk_result_t fs_dirtree_walk(void *pack, const char *base, walk_fn_t walkfn, void *user, const bool recur) { + fs_dirtree_t *tree = (fs_dirtree_t *)pack; + + fs_dirtree_entry_t *ent = fs_dirtree_find(tree, base); + if (!ent) return FS_WALK_NOTFOUND; + + return dirtree_walk_impl(ent, walkfn, user, recur); +} diff --git a/src/pc/fs/dirtree.h b/src/pc/fs/dirtree.h new file mode 100644 index 00000000..6793a3a0 --- /dev/null +++ b/src/pc/fs/dirtree.h @@ -0,0 +1,32 @@ +#ifndef _SM64_DIRTREE_H_ +#define _SM64_DIRTREE_H_ + +#include +#include + +#include "fs.h" + +#define FS_NUMBUCKETS 64 + +typedef struct fs_dirtree_entry_s { + const char *name; + bool is_dir; + struct fs_dirtree_entry_s *next_hash, *next_child, *next_sibling; +} fs_dirtree_entry_t; + +typedef struct { + fs_dirtree_entry_t *root; + fs_dirtree_entry_t *buckets[FS_NUMBUCKETS]; + size_t entry_len; +} fs_dirtree_t; + +bool fs_dirtree_init(fs_dirtree_t *tree, const size_t entry_len); +void fs_dirtree_free(fs_dirtree_t *tree); + +fs_dirtree_entry_t *fs_dirtree_add(fs_dirtree_t *tree, char *name, const bool is_dir); +fs_dirtree_entry_t *fs_dirtree_find(fs_dirtree_t *tree, const char *name); + +// the first arg is void* so this could be used in walk() methods of various packtypes +fs_walk_result_t fs_dirtree_walk(void *tree, const char *base, walk_fn_t walkfn, void *user, const bool recur); + +#endif // _SM64_DIRTREE_H_ diff --git a/src/pc/fs/fs.c b/src/pc/fs/fs.c new file mode 100644 index 00000000..d125a60b --- /dev/null +++ b/src/pc/fs/fs.c @@ -0,0 +1,443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#include "macros.h" +#include "../platform.h" +#include "fs.h" + +char fs_gamedir[SYS_MAX_PATH] = ""; +char fs_writepath[SYS_MAX_PATH] = ""; + +struct fs_dir_s { + void *pack; + const char *realpath; + fs_packtype_t *packer; + struct fs_dir_s *prev, *next; +}; + +extern fs_packtype_t fs_packtype_dir; +extern fs_packtype_t fs_packtype_zip; + +static fs_packtype_t *fs_packers[] = { + &fs_packtype_dir, + &fs_packtype_zip, +}; + +static fs_dir_t *fs_searchpaths = NULL; + +static inline fs_dir_t *fs_find_dir(const char *realpath) { + for (fs_dir_t *dir = fs_searchpaths; dir; dir = dir->next) + if (!sys_strcasecmp(realpath, dir->realpath)) + return dir; + return NULL; +} + +static int mount_cmp(const void *p1, const void *p2) { + const char *s1 = *(const char **)p1; + const char *s2 = *(const char **)p2; + + // check if one or both of these are basepacks + const int plen = strlen(FS_BASEPACK_PREFIX); + const bool is_base1 = !strncmp(s1, FS_BASEPACK_PREFIX, plen); + const bool is_base2 = !strncmp(s2, FS_BASEPACK_PREFIX, plen); + + // if both are basepacks, compare the postfixes only + if (is_base1 && is_base2) return strcmp(s1 + plen, s2 + plen); + // if only one is a basepack, it goes first + if (is_base1) return -1; + if (is_base2) return 1; + // otherwise strcmp order + return strcmp(s1, s2); +} + +static void scan_path_dir(const char *ropath, const char *dir) { + char dirpath[SYS_MAX_PATH]; + snprintf(dirpath, sizeof(dirpath), "%s/%s", ropath, dir); + + if (!fs_sys_dir_exists(dirpath)) return; + + // since filename order in readdir() isn't guaranteed, collect paths and sort them in strcmp() order + // (but with basepacks first) + fs_pathlist_t plist = fs_sys_enumerate(dirpath, false); + if (plist.paths) { + qsort(plist.paths, plist.numpaths, sizeof(char *), mount_cmp); + for (int i = 0; i < plist.numpaths; ++i) + fs_mount(plist.paths[i]); + fs_pathlist_free(&plist); + } + + // mount the directory itself + fs_mount(dirpath); +} + +bool fs_init(const char **rodirs, const char *gamedir, const char *writepath) { + char buf[SYS_MAX_PATH]; + + // expand and remember the write path + strncpy(fs_writepath, fs_convert_path(buf, sizeof(buf), writepath), sizeof(fs_writepath)); + fs_writepath[sizeof(fs_writepath)-1] = 0; + printf("fs: writepath set to `%s`\n", fs_writepath); + + // remember the game directory name + strncpy(fs_gamedir, gamedir, sizeof(fs_gamedir)); + fs_gamedir[sizeof(fs_gamedir)-1] = 0; + printf("fs: gamedir set to `%s`\n", fs_gamedir); + + // first, scan all possible paths and mount all basedirs in them + for (const char **p = rodirs; p && *p; ++p) + scan_path_dir(fs_convert_path(buf, sizeof(buf), *p), FS_BASEDIR); + scan_path_dir(fs_writepath, FS_BASEDIR); + + // then mount all the gamedirs in them, if the game dir isn't the same + if (sys_strcasecmp(FS_BASEDIR, fs_gamedir)) { + for (const char **p = rodirs; p && *p; ++p) + scan_path_dir(fs_convert_path(buf, sizeof(buf), *p), fs_gamedir); + scan_path_dir(fs_writepath, fs_gamedir); + } + + // as a special case, mount writepath itself + fs_mount(fs_writepath); + + return true; +} + +bool fs_mount(const char *realpath) { + if (fs_find_dir(realpath)) + return false; // already mounted + + const char *ext = sys_file_extension(realpath); + void *pack = NULL; + fs_packtype_t *packer = NULL; + bool tried = false; + for (unsigned int i = 0; i < sizeof(fs_packers) / sizeof(fs_packers[0]); ++i) { + if (ext && sys_strcasecmp(ext, fs_packers[i]->extension)) + continue; + tried = true; + pack = fs_packers[i]->mount(realpath); + if (pack) { + packer = fs_packers[i]; + break; + } + } + + if (!pack || !packer) { + if (tried) + fprintf(stderr, "fs: could not mount '%s'\n", realpath); + return false; + } + + fs_dir_t *dir = calloc(1, sizeof(fs_dir_t)); + if (!dir) { + packer->unmount(pack); + return false; + } + + dir->pack = pack; + dir->realpath = sys_strdup(realpath); + dir->packer = packer; + dir->prev = NULL; + dir->next = fs_searchpaths; + if (fs_searchpaths) + fs_searchpaths->prev = dir; + fs_searchpaths = dir; + + printf("fs: mounting '%s'\n", realpath); + + return true; +} + +bool fs_unmount(const char *realpath) { + fs_dir_t *dir = fs_find_dir(realpath); + if (dir) { + dir->packer->unmount(dir->pack); + free((void *)dir->realpath); + if (dir->prev) dir->prev->next = dir->next; + if (dir->next) dir->next->prev = dir->prev; + if (dir == fs_searchpaths) fs_searchpaths = dir->next; + free(dir); + return true; + } + return false; +} + +fs_walk_result_t fs_walk(const char *base, walk_fn_t walkfn, void *user, const bool recur) { + bool found = false; + for (fs_dir_t *dir = fs_searchpaths; dir; dir = dir->next) { + fs_walk_result_t res = dir->packer->walk(dir->pack, base, walkfn, user, recur); + if (res == FS_WALK_INTERRUPTED) + return res; + if (res != FS_WALK_NOTFOUND) + found = true; + } + return found ? FS_WALK_SUCCESS : FS_WALK_NOTFOUND; +} + +bool fs_is_file(const char *fname) { + for (fs_dir_t *dir = fs_searchpaths; dir; dir = dir->next) { + if (dir->packer->is_file(dir->pack, fname)) + return true; + } + return false; +} + +bool fs_is_dir(const char *fname) { + for (fs_dir_t *dir = fs_searchpaths; dir; dir = dir->next) { + if (dir->packer->is_dir(dir->pack, fname)) + return true; + } + return false; +} + +fs_file_t *fs_open(const char *vpath) { + for (fs_dir_t *dir = fs_searchpaths; dir; dir = dir->next) { + fs_file_t *f = dir->packer->open(dir->pack, vpath); + if (f) { + f->parent = dir; + return f; + } + } + return NULL; +} + +void fs_close(fs_file_t *file) { + if (!file) return; + file->parent->packer->close(file->parent->pack, file); +} + +int64_t fs_read(fs_file_t *file, void *buf, const uint64_t size) { + if (!file) return -1; + return file->parent->packer->read(file->parent->pack, file, buf, size); +} + +bool fs_seek(fs_file_t *file, const int64_t ofs) { + if (!file) return -1; + return file->parent->packer->seek(file->parent->pack, file, ofs); +} + +int64_t fs_tell(fs_file_t *file) { + if (!file) return -1; + return file->parent->packer->tell(file->parent->pack, file); +} + +int64_t fs_size(fs_file_t *file) { + if (!file) return -1; + return file->parent->packer->size(file->parent->pack, file); +} + +bool fs_eof(fs_file_t *file) { + if (!file) return true; + return file->parent->packer->eof(file->parent->pack, file); +} + +struct matchdata_s { + const char *prefix; + size_t prefix_len; + char *dst; + size_t dst_len; +}; + +static bool match_walk(void *user, const char *path) { + struct matchdata_s *data = (struct matchdata_s *)user; + if (!strncmp(path, data->prefix, data->prefix_len)) { + // found our lad, copy path to destination and terminate + strncpy(data->dst, path, data->dst_len); + data->dst[data->dst_len - 1] = 0; + return false; + } + return true; +} + +const char *fs_match(char *outname, const size_t outlen, const char *prefix) { + struct matchdata_s data = { + .prefix = prefix, + .prefix_len = strlen(prefix), + .dst = outname, + .dst_len = outlen, + }; + + if (fs_walk("", match_walk, &data, true) == FS_WALK_INTERRUPTED) + return outname; + + return NULL; +} + +static bool enumerate_walk(void *user, const char *path) { + fs_pathlist_t *data = (fs_pathlist_t *)user; + + if (data->listcap == data->numpaths) { + data->listcap *= 2; + char **newpaths = realloc(data->paths, data->listcap * sizeof(char *)); + if (!newpaths) return false; + data->paths = newpaths; + } + + data->paths[data->numpaths++] = sys_strdup(path); + return true; +} + +fs_pathlist_t fs_enumerate(const char *base, const bool recur) { + char **paths = malloc(sizeof(char *) * 32); + fs_pathlist_t pathlist = { paths, 0, 32 }; + + if (!paths) return pathlist; + + if (fs_walk(base, enumerate_walk, &pathlist, recur) == FS_WALK_INTERRUPTED) + fs_pathlist_free(&pathlist); + + return pathlist; +} + +void fs_pathlist_free(fs_pathlist_t *pathlist) { + if (!pathlist || !pathlist->paths) return; + for (int i = 0; i < pathlist->numpaths; ++i) + free(pathlist->paths[i]); + free(pathlist->paths); + pathlist->paths = NULL; + pathlist->numpaths = 0; +} + +const char *fs_readline(fs_file_t *file, char *dst, uint64_t size) { + int64_t rx = 0; + char chr, *p; + + // assume we got buffered input + for (p = dst, size--; size > 0; size--) { + if ((rx = fs_read(file, &chr, 1)) <= 0) + break; + *p++ = chr; + if (chr == '\n') + break; + } + + *p = 0; + if (p == dst || rx <= 0) + return NULL; + + return p; +} + +void *fs_load_file(const char *vpath, uint64_t *outsize) { + fs_file_t *f = fs_open(vpath); + if (!f) return NULL; + + int64_t size = fs_size(f); + if (size <= 0) { + fs_close(f); + return NULL; + } + + void *buf = malloc(size); + if (!buf) { + fs_close(f); + return NULL; + } + + int64_t rx = fs_read(f, buf, size); + fs_close(f); + + if (rx < size) { + free(buf); + return NULL; + } + + if (outsize) *outsize = size; + return buf; +} + +const char *fs_get_write_path(const char *vpath) { + static char path[SYS_MAX_PATH]; + snprintf(path, sizeof(path), "%s/%s", fs_writepath, vpath); + return path; +} + +const char *fs_convert_path(char *buf, const size_t bufsiz, const char *path) { + // ! means "executable directory" + if (path[0] == '!') { + snprintf(buf, bufsiz, "%s%s", sys_exe_path(), path + 1); + } else { + strncpy(buf, path, bufsiz); + buf[bufsiz-1] = 0; + } + + // change all backslashes + for (char *p = buf; *p; ++p) + if (*p == '\\') *p = '/'; + + return buf; +} + +/* these operate on the real file system */ + +bool fs_sys_file_exists(const char *name) { + struct stat st; + return (stat(name, &st) == 0 && S_ISREG(st.st_mode)); +} + +bool fs_sys_dir_exists(const char *name) { + struct stat st; + return (stat(name, &st) == 0 && S_ISDIR(st.st_mode)); +} + +bool fs_sys_walk(const char *base, walk_fn_t walk, void *user, const bool recur) { + char fullpath[SYS_MAX_PATH]; + DIR *dir; + struct dirent *ent; + + if (!(dir = opendir(base))) { + fprintf(stderr, "fs_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 (fs_sys_dir_exists(fullpath)) { + if (recur) { + if (!fs_sys_walk(fullpath, walk, user, recur)) { + ret = false; + break; + } + } + } else { + if (!walk(user, fullpath)) { + ret = false; + break; + } + } + } + + closedir(dir); + return ret; +} + +fs_pathlist_t fs_sys_enumerate(const char *base, const bool recur) { + char **paths = malloc(sizeof(char *) * 32); + fs_pathlist_t pathlist = { paths, 0, 32 }; + + if (!paths) return pathlist; + + if (!fs_sys_walk(base, enumerate_walk, &pathlist, recur)) + fs_pathlist_free(&pathlist); + + return pathlist; +} + +bool fs_sys_mkdir(const char *name) { + #ifdef _WIN32 + return _mkdir(name) == 0; + #else + return mkdir(name, 0777) == 0; + #endif +} diff --git a/src/pc/fs/fs.h b/src/pc/fs/fs.h new file mode 100644 index 00000000..e479cfbf --- /dev/null +++ b/src/pc/fs/fs.h @@ -0,0 +1,136 @@ +#ifndef _SM64_FS_H_ +#define _SM64_FS_H_ + +#include +#include +#include +#include + +#include "../platform.h" + +// FS_BASEDIR is usually defined in the build script +#ifndef FS_BASEDIR +# define FS_BASEDIR "res" +#endif + +#ifndef FS_BASEPACK_PREFIX +# define FS_BASEPACK_PREFIX "base" +#endif + +#define FS_TEXTUREDIR "gfx" +#define FS_SOUNDDIR "sound" + +extern char fs_gamedir[]; +extern char fs_userdir[]; +extern const char *fs_ropaths[]; + +// receives the full path +// should return `true` if traversal should continue +// first arg is user data +typedef bool (*walk_fn_t)(void *, const char *); + +typedef enum { + FS_WALK_SUCCESS = 0, + FS_WALK_INTERRUPTED = 1, + FS_WALK_NOTFOUND = 2, + FS_WALK_ERROR = 4, +} fs_walk_result_t; + +// opaque searchpath directory type +typedef struct fs_dir_s fs_dir_t; + +// virtual file handle +typedef struct fs_file_s { + void *handle; // opaque packtype-defined data + fs_dir_t *parent; // directory containing this file +} fs_file_t; + +// list of paths; returned by fs_enumerate() +typedef struct { + char **paths; + int numpaths; + int listcap; +} fs_pathlist_t; + +typedef struct { + const char *extension; // file extensions of this pack type + + void *(*mount)(const char *rpath); // open and initialize pack at real path `rpath` + void (*unmount)(void *pack); // free pack + + // walks the specified directory inside this pack, calling walkfn for each file + // returns FS_WALK_SUCCESS if the directory was successfully opened and walk() didn't ever return false + // returns FS_WALK_INTERRUPTED if the traversal started but walk() returned false at some point + // if recur is true, will recurse into subfolders + fs_walk_result_t (*walk)(void *pack, const char *base, walk_fn_t walkfn, void *user, const bool recur); + + bool (*is_file)(void *pack, const char *path); // returns true if `path` exists in this pack and is a file + bool (*is_dir)(void *pack, const char *path); // returns true if `path` exists in this pack and is a directory + + // file I/O functions; paths are virtual + fs_file_t *(*open)(void *pack, const char *path); // opens a virtual file contained in this pack for reading, returns NULL in case of error + int64_t (*read)(void *pack, fs_file_t *file, void *buf, const uint64_t size); // returns -1 in case of error + bool (*seek)(void *pack, fs_file_t *file, const int64_t ofs); // returns true if seek succeeded + int64_t (*tell)(void *pack, fs_file_t *file); // returns -1 in case of error, current virtual file position otherwise + int64_t (*size)(void *pack, fs_file_t *file); // returns -1 in case of error, size of the (uncompressed) file otherwise + bool (*eof)(void *pack, fs_file_t *file); // returns true if there's nothing more to read + void (*close)(void *pack, fs_file_t *file); // closes a virtual file previously opened with ->open() +} fs_packtype_t; + +// takes the supplied NULL-terminated list of read-only directories and mounts all the packs in them, +// then mounts the directories themselves, then mounts all the packs in `gamedir`, then mounts `gamedir` itself, +// then does the same with `userdir` +// initializes the `fs_gamedir` and `fs_userdir` variables +bool fs_init(const char **rodirs, const char *gamedir, const char *userdir); + +// mounts the pack at physical path `realpath` to the root of the filesystem +// packs mounted later take priority over packs mounted earlier +bool fs_mount(const char *realpath); + +// removes the pack at physical path from the virtual filesystem +bool fs_unmount(const char *realpath); + +/* generalized filesystem functions that call matching packtype functions for each pack in the searchpath */ + +// FIXME: this can walk in unorthodox patterns, since it goes through mountpoints linearly +fs_walk_result_t fs_walk(const char *base, walk_fn_t walkfn, void *user, const bool recur); + +// returns a list of files in the `base` directory +fs_pathlist_t fs_enumerate(const char *base, const bool recur); +// call this on a list returned by fs_enumerate() to free it +void fs_pathlist_free(fs_pathlist_t *pathlist); + +bool fs_is_file(const char *fname); +bool fs_is_dir(const char *fname); + +fs_file_t *fs_open(const char *vpath); +void fs_close(fs_file_t *file); +int64_t fs_read(fs_file_t *file, void *buf, const uint64_t size); +const char *fs_readline(fs_file_t *file, char *dst, const uint64_t size); +bool fs_seek(fs_file_t *file, const int64_t ofs); +int64_t fs_tell(fs_file_t *file); +int64_t fs_size(fs_file_t *file); +bool fs_eof(fs_file_t *file); + +void *fs_load_file(const char *vpath, uint64_t *outsize); +const char *fs_readline(fs_file_t *file, char *dst, uint64_t size); + +// tries to find the first file with the filename that starts with `prefix` +// puts full filename into `outname` and returns it or returns NULL if nothing matches +const char *fs_match(char *outname, const size_t outlen, const char *prefix); + +// takes a virtual path and prepends the write path to it +const char *fs_get_write_path(const char *vpath); + +// expands special chars in paths and changes backslashes to forward slashes +const char *fs_convert_path(char *buf, const size_t bufsiz, const char *path); + +/* these operate on the real filesystem and are used by fs_packtype_dir */ + +bool fs_sys_walk(const char *base, walk_fn_t walk, void *user, const bool recur); +fs_pathlist_t fs_sys_enumerate(const char *base, const bool recur); +bool fs_sys_file_exists(const char *name); +bool fs_sys_dir_exists(const char *name); +bool fs_sys_mkdir(const char *name); // creates with 0777 by default + +#endif // _SM64_FS_H_ diff --git a/src/pc/fs/fs_packtype_dir.c b/src/pc/fs/fs_packtype_dir.c new file mode 100644 index 00000000..afd0c97a --- /dev/null +++ b/src/pc/fs/fs_packtype_dir.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include + +#include "macros.h" +#include "../platform.h" +#include "fs.h" + +static void *pack_dir_mount(const char *realpath) { + if (!fs_sys_dir_exists(realpath)) + return NULL; + // the pack is actually just the real folder path + void *pack = (void *)sys_strdup(realpath); + return pack; +} + +static void pack_dir_unmount(void *pack) { + free(pack); +} + +struct walkdata_s { + size_t baselen; + walk_fn_t userwalk; + void *userdata; +}; + +// wrap the actual user walk function to return virtual paths instead of real paths +static bool packdir_walkfn(void *userdata, const char *path) { + struct walkdata_s *walk = (struct walkdata_s *)userdata; + return walk->userwalk(walk->userdata, path + walk->baselen); +} + +static fs_walk_result_t pack_dir_walk(void *pack, const char *base, walk_fn_t walkfn, void *user, const bool recur) { + char path[SYS_MAX_PATH]; + snprintf(path, SYS_MAX_PATH, "%s/%s", (const char *)pack, base); + + if (!fs_sys_dir_exists(path)) + return FS_WALK_NOTFOUND; + + struct walkdata_s walkdata = { strlen((const char *)pack) + 1, walkfn, user }; + return fs_sys_walk(path, packdir_walkfn, &walkdata, recur); +} + +static bool pack_dir_is_file(void *pack, const char *fname) { + char path[SYS_MAX_PATH]; + snprintf(path, sizeof(path), "%s/%s", (const char *)pack, fname); + return fs_sys_dir_exists(path); +} + +static bool pack_dir_is_dir(void *pack, const char *fname) { + char path[SYS_MAX_PATH]; + snprintf(path, sizeof(path), "%s/%s", (const char *)pack, fname); + return fs_sys_file_exists(path); +} + +static fs_file_t *pack_dir_open(void *pack, const char *vpath) { + char path[SYS_MAX_PATH]; + snprintf(path, sizeof(path), "%s/%s", (const char *)pack, vpath); + + FILE *f = fopen(path, "rb"); + if (!f) return NULL; + + fs_file_t *fsfile = malloc(sizeof(fs_file_t)); + if (!fsfile) { fclose(f); return NULL; } + + fsfile->parent = NULL; + fsfile->handle = f; + + return fsfile; +} + +static void pack_dir_close(UNUSED void *pack, fs_file_t *file) { + fclose((FILE *)file->handle); + free(file); +} + +static int64_t pack_dir_read(UNUSED void *pack, fs_file_t *file, void *buf, const uint64_t size) { + return fread(buf, 1, size, (FILE *)file->handle); +} + +static bool pack_dir_seek(UNUSED void *pack, fs_file_t *file, const int64_t ofs) { + return fseek((FILE *)file->handle, ofs, SEEK_SET) == 0; +} + +static int64_t pack_dir_tell(UNUSED void *pack, fs_file_t *file) { + return ftell((FILE *)file->handle); +} + +static int64_t pack_dir_size(UNUSED void *pack, fs_file_t *file) { + int64_t oldofs = ftell((FILE *)file->handle); + fseek((FILE *)file->handle, 0, SEEK_END); + int64_t size = ftell((FILE *)file->handle); + fseek((FILE *)file->handle, oldofs, SEEK_SET); + return size; +} + +static bool pack_dir_eof(UNUSED void *pack, fs_file_t *file) { + return feof((FILE *)file->handle); +} + +fs_packtype_t fs_packtype_dir = { + "", + pack_dir_mount, + pack_dir_unmount, + pack_dir_walk, + pack_dir_is_file, + pack_dir_is_dir, + pack_dir_open, + pack_dir_read, + pack_dir_seek, + pack_dir_tell, + pack_dir_size, + pack_dir_eof, + pack_dir_close, +}; diff --git a/src/pc/fs/fs_packtype_zip.c b/src/pc/fs/fs_packtype_zip.c new file mode 100644 index 00000000..d331cbe1 --- /dev/null +++ b/src/pc/fs/fs_packtype_zip.c @@ -0,0 +1,486 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include "macros.h" +#include "../platform.h" +#include "fs.h" +#include "dirtree.h" + +#define ZIP_BUFSIZE 16384 +#define ZIP_EOCD_BUFSIZE 65578 + +#define ZIP_LFH_SIG 0x04034b50 +#define ZIP_CDH_SIG 0x02014b50 +#define ZIP_EOCD_SIG 0x06054b50 + +typedef struct { + fs_dirtree_t tree; // this should always be first, so this could be used as a dirtree root + const char *realpath; // physical path to the zip file + FILE *zipf; // open zip file handle, if any +} zip_pack_t; + +typedef struct { + fs_dirtree_entry_t tree; // this should always be first, so this could be used as a dirtree entry + uint64_t ofs; // offset to compressed data in zip + uint16_t bits; // general purpose zip flags + uint16_t comptype; // compression method + uint32_t crc; // CRC-32 + uint64_t comp_size; // size of compressed data in zip + uint64_t uncomp_size; // size of decompressed data + uint16_t attr_int; // internal attributes + uint32_t attr_ext; // external attributes + bool ofs_fixed; // if true, `ofs` points to the file data, otherwise to LFH +} zip_entry_t; + +typedef struct { + zip_entry_t *entry; // the dirtree entry of this file + uint32_t comp_pos; // read position in compressed data + uint32_t uncomp_pos; // read position in uncompressed data + uint8_t *buffer; // decompression buffer (if compressed) + z_stream zstream; // tinfl zlib stream + FILE *fstream; // duplicate of zipf of the parent zip file +} zip_file_t; + +static int64_t zip_find_eocd(FILE *f, int64_t *outlen) { + // the EOCD is somewhere in the last 65557 bytes of the file + // get the total file size + fseek(f, 0, SEEK_END); + const int64_t fsize = ftell(f); + if (fsize <= 16) return -1; // probably not a zip + + const int64_t rx = (fsize < ZIP_EOCD_BUFSIZE ? fsize : ZIP_EOCD_BUFSIZE); + uint8_t *buf = malloc(rx); + if (!buf) return -1; + + // read that entire chunk and search for EOCD backwards from the end + fseek(f, fsize - rx, SEEK_SET); + if (fread(buf, rx, 1, f)) { + for (int64_t i = rx - 8; i >= 0; --i) { + if ((buf[i + 0] == 0x50) && (buf[i + 1] == 0x4B) && + (buf[i + 2] == 0x05) && (buf[i + 3] == 0x06)) { + // gotem + free(buf); + if (outlen) *outlen = fsize; + return fsize - rx + i; + } + } + } + + free(buf); + return -1; +} + +static bool zip_parse_eocd(FILE *f, uint64_t *cdir_ofs, uint64_t *data_ofs, uint64_t *count) { + int64_t fsize = 0; + + // EOCD record struct + struct eocd_s { + uint32_t sig; + uint16_t this_disk; + uint16_t cdir_disk; + uint16_t disk_entry_count; + uint16_t total_entry_count; + uint32_t cdir_size; + uint32_t cdir_ofs; + uint16_t comment_len; + // zip comment follows + } __attribute__((__packed__)); + struct eocd_s eocd; + + // find the EOCD and seek to it + int64_t pos = zip_find_eocd(f, &fsize); + if (pos < 0) return false; + fseek(f, pos, SEEK_SET); + + // read it + if (!fread(&eocd, sizeof(eocd), 1, f)) return false; + + // double check the sig + if (LE_TO_HOST32(eocd.sig) != ZIP_EOCD_SIG) return false; + + // disks should all be 0 + if (eocd.this_disk || eocd.cdir_disk) return false; + + // total entry count should be the same as disk entry count + if (eocd.disk_entry_count != eocd.total_entry_count) return false; + + *count = LE_TO_HOST16(eocd.total_entry_count); + *cdir_ofs = LE_TO_HOST32(eocd.cdir_ofs); + eocd.cdir_size = LE_TO_HOST32(eocd.cdir_size); + + // end of central dir can't be before central dir + if ((uint64_t)pos < *cdir_ofs + eocd.cdir_size) return false; + + *data_ofs = (uint64_t)(pos - (*cdir_ofs + eocd.cdir_size)); + *cdir_ofs += *data_ofs; + + // make sure end of comment matches end of file + eocd.comment_len = LE_TO_HOST16(eocd.comment_len); + return ((pos + 22 + eocd.comment_len) == fsize); +} + +static bool zip_fixup_offset(zip_file_t *zipfile) { + // LFH record struct + struct lfh_s { + uint32_t sig; + uint16_t version_required; + uint16_t bits; + uint16_t comptype; + uint16_t mod_time; + uint16_t mod_date; + uint32_t crc; + uint32_t comp_size; + uint32_t uncomp_size; + uint16_t fname_len; + uint16_t extra_len; + // file name, extra field and data follow + } __attribute__((__packed__)); + + struct lfh_s lfh; + + zip_entry_t *ent = zipfile->entry; + + fseek(zipfile->fstream, ent->ofs, SEEK_SET); + if (!fread(&lfh, sizeof(lfh), 1, zipfile->fstream)) return false; + + // we only need these two + lfh.fname_len = LE_TO_HOST16(lfh.fname_len); + lfh.extra_len = LE_TO_HOST16(lfh.extra_len); + + // ofs will now point to actual data + ent->ofs += sizeof(lfh) + lfh.fname_len + lfh.extra_len; + ent->ofs_fixed = true; // only need to do this once + + return true; +} + +static zip_entry_t *zip_load_entry(FILE *f, fs_dirtree_t *tree, const uint64_t data_ofs) { + // CDH record struct + struct cdh_s { + uint32_t sig; + uint16_t version_used; + uint16_t version_required; + uint16_t bits; + uint16_t comptype; + uint16_t mod_time; + uint16_t mod_date; + uint32_t crc; + uint32_t comp_size; + uint32_t uncomp_size; + uint16_t fname_len; + uint16_t extra_len; + uint16_t comment_len; + uint16_t start_disk; + uint16_t attr_int; + uint32_t attr_ext; + uint32_t lfh_ofs; + // file name, extra field and comment follow + } __attribute__((__packed__)); + + struct cdh_s cdh; + zip_entry_t zipent; + + memset(&zipent, 0, sizeof(zipent)); + + if (!fread(&cdh, sizeof(cdh), 1, f)) return NULL; + + // check cdir entry header signature + if (LE_TO_HOST32(cdh.sig) != ZIP_CDH_SIG) return NULL; + + // byteswap and copy some important fields + zipent.bits = LE_TO_HOST16(cdh.bits); + zipent.comptype = LE_TO_HOST16(cdh.comptype); + zipent.crc = LE_TO_HOST32(cdh.crc); + zipent.comp_size = LE_TO_HOST32(cdh.comp_size); + zipent.uncomp_size = LE_TO_HOST32(cdh.uncomp_size); + zipent.ofs = LE_TO_HOST32(cdh.lfh_ofs); + zipent.attr_int = LE_TO_HOST16(cdh.attr_int); + zipent.attr_ext = LE_TO_HOST32(cdh.attr_ext); + cdh.fname_len = LE_TO_HOST16(cdh.fname_len); + cdh.comment_len = LE_TO_HOST16(cdh.comment_len); + cdh.extra_len = LE_TO_HOST16(cdh.extra_len); + + // read the name + char *name = calloc(1, cdh.fname_len + 1); + if (!name) return NULL; + if (!fread(name, cdh.fname_len, 1, f)) { free(name); return NULL; } + + // this is a directory if the name ends in a path separator + bool is_dir = false; + if (name[cdh.fname_len - 1] == '/') { + is_dir = true; + name[cdh.fname_len - 1] = 0; + } + name[cdh.fname_len] = 0; + + // add to directory tree + zip_entry_t *retent = (zip_entry_t *)fs_dirtree_add(tree, name, is_dir); + free(name); + if (!retent) return NULL; + + // copy the data we read into the new entry + zipent.tree = retent->tree; + memcpy(retent, &zipent, sizeof(zipent)); + + // this points to the LFH now; will be fixed up on file open + // while the CDH includes an "extra field length" field, it's usually different + retent->ofs += data_ofs; + + // skip to the next CDH + fseek(f, cdh.extra_len + cdh.comment_len, SEEK_CUR); + + return retent; +} + +static inline bool zip_load_entries(FILE *f, fs_dirtree_t *tree, const uint64_t cdir_ofs, const uint64_t data_ofs, const uint64_t count) { + fseek(f, cdir_ofs, SEEK_SET); + for (uint64_t i = 0; i < count; ++i) { + if (!zip_load_entry(f, tree, data_ofs)) + return false; + } + return true; +} + +static inline bool is_zip(FILE *f) { + uint32_t sig = 0; + if (fread(&sig, sizeof(sig), 1, f)) { + // the first LFH might be at the start of the zip + if (LE_TO_HOST32(sig) == ZIP_LFH_SIG) + return true; + // no signature, might still be a zip because fuck you + // the only way now is to try and find the end of central directory + return zip_find_eocd(f, NULL) >= 0; + } + return false; +} + +static void *pack_zip_mount(const char *realpath) { + uint64_t cdir_ofs, data_ofs, count; + zip_pack_t *pack = NULL; + FILE *f = NULL; + + f = fopen(realpath, "rb"); + if (!f) goto _fail; + + if (!is_zip(f)) goto _fail; + + pack = calloc(1, sizeof(zip_pack_t)); + if (!pack) goto _fail; + + if (!zip_parse_eocd(f, &cdir_ofs, &data_ofs, &count)) + goto _fail; + + if (!fs_dirtree_init(&pack->tree, sizeof(zip_entry_t))) + goto _fail; + + if (!zip_load_entries(f, &pack->tree, cdir_ofs, data_ofs, count)) + goto _fail; + + pack->realpath = sys_strdup(realpath); + pack->zipf = f; + + return pack; + +_fail: + if (f) fclose(f); + if (pack) free(pack); + return NULL; +} + +static void pack_zip_unmount(void *pack) { + zip_pack_t *zip = (zip_pack_t *)pack; + fs_dirtree_free(&zip->tree); + if (zip->realpath) free((void *)zip->realpath); + if (zip->zipf) fclose(zip->zipf); + free(zip); +} + +static bool pack_zip_is_file(void *pack, const char *fname) { + zip_entry_t *ent = (zip_entry_t *)fs_dirtree_find((fs_dirtree_t *)pack, fname); + return ent && !ent->tree.is_dir; +} + +static bool pack_zip_is_dir(void *pack, const char *fname) { + zip_entry_t *ent = (zip_entry_t *)fs_dirtree_find((fs_dirtree_t *)pack, fname); + return ent && ent->tree.is_dir; +} + +static inline void pack_zip_close_zipfile(zip_file_t *zipfile) { + if (zipfile->buffer) { + inflateEnd(&zipfile->zstream); + free(zipfile->buffer); + } + if (zipfile->fstream) fclose(zipfile->fstream); + free(zipfile); +} + +static fs_file_t *pack_zip_open(void *pack, const char *vpath) { + fs_file_t *fsfile = NULL; + zip_file_t *zipfile = NULL; + zip_pack_t *zip = (zip_pack_t *)pack; + zip_entry_t *ent = (zip_entry_t *)fs_dirtree_find((fs_dirtree_t *)zip, vpath); + if (!ent || ent->tree.is_dir) goto _fail; // we're expecting a fucking file here + + zipfile = calloc(1, sizeof(zip_file_t)); + if (!zipfile) goto _fail; + zipfile->entry = ent; + + // obtain an additional file descriptor + // fdopen(dup(fileno())) is not very portable and might not create separate state + zipfile->fstream = fopen(zip->realpath, "rb"); + if (!zipfile->fstream) goto _fail; + + // make ent->ofs point to the actual file data if it doesn't already + if (!ent->ofs_fixed) + if (!zip_fixup_offset(zipfile)) + goto _fail; // this shouldn't generally happen but oh well + + // if there's compression, assume it's zlib + if (ent->comptype != 0) { + zipfile->buffer = malloc(ZIP_BUFSIZE); + if (!zipfile->buffer) + goto _fail; + if (inflateInit2(&zipfile->zstream, -MAX_WBITS) != Z_OK) + goto _fail; + } + + fsfile = malloc(sizeof(fs_file_t)); + if (!fsfile) goto _fail; + fsfile->handle = zipfile; + fsfile->parent = NULL; + + // point to the start of the file data + fseek(zipfile->fstream, ent->ofs, SEEK_SET); + + return fsfile; + +_fail: + if (zipfile) pack_zip_close_zipfile(zipfile); + if (fsfile) free(fsfile); + return NULL; +} + +static void pack_zip_close(UNUSED void *pack, fs_file_t *file) { + if (!file) return; + + zip_file_t *zipfile = (zip_file_t *)file->handle; + if (zipfile) pack_zip_close_zipfile(zipfile); + + free(file); +} + +static int64_t pack_zip_read(UNUSED void *pack, fs_file_t *file, void *buf, const uint64_t size) { + zip_file_t *zipfile = (zip_file_t *)file->handle; + zip_entry_t *ent = zipfile->entry; + + int64_t avail = ent->uncomp_size - zipfile->uncomp_pos; + int64_t max_read = ((int64_t)size > avail) ? avail : (int64_t)size; + int64_t rx = 0; + int err = 0; + + if (max_read == 0) return 0; + + if (ent->comptype == 0) { + // no compression, just read + rx = fread(buf, 1, size, zipfile->fstream); + } else { + zipfile->zstream.next_out = buf; + zipfile->zstream.avail_out = (unsigned int)max_read; + while (rx < max_read) { + const uint32_t before = (uint32_t)zipfile->zstream.total_out; + // check if we ran out of compressed bytes and read more if we did + if (zipfile->zstream.avail_in == 0) { + int32_t comp_rx = ent->comp_size - zipfile->comp_pos; + if (comp_rx > 0) { + if (comp_rx > ZIP_BUFSIZE) comp_rx = ZIP_BUFSIZE; + comp_rx = fread(zipfile->buffer, 1, comp_rx, zipfile->fstream); + if (comp_rx == 0) break; + zipfile->comp_pos += (uint32_t)comp_rx; + zipfile->zstream.next_in = zipfile->buffer; + zipfile->zstream.avail_in = (unsigned int)comp_rx; + } + } + // inflate + err = inflate(&zipfile->zstream, Z_SYNC_FLUSH); + rx += zipfile->zstream.total_out - before; + if (err != Z_OK) break; + } + } + + zipfile->uncomp_pos += rx; + return rx; +} + +static bool pack_zip_seek(UNUSED void *pack, fs_file_t *file, const int64_t ofs) { + zip_file_t *zipfile = (zip_file_t *)file->handle; + zip_entry_t *ent = zipfile->entry; + uint8_t buf[512]; + + if (ofs > (int64_t)ent->uncomp_size) return false; + + if (ent->comptype == 0) { + if (fseek(zipfile->fstream, ofs + ent->ofs, SEEK_SET) == 0) + zipfile->uncomp_pos = ofs; + } else { + // if seeking backwards, gotta redecode the stream from the start until that point + // so we make a copy of the zstream and clear it with a new one + if (ofs < zipfile->uncomp_pos) { + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + if (inflateInit2(&zstream, -MAX_WBITS) != Z_OK) + return false; + // reset the underlying file handle back to the start + if (fseek(zipfile->fstream, ent->ofs, SEEK_SET) != 0) + return false; + // free and replace the old one + inflateEnd(&zipfile->zstream); + memcpy(&zipfile->zstream, &zstream, sizeof(zstream)); + zipfile->uncomp_pos = zipfile->comp_pos = 0; + } + // continue decoding the stream until we hit the new offset + while (zipfile->uncomp_pos != ofs) { + uint32_t max_read = (uint32_t)(ofs - zipfile->uncomp_pos); + if (max_read > sizeof(buf)) max_read = sizeof(buf); + if (pack_zip_read(pack, file, buf, max_read) != max_read) + return false; + } + } + + return true; +} + +static int64_t pack_zip_tell(UNUSED void *pack, fs_file_t *file) { + return ((zip_file_t *)file->handle)->uncomp_pos; +} + +static int64_t pack_zip_size(UNUSED void *pack, fs_file_t *file) { + zip_file_t *zipfile = (zip_file_t *)file->handle; + return zipfile->entry->uncomp_size; +} + +static bool pack_zip_eof(UNUSED void *pack, fs_file_t *file) { + zip_file_t *zipfile = (zip_file_t *)file->handle; + return zipfile->uncomp_pos >= zipfile->entry->uncomp_size; +} + +fs_packtype_t fs_packtype_zip = { + "zip", + pack_zip_mount, + pack_zip_unmount, + fs_dirtree_walk, + pack_zip_is_file, + pack_zip_is_dir, + pack_zip_open, + pack_zip_read, + pack_zip_seek, + pack_zip_tell, + pack_zip_size, + pack_zip_eof, + pack_zip_close, +}; diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index 7909d341..a0c27bed 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -317,7 +317,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad fprintf(stderr, "Vertex shader compilation failed\n"); glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]); fprintf(stderr, "%s\n", &error_log[0]); - abort(); + sys_fatal("vertex shader compilation failed (see terminal)"); } GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); @@ -331,7 +331,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad fprintf(stderr, "Fragment shader compilation failed\n"); glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]); fprintf(stderr, "%s\n", &error_log[0]); - abort(); + sys_fatal("fragment shader compilation failed (see terminal)"); } GLuint shader_program = glCreateProgram(); diff --git a/src/pc/gfx/gfx_opengl_legacy.c b/src/pc/gfx/gfx_opengl_legacy.c index 21dc4a00..6ff04a78 100644 --- a/src/pc/gfx/gfx_opengl_legacy.c +++ b/src/pc/gfx/gfx_opengl_legacy.c @@ -516,17 +516,16 @@ static void gfx_opengl_init(void) { int vmajor, vminor; bool is_es = false; gl_get_version(&vmajor, &vminor, &is_es); - if (vmajor < 2 && vminor < 2 && !is_es) { - fprintf(stderr, "OpenGL 1.2+ is required. Reported version: %s%d.%d\n", is_es ? "ES" : "", vmajor, vminor); - abort(); - } + if (vmajor < 2 && vminor < 2 && !is_es) + sys_fatal("OpenGL 1.2+ is required. Reported version: %s%d.%d\n", is_es ? "ES" : "", vmajor, vminor); // check extensions that we need const bool supported = gl_check_ext("GL_ARB_multitexture") && gl_check_ext("GL_ARB_texture_env_combine"); - if (!supported) abort(); + if (!supported) + sys_fatal("required GL extensions are not supported"); gl_adv_fog = false; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 1e86ec5a..8e8a7e51 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -26,6 +26,7 @@ #include "../platform.h" #include "../configfile.h" +#include "../fs/fs.h" #define SUPPORT_CHECK(x) assert(x) @@ -494,6 +495,28 @@ static void import_texture_ci8(int tile) { #else // EXTERNAL_DATA +static inline void load_texture(const char *fullpath) { + int w, h; + u64 imgsize = 0; + u8 *imgdata = fs_load_file(fullpath, &imgsize); + if (!imgdata) { + fprintf(stderr, "could not open texture: `%s`\n", fullpath); + return; + } + + // TODO: implement stbi_callbacks or some shit instead of loading the whole texture + u8 *data = stbi_load_from_memory(imgdata, imgsize, &w, &h, NULL, 4); + free(imgdata); + if (!data) { + fprintf(stderr, "could not load texture: `%s`\n", fullpath); + return; + } + + gfx_rapi->upload_texture(data, w, h); + stbi_image_free(data); // don't need this anymore +} + + // this is taken straight from n64graphics static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) { static const struct { @@ -531,7 +554,7 @@ static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) { // 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) { +static bool preload_texture(void *user, const char *path) { // strip off the extension char texname[SYS_MAX_PATH]; strncpy(texname, path, sizeof(texname)); @@ -546,55 +569,20 @@ static bool preload_texture(const char *path) { 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; + char *actualname = texname; + // strip off the prefix // TODO: make a fs_ function for this shit + if (!strncmp(FS_TEXTUREDIR "/", actualname, 4)) actualname += 4; // 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); - } + if (!gfx_texture_cache_lookup(0, &n, actualname, fmt, siz)) + load_texture(path); // new texture, load it return true; } -static inline void load_texture(const char *name) { - static char fpath[SYS_MAX_PATH]; - int w, h; - const char *texname = name; - - if (!texname[0]) { - fprintf(stderr, "empty texture name at %p\n", texname); - return; - } - - snprintf(fpath, sizeof(fpath), "%s/%s.png", sys_data_path(), texname); - u8 *data = stbi_load(fpath, &w, &h, NULL, 4); - if (!data) { - fprintf(stderr, "could not load texture: `%s`\n", fpath); - return; - } - - gfx_rapi->upload_texture(data, w, h); - stbi_image_free(data); // don't need this anymore -} - #endif // EXTERNAL_DATA static void import_texture(int tile) { @@ -614,7 +602,9 @@ static void import_texture(int tile) { #ifdef EXTERNAL_DATA // 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 - load_texture((const char*)rdp.loaded_texture[tile].addr); + char texname[SYS_MAX_PATH]; + snprintf(texname, sizeof(texname), FS_TEXTUREDIR "/%s.png", (const char*)rdp.loaded_texture[tile].addr); + load_texture(texname); #else // the texture data is actual texture data int t0 = get_time(); @@ -625,7 +615,7 @@ static void import_texture(int tile) { else if (siz == G_IM_SIZ_16b) { import_texture_rgba16(tile); } else { - abort(); + sys_fatal("unsupported RGBA texture size: %u", siz); } } else if (fmt == G_IM_FMT_IA) { if (siz == G_IM_SIZ_4b) { @@ -635,7 +625,7 @@ static void import_texture(int tile) { } else if (siz == G_IM_SIZ_16b) { import_texture_ia16(tile); } else { - abort(); + sys_fatal("unsupported IA texture size: %u", siz); } } else if (fmt == G_IM_FMT_CI) { if (siz == G_IM_SIZ_4b) { @@ -643,7 +633,7 @@ static void import_texture(int tile) { } else if (siz == G_IM_SIZ_8b) { import_texture_ci8(tile); } else { - abort(); + sys_fatal("unsupported CI texture size: %u", siz); } } else if (fmt == G_IM_FMT_I) { if (siz == G_IM_SIZ_4b) { @@ -651,10 +641,10 @@ static void import_texture(int tile) { } else if (siz == G_IM_SIZ_8b) { import_texture_i8(tile); } else { - abort(); + sys_fatal("unsupported I texture size: %u", siz); } } else { - abort(); + sys_fatal("unsupported texture format: %u", fmt); } int t1 = get_time(); //printf("Time diff: %d\n", t1 - t0); @@ -1764,8 +1754,8 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi) { #ifdef EXTERNAL_DATA // 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); + printf("Precaching textures\n"); + fs_walk(FS_TEXTUREDIR, preload_texture, NULL, true); } #endif } diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index da548635..3a2d6613 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -22,6 +22,7 @@ #include "cliopts.h" #include "configfile.h" #include "controller/controller_api.h" +#include "fs/fs.h" #include "game/main.h" #include "game/thread6.h" @@ -153,6 +154,8 @@ void main_func(void) { main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0])); gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); + fs_init(sys_ropaths, FS_BASEDIR, sys_user_path()); + configfile_load(configfile_name()); wm_api = &gfx_sdl; diff --git a/src/pc/platform.c b/src/pc/platform.c index 80c0eb74..fb4b08ec 100644 --- a/src/pc/platform.c +++ b/src/pc/platform.c @@ -1,17 +1,26 @@ #include #include #include +#include #include -#include -#include -#include -#include #include -#ifdef _WIN32 -#include -#endif #include "cliopts.h" +#include "fs/fs.h" + +/* NULL terminated list of platform specific read-only data paths */ +/* priority is top first */ +const char *sys_ropaths[] = { + ".", // working directory + "!", // executable directory +#if defined(__linux__) || defined(__unix__) + // some common UNIX directories for read only stuff + "/usr/local/share/sm64pc", + "/usr/share/sm64pc", + "/opt/sm64pc", +#endif + NULL, +}; /* these are not available on some platforms, so might as well */ @@ -40,81 +49,24 @@ int sys_strcasecmp(const char *s1, const char *s2) { return result; } -/* file system stuff */ - -bool sys_file_exists(const char *name) { - struct stat st; - return (stat(name, &st) == 0 && S_ISREG(st.st_mode)); +const char *sys_file_extension(const char *fname) { + const char *dot = strrchr(fname, '.'); + if (!dot || !dot[1]) return NULL; + return dot + 1; } -bool sys_dir_exists(const char *name) { - struct stat st; - return (stat(name, &st) == 0 && S_ISDIR(st.st_mode)); -} +/* this calls a platform-specific impl function after forming the error message */ -bool sys_dir_walk(const char *base, walk_fn_t walk, const bool recur) { - char fullpath[SYS_MAX_PATH]; - DIR *dir; - struct dirent *ent; +static void sys_fatal_impl(const char *msg) __attribute__ ((noreturn)); - 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; -} - -void *sys_load_res(const char *name) { - char path[SYS_MAX_PATH] = { 0 }; - snprintf(path, sizeof(path), "%s/%s", sys_data_path(), name); - - FILE *f = fopen(path, "rb"); - if (!f) return NULL; - - fseek(f, 0, SEEK_END); - size_t size = ftell(f); - fseek(f, 0, SEEK_SET); - - void *buf = malloc(size); - if (!buf) { - fclose(f); - return NULL; - } - - fread(buf, 1, size, f); - fclose(f); - - return buf; -} - -bool sys_mkdir(const char *name) { - #ifdef _WIN32 - return _mkdir(name) == 0; - #else - return mkdir(name, 0777) == 0; - #endif +void sys_fatal(const char *fmt, ...) { + static char msg[2048]; + va_list args; + va_start(args, fmt); + vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + fflush(stdout); // push all crap out + sys_fatal_impl(msg); } #if USE_SDL @@ -122,125 +74,50 @@ bool sys_mkdir(const char *name) { // we can just ask SDL for most of this shit if we have it #include -const char *sys_data_path(void) { +const char *sys_user_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 (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 (sys_dir_exists(path)) return path; - - // then the save path - snprintf(path, sizeof(path), "%s/" DATADIR, sys_save_path()); - if (sys_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 (sys_dir_exists(try[i])) { - strcpy(path, try[i]); - return path; - } - } - #endif - - // hope for the best - strcpy(path, "./" DATADIR); + // get it from SDL + 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 (!fs_sys_dir_exists(path) && !fs_sys_mkdir(path)) + path[0] = 0; } - - 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 (!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 - } - } - - // 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 (!sys_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); + char *sdlpath = SDL_GetBasePath(); + if (sdlpath && sdlpath[0]) { + // 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 } - return path; } +static void sys_fatal_impl(const char *msg) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR , "Fatal error", msg, NULL); + fprintf(stderr, "FATAL ERROR:\n%s\n", msg); + fflush(stderr); + exit(1); +} + #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) { +const char *sys_user_path(void) { return "."; } @@ -248,4 +125,10 @@ const char *sys_exe_path(void) { return "."; } +static void sys_fatal_impl(const char *msg) { + fprintf(stderr, "FATAL ERROR:\n%s\n", msg); + fflush(stderr); + exit(1); +} + #endif // platform switch diff --git a/src/pc/platform.h b/src/pc/platform.h index 30b33dcc..53b2ad16 100644 --- a/src/pc/platform.h +++ b/src/pc/platform.h @@ -7,29 +7,22 @@ /* Platform-specific functions and whatnot */ -#define DATADIR "res" #define SYS_MAX_PATH 1024 // FIXME: define this on different platforms +// NULL terminated list of platform specific read-only data paths +extern const char *sys_ropaths[]; + // 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); -void *sys_load_res(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_user_path(void); const char *sys_exe_path(void); +const char *sys_file_extension(const char *fname); + +// shows an error message in some way and terminates the game +void sys_fatal(const char *fmt, ...) __attribute__ ((noreturn)); #endif // _SM64_PLATFORM_H_ diff --git a/src/pc/ultra_reimplementation.c b/src/pc/ultra_reimplementation.c index c28894f6..65e5f01b 100644 --- a/src/pc/ultra_reimplementation.c +++ b/src/pc/ultra_reimplementation.c @@ -3,6 +3,9 @@ #include "lib/src/libultra_internal.h" #include "macros.h" #include "platform.h" +#include "fs/fs.h" + +#define SAVE_FILENAME "sm64_save_file.bin" #ifdef TARGET_WEB #include @@ -120,17 +123,15 @@ s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) ret = 0; } #else - 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"); + fs_file_t *fp = fs_open(SAVE_FILENAME); if (fp == NULL) { return -1; } - if (fread(content, 1, 512, fp) == 512) { + if (fs_read(fp, content, 512) == 512) { memcpy(buffer, content + address * 8, nbytes); ret = 0; } - fclose(fp); + fs_close(fp); #endif return ret; } @@ -152,9 +153,7 @@ s32 osEepromLongWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes }, content); s32 ret = 0; #else - 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"); + FILE *fp = fopen(fs_get_write_path(SAVE_FILENAME), "wb"); if (fp == NULL) { return -1; } diff --git a/tools/mkzip.py b/tools/mkzip.py new file mode 100644 index 00000000..5481bc59 --- /dev/null +++ b/tools/mkzip.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import sys +import os +import zipfile + +if len(sys.argv) < 3: + print('usage: mkzip ') + sys.exit(1) + +lst = [] +with open(sys.argv[1], 'r') as f: + for line in f: + line = line.strip() + if line == '' or line[0] == '#': + continue + tok = line.split() + lst.append((tok[0], tok[1])) + +with zipfile.ZipFile(sys.argv[2], 'w', allowZip64=False) as zipf: + for (fname, aname) in lst: + zipf.write(fname, arcname=aname) From b9c94ad57dc2883d4ecb5367ea9cefdb65c8a300 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jun 2020 22:00:23 +0300 Subject: [PATCH 20/29] fix text saves --- src/game/text_save.inc.h | 9 +++++---- src/pc/fs/fs.h | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/game/text_save.inc.h b/src/game/text_save.inc.h index 1325f0a5..a9ce6c2a 100644 --- a/src/game/text_save.inc.h +++ b/src/game/text_save.inc.h @@ -4,8 +4,9 @@ #include "course_table.h" #include "pc/ini.h" #include "pc/platform.h" +#include "pc/fs/fs.h" -#define FILENAME_FORMAT "%s\\sm64_save_file_%d.sav" +#define FILENAME_FORMAT "%s/sm64_save_file_%d.sav" #define NUM_COURSES 15 #define NUM_BONUS_COURSES 10 #define NUM_FLAGS 21 @@ -79,10 +80,10 @@ static s32 write_text_save(s32 fileIndex) { struct SaveFile *savedata; struct MainMenuSaveData *menudata; char filename[SYS_MAX_PATH] = { 0 }; - char *value; + char value[64]; u32 i, bit, flags, coins, stars, starFlags; - if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) + if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, fs_writepath, fileIndex) < 0) return -1; file = fopen(filename, "wt"); @@ -210,7 +211,7 @@ static s32 read_text_save(s32 fileIndex) { u32 i, flag, coins, stars, starFlags; u32 capArea; - if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, sys_save_path(), fileIndex) < 0) + if (snprintf(filename, sizeof(filename), FILENAME_FORMAT, fs_writepath, fileIndex) < 0) return -1; savedata = ini_load(filename); diff --git a/src/pc/fs/fs.h b/src/pc/fs/fs.h index e479cfbf..c7765144 100644 --- a/src/pc/fs/fs.h +++ b/src/pc/fs/fs.h @@ -21,8 +21,7 @@ #define FS_SOUNDDIR "sound" extern char fs_gamedir[]; -extern char fs_userdir[]; -extern const char *fs_ropaths[]; +extern char fs_writepath[]; // receives the full path // should return `true` if traversal should continue From 0bf5a192f465f3f8d92497a0fe32e4006e9ed0f3 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jun 2020 22:00:49 +0300 Subject: [PATCH 21/29] fix sys_fatal() warnings in gfx --- src/pc/gfx/gfx_opengl.c | 1 + src/pc/gfx/gfx_opengl_legacy.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index a0c27bed..b1311442 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -33,6 +33,7 @@ #endif +#include "../platform.h" #include "gfx_cc.h" #include "gfx_rendering_api.h" diff --git a/src/pc/gfx/gfx_opengl_legacy.c b/src/pc/gfx/gfx_opengl_legacy.c index 6ff04a78..29a3a699 100644 --- a/src/pc/gfx/gfx_opengl_legacy.c +++ b/src/pc/gfx/gfx_opengl_legacy.c @@ -40,6 +40,7 @@ static PFNMGLFOGCOORDPOINTERPROC mglFogCoordPointer = NULL; #define GL_FOG_COORD 0x8451 #define GL_FOG_COORD_ARRAY 0x8457 +#include "../platform.h" #include "gfx_cc.h" #include "gfx_rendering_api.h" #include "macros.h" From 9ebde3c219feb6b8aa7b08c3e4275fc9ad2aa49a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jun 2020 22:00:57 +0300 Subject: [PATCH 22/29] add sky tiles to the zip as well --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8ec64322..791c1d16 100644 --- a/Makefile +++ b/Makefile @@ -564,7 +564,8 @@ ifeq ($(EXTERNAL_DATA),1) CC_CHECK += -DEXTERNAL_DATA -DFS_BASEDIR="\"$(BASEDIR)\"" CFLAGS += -DEXTERNAL_DATA -DFS_BASEDIR="\"$(BASEDIR)\"" # 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" + SKYTILE_DIR := $(BUILD_DIR)/textures/skybox_tiles + SKYCONV_ARGS := --store-names --write-tiles "$(SKYTILE_DIR)" endif ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) @@ -641,6 +642,7 @@ $(BASEPACK_LST): $(EXE) @echo "$(BUILD_DIR)/sound/sequences.bin sound/sequences.bin" >> $(BASEPACK_LST) @echo "$(BUILD_DIR)/sound/sound_data.ctl sound/sound_data.ctl" >> $(BASEPACK_LST) @echo "$(BUILD_DIR)/sound/sound_data.tbl sound/sound_data.tbl" >> $(BASEPACK_LST) + @$(foreach f, $(wildcard $(SKYTILE_DIR)/*), echo $(f) gfx/$(f:$(BUILD_DIR)/%=%) >> $(BASEPACK_LST);) @find actors -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; @find levels -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; @find textures -name \*.png -exec echo "{} gfx/{}" >> $(BASEPACK_LST) \; From 51651d52d0ef826c6270b9d028d6109f9bfe6221 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jun 2020 23:54:39 +0300 Subject: [PATCH 23/29] restore --savepath and replace --datapath with --gamedir --- src/pc/cliopts.c | 4 ++-- src/pc/cliopts.h | 2 +- src/pc/gfx/gfx_pc.c | 18 +++++++++--------- src/pc/gfx/gfx_pc.h | 1 + src/pc/pc_main.c | 17 +++++++++++++++-- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index bff335a2..fd07eb31 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -54,8 +54,8 @@ void parse_cli_opts(int argc, char* argv[]) { 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], "--gamedir") == 0 && (i + 1) < argc) + arg_string("--gamedir", argv[++i], gCLIOpts.GameDir); else if (strcmp(argv[i], "--savepath") == 0 && (i + 1) < argc) arg_string("--savepath", argv[++i], gCLIOpts.SavePath); diff --git a/src/pc/cliopts.h b/src/pc/cliopts.h index 2d084eda..f9a45e18 100644 --- a/src/pc/cliopts.h +++ b/src/pc/cliopts.h @@ -8,7 +8,7 @@ struct PCCLIOptions { unsigned int FullScreen; char ConfigFile[SYS_MAX_PATH]; char SavePath[SYS_MAX_PATH]; - char DataPath[SYS_MAX_PATH]; + char GameDir[SYS_MAX_PATH]; }; extern struct PCCLIOptions gCLIOpts; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 8e8a7e51..8dd91e08 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -1748,18 +1748,18 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi) { 0x05200200, 0x03200200 }; - for (size_t i = 0; i < sizeof(precomp_shaders) / sizeof(uint32_t); i++) { + + for (size_t i = 0; i < sizeof(precomp_shaders) / sizeof(uint32_t); i++) gfx_lookup_or_create_shader_program(precomp_shaders[i]); - } - #ifdef EXTERNAL_DATA - // preload all textures if needed - if (configPrecacheRes) { - printf("Precaching textures\n"); - fs_walk(FS_TEXTUREDIR, preload_texture, NULL, true); - } - #endif } +#ifdef EXTERNAL_DATA +void gfx_precache_textures(void) { + // preload all textures + fs_walk(FS_TEXTUREDIR, preload_texture, NULL, true); +} +#endif + void gfx_start_frame(void) { gfx_wapi->handle_events(); gfx_wapi->get_dimensions(&gfx_current_dimensions.width, &gfx_current_dimensions.height); diff --git a/src/pc/gfx/gfx_pc.h b/src/pc/gfx/gfx_pc.h index 8d62e2b7..53a1677b 100644 --- a/src/pc/gfx/gfx_pc.h +++ b/src/pc/gfx/gfx_pc.h @@ -15,6 +15,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi); void gfx_start_frame(void); void gfx_run(Gfx *commands); void gfx_end_frame(void); +void gfx_precache_textures(void); void gfx_shutdown(void); #endif diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 3a2d6613..ea322305 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -1,4 +1,5 @@ #include +#include #ifdef TARGET_WEB #include @@ -24,6 +25,7 @@ #include "controller/controller_api.h" #include "fs/fs.h" +#include "game/game_init.h" #include "game/main.h" #include "game/thread6.h" @@ -154,7 +156,9 @@ void main_func(void) { main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0])); gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); - fs_init(sys_ropaths, FS_BASEDIR, sys_user_path()); + const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR; + const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path(); + fs_init(sys_ropaths, gamedir, userpath); configfile_load(configfile_name()); @@ -173,9 +177,18 @@ void main_func(void) { sound_init(); thread5_game_loop(NULL); - + inited = true; +#ifdef EXTERNAL_DATA + // precache data if needed + if (configPrecacheRes) { + printf("precaching data\n"); + fflush(stdout); + gfx_precache_textures(); + } +#endif + #ifdef TARGET_WEB emscripten_set_main_loop(em_main_loop, 0, 0); request_anim_frame(on_anim_frame); From 504b38725ec08ec1dbf449a0fd6ccdb5abac8040 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 8 Jun 2020 06:06:40 +0300 Subject: [PATCH 24/29] use 'python3 mkzip' instead of just 'mkzip' --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 791c1d16..d7c5a6c6 100644 --- a/Makefile +++ b/Makefile @@ -649,7 +649,7 @@ $(BASEPACK_LST): $(EXE) # prepares the resource ZIP with base data $(BASEPACK_PATH): $(BASEPACK_LST) - @$(TOOLS_DIR)/mkzip.py $(BASEPACK_LST) $(BASEPACK_PATH) + @$(PYTHON) $(TOOLS_DIR)/mkzip.py $(BASEPACK_LST) $(BASEPACK_PATH) endif From 585c24a2822ea5b5b5f61f9d7d00da4360dd2b08 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 8 Jun 2020 06:38:41 +0300 Subject: [PATCH 25/29] updated usage text --- src/pc/cliopts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc/cliopts.c b/src/pc/cliopts.c index fd07eb31..b9e9ee77 100644 --- a/src/pc/cliopts.c +++ b/src/pc/cliopts.c @@ -16,7 +16,7 @@ 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\tSets additional data directory name (only 'res' is used by default).\n", "--gamedir DIRNAME"); 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"); From ef5eab2263099cabb678b86bd1f8f261d7d5139d Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 8 Jun 2020 07:44:03 +0300 Subject: [PATCH 26/29] fix sys_file_extension for folders that start with dot --- src/pc/platform.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pc/platform.c b/src/pc/platform.c index fb4b08ec..0aea20fa 100644 --- a/src/pc/platform.c +++ b/src/pc/platform.c @@ -51,7 +51,10 @@ int sys_strcasecmp(const char *s1, const char *s2) { const char *sys_file_extension(const char *fname) { const char *dot = strrchr(fname, '.'); - if (!dot || !dot[1]) return NULL; + const char *sep = strrchr(fname, '/'); + if (!sep) sep = strrchr(fname, '\\'); + if (!dot || !dot[1]) return NULL; // no dot + if (dot <= sep + 1) return NULL; // dot is before the last separator or right after it (e.g. /.local) return dot + 1; } From 326f8ed071b88196a1c6c18b2aa8ea59891a2a2e Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 8 Jun 2020 08:49:06 +0300 Subject: [PATCH 27/29] properly check for basepacks --- src/pc/fs/fs.c | 4 ++-- src/pc/platform.c | 15 +++++++++++---- src/pc/platform.h | 3 ++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pc/fs/fs.c b/src/pc/fs/fs.c index d125a60b..37f85edf 100644 --- a/src/pc/fs/fs.c +++ b/src/pc/fs/fs.c @@ -43,8 +43,8 @@ static inline fs_dir_t *fs_find_dir(const char *realpath) { } static int mount_cmp(const void *p1, const void *p2) { - const char *s1 = *(const char **)p1; - const char *s2 = *(const char **)p2; + const char *s1 = sys_file_name(*(const char **)p1); + const char *s2 = sys_file_name(*(const char **)p2); // check if one or both of these are basepacks const int plen = strlen(FS_BASEPACK_PREFIX); diff --git a/src/pc/platform.c b/src/pc/platform.c index 0aea20fa..d6bfd6e2 100644 --- a/src/pc/platform.c +++ b/src/pc/platform.c @@ -49,15 +49,22 @@ int sys_strcasecmp(const char *s1, const char *s2) { return result; } -const char *sys_file_extension(const char *fname) { +const char *sys_file_extension(const char *fpath) { + const char *fname = sys_file_name(fpath); const char *dot = strrchr(fname, '.'); - const char *sep = strrchr(fname, '/'); - if (!sep) sep = strrchr(fname, '\\'); if (!dot || !dot[1]) return NULL; // no dot - if (dot <= sep + 1) return NULL; // dot is before the last separator or right after it (e.g. /.local) + if (dot == fname) return NULL; // dot is the first char (e.g. .local) return dot + 1; } +const char *sys_file_name(const char *fpath) { + const char *sep1 = strrchr(fpath, '/'); + const char *sep2 = strrchr(fpath, '\\'); + const char *sep = sep1 > sep2 ? sep1 : sep2; + if (!sep) return fpath; + return sep + 1; +} + /* this calls a platform-specific impl function after forming the error message */ static void sys_fatal_impl(const char *msg) __attribute__ ((noreturn)); diff --git a/src/pc/platform.h b/src/pc/platform.h index 53b2ad16..168333d1 100644 --- a/src/pc/platform.h +++ b/src/pc/platform.h @@ -20,7 +20,8 @@ int sys_strcasecmp(const char *s1, const char *s2); // path stuff const char *sys_user_path(void); const char *sys_exe_path(void); -const char *sys_file_extension(const char *fname); +const char *sys_file_extension(const char *fpath); +const char *sys_file_name(const char *fpath); // shows an error message in some way and terminates the game void sys_fatal(const char *fmt, ...) __attribute__ ((noreturn)); From 3589d7cfedba84655bda7bf18a9e0586d9c2b30d Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 9 Jun 2020 05:23:15 +0300 Subject: [PATCH 28/29] texrename: put textures in gfx folder --- tools/texrename.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/texrename.py b/tools/texrename.py index e8ac24e0..600c8bfc 100644 --- a/tools/texrename.py +++ b/tools/texrename.py @@ -53,7 +53,7 @@ try: crc = int(crcstr[2:], 16) else: crc = int(crcstr) - crcmap.append((crc, os.path.join(outpath, tok[1].strip()))) + crcmap.append((crc, os.path.join(outpath, 'gfx', tok[1].strip()))) except OSError as e: print('could not open {0}: {1}'.format(mapfname, e)) except ValueError as e: From 13120042c97339d9bc899154c65c60c8ba7a998c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 9 Jun 2020 05:24:26 +0300 Subject: [PATCH 29/29] add crcmap for RICE-formatted texture packs --- tools/rice_crcmap.txt | 1700 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1700 insertions(+) create mode 100644 tools/rice_crcmap.txt diff --git a/tools/rice_crcmap.txt b/tools/rice_crcmap.txt new file mode 100644 index 00000000..f2726f09 --- /dev/null +++ b/tools/rice_crcmap.txt @@ -0,0 +1,1700 @@ +0xfff8437e, textures/spooky/bbh_textures.06800.rgba16.png +0xffea1ffe, textures/segment2/segment2.04000.rgba16.png +0xffdebbc5, textures/skybox_tiles/bitfs.17.rgba16.png +0xff6c67f0, textures/skybox_tiles/ssl.31.rgba16.png +0xff50bd43, textures/effect/lava_bubble.05020.rgba16.png +0xff309aa3, textures/skybox_tiles/bitfs.5.rgba16.png +0xff00d1bf, textures/machine/ttc_textures.06800.rgba16.png +0xfebedae8, textures/water/jrb_textures.06000.rgba16.png +0xfeb13915, textures/skybox_tiles/wdw.27.rgba16.png +0xfe7ec2b3, textures/sky/rr_textures.03000.rgba16.png +0xfe55b4f9, levels/ccm/9.ia16.png +0xfe391ddb, levels/castle_inside/36.rgba16.png +0xfe1ab8d0, levels/hmc/0.rgba16.png +0xfddf5c31, actors/breakable_box/cork_box_surface.rgba16.png +0xfdc48aeb, textures/skybox_tiles/ssl.10.rgba16.png +0xfdbce221, textures/generic/bob_textures.0A000.rgba16.png +0xfdb6de70, textures/skybox_tiles/clouds.4.rgba16.png +0xfdb50546, textures/inside/inside_castle_textures.06000.rgba16.png +0xfd9aa14e, actors/blue_fish/blue_fish.rgba16.png +0xfd83b121, actors/goomba/goomba_body.rgba16.png +0xfd820701, actors/door/polished_wooden_door.rgba16.png +0xfd6af08f, actors/mad_piano/mad_piano_body.rgba16.png +0xfd57ea27, actors/dorrie/dorrie_eye.rgba16.png +0xfd569cd5, actors/power_meter/power_meter_left_side.rgba16.png +0xfcfc8637, textures/skybox_tiles/bits.35.rgba16.png +0xfc6ef688, textures/skybox_tiles/bidw.24.rgba16.png +0xfc58ed51, textures/segment2/segment2.06C00.rgba16.png +0xfc53c33b, actors/bub/bub_eyes.rgba16.png +0xfc53c33b, actors/bubba/bubba_eyes_unused.rgba16.png +0xfc4b4762, levels/castle_inside/17.rgba16.png +0xfc489936, textures/skybox_tiles/water.53.rgba16.png +0xfc424ecc, textures/skybox_tiles/cloud_floor.13.rgba16.png +0xfc10a1b3, textures/segment2/segment2.02400.rgba16.png +0xfc0dd433, textures/skybox_tiles/bits.54.rgba16.png +0xfbec7687, textures/skybox_tiles/cake.8.rgba16.png +0xfbe08cab, actors/coin/coin_tilt_right.ia16.png +0xfbcb7598, levels/menu/main_menu_seg7.04C68.rgba16.png +0xfba28e17, actors/water_wave/water_wave_0.ia16.png +0xfb4e7d3c, textures/skybox_tiles/cloud_floor.17.rgba16.png +0xfb38796a, actors/mad_piano/mad_piano_mouth.rgba16.png +0xfb04de95, textures/skybox_tiles/cloud_floor.16.rgba16.png +0xfad8c6e1, levels/menu/main_menu_seg7.0E1A8.rgba16.png +0xfacea23f, actors/snufit/snufit_eye.rgba16.png +0xfaaff848, textures/skybox_tiles/bidw.41.rgba16.png +0xfa825d44, textures/skybox_tiles/cake.12.rgba16.png +0xfa49a60a, textures/skybox_tiles/cake.15.rgba16.png +0xfa421c73, actors/explosion/explosion_1.rgba16.png +0xfa11921a, actors/water_splash/water_splash_0.rgba16.png +0xf9889333, textures/skybox_tiles/bitfs.38.rgba16.png +0xf97dc072, actors/clam_shell/clam_shell_mouth.rgba16.png +0xf92708ad, textures/outside/castle_grounds_textures.05800.rgba16.png +0xf91048ed, textures/effect/lava_bubble.02020.rgba16.png +0xf902b80b, textures/mountain/ttm_textures.07800.rgba16.png +0xf8d78296, textures/mountain/ttm_textures.08000.rgba16.png +0xf8d3168e, textures/skybox_tiles/cake.5.rgba16.png +0xf8cc42d7, textures/skybox_tiles/bitfs.6.rgba16.png +0xf8cab46c, textures/skybox_tiles/wdw.29.rgba16.png +0xf8b79a21, textures/skybox_tiles/cake.4.rgba16.png +0xf8775564, actors/peach/peach_dress.rgba16.png +0xf861446c, textures/skybox_tiles/wdw.35.rgba16.png +0xf831589e, textures/snow/ccm_textures.05000.rgba16.png +0xf8303731, textures/outside/castle_grounds_textures.01000.rgba16.png +0xf7844a94, actors/king_bobomb/king_bob-omb_arm.rgba16.png +0xf765d232, textures/skybox_tiles/ssl.16.rgba16.png +0xf71bcbca, levels/lll/22.rgba16.png +0xf6c53a3c, levels/ddd/0.rgba16.png +0xf6beeb24, actors/bookend/bookend_mouth.rgba16.png +0xf6bb8446, textures/skybox_tiles/cloud_floor.25.rgba16.png +0xf6affec8, levels/lll/19.rgba16.png +0xf69986ce, textures/skybox_tiles/bits.45.rgba16.png +0xf66ca88b, actors/piranha_plant/piranha_plant_tongue.rgba16.png +0xf66ca88b, actors/bowser/bowser_tongue.rgba16.png +0xf66738c7, textures/skybox_tiles/cake.42.rgba16.png +0xf5e69d71, textures/skybox_tiles/bbh.26.rgba16.png +0xf5a3113c, textures/grass/wf_textures.09000.rgba16.png +0xf5974867, textures/segment2/segment2.03C00.rgba16.png +0xf566b5fa, textures/skybox_tiles/wdw.33.rgba16.png +0xf5013c4a, textures/skybox_tiles/wdw.45.rgba16.png +0xf4fab5f3, actors/sparkle/sparkle_4.rgba16.png +0xf4d429fd, levels/lll/8.rgba16.png +0xf476b374, textures/intro_raw/sparkle_2.rgba16.png +0xf4472db5, textures/skybox_tiles/ssl.53.rgba16.png +0xf3cc9e98, textures/generic/bob_textures.07800.rgba16.png +0xf3b23497, textures/grass/wf_textures.05000.rgba16.png +0xf399a4e9, actors/swoop/swoop_eye.rgba16.png +0xf37a7379, textures/skybox_tiles/wdw.2.rgba16.png +0xf3247d8b, textures/skybox_tiles/cake.26.rgba16.png +0xf2ede87d, textures/skybox_tiles/wdw.31.rgba16.png +0xf2979267, textures/segment2/segment2.06B00.rgba16.png +0xf2897e05, levels/castle_inside/5.rgba16.png +0xf22e4881, levels/cotmc/3.rgba16.png +0xf21f608e, actors/dirt/dirt_particle.rgba16.png +0xf1c23131, actors/power_meter/power_meter_full.rgba16.png +0xf19d33e5, textures/skybox_tiles/clouds.25.rgba16.png +0xf16f1966, textures/skybox_tiles/ssl.56.rgba16.png +0xf148ae1e, actors/bowser/bowser_nostrils.rgba16.png +0xf11e411f, actors/sparkle/sparkle_0.rgba16.png +0xf10816c6, textures/skybox_tiles/water.52.rgba16.png +0xf0fd9fe8, textures/skybox_tiles/clouds.38.rgba16.png +0xf0edea43, textures/skybox_tiles/wdw.57.rgba16.png +0xf0dd9d26, textures/skybox_tiles/cloud_floor.33.rgba16.png +0xf0b319a6, actors/flame/flame_2.ia16.png +0xf0a134bd, textures/spooky/bbh_textures.0B000.ia16.png +0xf09d711e, actors/wooden_signpost/wooden_signpost_back.rgba16.png +0xf0729e14, actors/unagi/unagi_body.rgba16.png +0xf05aadee, textures/skybox_tiles/cloud_floor.52.rgba16.png +0xf03aef7d, textures/skybox_tiles/cloud_floor.28.rgba16.png +0xef44fc69, textures/skybox_tiles/bitfs.31.rgba16.png +0xef35da31, textures/skybox_tiles/water.32.rgba16.png +0xef1d1e70, textures/skybox_tiles/ccm.57.rgba16.png +0xef161d97, textures/skybox_tiles/bitfs.44.rgba16.png +0xeed115d8, actors/sparkle_animation/sparkle_animation_1.ia16.png +0xeeb51695, textures/skybox_tiles/clouds.33.rgba16.png +0xee949d98, textures/skybox_tiles/bitfs.43.rgba16.png +0xee5c9999, textures/skybox_tiles/cloud_floor.20.rgba16.png +0xedff0bd2, textures/skybox_tiles/water.37.rgba16.png +0xedbbe3d1, actors/unagi/unagi_tooth.rgba16.png +0xeda45656, actors/haunted_cage/bbh_cage_ornament.rgba16.png +0xece06c79, levels/ssl/10.rgba16.png +0xecd57ce8, textures/segment2/segment2.06780.rgba16.png +0xecacf737, actors/peach/peach_eye_closed.rgba16.png +0xec819d1b, textures/sky/rr_textures.01000.rgba16.png +0xec60ed0c, levels/menu/main_menu_seg7.03468.rgba16.png +0xec390c33, textures/skybox_tiles/cake.35.rgba16.png +0xec24c279, textures/segment2/segment2.08150.rgba16.png +0xec004254, textures/skybox_tiles/bits.39.rgba16.png +0xeba8bfca, textures/skybox_tiles/cloud_floor.15.rgba16.png +0xeba48ba7, textures/skybox_tiles/cloud_floor.53.rgba16.png +0xeb871023, levels/castle_inside/14.rgba16.png +0xeb70d69c, textures/skybox_tiles/ccm.23.rgba16.png +0xeb5c820f, textures/skybox_tiles/cloud_floor.27.rgba16.png +0xeb37a9b8, levels/thi/0.rgba16.png +0xeb0dfb0a, textures/skybox_tiles/bbh.23.rgba16.png +0xeaa27132, actors/lakitu_enemy/lakitu_enemy_eyes_open.rgba16.png +0xeaa27132, actors/lakitu_cameraman/lakitu_cameraman_eyes_open.rgba16.png +0xea6f033e, actors/ukiki/ukiki_fur.rgba16.png +0xea566cb8, textures/skybox_tiles/bitfs.28.rgba16.png +0xea11fb10, levels/lll/23.rgba16.png +0xe9fcbf74, actors/mario/mario_mustache.rgba16.png +0xe9e0c62a, textures/snow/ccm_textures.05800.rgba16.png +0xe9cabb44, actors/warp_pipe/warp_pipe_side.rgba16.png +0xe944a81b, levels/wf/3.rgba16.png +0xe8fabcc5, levels/castle_inside/31.rgba16.png +0xe8f6fff7, textures/skybox_tiles/water.62.rgba16.png +0xe8e37186, textures/snow/ccm_textures.08800.rgba16.png +0xe7f503ac, textures/intro_raw/white_star_7.rgba16.png +0xe7d08e45, textures/skybox_tiles/cloud_floor.56.rgba16.png +0xe747f9b9, textures/skybox_tiles/cloud_floor.19.rgba16.png +0xe7161d98, textures/skybox_tiles/bitfs.45.rgba16.png +0xe702818c, textures/skybox_tiles/ccm.61.rgba16.png +0xe69d9617, textures/skybox_tiles/bitfs.42.rgba16.png +0xe6959da0, textures/skybox_tiles/bitfs.47.rgba16.png +0xe6919896, actors/scuttlebug/scuttlebug_eye.rgba16.png +0xe67c070b, textures/segment2/segment2.06D00.rgba16.png +0xe6640e91, textures/skybox_tiles/cloud_floor.30.rgba16.png +0xe61e849b, levels/wf/2.rgba16.png +0xe60ffd91, actors/treasure_chest/treasure_chest_lock.rgba16.png +0xe6061d88, textures/skybox_tiles/bitfs.40.rgba16.png +0xe5d87cd6, levels/menu/main_menu_seg7.04468.rgba16.png +0xe5bcf46e, actors/coin/coin_side.ia16.png +0xe56f0bbf, textures/cave/hmc_textures.02800.rgba16.png +0xe559fc96, levels/bbh/0.rgba16.png +0xe52ee127, actors/snowman/mr_blizzard_mouth.rgba16.png +0xe52ee127, levels/ccm/5.rgba16.png +0xe4bd5580, textures/segment2/segment2.00200.rgba16.png +0xe49dcfb8, textures/fire/lll_textures.03000.rgba16.png +0xe48f835f, levels/ccm/6.rgba16.png +0xe48f835f, actors/snowman/mr_blizzard_eye.rgba16.png +0xe47fb00e, textures/skybox_tiles/ccm.1.rgba16.png +0xe473fb5d, textures/sky/rr_textures.05800.rgba16.png +0xe447e6b0, textures/skybox_tiles/water.48.rgba16.png +0xe42d6aa8, levels/lll/11.rgba16.png +0xe3c3f224, textures/water/jrb_textures.0A000.rgba16.png +0xe3a23a76, textures/skybox_tiles/cake.44.rgba16.png +0xe3a23a76, textures/skybox_tiles/cake.47.rgba16.png +0xe398c0e5, textures/skybox_tiles/bitfs.2.rgba16.png +0xe383fd85, textures/mountain/ttm_textures.03000.rgba16.png +0xe361666a, textures/outside/castle_grounds_textures.08000.rgba16.png +0xe3548182, actors/moneybag/moneybag_mouth.rgba16.png +0xe351cff2, actors/bowser/bowser_claw_edge.rgba16.png +0xe348762e, textures/skybox_tiles/ccm.50.rgba16.png +0xe2fad209, textures/skybox_tiles/bbh.33.rgba16.png +0xe2e864a2, textures/fire/lll_textures.0A800.rgba16.png +0xe2de3e2b, textures/segment2/segment2.02200.rgba16.png +0xe22b8125, textures/outside/castle_grounds_textures.06000.rgba16.png +0xe20d5c69, textures/skybox_tiles/clouds.9.rgba16.png +0xe1ca8b50, textures/snow/ccm_textures.06000.rgba16.png +0xe169c3bf, textures/skybox_tiles/water.9.rgba16.png +0xe144c219, textures/skybox_tiles/bits.49.rgba16.png +0xe127cedd, actors/sushi/sushi_eye.rgba16.png +0xe0c22a3c, textures/mountain/ttm_textures.0A000.rgba16.png +0xe0c22a3c, textures/sky/rr_textures.06000.rgba16.png +0xe0bb9b61, actors/cannon_lid/cannon_lid.rgba16.png +0xe0901c5a, textures/skybox_tiles/cloud_floor.5.rgba16.png +0xe075472a, textures/skybox_tiles/wdw.53.rgba16.png +0xe04ef9fc, textures/skybox_tiles/water.21.rgba16.png +0xe04dcb5d, actors/water_splash/water_splash_4.rgba16.png +0xe01b30f4, textures/skybox_tiles/wdw.41.rgba16.png +0xe00d840e, textures/skybox_tiles/bitfs.20.rgba16.png +0xdffbb688, textures/segment2/segment2.11C58.rgba16.png +0xdff2a421, textures/intro_raw/white_star_4.rgba16.png +0xdf68e5a6, textures/skybox_tiles/ssl.27.rgba16.png +0xdf5317b2, levels/bowser_3/1.rgba16.png +0xdf2a6551, actors/swoop/swoop_nose.rgba16.png +0xdf22ebff, textures/intro_raw/white_star_0.rgba16.png +0xdf0e0d87, textures/skybox_tiles/bitfs.41.rgba16.png +0xdf07ed35, textures/skybox_tiles/bidw.20.rgba16.png +0xdeef869f, textures/skybox_tiles/ccm.56.rgba16.png +0xdee37e88, textures/intro_raw/white_star_1.rgba16.png +0xdeae047b, levels/castle_inside/34.rgba16.png +0xde5450b9, textures/skybox_tiles/wdw.50.rgba16.png +0xde415a3c, textures/skybox_tiles/bits.40.rgba16.png +0xde38650f, textures/skybox_tiles/bidw.46.rgba16.png +0xdde6049e, textures/skybox_tiles/wdw.59.rgba16.png +0xdde47b60, textures/effect/lava_bubble.03820.rgba16.png +0xdde2c14f, textures/skybox_tiles/water.20.rgba16.png +0xddd906e3, textures/skybox_tiles/ssl.50.rgba16.png +0xddcbd0bf, textures/skybox_tiles/ccm.39.rgba16.png +0xdd78fbd8, textures/generic/bob_textures.04800.rgba16.png +0xdd432c19, actors/fwoosh/fwoosh_face.ia16.png +0xdcf4de07, levels/wdw/3.rgba16.png +0xdcdca548, textures/skybox_tiles/bitfs.23.rgba16.png +0xdcd89861, actors/spindrift/spindrift_leaf.rgba16.png +0xdcc12774, actors/bubble/bubble.rgba16.png +0xdc7bde10, levels/wf/4.rgba16.png +0xdc55f053, levels/castle_inside/16.ia16.png +0xdc5422cc, textures/skybox_tiles/ccm.32.rgba16.png +0xdc28412d, textures/skybox_tiles/clouds.34.rgba16.png +0xdbf4274c, actors/peach/peach_crown_jewel.rgba16.png +0xdbca0482, textures/machine/ttc_textures.00800.rgba16.png +0xdbca0482, textures/inside/inside_castle_textures.04800.rgba16.png +0xdbc08093, textures/skybox_tiles/water.10.rgba16.png +0xdba34b25, textures/skybox_tiles/ssl.35.rgba16.png +0xdb6c3044, actors/lakitu_enemy/lakitu_enemy_eyes_closed.rgba16.png +0xdb6c3044, actors/lakitu_cameraman/lakitu_cameraman_eyes_closed.rgba16.png +0xdb5b2455, textures/skybox_tiles/clouds.13.rgba16.png +0xdb4b54d5, textures/skybox_tiles/wdw.22.rgba16.png +0xdb4164d7, actors/flame/flame_3.ia16.png +0xdb3edfed, textures/skybox_tiles/water.13.rgba16.png +0xdb37ff1f, textures/skybox_tiles/bits.48.rgba16.png +0xdb1cf863, actors/unagi/unagi_mouth.rgba16.png +0xdad0c429, actors/bowser/bowser_claw_horn_tooth.rgba16.png +0xdaa65afc, textures/skybox_tiles/bitfs.12.rgba16.png +0xda971b4e, textures/segment2/segment2.06380.rgba16.png +0xda83e7ab, textures/skybox_tiles/wdw.9.rgba16.png +0xda375ba5, levels/sl/3.rgba16.png +0xda354d71, textures/skybox_tiles/ccm.9.rgba16.png +0xd9e8f2f0, levels/lll/18.rgba16.png +0xd97fb4f5, textures/skybox_tiles/bidw.38.rgba16.png +0xd97d5a21, textures/skybox_tiles/bits.23.rgba16.png +0xd951b3da, textures/cave/hmc_textures.06800.rgba16.png +0xd91da963, levels/thi/1.rgba16.png +0xd910f455, textures/skybox_tiles/bbh.36.rgba16.png +0xd8f79383, textures/skybox_tiles/wdw.21.rgba16.png +0xd8e02894, textures/skybox_tiles/cloud_floor.63.rgba16.png +0xd8a463df, textures/skybox_tiles/bidw.48.rgba16.png +0xd89fbca9, textures/skybox_tiles/bidw.18.rgba16.png +0xd89b4538, textures/segment2/segment2.01E00.rgba16.png +0xd8903b0b, actors/koopa_flag/koopa_flag_banner.rgba16.png +0xd872cf6b, textures/machine/ttc_textures.05000.rgba16.png +0xd872790d, textures/sky/rr_textures.01800.rgba16.png +0xd8504ee4, actors/stomp_smoke/stomp_smoke_1.ia16.png +0xd8502ff0, textures/segment2/segment2.07000.rgba16.png +0xd83419b2, levels/ccm/10.rgba16.png +0xd816c431, textures/intro_raw/white_star_5.rgba16.png +0xd813a5e5, actors/bowser/bowser_muzzle.rgba16.png +0xd7d14c92, textures/outside/castle_grounds_textures.03000.rgba16.png +0xd7b09499, textures/skybox_tiles/clouds.6.rgba16.png +0xd795fe9f, levels/pss/2.rgba16.png +0xd742b346, textures/skybox_tiles/ccm.15.rgba16.png +0xd6f1a677, textures/segment2/segment2.06E80.rgba16.png +0xd6acb89d, textures/skybox_tiles/bits.16.rgba16.png +0xd68e7d47, textures/skybox_tiles/ccm.16.rgba16.png +0xd678c04f, textures/skybox_tiles/bbh.19.rgba16.png +0xd658ab33, textures/skybox_tiles/clouds.39.rgba16.png +0xd61dc576, textures/skybox_tiles/cloud_floor.11.rgba16.png +0xd6096833, actors/monty_mole/monty_mole_tooth.rgba16.png +0xd5bd2cf3, textures/outside/castle_grounds_textures.07800.rgba16.png +0xd5b932a2, levels/ssl/9.rgba16.png +0xd53a754e, actors/seaweed/seaweed_upper_center.rgba16.png +0xd4e4f405, textures/mountain/ttm_textures.09800.rgba16.png +0xd4c2dc38, textures/skybox_tiles/wdw.25.rgba16.png +0xd494eb3b, levels/lll/1.rgba16.png +0xd42e66e7, actors/whomp/whomp_back.rgba16.png +0xd4291cf0, textures/grass/wf_textures.02800.rgba16.png +0xd4178125, actors/sushi/sushi_tooth.rgba16.png +0xd41593d8, levels/ttm/2.rgba16.png +0xd405bfc1, actors/bowser/bowser_eye_far_left_1.rgba16.png +0xd405bfc1, actors/bowser/bowser_eye_far_left_0.rgba16.png +0xd404f7b3, textures/skybox_tiles/cloud_floor.58.rgba16.png +0xd3f0d281, textures/skybox_tiles/cloud_floor.18.rgba16.png +0xd3ea4d38, textures/skybox_tiles/wdw.28.rgba16.png +0xd3d96165, textures/skybox_tiles/cloud_floor.46.rgba16.png +0xd3d78f68, textures/skybox_tiles/cake.9.rgba16.png +0xd35575d6, actors/bully/bully_horn.rgba16.png +0xd314e722, textures/intro_raw/red_star_7.rgba16.png +0xd2ebc589, actors/manta/manta_gills.rgba16.png +0xd2e92870, textures/segment2/segment2.06280.rgba16.png +0xd2a5d574, textures/effect/lava_bubble.02820.rgba16.png +0xd2a5272b, textures/skybox_tiles/ccm.19.rgba16.png +0xd2a1c338, levels/castle_inside/28.rgba16.png +0xd2a05119, actors/capswitch/cap_switch_head.ia16.png +0xd26ee300, textures/skybox_tiles/ssl.30.rgba16.png +0xd220aa57, actors/swoop/swoop_body.rgba16.png +0xd1f883f5, textures/mountain/ttm_textures.0C000.rgba16.png +0xd1c5de12, levels/ttm/8.rgba16.png +0xd1c5de12, textures/mountain/ttm_textures.0A800.rgba16.png +0xd17f99c6, actors/exclamation_box_outline/exclamation_point.rgba16.png +0xd13a97c9, textures/skybox_tiles/wdw.13.rgba16.png +0xd135687e, levels/menu/main_menu_seg7.0D1A8.rgba16.png +0xd10d7b85, textures/inside/inside_castle_textures.08800.rgba16.png +0xd0ab7f94, textures/mountain/ttm_textures.05800.rgba16.png +0xd04a00d5, textures/intro_raw/red_star_2.rgba16.png +0xcfb45caf, textures/skybox_tiles/wdw.20.rgba16.png +0xcf717c3c, textures/sky/metal_hole.rgba16.png +0xcf52a490, textures/grass/wf_textures.01800.rgba16.png +0xcf390916, textures/skybox_tiles/bitfs.22.rgba16.png +0xceb6caa7, textures/skybox_tiles/bitfs.39.rgba16.png +0xcea7425d, textures/skybox_tiles/ssl.5.rgba16.png +0xce8e25fa, textures/segment2/segment2.06A80.rgba16.png +0xce142635, textures/skybox_tiles/bitfs.30.rgba16.png +0xcd7a591f, textures/skybox_tiles/ccm.2.rgba16.png +0xcd71304b, textures/sky/rr_textures.00000.rgba16.png +0xcd5f7595, actors/heart/spinning_heart.rgba16.png +0xcd56c1f2, textures/skybox_tiles/wdw.42.rgba16.png +0xcd381281, actors/purple_switch/purple_switch_base.rgba16.png +0xcd2a5787, actors/sand/sand_particle.rgba16.png +0xccfdae7d, levels/lll/20.rgba16.png +0xccfb8478, textures/skybox_tiles/ccm.40.rgba16.png +0xcceb38f6, textures/intro_raw/sparkle_1.rgba16.png +0xccad2f1e, textures/skybox_tiles/ccm.3.rgba16.png +0xcca2987c, levels/castle_inside/27.rgba16.png +0xcc89fe99, textures/skybox_tiles/bidw.39.rgba16.png +0xcc57ade9, levels/wdw/0.rgba16.png +0xcc4fe796, actors/peach/peach_eye_open.rgba16.png +0xcc25ce0f, levels/castle_inside/7.rgba16.png +0xcbe026c4, levels/bob/0.rgba16.png +0xcbbc8294, actors/koopa/koopa_eyes_open.rgba16.png +0xcbab007a, textures/skybox_tiles/wdw.39.rgba16.png +0xcb7b6e97, levels/castle_inside/9.rgba16.png +0xcb67da9f, textures/skybox_tiles/bidw.23.rgba16.png +0xcb57b47b, textures/segment2/segment2.10458.ia8.png +0xcb509d6a, textures/effect/tiny_bubble.0684C.rgba16.png +0xcb4982b2, actors/chain_ball/chain_ball.rgba16.png +0xcb3c5d47, textures/skybox_tiles/ssl.38.rgba16.png +0xcb2a2930, levels/cotmc/2.rgba16.png +0xcabc445d, textures/skybox_tiles/clouds.16.rgba16.png +0xca7e41b1, levels/bowser_1/2.rgba16.png +0xc9f30baf, actors/breakable_box/crazy_box_surface.rgba16.png +0xc9e2883e, textures/spooky/bbh_textures.08000.rgba16.png +0xc9a1f57e, actors/mad_piano/mad_piano_keys_edge.rgba16.png +0xc99f67f2, textures/skybox_tiles/bbh.3.rgba16.png +0xc99b5909, actors/door/three_star_door_sign.rgba16.png +0xc99707d9, textures/spooky/bbh_textures.09000.rgba16.png +0xc989266f, actors/seaweed/seaweed_base.rgba16.png +0xc96fd4b4, textures/skybox_tiles/clouds.29.rgba16.png +0xc9524eee, textures/machine/ttc_textures.08000.rgba16.png +0xc9425d35, textures/skybox_tiles/ccm.8.rgba16.png +0xc91c9210, textures/segment2/segment2.06A00.rgba16.png +0xc8922002, textures/skybox_tiles/ssl.2.rgba16.png +0xc8782e13, textures/skybox_tiles/cake.29.rgba16.png +0xc833ef43, actors/flyguy/flyguy_cloth_wrinkle.rgba16.png +0xc82a46f3, actors/water_mine/water_mine_left_side_unused.rgba16.png +0xc82a46f3, actors/bomb/bomb_left_side.rgba16.png +0xc80078c1, textures/skybox_tiles/bits.18.rgba16.png +0xc7b5dbc9, actors/stomp_smoke/stomp_smoke_2.ia16.png +0xc70e2879, textures/skybox_tiles/cloud_floor.23.rgba16.png +0xc6d80baf, textures/skybox_tiles/ssl.47.rgba16.png +0xc6b026aa, textures/fire/lll_textures.02800.rgba16.png +0xc6a1c158, actors/goomba/goomba_face.rgba16.png +0xc64ad046, levels/lll/25.rgba16.png +0xc63f7abb, textures/skybox_tiles/clouds.19.rgba16.png +0xc6028757, textures/generic/bob_textures.00800.rgba16.png +0xc6028757, actors/eyerok/eyerok_bricks.rgba16.png +0xc5e87355, levels/jrb/1.rgba16.png +0xc55ca18e, textures/skybox_tiles/bbh.22.rgba16.png +0xc55c829f, textures/outside/castle_grounds_textures.0A800.rgba16.png +0xc540c44c, actors/scuttlebug/scuttlebug_leg.rgba16.png +0xc518bf93, textures/fire/lll_textures.06800.rgba16.png +0xc4d1c3ce, actors/leaves/leaf.rgba16.png +0xc4c356fa, textures/skybox_tiles/bidw.50.rgba16.png +0xc4c331e8, textures/skybox_tiles/bidw.42.rgba16.png +0xc4845a3e, levels/castle_grounds/4.rgba16.png +0xc3f5c275, actors/klepto/klepto_eye.rgba16.png +0xc3eb2fc6, textures/skybox_tiles/water.54.rgba16.png +0xc3941398, textures/skybox_tiles/clouds.22.rgba16.png +0xc3459917, textures/water/jrb_textures.07800.rgba16.png +0xc30b4fe2, textures/skybox_tiles/bidw.40.rgba16.png +0xc2e48c81, actors/tree/pine_tree.rgba16.png +0xc20fc383, levels/wf/1.rgba16.png +0xc2050f68, actors/bomb/bomb_right_side.rgba16.png +0xc2050f68, actors/water_mine/water_mine_right_side_unused.rgba16.png +0xc199118a, textures/cave/hmc_textures.01800.rgba16.png +0xc136bc10, textures/skybox_tiles/cake.0.rgba16.png +0xc0bcccf4, levels/lll/4.rgba16.png +0xc0a7d217, textures/skybox_tiles/clouds.24.rgba16.png +0xc072c80f, textures/mountain/ttm_textures.04800.rgba16.png +0xbfe56f11, textures/skybox_tiles/bidw.53.rgba16.png +0xbfc9a9dd, textures/skybox_tiles/wdw.5.rgba16.png +0xbfaff600, textures/skybox_tiles/bitfs.9.rgba16.png +0xbf952514, actors/bubba/bubba_sunglasses.rgba16.png +0xbf89df6a, textures/skybox_tiles/ccm.37.rgba16.png +0xbf00c323, textures/skybox_tiles/cake.16.rgba16.png +0xbe721e4b, textures/skybox_tiles/bbh.10.rgba16.png +0xbe5ab2ee, textures/skybox_tiles/bidw.44.rgba16.png +0xbe04ce2e, textures/cave/hmc_textures.09800.rgba16.png +0xbde331e7, textures/skybox_tiles/bitfs.25.rgba16.png +0xbdd76307, textures/skybox_tiles/ccm.13.rgba16.png +0xbdc75108, textures/skybox_tiles/ssl.63.rgba16.png +0xbd9c82de, textures/skybox_tiles/bbh.30.rgba16.png +0xbd8c842f, textures/skybox_tiles/ssl.22.rgba16.png +0xbd4ba854, levels/wmotr/3.rgba16.png +0xbd423336, textures/grass/wf_textures.01000.rgba16.png +0xbd28248a, textures/spooky/bbh_textures.00800.rgba16.png +0xbcbd0842, actors/power_meter/power_meter_two_segments.rgba16.png +0xbc16978d, actors/checkerboard_platform/checkerboard_platform.rgba16.png +0xbbed1dad, textures/skybox_tiles/ccm.18.rgba16.png +0xbbd69d4a, actors/walk_smoke/walk_smoke_1.ia16.png +0xbbca6538, levels/lll/21.rgba16.png +0xbbc6b061, actors/door/door_lock.rgba16.png +0xbb980031, textures/title_screen_bg/title_screen_bg.033C0.rgba16.png +0xbb5327e0, textures/skybox_tiles/bitfs.15.rgba16.png +0xbb48f1bc, actors/stomp_smoke/stomp_smoke_4.ia16.png +0xbb2fb09f, textures/skybox_tiles/ccm.12.rgba16.png +0xba8930c5, textures/skybox_tiles/bbh.2.rgba16.png +0xba6d7331, textures/fire/lll_textures.04800.rgba16.png +0xba568bd1, textures/skybox_tiles/cake.24.rgba16.png +0xba25c107, textures/skybox_tiles/cloud_floor.14.rgba16.png +0xb9c749b9, actors/sparkle/sparkle_5.rgba16.png +0xb92bf6c1, textures/skybox_tiles/bits.52.rgba16.png +0xb9299e61, actors/eyerok/eyerok_eye_closed.rgba16.png +0xb8f6006f, textures/spooky/bbh_textures.06000.rgba16.png +0xb8e3120b, textures/skybox_tiles/water.2.rgba16.png +0xb8ab2c4e, textures/skybox_tiles/bitfs.4.rgba16.png +0xb8a77d4d, actors/pokey/pokey_face.rgba16.png +0xb8755755, textures/skybox_tiles/water.11.rgba16.png +0xb858a9a4, textures/skybox_tiles/ccm.29.rgba16.png +0xb8378cd9, textures/skybox_tiles/ssl.3.rgba16.png +0xb7c60055, actors/peach/peach_nostril.rgba16.png +0xb7c38322, levels/intro/1.rgba16.png +0xb7c222a8, textures/skybox_tiles/ssl.43.rgba16.png +0xb7b83492, textures/generic/bob_textures.02000.rgba16.png +0xb76d42dd, textures/skybox_tiles/bidw.21.rgba16.png +0xb6cec061, textures/skybox_tiles/water.28.rgba16.png +0xb6a89482, levels/castle_inside/32.rgba16.png +0xb63a3055, textures/sky/rr_textures.03800.rgba16.png +0xb616a7c2, textures/skybox_tiles/bbh.14.rgba16.png +0xb602ab34, textures/skybox_tiles/bits.53.rgba16.png +0xb5da0b63, textures/skybox_tiles/bits.10.rgba16.png +0xb5b2c148, textures/spooky/bbh_textures.00000.rgba16.png +0xb5ac8928, levels/castle_inside/19.rgba16.png +0xb59d468a, levels/ttm/4.rgba16.png +0xb596cb90, actors/explosion/explosion_4.rgba16.png +0xb55e9b94, textures/skybox_tiles/ssl.36.rgba16.png +0xb54d1a02, actors/water_splash/water_splash_5.rgba16.png +0xb5135c61, textures/water/jrb_textures.00000.rgba16.png +0xb50de959, textures/fire/lll_textures.09800.rgba16.png +0xb4cad4f7, textures/mountain/ttm_textures.0B800.rgba16.png +0xb4aa0e1c, actors/chillychief/chill_bully_right_side.rgba16.png +0xb48bb452, textures/skybox_tiles/ssl.9.rgba16.png +0xb484b601, textures/skybox_tiles/cloud_floor.7.rgba16.png +0xb45578dc, textures/skybox_tiles/bbh.34.rgba16.png +0xb453cc4a, textures/skybox_tiles/bitfs.24.rgba16.png +0xb452cbbe, actors/tree/tree_right_side.rgba16.png +0xb416574c, textures/skybox_tiles/cloud_floor.24.rgba16.png +0xb401e19f, levels/ttm/3.rgba16.png +0xb3f25163, textures/skybox_tiles/bbh.24.rgba16.png +0xb3c88877, textures/skybox_tiles/ssl.48.rgba16.png +0xb2efd400, textures/skybox_tiles/bidw.47.rgba16.png +0xb2dbccae, actors/penguin/penguin_eye_open.rgba16.png +0xb271db5b, textures/skybox_tiles/bits.60.rgba16.png +0xb2718db8, levels/ccm/3.rgba16.png +0xb26d42c0, textures/skybox_tiles/bits.51.rgba16.png +0xb267fdf0, actors/chain_chomp/chain_chomp_eye.rgba16.png +0xb2444e60, textures/skybox_tiles/bits.58.rgba16.png +0xb1f1cc42, textures/grass/wf_textures.07000.rgba16.png +0xb1e98f62, textures/skybox_tiles/ssl.32.rgba16.png +0xb1386a2e, textures/fire/lll_textures.00000.rgba16.png +0xb1330909, textures/skybox_tiles/ccm.11.rgba16.png +0xb1237167, levels/castle_inside/15.rgba16.png +0xb11fdc36, actors/boo/boo_eyes.rgba16.png +0xb11fdc36, actors/boo_castle/bbh_boo_eyes.rgba16.png +0xb114863b, textures/sky/rr_textures.07800.rgba16.png +0xb0fe2869, textures/skybox_tiles/ccm.42.rgba16.png +0xb0cd69ef, levels/bits/2.rgba16.png +0xb0a791ee, textures/skybox_tiles/ssl.39.rgba16.png +0xb09f7ff5, textures/skybox_tiles/cloud_floor.39.rgba16.png +0xb017cff7, levels/bowser_1/0.rgba16.png +0xafcc9de7, textures/skybox_tiles/ssl.7.rgba16.png +0xaf89c8f8, levels/wdw/4.rgba16.png +0xaf7b75c2, textures/skybox_tiles/bbh.38.rgba16.png +0xaef22277, textures/generic/bob_textures.05800.rgba16.png +0xaec008c0, textures/generic/bob_textures.09800.rgba16.png +0xae1d5dc1, actors/bomb/bomb_spike.rgba16.png +0xae1d5dc1, actors/water_mine/water_mine_spike_unused.rgba16.png +0xae019762, levels/bob/4.rgba16.png +0xadb81440, textures/skybox_tiles/bidw.51.rgba16.png +0xad35a744, actors/unagi/unagi_tail.rgba16.png +0xacec3f69, textures/skybox_tiles/bbh.37.rgba16.png +0xac05a9ff, levels/castle_grounds/5.ia8.png +0xab7a67d1, textures/skybox_tiles/clouds.18.rgba16.png +0xaacf41c9, textures/skybox_tiles/clouds.35.rgba16.png +0xaa5a7898, textures/skybox_tiles/bbh.11.rgba16.png +0xa9f1685a, textures/skybox_tiles/bits.17.rgba16.png +0xa9de87a8, textures/skybox_tiles/water.41.rgba16.png +0xa8ff4543, levels/castle_inside/26.rgba16.png +0xa87f6678, textures/skybox_tiles/cloud_floor.44.rgba16.png +0xa84756ae, textures/skybox_tiles/wdw.47.rgba16.png +0xa833e954, actors/mr_i_iris/mr_i_iris_closed.rgba16.png +0xa808d20a, textures/fire/lll_textures.07000.rgba16.png +0xa804c734, levels/lll/17.rgba16.png +0xa7c0a6eb, levels/totwc/3.ia16.png +0xa7bdd88f, actors/whirlpool/whirlpool.ia16.png +0xa7bdd88f, actors/tornado/tornado.ia16.png +0xa765aaa8, actors/exclamation_box/wing_cap_box_front.rgba16.png +0xa742c5e3, textures/skybox_tiles/wdw.60.rgba16.png +0xa7398f08, textures/segment2/segment2.081D0.rgba16.png +0xa72c7c50, textures/skybox_tiles/wdw.46.rgba16.png +0xa71d06b9, actors/bobomb/bob-omb_left_side.rgba16.png +0xa6e20840, textures/outside/castle_grounds_textures.08800.rgba16.png +0xa6d0d0cc, textures/skybox_tiles/ssl.61.rgba16.png +0xa65a6e86, levels/menu/main_menu_seg7_us.0B1C0.ia8.png +0xa6592f52, textures/skybox_tiles/wdw.34.rgba16.png +0xa6469110, actors/skeeter/skeeter_iris.rgba16.png +0xa6463a8d, textures/inside/inside_castle_textures.05000.rgba16.png +0xa6411501, actors/stomp_smoke/stomp_smoke_0.ia16.png +0xa608942f, textures/skybox_tiles/water.4.rgba16.png +0xa5e5250e, textures/skybox_tiles/clouds.17.rgba16.png +0xa58a82f8, textures/skybox_tiles/cake.19.rgba16.png +0xa554538a, textures/skybox_tiles/wdw.54.rgba16.png +0xa5063adb, textures/skybox_tiles/bitfs.36.rgba16.png +0xa4c2448b, textures/skybox_tiles/ssl.40.rgba16.png +0xa4b86dc8, textures/skybox_tiles/ssl.0.rgba16.png +0xa4af5230, textures/spooky/bbh_textures.0A000.rgba16.png +0xa4af5230, actors/haunted_cage/bbh_cage_floor.rgba16.png +0xa4908044, textures/skybox_tiles/cloud_floor.1.rgba16.png +0xa4841a07, actors/flame/flame_0.ia16.png +0xa46217ab, textures/skybox_tiles/bitfs.11.rgba16.png +0xa44df3e3, textures/segment2/shadow_quarter_circle.ia8.png +0xa436e205, textures/skybox_tiles/bits.29.rgba16.png +0xa4316e88, textures/skybox_tiles/bidw.31.rgba16.png +0xa3da7f18, textures/generic/bob_textures.08000.rgba16.png +0xa3da7f18, levels/ssl/7.rgba16.png +0xa3c0d76f, actors/mad_piano/mad_piano_keys_corner.rgba16.png +0xa3936ee4, textures/skybox_tiles/wdw.43.rgba16.png +0xa356667c, textures/skybox_tiles/cloud_floor.55.rgba16.png +0xa34f223c, levels/menu/main_menu_seg7.02018.rgba16.png +0xa349a078, textures/skybox_tiles/bits.36.rgba16.png +0xa34577b4, textures/skybox_tiles/ssl.42.rgba16.png +0xa3067f0b, textures/skybox_tiles/ccm.52.rgba16.png +0xa2f695a8, levels/vcutm/1.rgba16.png +0xa2f30414, actors/wiggler/wiggler_nose_right_side.rgba16.png +0xa2d48f6c, levels/bob/3.rgba16.png +0xa290798b, levels/bits/1.rgba16.png +0xa23342e2, actors/mushroom_1up/1-up_mushroom.rgba16.png +0xa22a5a73, levels/cotmc/0.rgba16.png +0xa2013a12, textures/segment2/segment2.03A00.rgba16.png +0xa1ae1a01, textures/water/jrb_textures.04800.rgba16.png +0xa15fb7b8, textures/intro_raw/white_star_2.rgba16.png +0xa1261baa, textures/skybox_tiles/clouds.31.rgba16.png +0xa11b5cf3, textures/grass/wf_textures.06000.rgba16.png +0xa11b5cf3, textures/sky/rr_textures.05000.rgba16.png +0xa11454a9, actors/bubba/bubba_fins.rgba16.png +0xa11454a9, actors/bub/bub_fins.rgba16.png +0xa0a0a907, textures/skybox_tiles/ssl.51.rgba16.png +0xa0974d75, textures/segment2/segment2.04A00.rgba16.png +0xa08e284c, levels/castle_inside/11.rgba16.png +0xa0869522, actors/bowser/bowser_eye_right_1.rgba16.png +0xa0869522, actors/bowser/bowser_eye_right_0.rgba16.png +0xa07bcde0, textures/skybox_tiles/clouds.20.rgba16.png +0xa055e62e, levels/cotmc/1.rgba16.png +0x9fcddce1, textures/inside/inside_castle_textures.09000.rgba16.png +0x9fbecef9, actors/mario/mario_eyes_half_closed.rgba16.png +0x9fb76a34, textures/skybox_tiles/cloud_floor.38.rgba16.png +0x9fa96b1f, textures/mountain/ttm_textures.01800.rgba16.png +0x9f82c465, textures/skybox_tiles/ccm.41.rgba16.png +0x9f6dd214, textures/skybox_tiles/bidw.17.rgba16.png +0x9f6bff93, textures/skybox_tiles/ccm.55.rgba16.png +0x9f02a40f, actors/power_meter/power_meter_five_segments.rgba16.png +0x9eb76583, textures/skybox_tiles/bitfs.34.rgba16.png +0x9e94b9f1, textures/skybox_tiles/bidw.26.rgba16.png +0x9e520cb2, textures/skybox_tiles/bbh.16.rgba16.png +0x9e4203ff, textures/skybox_tiles/bitfs.13.rgba16.png +0x9e30aed1, textures/skybox_tiles/bitfs.10.rgba16.png +0x9df06e15, levels/wdw/2.rgba16.png +0x9dc7c1e8, actors/spindrift/spindrift_head.rgba16.png +0x9dbb856e, textures/skybox_tiles/ccm.54.rgba16.png +0x9d15e307, levels/ccm/12.rgba16.png +0x9d13156e, textures/skybox_tiles/water.8.rgba16.png +0x9cfe9f81, textures/grass/wf_textures.0B000.ia16.png +0x9cfe9f81, textures/generic/bob_textures.0B000.ia16.png +0x9cfe9f81, textures/outside/castle_grounds_textures.0BC00.ia16.png +0x9cab9c3a, textures/snow/ccm_textures.04800.rgba16.png +0x9c977cff, actors/door/hmc_mural_door_overlay.rgba16.png +0x9c8d6967, textures/skybox_tiles/cake.10.rgba16.png +0x9c6fa38a, textures/skybox_tiles/bbh.18.rgba16.png +0x9c50af6d, actors/walk_smoke/walk_smoke_4.ia16.png +0x9c0e821e, textures/water/jrb_textures.09000.rgba16.png +0x9bf7992d, textures/skybox_tiles/ssl.25.rgba16.png +0x9be30b6e, textures/inside/inside_castle_textures.03000.rgba16.png +0x9bd37209, textures/skybox_tiles/cake.18.rgba16.png +0x9b6b4dbc, textures/snow/ccm_textures.03000.rgba16.png +0x9b650ed0, actors/heave_ho/heave-ho_logo.rgba16.png +0x9b61a230, textures/grass/wf_textures.08800.rgba16.png +0x9b4befb8, textures/cave/hmc_textures.04800.rgba16.png +0x9b42abea, actors/manta/manta_fin_edge.rgba16.png +0x9af43b47, textures/skybox_tiles/bits.61.rgba16.png +0x9ae320d1, textures/segment2/segment2.06F80.rgba16.png +0x9a729c51, textures/fire/lll_textures.03800.rgba16.png +0x9a6d7782, levels/menu/main_menu_seg7_us.0B4C0.ia8.png +0x9a5a2fb3, actors/door/bbh_door_overlay.rgba16.png +0x99a009d0, textures/skybox_tiles/ccm.58.rgba16.png +0x9965c006, actors/door/polished_wooden_door_overlay.rgba16.png +0x99302633, textures/skybox_tiles/bitfs.37.rgba16.png +0x992737d1, textures/skybox_tiles/cake.32.rgba16.png +0x98daf219, textures/skybox_tiles/wdw.63.rgba16.png +0x98c99a4d, textures/skybox_tiles/clouds.37.rgba16.png +0x98c45311, textures/skybox_tiles/clouds.23.rgba16.png +0x988f8d4a, textures/segment2/segment2.06D80.rgba16.png +0x981fc4c1, levels/castle_inside/37.rgba16.png +0x97e53259, textures/cave/hmc_textures.07800.rgba16.png +0x9791b947, textures/skybox_tiles/bits.56.rgba16.png +0x976dbc10, textures/outside/castle_grounds_textures.00000.rgba16.png +0x9759dcd0, actors/bowser/bowser_hair.rgba16.png +0x96fad568, textures/skybox_tiles/ssl.19.rgba16.png +0x96a88f3b, textures/skybox_tiles/water.3.rgba16.png +0x968fa8ce, textures/outside/castle_grounds_textures.0B400.rgba16.png +0x968ec1c4, actors/moneybag/moneybag_eyes.rgba16.png +0x9678001c, textures/snow/ccm_textures.02000.rgba16.png +0x9663b6f7, textures/skybox_tiles/bbh.27.rgba16.png +0x964a7e66, levels/menu/main_menu_seg7_us.0B200.ia8.png +0x962278d5, textures/segment2/segment2.06500.rgba16.png +0x95c4562e, levels/castle_inside/20.rgba16.png +0x9513887c, textures/segment2/segment2.00600.rgba16.png +0x94776f27, actors/cannon_barrel/cannon_barrel.rgba16.png +0x946f580c, actors/metal_box/metal_box_side.rgba16.png +0x946e561b, levels/castle_inside/18.rgba16.png +0x945c9872, levels/menu/main_menu_seg7_us.0B440.ia8.png +0x945943b1, levels/lll/5.rgba16.png +0x942949f4, textures/skybox_tiles/water.18.rgba16.png +0x940954ac, textures/skybox_tiles/wdw.40.rgba16.png +0x93d4ee01, actors/door/metal_door_overlay.rgba16.png +0x93ae5517, textures/grass/wf_textures.02000.rgba16.png +0x937650b4, textures/skybox_tiles/bidw.16.rgba16.png +0x9374994c, actors/stomp_smoke/stomp_smoke_5.ia16.png +0x93507e3b, textures/skybox_tiles/bidw.28.rgba16.png +0x934dc3b3, textures/intro_raw/red_star_1.rgba16.png +0x933c8f9c, textures/machine/ttc_textures.08400.rgba16.png +0x933976b9, textures/skybox_tiles/water.26.rgba16.png +0x931ab56d, levels/wf/5.ia8.png +0x931ab56d, textures/segment2/shadow_quarter_square.ia8.png +0x930392d9, textures/skybox_tiles/bits.44.rgba16.png +0x92f79940, textures/cave/hmc_textures.07000.rgba16.png +0x92e17e06, textures/skybox_tiles/wdw.3.rgba16.png +0x92ad1eef, textures/segment2/segment2.05600.rgba16.png +0x92a6e121, textures/skybox_tiles/ccm.46.rgba16.png +0x928d4e78, actors/water_splash/water_splash_3.rgba16.png +0x92828a2b, actors/walk_smoke/walk_smoke_2.ia16.png +0x92766b78, levels/menu/main_menu_seg7_us.0B400.ia8.png +0x923c687e, actors/flyguy/flyguy_face.rgba16.png +0x9205f8fc, textures/skybox_tiles/bidw.37.rgba16.png +0x91787803, textures/skybox_tiles/ssl.26.rgba16.png +0x912f6e5e, textures/skybox_tiles/ccm.44.rgba16.png +0x91252367, levels/bitfs/1.rgba16.png +0x90ef51bb, levels/castle_inside/22.rgba16.png +0x908bb0a5, textures/skybox_tiles/bidw.30.rgba16.png +0x906ff62e, actors/sparkle/sparkle_1.rgba16.png +0x9066e92b, levels/vcutm/0.rgba16.png +0x905d3214, actors/mario_cap/mario_cap_logo.rgba16.png +0x905d3214, actors/mario/mario_logo.rgba16.png +0x90581231, actors/klepto/klepto_chest_tuft.rgba16.png +0x9026cba3, textures/generic/bob_textures.08800.rgba16.png +0x90027a49, actors/poundable_pole/poundable_pole_side.rgba16.png +0x8fc7fac2, textures/sky/rr_textures.02000.rgba16.png +0x8f92529c, textures/skybox_tiles/water.5.rgba16.png +0x8f698cc1, actors/treasure_chest/treasure_chest_side.rgba16.png +0x8f523ef1, textures/mountain/ttm_textures.0B000.rgba16.png +0x8f25c650, levels/lll/32.rgba16.png +0x8ee5398c, levels/castle_inside/4.rgba16.png +0x8edc5be4, textures/skybox_tiles/bbh.32.rgba16.png +0x8ecffabb, textures/title_screen_bg/title_screen_bg.04040.rgba16.png +0x8e58d68a, textures/skybox_tiles/water.49.rgba16.png +0x8e41ffcd, actors/king_bobomb/king_bob-omb_hand.rgba16.png +0x8e41ffcd, actors/yellow_sphere/yellow_sphere.rgba16.png +0x8e41ffcd, actors/yellow_sphere_small/small_yellow_sphere.rgba16.png +0x8e28628b, levels/bitfs/2.rgba16.png +0x8db2e5ca, textures/snow/ccm_textures.06800.rgba16.png +0x8d6b1df6, actors/bowser/bowser_claw_horn_angle.rgba16.png +0x8d5f88c4, textures/skybox_tiles/cake.41.rgba16.png +0x8d2f37b0, levels/hmc/5.rgba16.png +0x8d030865, levels/castle_inside/13.rgba16.png +0x8cc10b27, textures/skybox_tiles/clouds.2.rgba16.png +0x8c748686, levels/menu/main_menu_seg7_us.0B380.ia8.png +0x8c1ebb7f, actors/manta/manta_fin_corner.rgba16.png +0x8b826df7, textures/title_screen_bg/title_screen_bg.01AC0.rgba16.png +0x8b6c6929, levels/castle_inside/33.rgba16.png +0x8b50e442, levels/ssl/0.rgba16.png +0x8b462047, textures/skybox_tiles/ccm.45.rgba16.png +0x8af0e7be, textures/skybox_tiles/water.1.rgba16.png +0x8ac74230, actors/chain_chomp/chain_chomp_bright_shine.rgba16.png +0x8a94d5a3, actors/walk_smoke/walk_smoke_0.ia16.png +0x8a6a5e6e, levels/menu/main_menu_seg7_us.0B3C0.ia8.png +0x8a687694, textures/segment2/font_graphics.06410.ia1.png +0x8a4df121, textures/skybox_tiles/cake.1.rgba16.png +0x8a4df121, textures/skybox_tiles/cake.2.rgba16.png +0x89cfd188, textures/skybox_tiles/clouds.7.rgba16.png +0x89b90233, actors/klepto/klepto_wing.rgba16.png +0x89ac3c05, textures/skybox_tiles/clouds.11.rgba16.png +0x890b9632, actors/heave_ho/heave-ho_face.rgba16.png +0x88e7e346, textures/skybox_tiles/ccm.43.rgba16.png +0x88dc2d34, actors/amp/amp_mouth.rgba16.png +0x88c0ccf9, actors/snowman/mr_blizzard_right_side.rgba16.png +0x889e61ff, textures/skybox_tiles/ccm.14.rgba16.png +0x889d2b5c, textures/skybox_tiles/cloud_floor.6.rgba16.png +0x8899587d, textures/spooky/bbh_textures.03800.rgba16.png +0x888f7075, textures/skybox_tiles/bbh.9.rgba16.png +0x88898880, levels/menu/main_menu_seg7_us.0B680.ia8.png +0x8886887e, levels/menu/main_menu_seg7_us.0B180.ia8.png +0x88788776, levels/menu/main_menu_seg7_us.0AFC0.ia8.png +0x88703c55, textures/segment2/segment2.05800.rgba16.png +0x886b2ff9, actors/king_bobomb/king_bob-omb_left_side.rgba16.png +0x88654139, textures/machine/ttc_textures.07000.rgba16.png +0x8853b016, textures/skybox_tiles/wdw.12.rgba16.png +0x88493238, levels/castle_inside/21.rgba16.png +0x880ed312, textures/skybox_tiles/cloud_floor.0.rgba16.png +0x87d447af, actors/treasure_chest/treasure_chest_lock_top.rgba16.png +0x87c25fe2, textures/skybox_tiles/water.40.rgba16.png +0x87805a7c, actors/sparkle_animation/sparkle_animation_3.ia16.png +0x87786913, actors/mr_i_eyeball/mr_i_eyeball_right_side.rgba16.png +0x877137a9, actors/door/hmc_mural_door.rgba16.png +0x875630d6, actors/blue_coin_switch/blue_coin_switch_top.rgba16.png +0x8726a741, textures/skybox_tiles/ccm.25.rgba16.png +0x86fb2f22, actors/koopa/koopa_shell_front_top.rgba16.png +0x86fb0c9f, textures/machine/ttc_textures.05800.rgba16.png +0x86b7d553, textures/segment2/segment2.03200.rgba16.png +0x86b5c15f, textures/skybox_tiles/cloud_floor.50.rgba16.png +0x86a4d0dc, textures/skybox_tiles/ccm.51.rgba16.png +0x869d1c9b, textures/skybox_tiles/bbh.12.rgba16.png +0x86868886, levels/menu/main_menu_seg7_us.0B640.ia8.png +0x8675f075, textures/skybox_tiles/wdw.1.rgba16.png +0x86712a04, actors/amp/amp_electricity.rgba16.png +0x861dc3cf, textures/grass/wf_textures.00000.rgba16.png +0x85a91338, textures/skybox_tiles/ssl.13.rgba16.png +0x85887ee4, actors/piranha_plant/piranha_plant_tooth.rgba16.png +0x8541d92c, textures/skybox_tiles/ccm.47.rgba16.png +0x852361b6, actors/koopa/koopa_eye_border.rgba16.png +0x85204772, levels/ssl/3.rgba16.png +0x84fed0d8, textures/snow/ccm_textures.00800.rgba16.png +0x84836b2d, actors/walk_smoke/walk_smoke_6.ia16.png +0x84806080, levels/menu/main_menu_seg7_us.0B140.ia8.png +0x84788778, levels/menu/main_menu_seg7_us.0B000.ia8.png +0x846a6656, levels/menu/main_menu_seg7_us.0B080.ia8.png +0x84651765, textures/skybox_tiles/cloud_floor.32.rgba16.png +0x8464cc0c, actors/whomp/whomp_surface.rgba16.png +0x8413a8fa, actors/exclamation_box/metal_cap_box_side.rgba16.png +0x83d5ba14, textures/machine/ttc_textures.04000.rgba16.png +0x83101fa2, levels/rr/quarter_flying_carpet.rgba16.png +0x8300dd14, levels/castle_inside/25.rgba16.png +0x82c55dc1, textures/skybox_tiles/clouds.15.rgba16.png +0x82b146cd, textures/fire/lll_textures.05000.rgba16.png +0x829b7107, levels/hmc/2.rgba16.png +0x8299c450, levels/ccm/4.rgba16.png +0x8296d820, textures/outside/castle_grounds_textures.03800.rgba16.png +0x82888684, levels/menu/main_menu_seg7_us.0B600.ia8.png +0x82868870, levels/menu/main_menu_seg7_us.0AC80.ia8.png +0x82487dab, textures/skybox_tiles/ccm.28.rgba16.png +0x822ff6df, actors/scuttlebug/scuttlebug_iris.rgba16.png +0x822b53ed, textures/skybox_tiles/ccm.33.rgba16.png +0x8213677c, actors/mad_piano/mad_piano_keys.rgba16.png +0x8202be27, textures/skybox_tiles/cake.21.rgba16.png +0x81f9d9f5, textures/grass/wf_textures.04800.rgba16.png +0x81bb18e0, textures/segment2/segment2.04800.rgba16.png +0x81b554a7, actors/monty_mole_hole/monty_mole_hole.ia16.png +0x8188e2dd, actors/sparkle/sparkle_3.rgba16.png +0x8141bbbc, textures/skybox_tiles/bits.42.rgba16.png +0x812626f9, textures/skybox_tiles/bitfs.33.rgba16.png +0x81175ed5, textures/skybox_tiles/bitfs.32.rgba16.png +0x810a6136, textures/fire/lll_textures.08800.rgba16.png +0x8093d98d, textures/skybox_tiles/bidw.12.rgba16.png +0x808c10c2, actors/king_bobomb/king_bob-omb_right_side.rgba16.png +0x80788486, levels/menu/main_menu_seg7_us.0B6C0.ia8.png +0x8076d349, textures/skybox_tiles/ccm.24.rgba16.png +0x8073de72, actors/bookend/bookend_cover.rgba16.png +0x8073de72, actors/book/book_cover.rgba16.png +0x80707e74, levels/menu/main_menu_seg7_us.0B100.ia8.png +0x80443eae, textures/skybox_tiles/cake.11.rgba16.png +0x7fcd908d, textures/skybox_tiles/clouds.26.rgba16.png +0x7fcb976c, textures/skybox_tiles/bidw.29.rgba16.png +0x7f9ccd83, textures/cave/hmc_textures.03000.rgba16.png +0x7f86b16b, textures/skybox_tiles/clouds.8.rgba16.png +0x7f832c86, textures/generic/bob_textures.00000.rgba16.png +0x7f5468e5, textures/skybox_tiles/bidw.43.rgba16.png +0x7f0c0d1a, textures/skybox_tiles/bbh.35.rgba16.png +0x7ecf9e44, textures/fire/lll_textures.04000.rgba16.png +0x7ebe7d5e, actors/exclamation_box/vanish_cap_box_front.rgba16.png +0x7eb3fe85, actors/bowser/bowser_shell_edge.rgba16.png +0x7e91d91e, textures/skybox_tiles/cloud_floor.37.rgba16.png +0x7e7433a6, levels/vcutm/3.rgba16.png +0x7e5c3a04, actors/exclamation_box/metal_cap_box_front.rgba16.png +0x7e5c24f7, textures/sky/rr_textures.07000.rgba16.png +0x7e28666b, textures/water/jrb_textures.0B800.rgba16.png +0x7e27e43f, textures/skybox_tiles/ssl.17.rgba16.png +0x7e216e16, actors/peach/peach_chest_jewel.rgba16.png +0x7e1d47db, textures/skybox_tiles/ssl.55.rgba16.png +0x7dcc1ab5, textures/skybox_tiles/bits.38.rgba16.png +0x7d398ef0, textures/skybox_tiles/bits.50.rgba16.png +0x7d23e625, textures/skybox_tiles/water.15.rgba16.png +0x7cfb23b0, textures/fire/lll_textures.0B000.rgba16.png +0x7ce8869d, actors/mist/mist.ia16.png +0x7cc51e15, textures/segment2/segment2.02000.rgba16.png +0x7cb09e26, textures/skybox_tiles/water.34.rgba16.png +0x7c9e686e, levels/menu/main_menu_seg7_us.0B500.ia8.png +0x7c98dfa7, textures/skybox_tiles/cloud_floor.8.rgba16.png +0x7c2d13c9, textures/segment2/segment2.00400.rgba16.png +0x7b8e4ac2, actors/peach/peach_eye_mostly_closed.rgba16.png +0x7b8e447d, levels/ddd/3.rgba16.png +0x7b84a495, actors/bowser/bowser_eye_left_1.rgba16.png +0x7b84a495, actors/bowser/bowser_eye_left_0.rgba16.png +0x7b7a6ad1, actors/chuckya/chuckya_hand_antenna.rgba16.png +0x7af76431, textures/skybox_tiles/bidw.45.rgba16.png +0x7af18328, actors/tree/palm_tree.rgba16.png +0x7ae8e843, levels/lll/28.rgba16.png +0x7ab277b8, textures/segment2/segment2.02A00.rgba16.png +0x7a96785c, levels/menu/main_menu_seg7_us.0AD80.ia8.png +0x7a86845c, levels/menu/main_menu_seg7_us.0ADC0.ia8.png +0x7a6ab5a7, textures/sky/rr_textures.08000.rgba16.png +0x7a1b62b1, textures/mountain/ttm_textures.07000.rgba16.png +0x79d8c749, textures/grass/wf_textures.05800.rgba16.png +0x79d25afb, textures/machine/ttc_textures.00000.rgba16.png +0x79c8997d, textures/skybox_tiles/ssl.14.rgba16.png +0x795fe3b9, textures/skybox_tiles/bits.25.rgba16.png +0x78b59e82, actors/penguin/penguin_beak.rgba16.png +0x78ab0f9f, textures/spooky/bbh_textures.07000.rgba16.png +0x78a6db75, actors/mr_i_iris/mr_i_iris_mostly_closed.rgba16.png +0x78986182, levels/menu/main_menu_seg7_us.0AF40.ia8.png +0x788c8286, levels/menu/main_menu_seg7_us.0B0C0.ia8.png +0x7889781a, textures/skybox_tiles/wdw.61.rgba16.png +0x786b7070, levels/menu/main_menu_seg7_us.0AF80.ia8.png +0x784949ca, textures/segment2/segment2.06E00.rgba16.png +0x783b816b, levels/sl/0.rgba16.png +0x77ec8240, textures/skybox_tiles/ccm.38.rgba16.png +0x77c0ff44, textures/skybox_tiles/cake.3.rgba16.png +0x775a5057, textures/water/jrb_textures.02800.rgba16.png +0x7749b0d9, textures/segment2/segment2.0F458.ia8.png +0x77290eb2, actors/lakitu_enemy/lakitu_enemy_frown.rgba16.png +0x77290eb2, actors/lakitu_cameraman/lakitu_cameraman_frown.rgba16.png +0x76f2963d, textures/skybox_tiles/cloud_floor.60.rgba16.png +0x76e8d87c, textures/mountain/ttm_textures.06800.rgba16.png +0x76abe6db, textures/skybox_tiles/cloud_floor.51.rgba16.png +0x767c6068, levels/menu/main_menu_seg7_us.0AF00.ia8.png +0x761b53e2, actors/bub/bub_eye_border.rgba16.png +0x761b53e2, actors/bubba/bubba_eye_border.rgba16.png +0x75ef9a90, textures/skybox_tiles/ssl.8.rgba16.png +0x75d9483a, textures/segment2/segment2.06980.rgba16.png +0x75701f22, textures/title_screen_bg/title_screen_bg.04CC0.rgba16.png +0x74c13ed4, textures/skybox_tiles/cloud_floor.36.rgba16.png +0x747b1b07, textures/skybox_tiles/bits.55.rgba16.png +0x746a5d31, textures/fire/lll_textures.00800.rgba16.png +0x74535372, textures/skybox_tiles/ccm.22.rgba16.png +0x744a7d8e, textures/snow/ccm_textures.02800.rgba16.png +0x742fd706, textures/grass/wf_textures.00800.rgba16.png +0x74141022, levels/wdw/1.rgba16.png +0x73d7c121, levels/castle_inside/8.rgba16.png +0x7378a96f, textures/effect/lava_bubble.04020.rgba16.png +0x73505869, textures/grass/wf_textures.03800.rgba16.png +0x73276400, textures/skybox_tiles/bbh.25.rgba16.png +0x7323e612, levels/lll/13.rgba16.png +0x730da5f2, textures/inside/inside_castle_textures.02000.rgba16.png +0x72d28485, textures/skybox_tiles/bbh.7.rgba16.png +0x72cb8c7f, levels/menu/main_menu_seg7.05468.rgba16.png +0x72a1d4b8, textures/skybox_tiles/cake.36.rgba16.png +0x729c6184, levels/menu/main_menu_seg7_us.0B340.ia8.png +0x726d3efe, textures/outside/castle_grounds_textures.04800.rgba16.png +0x723edcd4, actors/peach/peach_lips_scrunched.rgba16.png +0x71ffbf4d, textures/skybox_tiles/cloud_floor.41.rgba16.png +0x71d8c330, textures/skybox_tiles/cloud_floor.22.rgba16.png +0x718c4694, textures/skybox_tiles/bidw.34.rgba16.png +0x7134b6dd, textures/inside/inside_castle_textures.05800.rgba16.png +0x6ff2aac5, levels/castle_inside/39.rgba16.png +0x6fa30457, textures/fire/lll_textures.08000.rgba16.png +0x6f7df292, actors/amp/amp_body.rgba16.png +0x6f5155ba, textures/grass/wf_textures.0B800.ia16.png +0x6f32a4fb, textures/segment2/segment2.07B50.rgba16.png +0x6f146752, textures/skybox_tiles/water.51.rgba16.png +0x6eb6822e, textures/skybox_tiles/bidw.49.rgba16.png +0x6eb46458, levels/menu/main_menu_seg7_us.0B800.ia8.png +0x6e969590, textures/skybox_tiles/bitfs.46.rgba16.png +0x6e88f5e0, textures/skybox_tiles/bbh.39.rgba16.png +0x6e6a49ef, actors/bowser/bowser_body.rgba16.png +0x6e489603, actors/heave_ho/heave-ho_arm_ornament.rgba16.png +0x6e3243f8, textures/machine/ttc_textures.01800.rgba16.png +0x6dca9cd5, textures/generic/bob_textures.01000.rgba16.png +0x6db140ad, textures/skybox_tiles/ccm.31.rgba16.png +0x6dabf6c8, textures/skybox_tiles/bits.12.rgba16.png +0x6da0b1b9, textures/inside/inside_castle_textures.07000.rgba16.png +0x6d8cfa2f, levels/bowser_2/0.rgba16.png +0x6d6c38e3, actors/unagi/unagi_eye.rgba16.png +0x6d1039d9, textures/skybox_tiles/wdw.16.rgba16.png +0x6d0c18aa, textures/skybox_tiles/ssl.52.rgba16.png +0x6d083a48, actors/bookend/bookend_spine.rgba16.png +0x6d00c07c, textures/skybox_tiles/cloud_floor.29.rgba16.png +0x6cf04010, levels/sl/1.rgba16.png +0x6ca78364, actors/power_meter/power_meter_right_side.rgba16.png +0x6c902269, actors/dorrie/dorrie_skin.rgba16.png +0x6c889c54, levels/menu/main_menu_seg7_us.0AD00.ia8.png +0x6c706165, textures/skybox_tiles/cake.22.rgba16.png +0x6c6a6686, textures/segment2/font_graphics.06420.ia1.png +0x6c64eb0b, textures/segment2/segment2.01800.rgba16.png +0x6c5cc56f, actors/heave_ho/heave-ho_platform.rgba16.png +0x6c42dff7, textures/skybox_tiles/clouds.0.rgba16.png +0x6c3ce89f, textures/cave/hmc_textures.0C000.ia16.png +0x6c3ce89f, textures/spooky/bbh_textures.0A800.ia16.png +0x6c064a7f, textures/skybox_tiles/clouds.36.rgba16.png +0x6bf1d4ea, textures/intro_raw/sparkle_4.rgba16.png +0x6befedb8, levels/hmc/4.rgba16.png +0x6bcc2e51, actors/snufit/snufit_mouth.rgba16.png +0x6bc84af5, textures/skybox_tiles/cake.46.rgba16.png +0x6bc75681, textures/segment2/segment2.02E00.rgba16.png +0x6b8d43c4, actors/mario/mario_eyes_center.rgba16.png +0x6b3a40a5, actors/bowser/bowser_eye_center_0.rgba16.png +0x6b3a40a5, actors/bowser/bowser_eye_center_1.rgba16.png +0x6b1fc91a, textures/segment2/segment2.00000.rgba16.png +0x6af6b17f, actors/bowser/bowser_eyebrow.rgba16.png +0x6aca7d17, textures/skybox_tiles/water.38.rgba16.png +0x6ac8d5d1, actors/skeeter/skeeter_eye.rgba16.png +0x6abebff0, actors/klepto/klepto_wing_flap.rgba16.png +0x6aa1be26, textures/inside/inside_castle_textures.04000.rgba16.png +0x6a925357, levels/ddd/1.rgba16.png +0x6a925357, textures/cave/hmc_textures.01000.rgba16.png +0x6a925357, levels/jrb/0.rgba16.png +0x6a8bf6a8, textures/skybox_tiles/wdw.32.rgba16.png +0x6a799547, textures/skybox_tiles/cake.40.rgba16.png +0x6a748651, levels/lll/31.rgba16.png +0x6a4bef91, actors/snowman/mr_blizzard_mitten.rgba16.png +0x6a32a053, textures/effect/tiny_bubble.06AD8.rgba16.png +0x6a17a436, textures/skybox_tiles/ssl.11.rgba16.png +0x69553f79, levels/ttm/6.rgba16.png +0x6926316a, textures/skybox_tiles/cake.27.rgba16.png +0x6906c074, actors/coin/coin_front.ia16.png +0x6905fbf2, textures/skybox_tiles/ccm.30.rgba16.png +0x68cbbcd3, textures/skybox_tiles/bits.9.rgba16.png +0x68c4a756, textures/skybox_tiles/bidw.35.rgba16.png +0x6899f91f, textures/skybox_tiles/ssl.4.rgba16.png +0x688defb4, textures/skybox_tiles/bits.31.rgba16.png +0x688c825c, levels/menu/main_menu_seg7_us.0AE40.ia8.png +0x68886576, levels/menu/main_menu_seg7_us.0B040.ia8.png +0x68886272, levels/menu/main_menu_seg7_us.0B240.ia8.png +0x6879f1f6, textures/water/jrb_textures.0A800.rgba16.png +0x6872e4ff, textures/skybox_tiles/bitfs.14.rgba16.png +0x686c2f97, textures/intro_raw/red_star_6.rgba16.png +0x67d8b446, actors/water_wave/water_wave_3.ia16.png +0x67b3cf11, textures/skybox_tiles/ssl.44.rgba16.png +0x67ad777b, actors/flame/flame_4.ia16.png +0x67a98771, actors/warp_pipe/warp_pipe_top.rgba16.png +0x679a4c71, actors/clam_shell/clam_shell.rgba16.png +0x678bbbc1, levels/castle_inside/10.rgba16.png +0x677cf935, textures/skybox_tiles/cloud_floor.43.rgba16.png +0x677a5e03, textures/skybox_tiles/bits.41.rgba16.png +0x676b6cf3, textures/segment2/segment2.07F50.rgba16.png +0x674fa5c8, actors/water_splash/water_splash_2.rgba16.png +0x6695e997, actors/whomp/whomp_face.rgba16.png +0x66799dcc, levels/menu/main_menu_seg7.06328.rgba16.png +0x6626c09a, textures/fire/lll_textures.07800.rgba16.png +0x65bfa19a, levels/hmc/1.rgba16.png +0x65abbfe9, textures/skybox_tiles/water.30.rgba16.png +0x65542036, textures/cave/hmc_textures.0B800.ia16.png +0x65542036, levels/castle_inside/castle_light.ia16.png +0x6543184d, textures/snow/ccm_textures.00000.rgba16.png +0x6541dd48, levels/lll/15.rgba16.png +0x6505fac3, textures/skybox_tiles/ssl.28.rgba16.png +0x64df79e9, textures/skybox_tiles/ccm.49.rgba16.png +0x648dffc2, textures/skybox_tiles/cloud_floor.42.rgba16.png +0x646a9c64, levels/menu/main_menu_seg7_us.0B480.ia8.png +0x63f6e568, levels/lll/26.rgba16.png +0x63860579, textures/skybox_tiles/bitfs.16.rgba16.png +0x63820423, textures/skybox_tiles/bbh.28.rgba16.png +0x62c94802, actors/koopa/koopa_shell_front.rgba16.png +0x62c94802, actors/koopa_shell/koopa_shell_front.rgba16.png +0x62aefde2, textures/skybox_tiles/ssl.41.rgba16.png +0x629a458d, actors/swoop/swoop_wing.rgba16.png +0x626b987c, textures/skybox_tiles/cloud_floor.57.rgba16.png +0x6218470c, textures/skybox_tiles/bidw.14.rgba16.png +0x61c24b5e, levels/bowser_3/0.rgba16.png +0x61afcdd5, actors/bowser/bowser_armband.rgba16.png +0x617bfb7b, actors/flame/flame_5.ia16.png +0x613a2612, textures/skybox_tiles/cloud_floor.35.rgba16.png +0x611b82b3, levels/ccm/0.rgba16.png +0x610b81d3, levels/intro/2_copyright.rgba16.png +0x6108550a, textures/water/jrb_textures.08800.rgba16.png +0x60dd861c, textures/skybox_tiles/water.14.rgba16.png +0x60dd36f6, textures/grass/wf_textures.0A800.rgba16.png +0x60bcef6e, textures/skybox_tiles/cake.7.rgba16.png +0x60aa80aa, textures/generic/bob_textures.0A800.rgba16.png +0x607a828a, levels/menu/main_menu_seg7_us.0B700.ia8.png +0x6069e288, levels/bits/0.rgba16.png +0x603ab9fe, levels/castle_inside/35.rgba16.png +0x60351310, levels/bowser_1/1.rgba16.png +0x602ef33f, textures/generic/bob_textures.05000.rgba16.png +0x5ff8d3ef, actors/water_wave/water_wave_2.ia16.png +0x5fc183ba, textures/skybox_tiles/bitfs.26.rgba16.png +0x5f5e3df7, textures/skybox_tiles/ssl.46.rgba16.png +0x5f328955, textures/outside/castle_grounds_textures.09800.rgba16.png +0x5f035ec5, actors/koopa_shell/koopa_shell_back.rgba16.png +0x5f035ec5, actors/koopa/koopa_shell_back.rgba16.png +0x5ef65dd9, textures/segment2/segment2.00A00.rgba16.png +0x5e819c11, textures/skybox_tiles/bbh.5.rgba16.png +0x5dfa73ac, actors/bubble/mr_i_bubble.rgba16.png +0x5ddd4bf0, textures/skybox_tiles/bbh.8.rgba16.png +0x5d6b0678, actors/mario/mario_eyes_closed_unused_0.rgba16.png +0x5d6b0678, actors/mario/mario_eyes_closed.rgba16.png +0x5d6b0678, actors/mario/mario_eyes_closed_unused_1.rgba16.png +0x5d617ea0, actors/lakitu_enemy/lakitu_enemy_shell.rgba16.png +0x5d617ea0, actors/lakitu_cameraman/lakitu_cameraman_shell.rgba16.png +0x5d5bb4d6, textures/sky/rr_textures.00800.rgba16.png +0x5d58d20c, textures/skybox_tiles/cloud_floor.2.rgba16.png +0x5d3df26f, textures/fire/lll_textures.06000.rgba16.png +0x5cfeb1db, textures/mountain/ttm_textures.08800.rgba16.png +0x5cc5caf7, textures/skybox_tiles/ccm.4.rgba16.png +0x5cc4bed3, actors/mr_i_iris/mr_i_iris_mostly_open.rgba16.png +0x5c403031, textures/water/jrb_textures.01800.rgba16.png +0x5c3873c6, textures/grass/wf_textures.03000.rgba16.png +0x5c293288, textures/skybox_tiles/ccm.5.rgba16.png +0x5c153daf, textures/skybox_tiles/bits.34.rgba16.png +0x5bc5ca75, actors/piranha_plant/piranha_plant_leaf.rgba16.png +0x5b8676cf, actors/white_particle/snow_particle.rgba16.png +0x5af9dfde, levels/ssl/2.rgba16.png +0x5aea7079, actors/piranha_plant/piranha_plant_bottom_lip.rgba16.png +0x5ac90b8d, levels/cotmc/4.rgba16.png +0x5a967a74, levels/menu/main_menu_seg7_us.0B280.ia8.png +0x5a838c70, textures/skybox_tiles/clouds.30.rgba16.png +0x5a807466, levels/menu/main_menu_seg7_us.0AEC0.ia8.png +0x5a2fa13a, textures/skybox_tiles/water.31.rgba16.png +0x5a1a4fbf, textures/skybox_tiles/wdw.52.rgba16.png +0x59d072f0, textures/inside/inside_castle_textures.0B800.rgba16.png +0x59c798d4, textures/skybox_tiles/cake.31.rgba16.png +0x59c3cdd9, levels/bitdw/1.rgba16.png +0x59bbf047, actors/unagi/unagi_head_base.rgba16.png +0x599da7cb, textures/skybox_tiles/water.27.rgba16.png +0x5996660e, levels/lll/7.rgba16.png +0x5996660e, textures/fire/lll_textures.01800.rgba16.png +0x58f28a81, textures/skybox_tiles/ccm.20.rgba16.png +0x58c547bd, textures/skybox_tiles/bidw.19.rgba16.png +0x58a11d1e, textures/skybox_tiles/bits.37.rgba16.png +0x585285d7, actors/bobomb/bob-omb_buddy_left_side.rgba16.png +0x585285d7, actors/king_bobomb/bob-omb_buddy_left_side_unused.rgba16.png +0x580e00a9, textures/segment2/segment2.05A00.rgba16.png +0x57f55b58, actors/sparkle/sparkle_2.rgba16.png +0x57dd4de0, textures/skybox_tiles/cloud_floor.34.rgba16.png +0x57c29c7d, textures/machine/ttc_textures.02800.rgba16.png +0x57a58c22, textures/title_screen_bg/title_screen_bg.02740.rgba16.png +0x579d6c8a, textures/skybox_tiles/cloud_floor.62.rgba16.png +0x579c53ed, textures/water/jrb_textures.05800.rgba16.png +0x579b80b3, textures/skybox_tiles/cloud_floor.10.rgba16.png +0x578aa0e9, actors/penguin/penguin_eye_half_closed.rgba16.png +0x5730faaa, textures/skybox_tiles/water.35.rgba16.png +0x56da6b66, textures/snow/ccm_textures.04000.rgba16.png +0x5691c606, textures/skybox_tiles/bbh.17.rgba16.png +0x56886274, levels/menu/main_menu_seg7_us.0B2C0.ia8.png +0x5663d126, textures/skybox_tiles/cake.17.rgba16.png +0x56450e91, textures/skybox_tiles/wdw.55.rgba16.png +0x5643908b, textures/skybox_tiles/water.25.rgba16.png +0x563280bd, textures/title_screen_bg/title_screen_bg.05940.rgba16.png +0x55eb7a33, textures/skybox_tiles/ssl.33.rgba16.png +0x55e07c1c, textures/effect/lava_bubble.04820.rgba16.png +0x55da5d92, actors/scuttlebug/scuttlebug_right_side.rgba16.png +0x55620576, actors/bowser/bowser_chest.rgba16.png +0x5535f203, actors/pebble/pebble.rgba16.png +0x54fac607, actors/white_particle_small/small_snow_particle.rgba16.png +0x54f2c81a, levels/castle_inside/1.rgba16.png +0x54ca6ddc, textures/skybox_tiles/cloud_floor.40.rgba16.png +0x54670bb6, levels/bitdw/0.rgba16.png +0x540f30ff, textures/skybox_tiles/clouds.27.rgba16.png +0x53cbf3e0, textures/skybox_tiles/water.33.rgba16.png +0x53c1213e, actors/water_ring/water_ring.rgba16.png +0x537d0a34, textures/skybox_tiles/cake.37.rgba16.png +0x53405a73, textures/grass/wf_textures.04000.rgba16.png +0x531bebd4, textures/intro_raw/red_star_4.rgba16.png +0x530a2cf4, textures/title_screen_bg/title_screen_bg.001C0.rgba16.png +0x52fedeb7, actors/wiggler/wiggler_frown.rgba16.png +0x52f9e748, textures/machine/ttc_textures.03800.rgba16.png +0x52d5a8b9, textures/skybox_tiles/ssl.1.rgba16.png +0x52bc0e5e, textures/fire/lll_textures.05800.rgba16.png +0x52a84252, textures/segment2/segment2.03600.rgba16.png +0x527e926c, levels/menu/main_menu_seg7_us.0AD40.ia8.png +0x52749e6e, textures/skybox_tiles/ssl.18.rgba16.png +0x51d4da7f, levels/wmotr/2.rgba16.png +0x51d0a5d0, textures/skybox_tiles/ccm.7.rgba16.png +0x51b5cd93, textures/skybox_tiles/bbh.20.rgba16.png +0x51762e4c, levels/ttm/1.rgba16.png +0x514a29bc, actors/bowser/bowser_upper_face.rgba16.png +0x513bd6b7, actors/seaweed/seaweed_tip.rgba16.png +0x50964858, textures/sky/rr_textures.04800.rgba16.png +0x5095921b, textures/segment2/segment2.12458.rgba16.png +0x508e888f, levels/lll/9.rgba16.png +0x506d1a26, actors/yoshi/yoshi_eye.rgba16.png +0x5050548f, textures/skybox_tiles/bidw.22.rgba16.png +0x4fe1a0ed, actors/peach/peach_lips.rgba16.png +0x4f503c6e, textures/skybox_tiles/bits.24.rgba16.png +0x4f3ece62, textures/skybox_tiles/wdw.38.rgba16.png +0x4f265622, textures/grass/wf_textures.0A000.rgba16.png +0x4f1cac41, textures/skybox_tiles/bitfs.21.rgba16.png +0x4eeefe7d, textures/inside/inside_castle_textures.08000.rgba16.png +0x4ee951e9, textures/segment2/segment2.06C80.rgba16.png +0x4ee94f84, textures/intro_raw/sparkle_3.rgba16.png +0x4ed23be0, levels/hmc/6.rgba16.png +0x4ed18843, textures/skybox_tiles/bbh.13.rgba16.png +0x4eb8714c, actors/door/rough_wooden_door_overlay.rgba16.png +0x4e80fa6f, textures/skybox_tiles/bidw.15.rgba16.png +0x4e6eca8d, textures/cave/hmc_textures.0A000.rgba16.png +0x4e4571c1, textures/segment2/segment2.00800.rgba16.png +0x4e43931b, actors/wiggler/wiggler_nose_left_side.rgba16.png +0x4e0a3338, levels/lll/16.rgba16.png +0x4dedbc41, actors/whomp/whomp_hand.rgba16.png +0x4dc0bbdf, actors/power_meter/power_meter_seven_segments.rgba16.png +0x4d606a9b, textures/skybox_tiles/water.45.rgba16.png +0x4d03386e, textures/generic/bob_textures.03000.rgba16.png +0x4ceef375, textures/skybox_tiles/bits.15.rgba16.png +0x4cdb236c, textures/skybox_tiles/bidw.36.rgba16.png +0x4c947c72, levels/menu/main_menu_seg7_us.0B300.ia8.png +0x4c6ede9f, actors/flame/flame_6.ia16.png +0x4c26a305, textures/machine/ttc_textures.06000.rgba16.png +0x4c001ad4, textures/mountain/ttm_textures.00000.rgba16.png +0x4bcae8d6, textures/skybox_tiles/water.22.rgba16.png +0x4b0c0c56, actors/water_wave/water_wave_1.ia16.png +0x4b070bc3, textures/generic/bob_textures.03800.rgba16.png +0x4a750285, levels/lll/14.rgba16.png +0x4a5830ad, textures/effect/bubble.06048.rgba16.png +0x4a4683bc, textures/spooky/bbh_textures.04800.rgba16.png +0x4a0af053, textures/segment2/segment2.13458.ia16.png +0x4a043c67, textures/skybox_tiles/clouds.32.rgba16.png +0x49f74eb1, actors/ukiki/ukiki_face.rgba16.png +0x49d68918, textures/skybox_tiles/bitfs.3.rgba16.png +0x49a828db, textures/skybox_tiles/cloud_floor.12.rgba16.png +0x49a3631e, textures/grass/wf_textures.08000.rgba16.png +0x49997119, levels/jrb/3.rgba16.png +0x4944d2c9, actors/mips/mips_eyes.rgba16.png +0x49313621, actors/haunted_cage/bbh_cage_wooden_base.rgba16.png +0x48e57582, textures/skybox_tiles/bidw.13.rgba16.png +0x48bc2fc8, textures/skybox_tiles/water.57.rgba16.png +0x48b717ee, textures/machine/ttc_textures.07800.rgba16.png +0x48a5f126, textures/skybox_tiles/cloud_floor.3.rgba16.png +0x48a3e423, textures/segment2/segment2.06F00.rgba16.png +0x486f9bd1, textures/skybox_tiles/bits.27.rgba16.png +0x4844ccb0, actors/water_splash/water_splash_6.rgba16.png +0x4783c2bf, textures/skybox_tiles/bitfs.19.rgba16.png +0x474f8a1b, levels/menu/main_menu_seg7.00018.rgba16.png +0x46ee72e8, textures/skybox_tiles/ccm.21.rgba16.png +0x46beff45, textures/skybox_tiles/bbh.21.rgba16.png +0x46a556f1, levels/lll/12.rgba16.png +0x468bc569, textures/segment2/segment2.01C00.rgba16.png +0x4676f47d, levels/rr/2.rgba16.png +0x465f9b72, textures/skybox_tiles/wdw.49.rgba16.png +0x45f63ae1, textures/skybox_tiles/water.60.rgba16.png +0x458c0935, actors/snufit/snufit_body.rgba16.png +0x45667aed, textures/skybox_tiles/clouds.40.rgba16.png +0x452aad60, textures/skybox_tiles/bits.47.rgba16.png +0x44d5aa4b, textures/skybox_tiles/bits.43.rgba16.png +0x44ae3d51, textures/intro_raw/sparkle_0.rgba16.png +0x44789e8c, levels/menu/main_menu_seg7_us.0ACC0.ia8.png +0x444b37f6, actors/water_splash/water_splash_1.rgba16.png +0x4446f65d, actors/stomp_smoke/stomp_smoke_3.ia16.png +0x4443d529, actors/haunted_cage/bbh_cage_double_ornament.rgba16.png +0x438cc5be, textures/segment2/segment2.07D50.rgba16.png +0x432d56be, actors/mario_cap/mario_cap_metal.rgba16.png +0x432d56be, actors/mario/mario_metal.rgba16.png +0x431e1944, levels/menu/main_menu_seg7.03C68.rgba16.png +0x42f2325a, textures/skybox_tiles/bits.13.rgba16.png +0x42a20f7e, actors/explosion/explosion_5.rgba16.png +0x428d4124, actors/exclamation_box/exclamation_box_side.rgba16.png +0x428bef9c, textures/water/jrb_textures.00800.rgba16.png +0x4276db5e, levels/ccm/7.rgba16.png +0x41d56401, textures/skybox_tiles/bits.22.rgba16.png +0x4166f73d, textures/outside/castle_grounds_textures.02000.rgba16.png +0x41590b79, textures/skybox_tiles/wdw.23.rgba16.png +0x414026b4, textures/segment2/segment2.01400.rgba16.png +0x41304acc, levels/ttc/1.rgba16.png +0x40fa0dca, textures/cave/hmc_textures.05800.rgba16.png +0x40e6bbfb, textures/skybox_tiles/clouds.10.rgba16.png +0x40ad9dab, textures/skybox_tiles/cloud_floor.45.rgba16.png +0x40aa862f, textures/skybox_tiles/cake.6.rgba16.png +0x4089d798, textures/skybox_tiles/water.17.rgba16.png +0x408779a6, textures/skybox_tiles/cloud_floor.26.rgba16.png +0x40568542, textures/fire/lll_textures.0A000.rgba16.png +0x403c6122, levels/pss/0.rgba16.png +0x40226c48, textures/skybox_tiles/ccm.63.rgba16.png +0x401b923f, actors/door/bbh_door.rgba16.png +0x4010bae8, levels/jrb/2.rgba16.png +0x3ffa0be7, textures/skybox_tiles/ccm.59.rgba16.png +0x3ff93da3, levels/ccm/11.rgba16.png +0x3fb69c59, actors/tree/snowy_pine_tree.rgba16.png +0x3f817c21, textures/fire/lll_textures.09000.rgba16.png +0x3f817c21, textures/segment2/segment2.13C58.rgba16.png +0x3ec818de, textures/skybox_tiles/wdw.11.rgba16.png +0x3e5af02c, actors/bookend/bookend_pages.rgba16.png +0x3e40e693, textures/cave/hmc_textures.08800.rgba16.png +0x3de0ed4e, textures/segment2/segment2.06400.rgba16.png +0x3d51e423, levels/intro/3_tm.rgba16.png +0x3d354167, textures/skybox_tiles/water.42.rgba16.png +0x3d244f64, textures/skybox_tiles/water.55.rgba16.png +0x3d21394e, textures/skybox_tiles/water.39.rgba16.png +0x3cfba273, textures/skybox_tiles/wdw.62.rgba16.png +0x3ce9e494, textures/segment2/segment2.06900.rgba16.png +0x3ccf8886, textures/skybox_tiles/bidw.27.rgba16.png +0x3cc93124, textures/skybox_tiles/ccm.6.rgba16.png +0x3cb6f1a9, actors/walk_smoke/walk_smoke_3.ia16.png +0x3c183177, textures/skybox_tiles/ssl.54.rgba16.png +0x3bac2b9a, levels/ccm/8.ia16.png +0x3bac2b9a, levels/lll/27.ia16.png +0x3ba40ee9, levels/intro/0.rgba16.png +0x3b111d77, actors/heave_ho/heave-ho_turnkey.rgba16.png +0x3b0d1e46, actors/koopa/koopa_shoe.rgba16.png +0x3ae6bec9, textures/skybox_tiles/water.47.rgba16.png +0x3ac6c19c, actors/purple_switch/purple_switch_exclamation_point.rgba16.png +0x3aadb102, textures/skybox_tiles/water.16.rgba16.png +0x3a9a3561, levels/lll/10.rgba16.png +0x39f5a629, actors/toad/toad_face.rgba16.png +0x39e90b67, textures/segment2/segment2.06700.rgba16.png +0x39e470dd, levels/ttc/0.rgba16.png +0x39d86d67, actors/thwomp/thwomp_surface.rgba16.png +0x39cc9592, actors/bowser/bowser_eye_closed_0.rgba16.png +0x39cc9592, actors/bowser/bowser_eye_closed_1.rgba16.png +0x39c55c7f, textures/skybox_tiles/ccm.26.rgba16.png +0x39a50598, textures/skybox_tiles/cake.14.rgba16.png +0x397f1da4, textures/skybox_tiles/wdw.19.rgba16.png +0x393ba6ae, textures/skybox_tiles/ssl.34.rgba16.png +0x3909f67d, textures/snow/ccm_textures.01000.rgba16.png +0x3902d1b8, actors/monty_mole/monty_mole_eye.rgba16.png +0x38ec1b66, textures/skybox_tiles/ssl.29.rgba16.png +0x38afcd8f, textures/segment2/segment2.06580.rgba16.png +0x38afccee, levels/ssl/6.rgba16.png +0x38894888, actors/bobomb/bob-omb_right_side.rgba16.png +0x387d6d33, actors/mario_cap/mario_cap_wing_tip.rgba16.png +0x387d6d33, actors/mario/mario_wing_tip.rgba16.png +0x386a9785, actors/bowser/bowser_shell.rgba16.png +0x3867cbee, actors/wiggler/wiggler_segment_left_side.rgba16.png +0x385055f4, textures/skybox_tiles/wdw.37.rgba16.png +0x384e2a31, actors/goomba/goomba_face_blink.rgba16.png +0x383bbd9b, actors/toad/toad_head.rgba16.png +0x381ea750, levels/bbh/3.rgba16.png +0x37f10a8c, actors/bookend/bookend_tooth.rgba16.png +0x374e253a, actors/bowser/bowser_armband_spike.rgba16.png +0x373df028, actors/piranha_plant/piranha_plant_skin.rgba16.png +0x370fc06b, textures/outside/castle_grounds_textures.0A000.rgba16.png +0x36fc4c04, levels/lll/24.rgba16.png +0x36f00556, textures/cave/hmc_textures.0A800.rgba16.png +0x36d9c81e, actors/bully/bully_right_side.rgba16.png +0x36b1482f, actors/pokey/pokey_face_blink.rgba16.png +0x362e3e52, textures/segment2/segment2.05C00.rgba16.png +0x35bbd200, actors/bullet_bill/bullet_bill_eye.rgba16.png +0x3556a0c8, textures/skybox_tiles/bbh.4.rgba16.png +0x35456b51, actors/bobomb/bob-omb_eyes_blink.rgba16.png +0x354089bb, actors/dorrie/dorrie_tongue.rgba16.png +0x354089bb, actors/chain_chomp/chain_chomp_tongue.rgba16.png +0x34e02944, textures/skybox_tiles/bits.46.rgba16.png +0x349b3bbd, actors/scuttlebug/scuttlebug_left_side.rgba16.png +0x3486bf66, actors/checkerboard_platform/checkerboard_platform_side.rgba16.png +0x3411743e, actors/wiggler/wiggler_segment_right_side.rgba16.png +0x33ea5d90, actors/chuckya/chuckya_body_arm_right_side.rgba16.png +0x33c58d86, textures/cave/hmc_textures.03800.rgba16.png +0x33b314af, levels/wmotr/1.rgba16.png +0x33ae70aa, levels/castle_inside/40.rgba16.png +0x339b3765, textures/skybox_tiles/bbh.31.rgba16.png +0x336d534a, textures/segment2/segment2.00E00.rgba16.png +0x3342ae2e, textures/skybox_tiles/bitfs.18.rgba16.png +0x32da5c54, textures/skybox_tiles/cloud_floor.48.rgba16.png +0x32beb053, textures/skybox_tiles/ssl.6.rgba16.png +0x32b61b3e, textures/skybox_tiles/ccm.53.rgba16.png +0x325a3830, levels/ssl/8.rgba16.png +0x32169e73, levels/rr/1.rgba16.png +0x31c66e6f, actors/ukiki/ukiki_butt.rgba16.png +0x31b77240, actors/poundable_pole/poundable_pole_top.rgba16.png +0x31764a00, actors/amp/amp_eyes.rgba16.png +0x3163aa92, levels/totwc/2.rgba16.png +0x3157cd18, textures/spooky/bbh_textures.05000.rgba16.png +0x308c95f5, textures/skybox_tiles/bits.20.rgba16.png +0x304306e0, textures/cave/hmc_textures.00000.rgba16.png +0x2fc064c1, textures/skybox_tiles/bidw.32.rgba16.png +0x2fa4b137, textures/skybox_tiles/bitfs.27.rgba16.png +0x2f5f1297, actors/door/metal_door.rgba16.png +0x2f3fdba3, textures/skybox_tiles/clouds.21.rgba16.png +0x2f25120f, actors/pokey/pokey_body.rgba16.png +0x2ed4ba24, actors/bobomb/bob-omb_eyes.rgba16.png +0x2ece83fa, textures/skybox_tiles/bits.8.rgba16.png +0x2eb2480c, textures/spooky/bbh_textures.0B800.ia16.png +0x2eb2480c, levels/castle_inside/2.ia16.png +0x2e5dd16d, textures/skybox_tiles/water.7.rgba16.png +0x2e1eb8aa, levels/ssl/5.rgba16.png +0x2e0c1e02, actors/bowser/bowser_eye_half_closed_1.rgba16.png +0x2e0c1e02, actors/bowser/bowser_eye_half_closed_0.rgba16.png +0x2dec812e, actors/bub/bub_scales.rgba16.png +0x2ddb1ab2, textures/skybox_tiles/cloud_floor.61.rgba16.png +0x2dc59b5c, levels/castle_inside/3.rgba16.png +0x2d898713, textures/segment2/segment2.06480.rgba16.png +0x2d6492f4, textures/skybox_tiles/ssl.12.rgba16.png +0x2d31f48b, textures/skybox_tiles/cloud_floor.9.rgba16.png +0x2d0c2e11, textures/segment2/segment2.0FC58.ia8.png +0x2ce5532e, textures/skybox_tiles/bits.63.rgba16.png +0x2cdb87de, levels/wmotr/0.rgba16.png +0x2c44217c, textures/skybox_tiles/bits.57.rgba16.png +0x2c246943, textures/skybox_tiles/bits.59.rgba16.png +0x2bea0a29, actors/mario/mario_sideburn.rgba16.png +0x2bc420f5, textures/grass/wf_textures.06800.rgba16.png +0x2b851f69, textures/segment2/segment2.02C00.rgba16.png +0x2b846815, actors/power_meter/power_meter_six_segments.rgba16.png +0x2b8359bb, textures/skybox_tiles/wdw.0.rgba16.png +0x2b644522, textures/water/jrb_textures.03800.rgba16.png +0x2b3f9b9c, textures/skybox_tiles/bits.33.rgba16.png +0x2b08f032, levels/totwc/1.rgba16.png +0x2aab5196, actors/door/zero_star_door_sign.rgba16.png +0x2a9f12c7, textures/skybox_tiles/bits.14.rgba16.png +0x2a93afc0, actors/mr_i_iris/mr_i_iris_open.rgba16.png +0x2a83d55a, levels/lll/0.rgba16.png +0x2a359204, textures/segment2/segment2.01000.rgba16.png +0x2a283a6a, actors/sparkle_animation/sparkle_animation_2.ia16.png +0x29f15a68, actors/piranha_plant/piranha_plant_stem.rgba16.png +0x29c0c7d2, actors/koopa/koopa_eyes_closed.rgba16.png +0x29904548, textures/skybox_tiles/water.63.rgba16.png +0x292e5fd8, actors/king_bobomb/bob-omb_buddy_right_side_unused.rgba16.png +0x292e5fd8, actors/bobomb/bob-omb_buddy_right_side.rgba16.png +0x292c40a1, textures/skybox_tiles/cake.13.rgba16.png +0x28df6c96, actors/flame/flame_1.ia16.png +0x28a7f52b, textures/segment2/segment2.01200.rgba16.png +0x28964b59, actors/mario/mario_eyes_dead.rgba16.png +0x2811c57f, textures/segment2/segment2.06880.rgba16.png +0x28061018, levels/ttm/5.rgba16.png +0x27ece31d, textures/outside/castle_grounds_textures.04000.rgba16.png +0x27b29129, textures/mountain/ttm_textures.00800.rgba16.png +0x27b1aa10, textures/skybox_tiles/bitfs.1.rgba16.png +0x276489c6, textures/segment2/segment2.06800.rgba16.png +0x27183c4f, levels/castle_inside/30.rgba16.png +0x26dfc97d, actors/butterfly/butterfly_wing.rgba16.png +0x26a34f80, textures/skybox_tiles/ccm.48.rgba16.png +0x268b611d, actors/power_meter/power_meter_three_segments.rgba16.png +0x2677a2a0, textures/skybox_tiles/cake.33.rgba16.png +0x266a1564, levels/ccm/2.rgba16.png +0x25ee1ba5, actors/blue_coin_switch/blue_coin_switch_side.rgba16.png +0x258a8627, textures/skybox_tiles/water.46.rgba16.png +0x2563bf4c, actors/cyan_fish/cyan_fish.rgba16.png +0x252a4b98, textures/snow/ccm_textures.09800.ia16.png +0x24ec3198, textures/skybox_tiles/ccm.35.rgba16.png +0x24e61683, textures/segment2/segment2.06200.rgba16.png +0x24d27245, textures/skybox_tiles/water.0.rgba16.png +0x24ad7055, textures/skybox_tiles/bits.26.rgba16.png +0x24a049bd, textures/skybox_tiles/cloud_floor.31.rgba16.png +0x2499ce37, textures/skybox_tiles/water.50.rgba16.png +0x24767d89, levels/bbh/1.rgba16.png +0x2465b806, actors/sparkle_animation/sparkle_animation_0.ia16.png +0x245ea00f, levels/bob/2.rgba16.png +0x2447b7f9, textures/segment2/segment2.06680.rgba16.png +0x23f84d6a, actors/exclamation_box/exclamation_box_front.rgba16.png +0x239f9e44, levels/castle_inside/38.rgba16.png +0x2395da7b, actors/snowman/mr_blizzard_left_side.rgba16.png +0x22f743bf, textures/outside/castle_grounds_textures.06800.rgba16.png +0x2282c30a, textures/skybox_tiles/cake.45.rgba16.png +0x22628916, textures/skybox_tiles/ccm.10.rgba16.png +0x22348f8b, textures/skybox_tiles/bitfs.7.rgba16.png +0x222768fa, levels/bbh/2.rgba16.png +0x221c9f08, textures/skybox_tiles/ccm.62.rgba16.png +0x21f3a705, actors/monty_mole/monty_mole_cheek.rgba16.png +0x21dd7803, textures/skybox_tiles/water.58.rgba16.png +0x21bfea1a, actors/chair/chair_leg.rgba16.png +0x21a99bef, textures/skybox_tiles/cake.39.rgba16.png +0x2193cd76, textures/skybox_tiles/ssl.60.rgba16.png +0x21854115, textures/skybox_tiles/bits.30.rgba16.png +0x216a674d, textures/skybox_tiles/bidw.54.rgba16.png +0x21676bdd, textures/skybox_tiles/clouds.1.rgba16.png +0x215ce254, textures/generic/bob_textures.09000.rgba16.png +0x214f09c8, textures/skybox_tiles/clouds.14.rgba16.png +0x213ebd50, textures/skybox_tiles/ssl.15.rgba16.png +0x212a4546, textures/skybox_tiles/cloud_floor.54.rgba16.png +0x21247806, actors/bully/bully_eye.rgba16.png +0x21247806, actors/chillychief/chill_bully_eye.rgba16.png +0x211edf33, textures/skybox_tiles/bitfs.48.rgba16.png +0x211edf33, textures/skybox_tiles/bbh.40.rgba16.png +0x20e1ea4d, actors/seaweed/seaweed_lower_center.rgba16.png +0x208f2137, textures/skybox_tiles/water.19.rgba16.png +0x20725250, actors/flyguy/flyguy_propeller.ia16.png +0x204d81e4, levels/bowser_3/2.rgba16.png +0x202d35be, textures/segment2/segment2.01A00.rgba16.png +0x20167de7, levels/totwc/0.rgba16.png +0x1fc70576, levels/sl/4.rgba16.png +0x1f71da85, actors/capswitch/cap_switch_base.rgba16.png +0x1f6da0f2, levels/ssl/1.ia16.png +0x1f5b1636, textures/machine/ttc_textures.01000.rgba16.png +0x1f4cdab4, actors/snufit/snufit_mask_strap.rgba16.png +0x1f3b7abc, textures/mountain/ttm_textures.05000.rgba16.png +0x1f31633f, textures/intro_raw/red_star_0.rgba16.png +0x1f04daf4, actors/exclamation_box_outline/exclamation_box_outline.rgba16.png +0x1effd4e0, textures/grass/wf_textures.07800.rgba16.png +0x1eed9296, textures/skybox_tiles/water.36.rgba16.png +0x1ecb06af, levels/lll/6.rgba16.png +0x1ebae88a, levels/castle_inside/6.rgba16.png +0x1e940db1, textures/skybox_tiles/water.12.rgba16.png +0x1e834eb0, actors/explosion/explosion_0.rgba16.png +0x1e520811, textures/inside/inside_castle_textures.01000.rgba16.png +0x1cb6e388, levels/ssl/11.rgba16.png +0x1cb6dc98, textures/segment2/segment2.06600.rgba16.png +0x1ca18f8f, textures/skybox_tiles/water.61.rgba16.png +0x1c786ee9, levels/castle_inside/12.rgba16.png +0x1c62cc15, actors/haunted_cage/bbh_cage_bars.rgba16.png +0x1c3b41cf, levels/ttc/2.rgba16.png +0x1b6acd5e, actors/treasure_chest/treasure_chest_front.rgba16.png +0x1b1fa1c6, textures/skybox_tiles/wdw.30.rgba16.png +0x1ae70860, actors/flame/flame_7.ia16.png +0x1adecd70, textures/skybox_tiles/ssl.62.rgba16.png +0x1a808da7, textures/water/jrb_textures.06800.rgba16.png +0x1a6f8a0e, textures/skybox_tiles/cake.34.rgba16.png +0x1a66c67f, textures/skybox_tiles/water.43.rgba16.png +0x1a4bcc77, levels/castle_inside/24_us.rgba16.png +0x1a43df6a, actors/walk_smoke/walk_smoke_5.ia16.png +0x19e8f076, levels/pss/1.ia16.png +0x19d0a651, textures/skybox_tiles/wdw.36.rgba16.png +0x19cf329b, textures/skybox_tiles/ssl.57.rgba16.png +0x19bb64c1, textures/machine/ttc_textures.03000.rgba16.png +0x19442fc9, actors/mario/mario_overalls_button.rgba16.png +0x192fa726, actors/tree/tree_left_side.rgba16.png +0x19132bcc, textures/skybox_tiles/water.6.rgba16.png +0x18a7104c, textures/skybox_tiles/bits.19.rgba16.png +0x188b6465, textures/intro_raw/white_star_6.rgba16.png +0x1872fa6c, actors/explosion/explosion_2.rgba16.png +0x184368ca, levels/castle_inside/29.rgba16.png +0x184368ca, levels/hmc/7.rgba16.png +0x18102121, textures/skybox_tiles/bidw.52.rgba16.png +0x180bde92, actors/penguin/penguin_eye_closed.rgba16.png +0x17f35f3c, textures/skybox_tiles/bits.32.rgba16.png +0x17eb8cf3, textures/title_screen_bg/title_screen_bg.00E40.rgba16.png +0x17ea3392, textures/snow/ccm_textures.09000.ia16.png +0x17cde57d, actors/thwomp/thwomp_face.rgba16.png +0x17c50cf2, actors/mario_cap/mario_cap_wing.rgba16.png +0x17c50cf2, actors/mario/mario_wing.rgba16.png +0x177d197c, levels/bitdw/3.rgba16.png +0x176c2e93, actors/coin/coin_tilt_left.ia16.png +0x17405808, levels/bbh/5.rgba16.png +0x17060726, actors/yoshi/yoshi_nostril.rgba16.png +0x16db7146, textures/skybox_tiles/cake.38.rgba16.png +0x16ce5dc5, textures/intro_raw/mario_face_shine.ia8.png +0x167cac52, levels/ttm/7.rgba16.png +0x16733b9a, textures/skybox_tiles/wdw.17.rgba16.png +0x166dd880, actors/explosion/explosion_6.rgba16.png +0x1660c971, levels/ttm/0.ia16.png +0x165f940a, textures/skybox_tiles/bbh.6.rgba16.png +0x164fbe11, levels/ddd/2.rgba16.png +0x163f6e7c, textures/skybox_tiles/cake.28.rgba16.png +0x15d30589, textures/spooky/bbh_textures.02800.rgba16.png +0x15b65397, textures/skybox_tiles/ssl.23.rgba16.png +0x158aa64c, textures/skybox_tiles/wdw.18.rgba16.png +0x15686bed, levels/ccm/1.rgba16.png +0x1541a06e, levels/lll/30.rgba16.png +0x1501ad26, actors/chuckya/chuckya_body_arm_left_side.rgba16.png +0x14c95ba0, actors/water_bubble/water_bubble.rgba16.png +0x146f813f, levels/castle_grounds/0.rgba16.png +0x1465e49f, textures/skybox_tiles/water.24.rgba16.png +0x1450f56e, textures/skybox_tiles/bits.21.rgba16.png +0x144c8cf3, levels/lll/29.rgba16.png +0x1448c073, textures/generic/bob_textures.01800.rgba16.png +0x1411177b, textures/skybox_tiles/ssl.24.rgba16.png +0x13e4332a, textures/mountain/ttm_textures.04000.rgba16.png +0x13c541ea, levels/wf/0.rgba16.png +0x134a35b3, textures/segment2/segment2.03800.rgba16.png +0x13207bbb, actors/spindrift/spindrift_face.rgba16.png +0x13132153, levels/bitdw/2.rgba16.png +0x130ca9a8, textures/snow/ccm_textures.08000.rgba16.png +0x12c0f052, textures/skybox_tiles/wdw.8.rgba16.png +0x12733b4f, actors/door/rough_wooden_door.rgba16.png +0x125e068d, actors/wooden_signpost/wooden_signpost_front.rgba16.png +0x1203baa7, actors/manta/manta_eye.rgba16.png +0x11f1b791, textures/skybox_tiles/ssl.20.rgba16.png +0x11a852cb, textures/skybox_tiles/ccm.36.rgba16.png +0x1198c8ab, actors/chair/chair_front.rgba16.png +0x11543850, textures/skybox_tiles/bits.62.rgba16.png +0x112c8257, textures/skybox_tiles/water.44.rgba16.png +0x10f30b26, actors/power_meter/power_meter_four_segments.rgba16.png +0x10e998f8, actors/star/star_eye.rgba16.png +0x10e998f8, actors/wiggler/wiggler_eye.rgba16.png +0x10e452c9, textures/fire/lll_textures.01000.rgba16.png +0x10c87d57, textures/skybox_tiles/cake.23.rgba16.png +0x1096c02e, textures/skybox_tiles/water.56.rgba16.png +0x108d6cae, textures/skybox_tiles/cake.43.rgba16.png +0x10675a01, textures/fire/lll_textures.0B800.rgba16.png +0x1056b1f2, levels/menu/main_menu_seg7.06B28.rgba16.png +0x101ca508, textures/skybox_tiles/ssl.49.rgba16.png +0x0ff0d650, textures/skybox_tiles/wdw.10.rgba16.png +0x0fdd80ca, levels/castle_grounds/1.rgba16.png +0x0f8eba38, actors/spindrift/spindrift_petal.rgba16.png +0x0f5d756e, actors/water_splash/water_splash_7.rgba16.png +0x0f1c2159, textures/skybox_tiles/cloud_floor.47.rgba16.png +0x0ee19c09, textures/skybox_tiles/bidw.25.rgba16.png +0x0e9c4e15, actors/wiggler/wiggler_flower.rgba16.png +0x0e7107e3, actors/klepto/klepto_beak.rgba16.png +0x0e40fa10, actors/heave_ho/heave-ho_roller.rgba16.png +0x0e1e7eb2, textures/skybox_tiles/wdw.56.rgba16.png +0x0df6bdff, actors/door/one_star_door_sign.rgba16.png +0x0ddc6f87, textures/skybox_tiles/water.29.rgba16.png +0x0ddbbc70, levels/bob/1.rgba16.png +0x0d9fd7e4, actors/koopa/koopa_nostrils.rgba16.png +0x0d6a8490, textures/skybox_tiles/bbh.29.rgba16.png +0x0d487556, textures/inside/inside_castle_textures.0A000.rgba16.png +0x0d344fc8, textures/skybox_tiles/clouds.28.rgba16.png +0x0d09f13e, levels/castle_grounds/2.rgba16.png +0x0c89d16b, textures/outside/castle_grounds_textures.00800.rgba16.png +0x0be35913, textures/skybox_tiles/wdw.4.rgba16.png +0x0ba8d96e, textures/skybox_tiles/ccm.17.rgba16.png +0x0b962372, levels/lll/2.rgba16.png +0x0b6d2926, actors/explosion/explosion_3.rgba16.png +0x0ad7a8f7, textures/spooky/bbh_textures.08800.rgba16.png +0x0ab43f69, actors/yoshi/yoshi_eye_blink.rgba16.png +0x0a45ef5b, textures/skybox_tiles/wdw.48.rgba16.png +0x0a18adca, textures/skybox_tiles/bits.28.rgba16.png +0x0a10018c, textures/skybox_tiles/clouds.3.rgba16.png +0x09cabb08, actors/bully/bully_left_side.rgba16.png +0x0993e63e, actors/lakitu_cameraman/lakitu_camera_lens.rgba16.png +0x09820848, textures/outside/castle_grounds_textures.09000.rgba16.png +0x09740389, actors/mad_piano/mad_piano_tooth.rgba16.png +0x09740389, actors/chain_chomp/chain_chomp_tooth.rgba16.png +0x094b9235, levels/vcutm/2.rgba16.png +0x09208466, textures/generic/bob_textures.04000.rgba16.png +0x08c865bc, textures/segment2/segment2.03000.rgba16.png +0x08b8530e, levels/castle_inside/23_us.rgba16.png +0x087f8f7b, textures/intro_raw/white_star_3.rgba16.png +0x08758cde, textures/mountain/ttm_textures.03800.rgba16.png +0x086772e7, textures/skybox_tiles/cake.30.rgba16.png +0x082cd478, textures/skybox_tiles/ssl.37.rgba16.png +0x08170b98, textures/skybox_tiles/water.59.rgba16.png +0x07ff7cd2, textures/skybox_tiles/bitfs.29.rgba16.png +0x07cf15a6, textures/mountain/ttm_textures.02800.rgba16.png +0x07c7c401, textures/skybox_tiles/cake.20.rgba16.png +0x076b5c8f, actors/power_meter/power_meter_one_segment.rgba16.png +0x074933da, textures/skybox_tiles/ssl.45.rgba16.png +0x0731beea, textures/skybox_tiles/wdw.44.rgba16.png +0x07155d85, textures/skybox_tiles/bitfs.35.rgba16.png +0x070e836f, actors/boo_castle/bbh_boo_mouth.rgba16.png +0x070e836f, actors/boo/boo_mouth.rgba16.png +0x07059f23, textures/skybox_tiles/wdw.51.rgba16.png +0x0702fde6, textures/inside/inside_castle_textures.0B000.rgba16.png +0x06ab9733, textures/skybox_tiles/ssl.21.rgba16.png +0x06682e2e, levels/hmc/3.rgba16.png +0x0659ab56, textures/segment2/segment2.00C00.rgba16.png +0x064f172d, actors/sparkle_animation/sparkle_animation_4.ia16.png +0x064b5c5f, levels/castle_grounds/3.rgba16.png +0x06343afc, actors/monty_mole/monty_mole_claw.rgba16.png +0x061a6c74, textures/generic/bob_textures.06000.rgba16.png +0x0612269d, actors/cannon_base/cannon_base.rgba16.png +0x05ec9e16, textures/skybox_tiles/cloud_floor.21.rgba16.png +0x05d86d02, textures/skybox_tiles/bidw.55.rgba16.png +0x0571fc7c, textures/skybox_tiles/bbh.15.rgba16.png +0x04f846f7, levels/wmotr/4.rgba16.png +0x04a6ffc8, actors/monty_mole/monty_mole_nose.rgba16.png +0x04a35759, textures/generic/bob_textures.02800.rgba16.png +0x044f24ef, textures/effect/lava_bubble.03020.rgba16.png +0x0430de55, textures/skybox_tiles/cake.25.rgba16.png +0x042dee1b, textures/spooky/bbh_textures.01800.rgba16.png +0x03eeab38, textures/skybox_tiles/ccm.27.rgba16.png +0x03daf3d5, actors/peach/peach_eye_mostly_open.rgba16.png +0x0391ee74, textures/skybox_tiles/wdw.24.rgba16.png +0x038be28f, textures/snow/ccm_textures.07000.rgba16.png +0x0374425d, textures/skybox_tiles/wdw.26.rgba16.png +0x03298536, actors/bullet_bill/bullet_bill_mouth.rgba16.png +0x031dc071, textures/skybox_tiles/cloud_floor.49.rgba16.png +0x0303136f, textures/inside/inside_castle_textures.00000.rgba16.png +0x02cfd740, actors/mr_i_eyeball/mr_i_eyeball_left_side.rgba16.png +0x02c423f8, textures/skybox_tiles/clouds.12.rgba16.png +0x02aaddf6, textures/skybox_tiles/cloud_floor.59.rgba16.png +0x027c89db, textures/skybox_tiles/cloud_floor.4.rgba16.png +0x02429854, textures/skybox_tiles/bbh.1.rgba16.png +0x02330ccd, textures/segment2/segment2.06300.rgba16.png +0x022f69e3, textures/inside/inside_castle_textures.03800.rgba16.png +0x02040b88, textures/intro_raw/red_star_3.rgba16.png +0x01bf1983, textures/intro_raw/red_star_5.rgba16.png +0x01a60ccd, actors/chain_chomp/chain_chomp_dull_shine.rgba16.png +0x019bfb97, textures/skybox_tiles/clouds.5.rgba16.png +0x01755b95, textures/grass/wf_textures.09800.rgba16.png +0x014c6e73, textures/skybox_tiles/ccm.34.rgba16.png +0x011c8c77, textures/skybox_tiles/water.23.rgba16.png +0x0110314c, textures/machine/ttc_textures.02000.rgba16.png +0x00b11930, textures/skybox_tiles/bidw.33.rgba16.png +0x00866b3f, actors/chillychief/chill_bully_left_side.rgba16.png +0x006a1516, textures/skybox_tiles/wdw.58.rgba16.png +0x0010fdc4, actors/sushi/sushi_snout.rgba16.png +0x1195aecc, actors/chair/chair_bottom.rgba16.png +0xb16edfa9, actors/exclamation_box/vanish_cap_box_sides.rgba16.png +0x4838a16e, actors/exclamation_box/wing_cap_box_sides.rgba16.png +0x2c14636c, actors/eyerok/eyerok_eye_mostly_closed.rgba16.png +0x761e51a0, actors/eyerok/eyerok_eye_mostly_open.rgba16.png +0x93944d54, actors/eyerok/eyerok_eye_open.rgba16.png +0x9df33cc7, actors/hoot/hoot_eyes.rgba16.png +0x0ce27cd0, actors/hoot/hoot_wing.rgba16.png +0x1f8b71ca, actors/hoot/hoot_wing_tip.rgba16.png +0x3cf309e4, actors/impact_ring/impact_ring_left_side.ia16.png +0x20655b3c, actors/impact_ring/impact_ring_right_side.ia16.png +0x2996ca88, actors/king_bobomb/king_bob-omb_crown_rim.rgba16.png +0xa7c43afc, levels/bitfs/0.rgba16.png +0x1d6fcb73, levels/ddd/4.rgba16.png +0x3c99819f, levels/menu/main_menu_seg7.00818.rgba16.png +0xfae4a688, levels/menu/main_menu_seg7.01018.rgba16.png +0x8a748466, levels/menu/main_menu_seg7_us.0AC40.ia8.png +0x66729882, levels/menu/main_menu_seg7_us.0AE00.ia8.png +0x72768866, levels/menu/main_menu_seg7_us.0AE80.ia8.png +0x686c9480, levels/menu/main_menu_seg7_us.0B540.ia8.png +0x4c8a74ac, levels/menu/main_menu_seg7_us.0B580.ia8.png +0x76406e6e, levels/menu/main_menu_seg7_us.0B5C0.ia8.png +0xc4f693e5, levels/menu/main_menu_seg7_us.0B740.ia8.png +0x7e87867a, levels/menu/main_menu_seg7_us.0B780.ia8.png +0x8c868486, levels/menu/main_menu_seg7_us.0B7C0.ia8.png +0x2ea7c781, textures/fire/lll_textures.02000.rgba16.png +0xa2c3484f, textures/outside/castle_grounds_textures.0B000.rgba16.png +0x98bb898e, textures/segment2/font_graphics.05900.ia4.png +0xd057b494, textures/segment2/font_graphics.05940.ia4.png +0xb0f373b0, textures/segment2/font_graphics.05980.ia4.png +0x87ba54c8, textures/segment2/font_graphics.059C0.ia4.png +0x60d4a5c2, textures/segment2/font_graphics.05A00.ia4.png +0xb6ba71d3, textures/segment2/font_graphics.05A40.ia4.png +0x97baa58e, textures/segment2/font_graphics.05A80.ia4.png +0x68f155a5, textures/segment2/font_graphics.05AC0.ia4.png +0x87ba9198, textures/segment2/font_graphics.05B00.ia4.png +0xb0d568a0, textures/segment2/font_graphics.05B40.ia4.png +0x6cab6e7c, textures/segment2/font_graphics.05B80.ia4.png +0xaeb2b780, textures/segment2/font_graphics.05BC0.ia4.png +0x897ab77f, textures/segment2/font_graphics.05C00.ia4.png +0x86a979a6, textures/segment2/font_graphics.05C40.ia4.png +0x8798cfbf, textures/segment2/font_graphics.05C80.ia4.png +0x69b6b1a1, textures/segment2/font_graphics.05CC0.ia4.png +0x8894b7a4, textures/segment2/font_graphics.05D00.ia4.png +0x78a6e268, textures/segment2/font_graphics.05D40.ia4.png +0xb9a790a1, textures/segment2/font_graphics.05D80.ia4.png +0x9f8995a3, textures/segment2/font_graphics.05DC0.ia4.png +0xa8df6863, textures/segment2/font_graphics.05E00.ia4.png +0x988aa5ae, textures/segment2/font_graphics.05E40.ia4.png +0xafb97693, textures/segment2/font_graphics.05E80.ia4.png +0xb0ab7771, textures/segment2/font_graphics.05EC0.ia4.png +0x887ab795, textures/segment2/font_graphics.05F00.ia4.png +0x69b2b1a2, textures/segment2/font_graphics.05F40.ia4.png +0xa698b795, textures/segment2/font_graphics.05F80.ia4.png +0x6bb0b3a0, textures/segment2/font_graphics.05FC0.ia4.png +0xc1799951, textures/segment2/font_graphics.06000.ia4.png +0xb9a79083, textures/segment2/font_graphics.06040.ia4.png +0x9789a886, textures/segment2/font_graphics.06080.ia4.png +0x8d8f8692, textures/segment2/font_graphics.060C0.ia4.png +0x7d8d66c4, textures/segment2/font_graphics.06100.ia4.png +0xbdf14875, textures/segment2/font_graphics.06140.ia4.png +0xac848284, textures/segment2/font_graphics.06180.ia4.png +0xb97d6191, textures/segment2/font_graphics.061C0.ia4.png +0x80a7c266, textures/segment2/font_graphics.06200.ia4.png +0x6089a2c3, textures/segment2/font_graphics.06240.ia4.png +0xc089a462, textures/segment2/font_graphics.06280.ia4.png +0x8187c266, textures/segment2/font_graphics.062C0.ia4.png +0xbea7a284, textures/segment2/font_graphics.06300.ia4.png +0xaa77a182, textures/segment2/font_graphics.06340.ia4.png +0x8d8682b6, textures/segment2/font_graphics.06380.ia4.png +0x62a7c2a1, textures/segment2/font_graphics.063C0.ia4.png +0x788aa257, textures/segment2/font_graphics.06400.ia4.png +0x81697994, textures/segment2/font_graphics.06440.ia4.png +0x49e284a3, textures/segment2/font_graphics.06480.ia4.png +0x6aa886a1, textures/segment2/font_graphics.064C0.ia4.png +0x64c774d2, textures/segment2/font_graphics.06500.ia4.png +0x62a980c3, textures/segment2/font_graphics.06540.ia4.png +0x8089a286, textures/segment2/font_graphics.06580.ia4.png +0xa087a286, textures/segment2/font_graphics.065C0.ia4.png +0x8187c284, textures/segment2/font_graphics.06600.ia4.png +0xa2c46681, textures/segment2/font_graphics.06640.ia4.png +0xc5c3a662, textures/segment2/font_graphics.06680.ia4.png +0x8c87859e, textures/segment2/font_graphics.066C0.ia4.png +0x7f8ac166, textures/segment2/font_graphics.06700.ia4.png +0xc3688681, textures/segment2/font_graphics.06740.ia4.png +0x9fa8c268, textures/segment2/font_graphics.06780.ia4.png +0xa2c49f94, textures/segment2/font_graphics.067C0.ia4.png +0xbd8c84af, textures/segment2/font_graphics.06800.ia4.png +0xc2a56782, textures/segment2/font_graphics.06840.ia4.png +0x8c7275a4, textures/segment2/font_graphics.068C0.ia4.png +0xa88fc5a2, textures/segment2/font_graphics.06900.ia4.png +0xa48a62b0, textures/segment2/font_graphics.06940.ia4.png +0xa77a8863, textures/segment2/font_graphics.06980.ia4.png +0x637878b3, textures/segment2/font_graphics.06A00.ia4.png +0x8a6886a4, textures/segment2/font_graphics.06A80.ia4.png +0x8a4886a6, textures/segment2/font_graphics.06B40.ia4.png +0x8a688695, textures/segment2/font_graphics.06B80.ia4.png +0x5297b884, textures/segment2/font_graphics.06BC0.ia4.png +0x7771686e, textures/segment2/font_graphics.06C00.ia4.png +0x9a887684, textures/segment2/font_graphics.06C80.ia4.png +0x9b877585, textures/segment2/font_graphics.06CC0.ia4.png +0xb35be951, textures/segment2/font_graphics.06D80.ia4.png +0xd1d18587, textures/segment2/font_graphics.06DC0.ia4.png +0x9ac5a4a5, textures/segment2/font_graphics.06E00.ia4.png +0xb97c9fad, textures/segment2/font_graphics.06E40.ia4.png +0x0ecc73b4, textures/segment2/font_graphics.06E80.ia4.png +0xb1c091a7, textures/segment2/font_graphics.06EC0.ia4.png +0xb0c2949a, textures/segment2/font_graphics.06F00.ia4.png +0x92819878, textures/segment2/font_graphics.06F40.ia4.png +0x92a5a679, textures/segment2/font_graphics.06FC0.ia4.png +0xdb3c7c79, textures/segment2/segment2.02800.rgba16.png +0x095ccd5f, textures/segment2/segment2.04400.rgba16.png +0x98347689, textures/segment2/segment2.11458.ia8.png +0x543ae92e, textures/skybox_tiles/bbh.8.rgba16.png +0x543ae92e, textures/skybox_tiles/bbh.0.rgba16.png +0x3d7adde3, textures/skybox_tiles/bitfs.18.rgba16.png +0x3d7adde3, textures/skybox_tiles/bitfs.10.rgba16.png +0x14c6a0db, textures/skybox_tiles/bits.13.rgba16.png +0x5e2b9c03, textures/skybox_tiles/wdw.6.rgba16.png +0xa6c56aa3, textures/skybox_tiles/wdw.7.rgba16.png +0x6df82bbe, textures/skybox_tiles/wdw.16.rgba16.png +0xb3b76bce, textures/skybox_tiles/wdw.17.rgba16.png