Mario Kart 64
General hacking discussion pertaining to textures and misc.
Superb Resource
Contains a lot of data finds and a course viewer. (Fair amount displayed at the bottom of this page)
https://github.com/RenaKunisaki/mariokart64/wiki
Functions
Native Functions
/* 0x800936B8 */ extern void mk64_draw_text ( int x, int y, char * s, float xscale, float yscale, int u ); /* 0x80057710 */ extern void mk64_debug_text_preface ( void ); /* 0x800577A4 */ extern void mk64_draw_debug_text ( int x, int y, char * ); /* 0x80098DF8 */ extern void mk64_draw_square ( void *, int up_x, int up_y, int low_x, int low_y, u8, u8, u8, u8 ); /* 0x800400D0 */ extern void mk64_mio0_decode ( void * input, void * output );
OS Functions
0x800cbf70,osCreateThread 0x800cc0c0,osInitialize 0x800cc360,osStartThread 0x800cc4b0,osCreateViManager 0x800cc850,osViSetMode 0x800cc8c0,osViBlack 0x800cc930,osViSetSpecialFeatures 0x800ce8e0,osPfsNumFiles 0x800cea30,osPfsFileState 0x800ced20,osPfsFreeBlocks 0x800cee70,guRotateF 0x800cf004,guRotate 0x800cf060,guScaleF 0x800cf0b4,guScale 0x800cf100,guPerspectiveF 0x800cf330,guPerspective 0x800cf390,guLookAtF 0x800cf648,guLookAt 0x800cf6c0,guTranslateF 0x800cf708,guTranslate 0x800cf760,osSyncPrintf 0x800cf7c0,guMtxXFML 0x800cf820,guMtxCatL 0x800cf880,osPfsFindFile 0x800cfa40,osPfsDeleteFile 0x800cfd20,__osPfsReleasePages 0x800cff58,__osBlockSum 0x800d02d0,osPfsReadWriteFile 0x800d07d0,osPfsAllocateFile 0x800d0c54,__osPfsDeclearPage 0x800d0f80,osAiSetFrequency 0x800d10e0,osAiGetLength 0x800d10f0,osAiSetNextBuffer 0x800d11a0,osGetCount 0x800d1ab0,__osDisableInt 0x800d1ad0,__osRestoreInt 0x800d1af0,__osDequeueThread 0x800d1b30,__osSetSR 0x800d1b40,__osGetSR 0x800d1b50,__osSetFpcCsr 0x800d1b60,__osSiRawReadIo 0x800d1b60,__osSpRawReadIo 0x800d1bb0,__osSpRawWriteIo 0x800d1bb0,__osSiRawWriteIo 0x800d1c00,osWritebackDCache 0x800d1c80,osMapTLBRdb 0x800d1ce0,osPiRawReadIo 0x800d1d40,__osSetHWIntrRoutine 0x800d2610,__osTimerServicesInit 0x800d269c,__osTimerInterrupt 0x800d2814,__osSetTimerIntr 0x800d2888,__osInsertTimer 0x800d2a10,osGetThreadPri 0x800d2a30,__osViInit 0x800d2b90,__osViSwapContext 0x800d2fb0,osPiRawStartDma 0x800d3090,osEPiRawStartDma 0x800d3520,bcopy/_bcopy 0x800d3830,osVirtualToPhysical 0x800d38b0,__osSpSetStatus 0x800d38c0,__osSpSetPc 0x800d3900,__osSpRawStartDma 0x800d3990,__osSpDeviceBusy 0x800d39c0,osSetTimer 0x800d3aa0,__osSiRawStartDma 0x800d3c10,osJamMesg 0x800d3d60,osPiGetCmdQueue 0x800d3d90,__osSpGetStatus 0x800d3da0,guMtxF2L 0x800d3ea0,guMtxIdentF 0x800d3f28,guMtxIdent 0x800d3f58,guMtxL2F 0x800d4010,osEepromWrite 0x800d42cc,__osEepStatus 0x800d44f0,__osSumcalc 0x800d454c,__osIdCheckSum 0x800d45b4,__osRepairPackId 0x800d49cc,__osCheckPackId 0x800d4b64,__osGetId 0x800d4dc0,__osCheckId 0x800d4ebc,__osPfsRWInode 0x800d51dc,__osPfsSelectBank 0x800d5250,osPfsChecker 0x800d5914,corrupted_init 0x800d5ac8,corrupted 0x800d5cb0,__osContRamRead 0x800d6060,guNormalize 0x800d60f0,__sinf/fsin/sinf 0x800d62b0,__cosf/fcos/cosf 0x800d6420,_Printf 0x800d70e0,guMtxXFMF 0x800d7180,guMtxCatF 0x800d72f0,__osContRamWrite 0x800d76a0,osEepromRead 0x800d79a0,__osAiDeviceBusy 0x800d79d0,osSetIntMask 0x800d7a70,osDestroyThread 0x800d7b70,__osSiDeviceBusy 0x800d7c90,__osSetCompare 0x800d7ca0,__osResetGlobalIntMask 0x800d7d00,osEPiRawWriteIo 0x800d7d50,osYieldThread 0x800d7da0,__osProbeTLB 0x800d7e60,__osContAddressCrc 0x800d7f10,__osContDataCrc 0x800d7fe0,memcpy 0x800d800c,strlen 0x800d8034,strchr 0x800d8080,_Litob 0x800d8320,_Ldtob 0x800d8de0,lldiv 0x800d8ee0,ldiv 0x800ea5e0,osClockRate 0x800ea5e8,__osShutdown 0x800ea5ec,__OSGlobalIntMask 0x800ea5f0,osDiskExist 0x800ea620,osViModeNtscLpn1 0x800ea620,osViModeTable 0x800ea670,osViModeNtscLpf1 0x800ea710,osViModeNtscLaf1 0x800ea760,osViModeNtscLpn2 0x800ea7b0,osViModeNtscLpf2 0x800ea800,osViModeNtscLan2 0x800ea850,osViModeNtscLaf2 0x800ea8a0,osViModeNtscHpn1 0x800ea8f0,osViModeNtscHpf1 0x800ea940,osViModeNtscHan1 0x800ea990,osViModeNtscHaf1 0x800ea9e0,osViModeNtscHpn2 0x800eaa30,osViModeNtscHpf2 0x800eaa80,osViModePalLpn1 0x800eaad0,osViModePalLpf1 0x800eab70,osViModePalLaf1 0x800eabc0,osViModePalLpn2 0x800eac10,osViModePalLpf2 0x800eac60,osViModePalLan2 0x800eacb0,osViModePalLaf2 0x800ead00,osViModePalHpn1 0x800ead50,osViModePalHpf1 0x800eada0,osViModePalHan1 0x800eadf0,osViModePalHaf1 0x800eae40,osViModePalHpn2 0x800eae90,osViModePalHpf2 0x800eaee0,osViModeMpalLpn1 0x800eaf30,osViModeMpalLpf1 0x800eafd0,osViModeMpalLaf1 0x800eb020,osViModeMpalLpn2 0x800eb070,osViModeMpalLpf2 0x800eb0c0,osViModeMpalLan2 0x800eb110,osViModeMpalLaf2 0x800eb160,osViModeMpalHpn1 0x800eb1b0,osViModeMpalHpf1 0x800eb200,osViModeMpalHan1 0x800eb250,osViModeMpalHaf1 0x800eb2a0,osViModeMpalHpn2 0x800eb2f0,osViModeMpalHpf2 0x800f3c10,__osRcpImTable
Symbols
0x800046AC { osViExtendVStart } Auxiliary symbols for `osViExtendVStart`: 0x80162D5C = __additional_scanline 0x80028F5C { osSyncPrintf, rmonPrintf } 0x8005994C { leoInitUnit_atten } Auxiliary symbols for `leoInitUnit_atten`: 0x8005C654 { alSynDelete } 0x800CE130 0x800D2B80 { __osViGetCurrentContext, __osViGetNextContext, osPiGetDeviceType, __osGetActiveQueue, __osGetCurrFaultedThread, leoChkUnit_atten } Auxiliary symbols for `__osViGetCurrentContext`: 0x800EB3AC = __osViCurr Auxiliary symbols for `__osViGetNextContext`: 0x800EB3AC = __osViNext Auxiliary symbols for `osPiGetDeviceType`: 0x800EB3AC = osRomType Auxiliary symbols for `__osGetActiveQueue`: 0x800EB3AC = __osActiveQueue Auxiliary symbols for `__osGetCurrFaultedThread`: 0x800EB3AC = __osFaultedThread Auxiliary symbols for `leoChkUnit_atten`: 0x800D2A10 { osGetThreadPri } Auxiliary symbols for `osGetThreadPri`: 0x800EB3B0 = __osRunningThread
Stack Traces
Various
#00 0x800936B8 SRC:0x800A05B4 ARG:{0x00000010,0x00000024,0x800EF868,0x00000008} #01 0x8009F5E0 SRC:0x800A81E4 ARG:{0x8018DEB8,0x801431C8,0x06000000,0x0000013F} #02 0x800A7A4C SRC:0x800A8238 ARG:{0x00000000,0x000000FF,0x8019F7C8,0x00000006} #03 0x800A8230 SRC:0x80094278 ARG:{0x00000000,0x000000FF,0x8019F7C8,0x00000006} #04 0x800940EC SRC:0x80093AB4 ARG:{0x800F0000,0x00000000,0x0000F7FD,0x8014EF40} #05 0x80093A5C SRC:0x802A5C84 ARG:{0x00000000,0x80150298,0x0000F7FD,0x8014EF40} #06 0x802A59A4 SRC:0x80001608 ARG:{0x00000001,0x800DC668,0x00000001,0x80162600} #07 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #08 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000}
Spinning Nintendo logo (guRotate)
Stack trace for thread 5 (0x801589D0): #00 0x800CF0B4 SRC:0x800943C4 ARG:{0x00000002,0x3F800000,0x3F800000,0x40400000} #01 0x800942D0 SRC:0x80094744 ARG:{0x00000002,0xF63C0000,0x00000004,0x8015A9B0} #02 0x80094660 SRC:0x8009F6D4 ARG:{0x801263D0,0x000000FF,0x8019F7C8,0x00000006} #03 0x8009F5E0 SRC:0x800A81E4 ARG:{0x49018008,0x000000FF,0x8019F7C8,0x00000006} #04 0x800A7A4C SRC:0x800A8238 ARG:{0x00000000,0x000000FF,0x8019F7C8,0x00000006} #05 0x800A8230 SRC:0x80094BE8 ARG:{0x00000000,0x000000FF,0x8019F7C8,0x00000006} #06 0x80094A64 SRC:0x80001F28 ARG:{0x80150000,0x80150298,0x00000000,0x00000048} #07 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000}
"Cannot save race data for ghost"
(m64p) watch 80092C98 Now watching 0x80092C98. (m64p) continue Breakpoint triggered at 0x80092C98. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x80092C90 SRC:0x80093068 ARG:{0x800F0938,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015A898 size: 40b #01 0x80093034 SRC:0x800A7118 ARG:{0x800F0938,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015A8C0 size: 72b #02 0x800A70E8 SRC:0x800A07EC ARG:{0x8018DAA8,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015A908 size: 176b #03 0x8009F5E0 SRC:0x800A81E4 ARG:{0x8018DAA8,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015A9B8 size: 56b #04 0x800A7A4C SRC:0x800A8238 ARG:{0x00000000,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015A9F0 size: 24b #05 0x800A8230 SRC:0x80094278 ARG:{0x00000000,0x000000FF,0x8019F7A8,0x00000006} $sp:0x8015AA08 size: 48b #06 0x800940EC SRC:0x80093AB4 ARG:{0x00000000,0x00000000,0x00000000,0x8014EF40} $sp:0x8015AA38 size: 24b #07 0x80093A5C SRC:0x802A5C84 ARG:{0x00000000,0x80150298,0x00000000,0x8014EF40} $sp:0x8015AA50 size: 192b #08 0x802A59A4 SRC:0x80001608 ARG:{0x00000000,0x800DC668,0x00000001,0x80162600} $sp:0x8015AB10 size: 40b #09 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} $sp:0x8015AB38 size: 24b #10 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} $sp:0x8015AB50 size: ?
Thwomp in Bowser's Castle
This is the first function that writes meaningful data to the thwomp's context.
Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x80080054 ARG:{0x00000015,0x800F6990,0x00004000,0x00000000} #01 0x8007FFC0 SRC:0x80081338 ARG:{0x00000011,0x00000400,0x00010000,0x00010000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000}
Notes
(m64p) list 0x8008BF04: or a2,t2,$zero 0x8008BF08: lw $ra,20($sp) 0x8008BF0C: addiu $sp,$sp,32 0x8008BF10: jr $ra 0x8008BF14: nop 0x8008BF18: sll t6,a0,3 0x8008BF1C: subu t6,t6,a0 0x8008BF20: lui t7,0x8016 0x8008BF24: addiu t7,t7,23576 0x8008BF28: sll t6,t6,5 (m64p) regs Registers for thread 5 at 0x8008BF18: GPR: $r0 0000000000000000h $at 0000000000000001h v0 0000000000000000h v1 FFFFFFFF80168378h a0 000000000000002Dh a1 FFFFFFFFC37A0000h a2 FFFFFFFFBFC00000h a3 000000000000002Dh t0 FFFFFFFF80168378h t1 FFFFFFFFFFFFFFFFh t2 0000000000002760h t3 FFFFFFFF80165C18h t4 0000000000000002h t5 0000000000000005h t6 0000000000002760h t7 FFFFFFFF80165C18h s0 000000000000002Dh s1 FFFFFFFF80168378h s2 FFFFFFFF80183EC8h s3 FFFFFFFF800DDB40h s4 000000000000000Ah s5 0000000000000000h s6 0000000000000000h s7 0000000000000000h t8 0000000004002220h t9 FFFFFFFFFFFFFF40h k0 FFFFFFFFA430000Ch k1 0000000000000AAAh $gp 0000000000000000h $sp FFFFFFFF8015AA48h s8 FFFFFFFF80165750h $ra FFFFFFFF800808BCh FPR (single): $f00 -1.5000 $f01 0.0000 $f02 -1623.0000 $f03 0.0000 $f04 -3.0000 $f05 1.5250 $f06 -3.0000 $f07 2.5041 $f08 -1552.0000 $f09 2.4326 $f10 0.0000 $f11 2.0000 $f12 -250.0000 $f13 0.0000 $f14 -1.5000 $f15 3.0625 $f16 0.0000 $f17 0.8140 $f18 70.0000 $f19 -0.8140 $f20 -0.0000 $f21 1.1333 $f22 0.0000 $f23 0.0000 $f24 0.0000 $f25 0.0000 $f26 0.0000 $f27 0.0000 $f28 0.0000 $f29 0.0000 $f30 0.0000 $f31 0.0000 FPR (double): $f00 0.0000 $f02 0.0000 $f04 0.1500 $f06 8.1313 $f08 6.9223 $f10 2.0000 $f12 0.0000 $f14 40.0000 $f16 0.0010 $f18 -0.0010 $f20 0.0167 $f22 0.0000 $f24 0.0000 $f26 0.0000 $f28 0.0000 $f30 0.0000 (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x800808B4 ARG:{0x801683A8,0xC37A0000,0xBFC00000,0x0000002D} #01 0x8008085C SRC:0x80080970 ARG:{0x0000002D,0x00004000,0x00000003,0x00000001} #02 0x800808CC SRC:0x80081368 ARG:{0x19036045,0x8018F0A4,0x00000000,0x8018F0B8} #03 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #05 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #06 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #07 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x8007EE2C ARG:{0x00000005,0x00000000,0x0000000C,0x8018CA70} #01 0x8007ED6C SRC:0x80081318 ARG:{0x00000000,0x00000008,0x0000000C,0x8018CA70} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x8007EE2C ARG:{0x00000009,0x00000000,0x0000000C,0x8018CA70} #01 0x8007ED6C SRC:0x80081318 ARG:{0x00000005,0x00000000,0x0000000C,0x8018CA70} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x8007F63C ARG:{0x0000000D,0x00000800,0x00007000,0x00008000} #01 0x8007F5A8 SRC:0x80081328 ARG:{0x00000009,0x00000000,0x0000000C,0x8018CA70} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x8007F63C ARG:{0x00000011,0x00000400,0x0000F800,0x00010000} #01 0x8007F5A8 SRC:0x80081328 ARG:{0x0000000D,0x00000800,0x00007000,0x00008000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x80080054 ARG:{0x00000015,0x800F6990,0x0000F800,0x00010000} #01 0x8007FFC0 SRC:0x80081338 ARG:{0x00000011,0x00000400,0x0000F800,0x00010000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x80080054 ARG:{0x00000015,0x800F6990,0x0000F800,0x00010000} #01 0x8007FFC0 SRC:0x80081338 ARG:{0x00000011,0x00000400,0x0000F800,0x00010000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) unwatch 0x801589D0 0x801589D0 is not being watched. (m64p) watch 8008123C Now watching 0x8008123C. (m64p) continue Breakpoint triggered at 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x80080054 ARG:{0x00000019,0x800F6990,0x0000F800,0x00010000} #01 0x8007FFC0 SRC:0x80081338 ARG:{0x00000015,0x800F6990,0x0000F800,0x00010000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) unwatch 8008BF18 Removed PC watch 0x8008BF18. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8008BF18 SRC:0x80080054 ARG:{0x00000019,0x800F6990,0x0000F800,0x00010000} #01 0x8007FFC0 SRC:0x80081338 ARG:{0x00000015,0x800F6990,0x0000F800,0x00010000} #02 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #03 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #04 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #05 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #06 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) continue Breakpoint triggered at 0x8008123C. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #01 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #02 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #03 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #04 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) unwatch 0x8008123C Removed PC watch 0x8008123C. (m64p) watch 80081210 Now watching 0x80081210. (m64p) continue Breakpoint triggered at 0x80081210. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x80081210 SRC:0x8005A734 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #01 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #02 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #03 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #04 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} (m64p) unwatch 0x80081210 Removed PC watch 0x80081210. (m64p) watch 8005A71C Now watching 0x8005A71C. (m64p) continue Breakpoint triggered at 0x8005A71C. (m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x8005A71C SRC:0x80059C28 ARG:{0x00000003,0x80165890,0x0000000C,0x8018CA70} #01 0x80059AC8 SRC:0x800015A4 ARG:{0x800FCA78,0x801646F0,0x00000007,0x00000000} #02 0x8000142C SRC:0x80001F38 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000} #03 0x80001ECC SRC:0x800028A4 ARG:{0x800DC4C0,0x800DC4C4,0x800DC4C8,0x00000000}
Player Data
Pointers to the 8 individual drivers are at 0x800DC4DC. Each driver structure appears to be 3544 bytes long.
struct mk64_player { float unkn; u32 u1; u32 u2; u32 u3; u32 u4; float x, y, z; u16 u5; u16 rotation; float unkn; float x_accel, y_accel, z_accel; };
Map Data
The code that processes the DMA and decompression of map files is dynamically loaded.
0x802AA918: sll t6,a0,2 0x802AA91C: subu t6,t6,a0 0x802AA920: lui t7,0x802c 0x802AA924: addiu t7,t7,-29312 0x802AA928: sll t6,t6,4 0x802AA92C: addu v0,t6,t7 0x802AA930: addiu $sp,$sp,-96 0x802AA934: lui v1,0x800e 0x802AA938: lw v1,-15092(v1) 0x802AA93C: lw t8,0(v0) 0x802AA940: lw t9,4(v0) 0x802AA944: lw t0,8(v0) 0x802AA948: lw t1,12(v0) 0x802AA94C: lw t2,40(v0) 0x802AA950: lw t3,24(v0) 0x802AA954: lw t4,32(v0) 0x802AA958: lw t5,28(v0) 0x802AA95C: lw t6,36(v0) 0x802AA960: lhu t7,44(v0) 0x802AA964: li $at,5 0x802AA968: sw $ra,20($sp) 0x802AA96C: lw a2,16(v0) 0x802AA970: lw a1,20(v0) 0x802AA974: sw t8,72($sp) 0x802AA978: sw t9,68($sp) 0x802AA97C: sw t0,64($sp) 0x802AA980: sw t1,60($sp) 0x802AA984: sw t2,48($sp) 0x802AA988: sw t3,44($sp) 0x802AA98C: sw t4,40($sp) 0x802AA990: sw t5,36($sp) 0x802AA994: sw t6,32($sp) 0x802AA998: beq v1,$at,0x802AA9AC 0x802AA99C: sw t7,28($sp) 0x802AA9A0: li $at,9 0x802AA9A4: bne v1,$at,0x802AA9BC 0x802AA9A8: lui t9,0x8028 0x802AA9AC: lui t8,0x8028 0x802AA9B0: lui $at,0x8016 0x802AA9B4: b 0x802AA9C8 0x802AA9B8: sw t8,-2260($at) 0x802AA9BC: ori t9,t9,0xdf00 0x802AA9C0: lui $at,0x8016 0x802AA9C4: sw t9,-2260($at) 0x802AA9C8: jal 0x802A7D70 0x802AA9CC: or a0,a2,$zero 0x802AA9D0: li a0,9 0x802AA9D4: jal 0x802A7B94 0x802AA9D8: or a1,v0,$zero 0x802AA9DC: lui t0,0x800e 0x802AA9E0: lw t0,-15092(t0) 0x802AA9E4: li $at,5 0x802AA9E8: lw a0,72($sp) 0x802AA9EC: beq t0,$at,0x802AAA08 0x802AA9F0: nop 0x802AA9F4: jal 0x802AA88C /* Map is decompressed further down the line here */ 0x802AA9F8: lw a1,68($sp) 0x802AA9FC: li a0,6
Stack trace hereto:
(m64p) bt Stack trace for thread 5 (0x801589D0): #00 0x800400D0 SRC:0x802AA8E8 ARG:{0x802899C0,0x801CCF10,0x00000001,0x802BA360} $sp:0x8015AA90 size: 48b #01 0x802AA88C SRC:0x802AA9F4 ARG:{0x0084E8E0,0x00852E20,0x00000001,0x802BA360} $sp:0x8015AAC0 size: 96b #02 0x802AA918 SRC:0x80002AF4 ARG:{0x00000008,0x0002C470,0x00000001,0x802BA360} $sp:0x8015AB20 size: 24b #03 0x80002A18 SRC:0x8000271C ARG:{0x8028DF00,0x0002C470,0x00000001,0x802BA360} $sp:0x8015AB38 size: 24b #04 0x80002684 SRC:0x80002884 ARG:{0x00000001,0x00006D6E,0x00000000,0x00000000} $sp:0x8015AB50 size: ? For the record, I loaded the first track of the first series.
Storage
The map data array begins at 0x802B8D80. The records are 48 bytes each. The structure appears to follow this format:
struct mk64_map_data_t { unsigned rom_start; unsigned rom_end; ... };
Filesystem
Mario Kart 64 doesn't have a single unified filesystem. A search for "MIO0\x00\x00\x10\x00" confirms this. Files are either loaded via distinct tables or through direct lui/addiu operations. This does not dismiss the possibility of being able to change the compression algorithm the ROM uses, however. A hash table could be employed with the original offsets of the file being used as the key. Thus, a DMA function could be intercepted and the proper file loaded regardless of new location.
I've done some trials with LZO and what I ASSUME to be the map data. The program can be found here(Missing). Output:
$ ./recomp ../mk64wrk/MK64-MASTER.Z64 #00 0x008284D0 - 0x0082B620 (MIO0: 12.33kb LZO: 10.43kb) -> 37.99kb #01 0x0088FA10 - 0x0089B510 (MIO0: 46.75kb LZO: 37.50kb) -> 78.71kb #02 0x0082B620 - 0x0082DF40 (MIO0: 10.28kb LZO: 8.54kb) -> 29.26kb #03 0x0089B510 - 0x008A7640 (MIO0: 48.30kb LZO: 39.42kb) -> 76.02kb #04 0x0082DF40 - 0x00831DC0 (MIO0: 15.62kb LZO: 13.97kb) -> 37.25kb #05 0x008A7640 - 0x008B9630 (MIO0: 71.98kb LZO: 56.75kb) -> 130.25kb #06 0x00831DC0 - 0x00835BA0 (MIO0: 15.47kb LZO: 13.35kb) -> 45.47kb #07 0x008B9630 - 0x008C2510 (MIO0: 35.72kb LZO: 27.17kb) -> 67.61kb #08 0x00835BA0 - 0x0083F740 (MIO0: 38.91kb LZO: 32.89kb) -> 97.47kb #09 0x008C2510 - 0x008CC900 (MIO0: 40.98kb LZO: 28.33kb) -> 50.86kb #10 0x0083F740 - 0x00842E40 (MIO0: 13.75kb LZO: 12.35kb) -> 30.78kb #11 0x008CC900 - 0x008D8E50 (MIO0: 49.33kb LZO: 37.88kb) -> 75.59kb #12 0x00842E40 - 0x0084ABD0 (MIO0: 31.39kb LZO: 25.32kb) -> 101.95kb #13 0x008D8E50 - 0x008EC390 (MIO0: 77.31kb LZO: 62.53kb) -> 128.19kb #14 0x0084ABD0 - 0x0084E8E0 (MIO0: 15.27kb LZO: 12.21kb) -> 55.97kb #15 0x008EC390 - 0x008FE640 (MIO0: 72.67kb LZO: 56.91kb) -> 113.56kb #16 0x0084E8E0 - 0x00852E20 (MIO0: 17.31kb LZO: 14.59kb) -> 64.67kb #17 0x008FE640 - 0x0090B3E0 (MIO0: 51.41kb LZO: 37.25kb) -> 81.16kb #18 0x00852E20 - 0x00857E80 (MIO0: 20.09kb LZO: 14.80kb) -> 81.78kb #19 0x0090B3E0 - 0x0091B980 (MIO0: 65.41kb LZO: 50.44kb) -> 108.99kb #20 0x00857E80 - 0x008666A0 (MIO0: 58.03kb LZO: 50.18kb) -> 143.03kb #21 0x0091B980 - 0x00928C70 (MIO0: 52.73kb LZO: 39.96kb) -> 86.94kb #22 0x008666A0 - 0x0086ECF0 (MIO0: 33.58kb LZO: 24.61kb) -> 140.91kb #23 0x00928C70 - 0x00936FD0 (MIO0: 56.84kb LZO: 42.84kb) -> 87.40kb #24 0x0086ECF0 - 0x00872A00 (MIO0: 15.27kb LZO: 13.55kb) -> 39.22kb #25 0x00936FD0 - 0x0093CC60 (MIO0: 23.14kb LZO: 17.74kb) -> 36.61kb #26 0x00872A00 - 0x008804A0 (MIO0: 54.66kb LZO: 51.20kb) -> 89.37kb #27 0x0093CC60 - 0x009438C0 (MIO0: 27.09kb LZO: 21.26kb) -> 42.53kb #28 0x008804A0 - 0x00885630 (MIO0: 20.39kb LZO: 18.58kb) -> 51.30kb #29 0x009438C0 - 0x00951780 (MIO0: 55.69kb LZO: 40.06kb) -> 82.95kb #30 0x00885630 - 0x00885780 (MIO0: 0.33kb LZO: 0.28kb) -> 0.34kb #31 0x00951780 - 0x00953890 (MIO0: 8.27kb LZO: 6.50kb) -> 14.88kb #32 0x00885780 - 0x008858A0 (MIO0: 0.28kb LZO: 0.24kb) -> 0.32kb #33 0x00953890 - 0x00955620 (MIO0: 7.39kb LZO: 5.91kb) -> 14.85kb #34 0x008858A0 - 0x00885A10 (MIO0: 0.36kb LZO: 0.31kb) -> 0.38kb #35 0x00955620 - 0x00956670 (MIO0: 4.08kb LZO: 3.25kb) -> 7.59kb #36 0x00885A10 - 0x0088CC50 (MIO0: 28.56kb LZO: 24.44kb) -> 81.70kb #37 0x00956670 - 0x00963EF0 (MIO0: 54.12kb LZO: 39.47kb) -> 77.64kb #38 0x0088CC50 - 0x0088CD70 (MIO0: 0.28kb LZO: 0.25kb) -> 0.28kb #39 0x00963EF0 - 0x00966260 (MIO0: 8.86kb LZO: 6.87kb) -> 15.93kb Summary: Total: 2507.69kb MIO0: 1260.23kb LZO: 1000.14kb Ratio: 79.36%
Extractor
A rudimentary extractor which picks out MIO0 blocks and infers their length via the compression format can be found here(missing). You can also download the Windows binary(missing).
Codes
These codes will only work when applied on a live emulator with Galatea. This is because they rely on initialized mutable pointers to their own data. While a Gameshark code would initialize them, it will continually write the value of the pointer to its storage location, thereby making it unmodifiable and useless.
Play as that fat ugly fuck in Bowser's Castle
.org 0x8008A178 .set noreorder #include <mips.h> /* Replace function call with our own */ jal hook_func /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ .org 0x80400000 .set noreorder #include <mips.h> .global hook_func hook_func: la $at,ra_store sw $ra,0($at) jal 0x00041770 nop li $4,0x80166E78 li $5,0x800F6990 lwc1 $f0,20($5) li.s $f2,10.0 swc1 $f0,4($4) lwc1 $f0,24($5) add.s $f0,$f0,$f2 swc1 $f0,8($4) lwc1 $f0,28($5) la $at,ra_store lw $ra,0($at) jr $ra swc1 $f0,12($4) ra_store: .word 0
DMA Logger
.org 0x800D2FC4 .set noreorder .set noat #include <mips.h> j hook .global after after: .org 0x80400000 .set noreorder .set noat #include <mips.h> .global hook hook: sltiu v0,a3,0x100 beq $zero,v0,log sw a3,0x34($sp) cont: j after nop log: la v0,stackp lw v1,0(v0) lui $at,0x8080 beq $at,v1,cont nop sw a0,0(v1) sw a1,4(v1) sw a2,8(v1) sw a3,12(v1) addiu v1,16 j cont sw v1,0(v0) stackp: .word stack stack: .word 0
DMA Logger v2
.org 0x800D2FC4 .set noreorder .set noat #include <mips.h> j hook .global after after: .org 0x80400000 .set noreorder .set noat #include <mips.h> .global hook hook: sltiu v0,a3,0x100 beq $zero,v0,log sw a3,0x34($sp) cont: j after nop log: la v0,stackp lw v1,0(v0) lui $at,0x8080 beq $at,v1,cont lui $gp,%hi(exempt) /* Check exemptions */ addiu $gp,$gp,%lo(exempt) loop: lw $at,0($gp) beq $at,a3,cont addiu $gp,$gp,4 bnez $at,loop nop sw a0,0(v1) sw a1,4(v1) sw a2,8(v1) sw a3,12(v1) /* store line */ li $at,(('!' << 24) | ('!' << 16) | ('!' << 8) | '!') sw $at,16(v1) sw $at,20(v1) sw $at,24(v1) sw $at,28(v1) addiu v1,32 j cont sw v1,0(v0) /* Exempt from logging */ exempt: .word 0x5A0 .word 0x100 .word 0 /* Zero terminate list */ stackp: .word stack stack: .word 0
All 3D objects 50% their scale
.org 0x800CF0C0 .set noreorder .set noat #include <mips.h> j hook addiu $sp,$sp,-88 .global after after: .org 0x80400000 .set noreorder #include <mips.h> .global hook hook: li.s $f0,0.5 mul.s $f12,$f12,$f0 mul.s $f14,$f14,$f0 mul.s $f16,$f16,$f0 j after sw $ra,0x14($sp)
Software
Some experimental code printing the X/Y/Z coordinates of player one is available here. It uses the standard N64 ROM code injection method.
Misc Data
Found outside of the community:
Shygoo "Hacking doc"
ROM/RAM map
ROM RAM Description CODE ?????? 800067C4 Set places (1st, 2nd, etc) ?????? 800115F4 Process path data on course load ?????? 8002F35C Controls cpu movement along track while player is moving ?????? 800400D0 MIO0 decoder ?????? 800404C0 MIO0 encoder ?????? 800405D0 TKMK00 decoder ?????? 80093134 Print text ?????? 8009338C Print text ?????? 80093788 Print text ?????? 80099124 Segmented to virtual address converter ?????? 80099154 Segmented to virtual address converter (duplicate) ?????? 800C4148 Play sound DATA ------ 800DC53C Game mode selection ------ 800DC598 Course timer (float) ------ 800DC5A0 Course selection 0E3AD0 800E2ED0 Kart unique settings table, 40 bytes per entry 0F0468 800EF868 Ascii text bank 0F4BB0 ???????? "RSP Gfx ucode F3DEX 0.95 Yoshitaka Yasumoto Nintendo." 0F53B0 ???????? "RSP Gfx ucode F3DLX 0.95 Yoshitaka Yasumoto Nintendo." ------ 80150258 RAM Segments table ------ 80165C18 Course RAM objects array? (bowser whomps, luigi hot air balloon) ------ 8018EDE4 Character selections ------ 8018EDF0 Player count selection CODE ?????? 8029D584 Place x with segment 06 offset ?????? 8029D60C Place bushes with segment 06 offset (bowser's castle) ?????? 8029D830 Place all item boxes using segment 06 offset ?????? 802A7B94 Segment base setter ?????? 802A85CC MIO0 '0F' list related ?????? 802A9AF4 Display list unpacker (A0 = segmented address of packed dlist, A1 = length) ?????? 802AA918 Course data main loader DATA 122390 802B8D80 Course data reference table 1232A4 802B9C94 Jump table for segment 7 display list unpacking ------ 802BA274 Index for packed dlist commands 12A1F0 ???????? Ascii text bank (credits) 132B50 -------- First MIO0 block 145470 -------- Kart texture and palette bank (MIO0 8CI textures, raw RGBA5551 palettes) 641F70 -------- Course texture bank 712DC0 -------- An MIO0 bank (kart exaust textures?) 729A30 -------- MIO0 Large character face textures 7FA3C0 -------- TKMK00 bank 820FC0 -------- Last TKMK block in ROM 821D10 -------- Two MIO0 blocks 8284D0 -------- Course assets MIO0 bank 88CD70 -------- Course texture/Seg06 dlist reference bank 88FA10 -------- Course MIO0 vertex data & special dlist bank 963EF0 -------- Last MIO0 block in ROM BC5F60 ???????? M64 music data BE9160 -------- End of ROM, 93856 padding bytes ______________________________________________________
RAM segments table (80150258)
00 General purpose, always 0x00000000 01 ? 02 ? 03 Common textures 04 Course mesh, for both collisions and graphics 05 Course textures 06 Some display lists, item box placements, path data 07 Generated display lists which reference the course mesh data 08 ? 09 Texture list and segment 06 display list jump table is loaded here 0A ? 0B ? 0C ? 0D ? 0F Temporary buffer for course mesh MIO0 and packed dlists || Course collisions table (44 byte entries)
Course data reference table (122390 / 802B8D80)
This table references course display lists, vertex data, textures, object placements; each entry is 0x30 bytes: 00 04 08 0C 10 14 18 1C 20 24 28 2C Mario Raceway 0000: [8284D0 82B620] [88FA10 89B510] [88CD70 88D070] 0F000000 0000167D 0F0096F4 00006930 09000000 00000000 Choco Mountain 0001: [82B620 82DF40] [89B510 8A7640] [88D070 88D340] 0F000000 000015B8 0F00A0B4 00005AE8 09000000 00010000 Bowser's Castle 0002: [82DF40 831DC0] [8A7640 8B9630] [88D340 88D6C0] 0F000000 00002537 0F00E368 00009918 09000000 00000000 Banshee Boardwalk 0003: [831DC0 835BA0] [8B9630 8C2510] [88D6C0 88D9C0] 0F000000 00001351 0F0068E8 00007340 09000000 00010000 Yoshi Valley 0004: [835BA0 83F740] [8C2510 8CC900] [88D9C0 88DAB0] 0F000000 00000E88 0F007D90 00008158 09000000 00000000 Frappe Snowland 0005: [83F740 842E40] [8CC900 8D8E50] [88DAB0 88DB40] 0F000000 00001599 0F009D24 00006648 09000000 00000000 Koopa Troopa Beach 0006: [842E40 84ABD0] [8D8E50 8EC390] [88DB40 88DC50] 0F000000 000024A0 0F00FD78 0000B2B8 09000000 00000000 Royal Raceway 0007: [84ABD0 84E8E0] [8EC390 8FE640] [88DC50 88E120] 0F000000 00002072 0F00EC60 0000B128 09000000 00000000 Luigi Raceway 0008: [84E8E0 852E20] [8FE640 90B3E0] [88E120 88E590] 0F000000 00001730 0F009800 0000C738 09000000 00000000 Moo Moo Farm 0009: [852E20 857E80] [90B3E0 91B980] [88E590 88E8D0] 0F000000 00001F24 0F00DAEC 00006738 09000000 00000000 Toad's Turnpike 000A: [857E80 8666A0] [91B980 928C70] [88E8D0 88ECD0] 0F000000 000018D7 0F00A5D0 00006B10 09000000 00000000 Kalimari Desert 000B: [8666A0 86ECF0] [928C70 936FD0] [88ECD0 88EFB0] 0F000000 000018F9 0F00B394 0000A678 09000000 00000000 Sherbet Land 000C: [86ECF0 872A00] [936FD0 93CC60] [88EFB0 88F2A0] 0F000000 00000A76 0F0049F8 00003850 09000000 00000000 Rainbow Road 000D: [872A00 8804A0] [93CC60 9438C0] [88F2A0 88F300] 0F000000 00000C27 0F005A5C 00002100 09000000 00000000 Wario Stadium 000E: [8804A0 885630] [9438C0 951780] [88F300 88F600] 0F000000 000017B3 0F00A9CC 0000A4B8 09000000 00000000 Block Fort 000F: [885630 885780] [951780 953890] [88F600 88F680] 0F000000 00000440 0F0018D8 000015D0 09000000 00000000 Skyscraper 0010: [885780 8858A0] [953890 955620] [88F680 88F800] 0F000000 0000043E 0F001678 00001118 09000000 00000000 Double Deck 0011: [8858A0 885A10] [955620 956670] [88F800 88F830] 0F000000 0000022B 0F000CD4 00000748 09000000 00000000 DK's Jungle Parkway 0012: [885A10 88CC50] [956670 963EF0] [88F830 88F9C0] 0F000000 0000162F 0F00A45C 00009C20 09000000 00000000 Big Donut 0013: [88CC50 88CD70] [963EF0 966260] [88F9C0 88FA10] 0F000000 0000048D 0F001B84 00001078 09000000 00000000 +---0x00: 008284D0 0082B620 // MIO0 block containing display lists, item box placements, path data, and ??; decoded to segment 06 |+--0x08: 0088FA10 0089B510 // Copied to segment 0F - MIO0 block of course vertex data (gfx & collisions); decoded to segment 04, followed by packed display list, decoded to segment 07 ||+-0x10: 0088CD70 0088D070 // Course texture MIO0 block references (segment 05), segment 06 display list references ||| 0x18: 0F000000 // Segment to load vertex data and packed dlists pre-decompression/unpacking ? ||| 0x1C: 0000167D // ? (gets multiplied by 24 at some point) ||| 0x20: 0F0096F4 // Segment offset of packed display list (unpacked to segment 7) ||| 0x24: 00006930 // Segment 7 unpacked dlist size? ||| 0x28: 09000000 // Segment to load texture list and dlist jump table? ||| 0x2C: 0000 // ? 0000 or 0001 ||| 0x2E: ---- // struct padding, unused ||| ||+-> Reference structure (16 bytes each): // related function 802A85CC || 0x00: 0F001080 // Offset of an MIO0 block relative to 641F70 (the '0F' prefix is ANDed out) || 0x04: 00000149 // MIO0 block size || 0x08: 00000800 // Decompressed image size (eg 32x32 = 0x800, 64x32 = 0x1000) || 0x0C: 00000000 // ? Always 0 || || At the end of the MIO0 block reference list there are 16 bytes of null padding followed by a list of segmented addresses referencing display lists in segment 06 || |+--> Mesh vertex structure: | ROM (14 bytes): | RAM (16 bytes): | 0x00: s16 Vx | 0x00: s16 Vx | 0x02: s16 Vy | 0x02: s16 Vy | 0x04: s16 Vz | 0x04: s16 Vz | 0x06: s16 U | 0x06: u16 ? | 0x08: s16 V | 0x08: s16 U | 0x0A: ? | 0x0A: s16 V | 0x0B: ? | 0x0C: u8 R | 0x0C: ? | 0x0D: u8 G | 0x0D: ? | 0x0E: u8 B | | 0x0F: u8 A | | Looks like a,b,c,d (rom) are the vertex color channels but the data differs slightly in ram, code should be checked | +---> Offsets for segment 6 assets are hardcoded 802AA918 Function called to load a course's assets using the course data table 800DC5A0 holds the current course selection ID, which is passed to this function ______________________________________________________
Segment 0F collision structure
0x00 u16 ? 0x02 u8 unused 0x03 u8 collision attribute 0x04 s16 ? 0x06 s16 ? 0x08 s16 ? 0x0A s16 ? 0x0C s16 ? 0x0E s16 ? 0x10 s16* vertex reference 0x14 s16* vertex reference 0x18 s16* vertex reference 0x1C float ? 0x20 float ? 0x24 float ? 0x28 float ? Collision attributes: 0x00 ? 0x01 Asphalt 0x02 Slightly bumpy 0x03 Dirt 0x04 ? 0x05 Snow? 0x06 ? 0x07 Sand? 0x08 Grass (slows kart) 0x09 Ice (creates reflection) 0x0A Dirt? 0x0B Snow? 0x0C ? 0x0D Clay? (red dust) 0x0E Railroad tracks (creates sound) 0x0F ? 0x10 Bumpy (creates sound) 0x11 Bumpy (creates sound) 0x12 ? 0x13 ? 0x14 ? (check 802AE9D0) ______________________________________________________
ASCII Text Bank
800EF868 / F0468 Ascii text bank Printer functions: 8009338C (a0 = x, a1 = y, a2 = pointer to asciiz string, a3 = controls text spacing) large 80093788 80093134 Special ascii sequences: A3 EE small "ND" A3 F2 small "RD" A3 F3 small "ST" A3 F4 small "TH" ______________________________________________________
80040EE0 void thwomp_move(float* thwomp_y) moves a thwomp up and down 8008B80C object x,y,z initialisation // callers: 80074C24, 80085484 800DC59B float course timer 801660A4 float Y coordinate of Luigi raceway hot air balloon 80166424 float Y coordinate of a thwomp, 801675A4 another one course item box array 80160218 item_box { ... float shadow_coord_y; // 0x08 ... float coord_x; // 0x1C float coord_y; // 0x20 float coord_z; // 0x24 ... } 80165C18 course complex object array course_object { // 224 bytes each ... float coord_x; // 0x28 float coord_y; // 0x2C float coord_z; // 0x30 ... } ______________________________________________________
Other notes
TKMK00 blocks seem to only contain image data for the background on startup, and startup selection screens 800BC360 m64 related code Todo: Check on vertex color rom -> ram change Find where collision data comes from Collect all hardcoded segment 06 pointers Draft "course script" engine to replace the hardcoded stuff Add parameter to course table for optional raw display list Find course m64 references Find course complex object placement method
Orbitaldecay's Notes
Yeah, I've seen the table at 800E2ED0, but I haven't figured out exactly what it does yet. Here are most of the tables I've identified so far: Kart properties: ROM RAM Description ?????? 800DDBD4 Kart Scale ?????? 800DDE34 Kart Graphics (Wheel Base) (Pointers) ?????? 800E257C 50cc Kart Speed ?????? 800E259C 100cc Kart Speed ?????? 800E25BC 150cc Kart Speed ?????? 800E25DC Extra Kart Speed ?????? 800E25FC Battle Kart Speed ?????? 800E2630 Kart Friction ?????? 800E2650 Kart Gravity? ?????? 800E2690 Kart Top Speed ?????? 800E26B0 Kart Bounding Box Size (also affects camera angle) ?????? 800E3010 Kart Acceleration (Pointers to structs) ?????? 800E3630 Kart Handling (Turn Angle) ?????? 800E3670 Kart Turn Speed Reduction Coefficient ?????? 800E3690 Kart Turn Speed Reduction Coefficient 2 ?????? 800E36D0 Kart Hop Height ?????? 800E36F0 Kart Hop Fall Speed 121DA0 802B8790 Kart Weight (this gets dma-ed over every time we load a track) Probability tables: ?????? 801A7A90 Item Table (GP Human) - 8 Entries ?????? 801A7DB0 Item Table (GP Computer) - 8 Entries ?????? 801A80D0 Item Table (VS 2 Player) - 2 Entries ?????? 801A8198 Item Table (VS 3 Player) - 3 Entries ?????? 801A82C4 Item Table (VS 4 Player) - 4 Entries ?????? 801A8454 Item Table (Battle) - 1 Entry Weapon values: 00: Nothing 01: Single Bananna Peel 02: Triple Bananna Peels 03: Single Green Shell 04: Triple Green Shell 05: Single Red Shell 06: Triple Red Shell 07: Blue Shell 08: Lightning Bolt 09: Evil Item Box 0A: Star 0B: Ghost 0C: Single Mushroom 0D: Two Mushrooms 0E: Three Mushrooms 0F: Super Mushroom The probability tables work like this: Each race position has 1 entry. Each entry has 100 cells. Each cell has a weapon value in it. A cell is chosen at random when we hit an item box in the given position. Things like the player current weapon variables, etc. are pretty easy to find and I haven't included them. Segment 09 points to a table. The first half of the table contains offsets of compressed textures in the texture bank. It has the following format: 00 offset in texture bank 04 compressed size 08 uncompressed size 0C unused (0) Compressed texture bank address is 641F70 in ROM. Offsets are relative to this. After this in the segment 9 table comes a NULL terminator, followed by a bunch of segment pointers to segment 6 (I think this is display list related)? I am also hanging around the IRC. I'll be in touch about the collab.
Root 1 Items Inventory MEM 0x80165F5E: Player 1 Inventory Item Probability Tables MEM 0x801A7A90: GP Human MEM 0x801A7DB0: GP Computer MEM 0x801A80D0: VS 2 Player MEM 0x801A8198: VS 3 Player MEM 0x801A82C4: VS 4 Player MEM 0x801A82C4: VS 4 Player MEM 0x801A8454: Battle Miscellaneous Utilities Compression CPU 0x800400D0: MIO0_Decompress(A0=compressed_buffer, A1=dest_buffer, A2=1??) Memory Transfer CPU 0x80001158: LoadFromCart(A0 = dest_buffer, A1 = src_buffer, A2 = length) CPU 0x800CDB80: Cache???(A0 = ptr, A1 = length) CPU 0x800CDC30: ???(A0 = 8014F0A0, A1 = 0, A2 = 0, A3 = src_table) CPU 0x800CD8C0: ????(A0 = ptr2, A1 = ptr, A2 = 0) CPU 0x800D3D60: GetPointer1() CPU 0x800D2FB0: CartDMA CPU 0x800D3900: RspDMA Tracks Functions CPU 0x802AA918: LoadTrackData(A0 = TrackIndex) CPU 0x802A7B94: SaveSegmentPointer(A0=index, A1=ptr) CPU 0x802A7D70: V0 = LoadImageTable(A0=ImageTableStart, A1=ImageTableEnd) CPU 0x802A7D1C: Malloc (A0 = Size) CPU 0x802A82E4: V0 = LoadVertexList(A0=start, A1=end) CPU 0x802A87A8: V0 = DecompressVertexList(A0=vertex list segment, A1=# of vertices) CPU 0x802A9AF4: Unpack2ndHalfofVertexList(A0=segment address, A1=???, A2=???) CPU 0x802AA7C8: DecompressTrackTextures() CPU 0x802A85CC: V0 = DecompressTexture(A0=compressed, A1=compressed size, A2=decompressed size) CPU 0x802AA840: DecompressTexturesLoop CPU 0x802AA88C: V0 = LoadDisplayList(A0=DisplayListStart, A1=DisplayListEnd) Memory MEM 0x10122390: Track Data Tables (ROM) MEM 0x80150258: SegmentPointerTable (5=decomp textures, 6=display list) MEM 0x802B8D80: Track Data Tables (RAM)