Lakitu fix (#35)

* Fix menu bug

* Fix undefined behaviour

* Fix kart textures

* Fix boost texture

* Rename as per review

* Fix buffer overflows

* Fix lakitu progress

* Fix race starter character

---------

Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
This commit is contained in:
MegaMech
2024-08-03 20:57:07 -06:00
committed by GitHub
parent 016b16a484
commit c270c11c9b
9 changed files with 80 additions and 73 deletions
+3 -3
View File
@@ -23,15 +23,15 @@ typedef struct
/* 0x54 */ s32 status;
/* 0x58 */ s32 unk_058;
/* 0x5C */ s32 unk_05C;
/* 0x60 */ u8 *activeTLUT;
/* 0x64 */ u8 *activeTexture;
/* 0x60 */ const char *activeTLUT;
/* 0x64 */ const char *activeTexture;
/**
* "list" is something of a misnomer for the names here
* they can be pointers to just 1 tlut/texture, but it is common for one or the other
* to be a pointer to an array of tluts/textures.
**/
/* 0x68 */ u8 *tlutList; // I feel like this should actually be `u8 (*tlutList)[512]`, but that causes mismatches
/* 0x6C */ u8 *textureList;
/* 0x6C */ const char **textureList;
/* 0x70 */ Gfx *model;
/* 0x74 */ Vtx *vertex;
/* 0x78 */ s8 unk_078[0x04];
+2 -2
View File
@@ -287,14 +287,14 @@ s32 indexObjectList2[32];
* I'm also not certain about its dimensions
* I think the entires in this array are way over-sized
*/
u8 D_80183FA8[4][0x2000];
const char *gLakituTextureBuffer[4][2];
/**
* Boos in Banshee Boardwalk
* Spawners for the 4 small fire breaths inside Bowser's Castle
*/
s32 indexObjectList3[32];
//! Seemingly a pointer to Lakitu texture(s)
u8 *D_8018C028;
const char **gLakituTexturePtr;
/**
* Unused list of object indices
*/
+2 -2
View File
@@ -410,10 +410,10 @@ extern Vec3su D_80183E98;
// extern s32 indexObjectList1[]; -> objects.h
// extern s32 indexObjectList2[]; -> objects.h
extern u8 D_80183FA8[4][0x2000];
extern const char *gLakituTextureBuffer[4][2];
// extern s32 indexObjectList3[]; -> objects.h
extern u8 *D_8018C028;
extern const char **gLakituTexturePtr;
// extern s32 indexObjectList4[]; -> objects.h
// extern Collision D_8018C0B0[]; -> objects.h
// extern s32 gObjectParticle1[]; -> objects.h
+1 -2
View File
@@ -1509,8 +1509,7 @@ NewCourseTable gNewCourseTable[] = {
};
/** Load Lakitu Textures **/
u8 *load_lakitu_textures_x64(const char** textureList, size_t length) {
u8 *load_lakitu_tlut_x64(const char** textureList, size_t length) {
// Calculate lakitu texture size to allocate
size_t size = 0;
for (size_t i = 0; i < length; i++) {
+1
View File
@@ -42,6 +42,7 @@ struct AllocOnlyPool {
extern f32 vtxStretchY;
u8 *load_lakitu_textures_x64(const char** textureList, size_t length);
u8 *load_lakitu_tlut_x64(const char**textureList, size_t length);
void *get_next_available_memory_addr(uintptr_t);
uintptr_t set_segment_base_addr(s32, void*);
void *get_segment_base_addr(s32);
+7 -7
View File
@@ -612,17 +612,17 @@ void func_80047068(u8 *tlut, u8 *texture, Vtx *arg2, UNUSED s32 arg3, s32 arg4,
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
}
void draw_rectangle_texture_overlap(u8 *tlut, u8 *texture, Vtx *arg2, UNUSED s32 arg3, s32 arg4, s32 width, s32 height) {
void draw_rectangle_texture_overlap(u8 *tlut, u8 *texture, Vtx *arg2, UNUSED s32 w, s32 height, s32 width, s32 heighthalf) {
s32 heightIndex;
s32 vertexIndex = 0;
u8 *img = texture;
u8 *img = (u8 *) LOAD_ASSET(texture);
gDPLoadTLUT_pal256(gDisplayListHead++, tlut);
for (heightIndex = 0; heightIndex < arg4 / height; heightIndex++) {
rsp_load_texture(img, width, height);
for (heightIndex = 0; heightIndex < height / heighthalf; heightIndex++) {
rsp_load_texture(img, width, heighthalf);
gSPVertex(gDisplayListHead++, &arg2[vertexIndex], 4, 0);
gSPDisplayList(gDisplayListHead++, common_rectangle_display);
img += width * (height - 1);
img += width * (heighthalf - 1);
vertexIndex += 4;
}
gSPTexture(gDisplayListHead++, 1, 1, 0, G_TX_RENDERTILE, G_OFF);
@@ -761,10 +761,10 @@ UNUSED void func_80048038(Vec3f arg0, Vec3su arg1, f32 arg2, u8 *tlut, u8 *textu
func_80047068(tlut, texture, arg5, arg6, arg7, arg8, arg9);
}
void draw_2d_texture_at(Vec3f arg0, Vec3su arg1, f32 arg2, u8 *tlut, u8 *texture, Vtx *arg5, s32 arg6, s32 arg7, s32 arg8, s32 arg9) {
void draw_2d_texture_at(Vec3f arg0, Vec3su arg1, f32 arg2, u8 *tlut, u8 *texture, Vtx *arg5, s32 width, s32 height, s32 width2, s32 height2) {
rsp_set_matrix_transformation(arg0, arg1, arg2);
gSPDisplayList(gDisplayListHead++, D_0D007D78);
draw_rectangle_texture_overlap(tlut, texture, arg5, arg6, arg7, arg8, arg9);
draw_rectangle_texture_overlap(tlut, texture, arg5, width, height, width2, height2);
}
void func_80048130(Vec3f arg0, Vec3su arg1, f32 arg2, u8 *tlut, u8 *texture, Vtx *arg5, s32 arg6, s32 arg7, s32 arg8, s32 arg9, s32 argA) {
+2 -2
View File
@@ -1787,8 +1787,8 @@ void func_80026B4C(Player *player, s8 playerId, s8 screenId, s8 arg3) {
s16 temp_t2 = player->unk_240;
s16 temp_num = 0x40; // setting this as a variable gets rid of regalloc
u8 *wheel0 = LOAD_ASSET(D_800DDE34[player->characterId][temp_t1]);
u8 *wheel1 = LOAD_ASSET(D_800DDE54[player->characterId][temp_t1]);
u16 *wheel0 = (u16 *) LOAD_ASSET(D_800DDE34[player->characterId][temp_t1]);
u16 *wheel1 = (u16 *) LOAD_ASSET(D_800DDE54[player->characterId][temp_t1]);
if (((player->effects & 0x4000) == 0x4000) && ((player->type & PLAYER_START_SEQUENCE) == 0)) {
if (((player->effects & 0x80) != 0x80) && ((player->effects & 0x40) != 0x40)
+55 -48
View File
@@ -730,7 +730,7 @@ void func_80073404(s32 objectIndex, u8 arg1, u8 arg2, Vtx *arg3) {
gObjectList[objectIndex].status = 0;
}
void init_texture_object(s32 objectIndex, u8 *texture, u8* arg2, u8 arg3, u16 arg4) {
void init_texture_object(s32 objectIndex, u8 *texture, const char **arg2, u8 arg3, u16 arg4) {
gObjectList[objectIndex].tlutList = texture;
gObjectList[objectIndex].textureList = arg2;
gObjectList[objectIndex].textureWidth = arg3;
@@ -762,7 +762,7 @@ void update_neon_texture(s32 objectIndex) {
void func_80073514(s32 objectIndex) {
gObjectList[objectIndex].activeTLUT = gObjectList[objectIndex].tlutList;
gObjectList[objectIndex].activeTexture = gObjectList[objectIndex].textureList + (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * gObjectList[objectIndex].itemDisplay);
gObjectList[objectIndex].activeTexture = gObjectList[objectIndex].textureList[gObjectList[objectIndex].itemDisplay];
}
UNUSED void func_80073568() {
@@ -1201,20 +1201,20 @@ void func_800744CC(void) {
}
}
void func_80074510(uintptr_t devAddr, void *vaddr, size_t nbytes) {
u8 *texture = (u8 *) LOAD_ASSET(devAddr);
uintptr_t devaddr2;
void func_80074510(const char **lakituTexturePtr, const char* devAddr, size_t vaddr, size_t nbytes) {
func_800744CC();
//osPiStartDma(&gDmaIoMesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vaddr, nbytes, &gDmaMesgQueue);
memcpy(vaddr, texture, nbytes);
lakituTexturePtr[vaddr] = devAddr;
D_8018D224 = 1;
}
void func_80074574(u8 *arg0, void *arg1, u16 arg2, u16 arg3) {
func_80074510((uintptr_t) (arg0), arg1, arg2 * arg3);
void func_80074574(const char **lakituTexturePtr, const char *devAddr, size_t vaddr, u16 width, u16 height) {
func_80074510(lakituTexturePtr, devAddr, vaddr, width * height);
}
//! @todo arg1 should likely be a u8 *
void func_800745C8(s32 objectIndex, uintptr_t arg1) {
void func_800745C8(s32 objectIndex, const char **lakituTexturePtr) {
s32 phi_a1;
if ((gObjectList[objectIndex].status & 1) != 0) {
@@ -1228,28 +1228,28 @@ void func_800745C8(s32 objectIndex, uintptr_t arg1) {
phi_a1 = 1;
}
gObjectList[objectIndex].activeTexture = (u8 *) (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * phi_a1) + arg1;
gObjectList[objectIndex].activeTexture = lakituTexturePtr[phi_a1];
func_800744A0(objectIndex);
}
}
void func_8007466C(s32 objectIndex, uintptr_t arg1) {
void func_8007466C(s32 objectIndex, const char **lakituTexturePtr) {
s32 phi_a1;
if ((gObjectList[objectIndex].status & 1) != 0) {
// I have no idea why this typecase works
gObjectList[objectIndex].activeTLUT = (u8*) ((u32*)gObjectList[objectIndex].tlutList + (gObjectList[objectIndex].unk_0D3 << 7)) ;
gObjectList[objectIndex].activeTLUT = (u8*) ((u32*)gObjectList[objectIndex].tlutList + (gObjectList[objectIndex].unk_0D3 << 7));
gObjectList[objectIndex].status ^= 2;
phi_a1 = 0;
if ((gObjectList[objectIndex].status & 2) != 0) {
phi_a1 = 1;
}
gObjectList[objectIndex].activeTexture = (u8 *) (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * phi_a1) + arg1;
gObjectList[objectIndex].activeTexture = lakituTexturePtr[phi_a1];
func_800744A0(objectIndex);
}
}
void func_80074704(s32 objectIndex, uintptr_t arg1) {
void func_80074704(s32 objectIndex, const char **lakituTexturePtr) {
s32 phi_a1;
if ((gObjectList[objectIndex].status & 1) != 0) {
@@ -1259,12 +1259,13 @@ void func_80074704(s32 objectIndex, uintptr_t arg1) {
if ((gObjectList[objectIndex].status & 2) != 0) {
phi_a1 = 1;
}
gObjectList[objectIndex].activeTexture = (u8 *) (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * phi_a1) + arg1;
gObjectList[objectIndex].activeTexture = lakituTexturePtr[phi_a1];
func_800744A0(objectIndex);
}
}
u8 *func_80074790(s32 objectIndex, u8 *arg1) {
// Since the buffer only holds two textures, phi_a2 chooses which spot to load into
size_t func_80074790(s32 objectIndex, const char **lakituTexturePtr) {
s32 phi_a2;
gObjectList[objectIndex].status ^= 4;
@@ -1272,32 +1273,35 @@ u8 *func_80074790(s32 objectIndex, u8 *arg1) {
if ((gObjectList[objectIndex].status & 4) != 0) {
phi_a2 = 1;
}
return (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * phi_a2) + arg1;
return phi_a2;
}
void func_800747F0(s32 objectIndex, u8 *arg1) {
u8 *sp24;
void func_800747F0(s32 objectIndex, const char **lakituTexturePtr) {
const char *nextTexture = NULL;
if (gObjectList[objectIndex].itemDisplay != gObjectList[objectIndex].unk_0D3) {
sp24 = gObjectList[objectIndex].textureList + (gObjectList[objectIndex].textureWidth * gObjectList[objectIndex].textureHeight * gObjectList[objectIndex].itemDisplay);
func_80074574(sp24, (void *) func_80074790(objectIndex, arg1), gObjectList[objectIndex].textureWidth, gObjectList[objectIndex].textureHeight);
gObjectList[objectIndex].unk_0D3 = gObjectList[objectIndex].itemDisplay;
func_80074478(objectIndex);
nextTexture = gObjectList[objectIndex].textureList[gObjectList[objectIndex].itemDisplay];
if (nextTexture != NULL) {
func_80074574(lakituTexturePtr, nextTexture, func_80074790(objectIndex, lakituTexturePtr), gObjectList[objectIndex].textureWidth, gObjectList[objectIndex].textureHeight);
gObjectList[objectIndex].unk_0D3 = gObjectList[objectIndex].itemDisplay;
func_80074478(objectIndex);
}
}
}
void func_80074894(s32 objectIndex, u8 *arg1) {
func_800747F0(objectIndex, arg1);
func_800745C8(objectIndex, (uintptr_t)arg1);
void func_80074894(s32 objectIndex, const char **lakituTexturePtr) {
func_800747F0(objectIndex, lakituTexturePtr);
func_800745C8(objectIndex, lakituTexturePtr);
}
void func_800748C4(s32 objectIndex, u8 *arg1) {
func_800747F0(objectIndex, arg1);
func_8007466C(objectIndex, (uintptr_t)arg1);
void func_800748C4(s32 objectIndex, const char **lakituTexturePtr) {
func_800747F0(objectIndex, lakituTexturePtr);
func_8007466C(objectIndex, lakituTexturePtr);
}
void func_800748F4(s32 objectIndex, u8 *arg1) {
func_800747F0(objectIndex, arg1);
func_80074704(objectIndex, (uintptr_t)arg1);
void func_800748F4(s32 objectIndex, const char **lakituTexturePtr) {
func_800747F0(objectIndex, lakituTexturePtr);
func_80074704(objectIndex, lakituTexturePtr);
}
void func_80074924(s32 objectIndex) {
@@ -2921,7 +2925,7 @@ void func_80079114(s32 objectIndex, s32 playerId, s32 arg2) {
if (gObjectList[objectIndex].state >= 2) {
if ((u8)gObjectList[objectIndex].unk_0D8 == 1) {
if (playerId == 0) {
func_80074894(objectIndex, D_8018C028);
func_80074894(objectIndex, gLakituTexturePtr);
return;
}
a = gIndexLakituList[0];
@@ -2932,13 +2936,13 @@ void func_80079114(s32 objectIndex, s32 playerId, s32 arg2) {
}
switch (arg2) {
case 0:
func_800748F4(objectIndex, D_8018C028);
func_800748F4(objectIndex, gLakituTexturePtr);
break;
case 1:
func_800748C4(objectIndex, D_8018C028);
func_800748C4(objectIndex, gLakituTexturePtr);
break;
case 2:
func_80074894(objectIndex, D_8018C028);
func_80074894(objectIndex, gLakituTexturePtr);
break;
}
}
@@ -2986,7 +2990,7 @@ void init_obj_lakitu_red_flag_countdown(s32 objectIndex, s32 playerId) {
//u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_countdown);
//u8 *lights = (u8 *) LOAD_ASSET(gTextureLakituNoLights1);
init_texture_object(objectIndex, (u8 *) load_lakitu_textures_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)), load_lakitu_textures_x64(sLakituTextures, ARRAY_COUNT(sLakituTextures)), 56, (u16) 72);
init_texture_object(objectIndex, (u8 *) load_lakitu_tlut_x64(common_tlut_lakitu_countdown, ARRAY_COUNT(common_tlut_lakitu_countdown)), sLakituTextures, 56, (u16) 72);
Vtx *vtx = (Vtx *) LOAD_ASSET(common_vtx_lakitu);
gObjectList[objectIndex].vertex = vtx;
gObjectList[objectIndex].sizeScaling = 0.15f;
@@ -3093,12 +3097,12 @@ void init_obj_lakitu_red_flag(s32 objectIndex, s32 playerIndex) {
func_800791F0(objectIndex, playerIndex);
u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_checkered_flag);
u8 *tex = (u8 *) LOAD_ASSET(common_tlut_lakitu_checkered_flag);
Vtx *vtx = (Vtx *) LOAD_ASSET(common_vtx_also_lakitu);
init_texture_object(objectIndex, (u8*) tlut, load_lakitu_textures_x64(sLakituCheckeredList, ARRAY_COUNT(sLakituCheckeredList)), 0x48U, (u16) 0x00000038);
init_texture_object(objectIndex, (u8*) tex, sLakituCheckeredList, 0x48U, (u16) 0x00000038);
object = &gObjectList[objectIndex];
object->activeTexture = D_8018C028;
object->activeTexture = *gObjectList[objectIndex].textureList;
object->vertex = vtx;
object->pos[2] = 5000.0f;
object->pos[1] = 5000.0f;
@@ -3181,7 +3185,7 @@ void init_obj_lakitu_red_flag_fishing(s32 objectIndex, s32 arg1) {
Vtx *vtx = (Vtx *) LOAD_ASSET(D_0D005F30);
func_800791F0(objectIndex, arg1);
init_texture_object(objectIndex, (u8*) tlut, load_lakitu_textures_x64(sLakituFishingTextures, ARRAY_COUNT(sLakituFishingTextures)), 0x38U, (u16) 0x00000048);
init_texture_object(objectIndex, tlut, sLakituFishingTextures, 0x38U, (u16) 0x00000048);
gObjectList[objectIndex].vertex = vtx;
gObjectList[objectIndex].sizeScaling = 0.15f;
func_80086E70(objectIndex);
@@ -3360,11 +3364,12 @@ void func_8007A060(s32 objectIndex, s32 playerIndex) {
func_800791F0(objectIndex, playerIndex);
u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_second_lap);
Vtx *vtx = (Vtx *) LOAD_ASSET(common_vtx_also_lakitu);
init_texture_object(objectIndex, (u8*) common_tlut_lakitu_second_lap, load_lakitu_textures_x64(sLakituSecondLapTextures, ARRAY_COUNT(sLakituSecondLapTextures)), 0x48U, (u16) 0x00000038);
init_texture_object(objectIndex, tlut, sLakituSecondLapTextures, 0x48U, (u16) 0x00000038);
object = &gObjectList[objectIndex];
object->activeTexture = D_8018C028;
object->activeTexture = *gObjectList[objectIndex].textureList;
object->vertex = vtx;
object->pos[2] = 5000.0f;
object->pos[1] = 5000.0f;
@@ -3418,11 +3423,12 @@ void func_8007A228(s32 objectIndex, s32 playerIndex) {
func_800791F0(objectIndex, playerIndex);
u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_final_lap);
Vtx *vtx = (Vtx *) LOAD_ASSET(common_vtx_also_lakitu);
init_texture_object(objectIndex, (u8*) common_tlut_lakitu_final_lap, load_lakitu_textures_x64(sLakituFinalLapTextures, ARRAY_COUNT(sLakituFinalLapTextures)), 0x48U, (u16) 0x00000038);
init_texture_object(objectIndex, tlut, sLakituFinalLapTextures, 0x48U, (u16) 0x00000038);
object = &gObjectList[objectIndex];
object->activeTexture = D_8018C028;
object->activeTexture = *gObjectList[objectIndex].textureList;
object->vertex = vtx;
object->pos[2] = 5000.0f;
object->pos[1] = 5000.0f;
@@ -3475,10 +3481,11 @@ void func_8007A3F0(s32 objectIndex, s32 arg1) {
f32 var = 5000.0f;
func_800791F0(objectIndex, arg1);
u8 *tlut = (u8 *) LOAD_ASSET(common_tlut_lakitu_reverse);
Vtx *vtx = (Vtx *) LOAD_ASSET(common_vtx_also_lakitu);
init_texture_object(objectIndex, (u8*) common_tlut_lakitu_reverse, load_lakitu_textures_x64(sLakituReverseTextures, ARRAY_COUNT(sLakituReverseTextures)), 72, (u16) 56);
gObjectList[objectIndex].activeTexture = D_8018C028;
init_texture_object(objectIndex, tlut, sLakituReverseTextures, 72, (u16) 56);
gObjectList[objectIndex].activeTexture = *gObjectList[objectIndex].textureList;
gObjectList[objectIndex].vertex = vtx;
gObjectList[objectIndex].pos[2] = var;
gObjectList[objectIndex].pos[1] = var;
@@ -3614,7 +3621,7 @@ void func_8007AA44(s32 playerId) {
func_8007A910(playerId);
objectIndex = gIndexLakituList[playerId];
D_8018C028 = D_80183FA8[playerId];
gLakituTexturePtr = &gLakituTextureBuffer[playerId];
switch (gObjectList[objectIndex].unk_0D8) {
case 1:
func_80079114(objectIndex, playerId, 2);
+7 -7
View File
@@ -59,7 +59,7 @@ bool func_80072F88(s32, s32, s32, s32, s32, s32);
bool func_800730BC(s32, s32, s32, s32, s32, s32);
s32 func_8007326C(s32, s32, s32, s32, s32, s32);
void func_80073404(s32, u8, u8, Vtx*);
void init_texture_object(s32, u8*, u8*, u8, u16);
void init_texture_object(s32, u8*, const char**, u8, u16);
void func_8007348C(s32, u8*, u8, u8, Vtx *);
void func_800734D4(void);
void update_neon_texture(s32);
@@ -103,15 +103,15 @@ void func_80074344(s32, f32*, f32, f32, f32, s32, s32);
void func_80074478(s32);
void func_800744A0(s32);
void func_800744CC(void);
void func_80074510(uintptr_t, void*, size_t);
void func_80074510(uintptr_t, void*, size_t, size_t);
void func_800745C8(s32, uintptr_t);
void func_8007466C(s32, uintptr_t);
void func_80074704(s32, uintptr_t);
u8 *func_80074790(s32, u8*);
void func_800747F0(s32, u8*);
void func_80074894(s32, u8*);
void func_800748C4(s32, u8*);
void func_800748F4(s32, u8*);
size_t func_80074790(s32, const char**);
void func_800747F0(s32, const char**);
void func_80074894(s32, const char**);
void func_800748C4(s32, const char**);
void func_800748F4(s32, const char**);
void func_80074924(s32);
void func_80074D94(s32);
void func_80074E28(s32);