summaryrefslogtreecommitdiff
path: root/src/racing
diff options
context:
space:
mode:
authorcoco875 <59367621+coco875@users.noreply.github.com>2025-07-01 23:42:14 +0000
committerGitHub <noreply@github.com>2025-07-01 17:42:14 -0600
commit7937896598f3df46eb78c158bde787bc4f12ad7f (patch)
tree876548daaec2f8a5bb284374d834abcf9aad15b9 /src/racing
parentb57afa83b42bb14e526043be4ca9f6e322788edb (diff)
make some texture more flexible and editable + port documentation from the decomp + fix some bug (#309)
* support a more flexible background * remove useless function * rename of some font * experimental png * migrate to the new initdata * fix skybox and adjust minimap * format in audio * simplify player render * simplify shell render and support custom texture of shell * clean redshell texture * format and multiple fix * some update of name * allow change icon of character * more rename * continue rename * more documentation and simplification * change lus and continue rename * continue rename * few fix for asan * fix ghost * Update menu_items.c * fix mac error * some test of tweak for texture * some tweak * some button constant * finish fix ghost * Update menu_items.c * Update render_objects.c * Update menu_items.c * Update libultraship * Update libultraship * Delete valgrind.report * Update libultraship * callgrind benchmark * Update valgrind_callgrind.sh * fix animation * some rename * remove useless submodule * Update libultraship * fix assets * fix mistake * fix more mistake * Update menu_items.c * sync more rename with the decom + fix review * fix a mistake * fix more mistake * re add the limit of fps * fix some hd texture and minimap * fix a name * Update menu_items.c * fix a regression * fix some segment 5 texture (not all) * Update camera.c * improve performance of custom sprite * fix flatten bug and add documentation on player vertex * Update render_player.c * fix data menu * fix trophy for 50 and 150 * Update memory.c * Update code_80057C60.c * fix ghost * fix boo tlut * fix a mistake in yaml * fix yaml * Update common_data.yml * add comment for segment 3 * allow even more change in texture * Update common_data.yml * Update update.inc.c * Update camera.c * Update some_data.c * wip changes * Update other_textures.yml * More changes * Update update_objects.c * Fix compile * Update memory.c * Update memory.c --------- Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
Diffstat (limited to 'src/racing')
-rw-r--r--src/racing/actors.c88
-rw-r--r--src/racing/collision.c5
-rw-r--r--src/racing/math_util.c2
-rw-r--r--src/racing/memory.c74
-rw-r--r--src/racing/memory.h4
-rw-r--r--src/racing/skybox_and_splitscreen.c14
6 files changed, 130 insertions, 57 deletions
diff --git a/src/racing/actors.c b/src/racing/actors.c
index e30f67e25..17742bf03 100644
--- a/src/racing/actors.c
+++ b/src/racing/actors.c
@@ -38,8 +38,18 @@
// Appears to be textures
// or tluts
-u8* D_802BA050;
-u8* D_802BA054;
+char* texture_green_shell[] = {
+ texture_green_shell_0, texture_green_shell_1, texture_green_shell_2, texture_green_shell_3,
+ texture_green_shell_4, texture_green_shell_5, texture_green_shell_6, texture_green_shell_7,
+};
+char* gTextureBlueshell[] = {
+ texture_blue_shell_0, texture_blue_shell_1, texture_blue_shell_2, texture_blue_shell_3,
+ texture_blue_shell_4, texture_blue_shell_5, texture_blue_shell_6, texture_blue_shell_7,
+};
+char* texture_red_shell[] = {
+ texture_red_shell_0, texture_red_shell_1, texture_red_shell_2, texture_red_shell_3,
+ texture_red_shell_4, texture_red_shell_5, texture_red_shell_6, texture_red_shell_7,
+};
u8* D_802BA058;
struct Actor* gActorHotAirBalloonItemBox;
@@ -716,15 +726,9 @@ void render_palm_trees(Camera* camera, Mat4 arg1) {
#include "actors/kiwano_fruit/render.inc.c"
void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
- UNUSED s16 pad;
- u16 temp_t8;
- UNUSED s32 pad2;
- s16 sp58[15] = // D_802B87E8;
- { 0x0000, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00,
- 0x1c00, 0x1800, 0x1400, 0x1000, 0x0c00, 0x0800, 0x0400 };
- //! @todo Is this making the shell spin?
- // Is it doing this by modifying a an address?
- uintptr_t phi_t3;
+ u16 index;
+ char* phi_t3;
+ bool reverseShell = false;
// @port: Tag the transform.
FrameInterpolation_RecordOpenChild("Shell", TAG_ITEM_ADDR(shell));
@@ -744,13 +748,24 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
if (temp_f0 < 40000.0f) {
func_802979F8((struct Actor*) shell, 3.4f);
}
- if (shell->type == ACTOR_BLUE_SPINY_SHELL) {
- phi_t3 = (uintptr_t) D_802BA054;
- } else {
- phi_t3 = (uintptr_t) D_802BA050;
+
+ index = (u16) shell->rotVelocity / 4369; // Give a number between 0-15
+ if (index >= 8) {
+ reverseShell = true;
+ index = 15 - index;
+ }
+
+ switch (shell->type) {
+ case ACTOR_GREEN_SHELL:
+ phi_t3 = texture_green_shell[index];
+ break;
+ case ACTOR_RED_SHELL:
+ phi_t3 = texture_red_shell[index];
+ break;
+ case ACTOR_BLUE_SPINY_SHELL:
+ phi_t3 = gTextureBlueshell[index];
+ break;
}
- temp_t8 = (u16) shell->rotVelocity / 4369; // Give a number between 0-15
- phi_t3 += sp58[temp_t8]; // Select sprite
matrix[3][0] = shell->pos[0];
matrix[3][1] = (shell->pos[1] - shell->boundingBoxSize) + 1.0f;
@@ -765,7 +780,7 @@ void render_actor_shell(Camera* camera, Mat4 matrix, struct ShellActor* shell) {
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
- if (temp_t8 < 8) { // Reverse shell ?
+ if (reverseShell) { // Reverse shell ?
gSPDisplayList(gDisplayListHead++, D_0D005338);
} else {
gSPDisplayList(gDisplayListHead++, D_0D005368);
@@ -1219,32 +1234,17 @@ void spawn_course_actors(void) {
*/
void init_actors_and_load_textures(void) {
set_segment_base_addr_x64(3, (void*) gNextFreeMemoryAddress);
- D_802BA050 = dma_textures(gTextureGreenShell0, 0x00000257U, 0x00000400U);
- dma_textures(gTextureGreenShell1, 0x00000242U, 0x00000400U);
- dma_textures(gTextureGreenShell2, 0x00000259U, 0x00000400U);
- dma_textures(gTextureGreenShell3, 0x00000256U, 0x00000400U);
- dma_textures(gTextureGreenShell4, 0x00000246U, 0x00000400U);
- dma_textures(gTextureGreenShell5, 0x0000025EU, 0x00000400U);
- dma_textures(gTextureGreenShell6, 0x0000025CU, 0x00000400U);
- dma_textures(gTextureGreenShell7, 0x00000254U, 0x00000400U);
- D_802BA054 = dma_textures(gTextureBlueShell0, 0x0000022AU, 0x00000400U);
- dma_textures(gTextureBlueShell1, 0x00000237U, 0x00000400U);
- dma_textures(gTextureBlueShell2, 0x0000023EU, 0x00000400U);
- dma_textures(gTextureBlueShell3, 0x00000243U, 0x00000400U);
- dma_textures(gTextureBlueShell4, 0x00000255U, 0x00000400U);
- dma_textures(gTextureBlueShell5, 0x00000259U, 0x00000400U);
- dma_textures(gTextureBlueShell6, 0x00000239U, 0x00000400U);
- dma_textures(gTextureBlueShell7, 0x00000236U, 0x00000400U);
- dma_textures(gTextureFinishLineBanner1, 0x0000028EU, 0x00000800U);
- dma_textures(gTextureFinishLineBanner2, 0x000002FBU, 0x00000800U);
- dma_textures(gTextureFinishLineBanner3, 0x00000302U, 0x00000800U);
- dma_textures(gTextureFinishLineBanner4, 0x000003B4U, 0x00000800U);
- dma_textures(gTextureFinishLineBanner5, 0x0000031EU, 0x00000800U);
- dma_textures(gTextureFinishLineBanner6, 0x0000036EU, 0x00000800U);
- dma_textures(gTextureFinishLineBanner7, 0x0000029CU, 0x00000800U);
- dma_textures(gTextureFinishLineBanner8, 0x0000025BU, 0x00000800U);
- dma_textures(gTexture671A88, 0x00000400U, 0x00000800U);
- dma_textures(gTexture6774D8, 0x00000400U, 0x00000800U);
+ allocate_memory(0x400 * 16);
+ dma_textures(gTextureFinishLineBanner1, 0x0000028EU, 0x00000800U); // 0x03004000
+ dma_textures(gTextureFinishLineBanner2, 0x000002FBU, 0x00000800U); // 0x03004800
+ dma_textures(gTextureFinishLineBanner3, 0x00000302U, 0x00000800U); // 0x03005000
+ dma_textures(gTextureFinishLineBanner4, 0x000003B4U, 0x00000800U); // 0x03005800
+ dma_textures(gTextureFinishLineBanner5, 0x0000031EU, 0x00000800U); // 0x03006000
+ dma_textures(gTextureFinishLineBanner6, 0x0000036EU, 0x00000800U); // 0x03006800
+ dma_textures(gTextureFinishLineBanner7, 0x0000029CU, 0x00000800U); // 0x03007000
+ dma_textures(gTextureFinishLineBanner8, 0x0000025BU, 0x00000800U); // 0x03007800
+ dma_textures(gTexture671A88, 0x00000400U, 0x00000800U); // 0x03008000
+ dma_textures(gTexture6774D8, 0x00000400U, 0x00000800U); // 0x03008800
CM_LoadTextures();
diff --git a/src/racing/collision.c b/src/racing/collision.c
index a394f0080..e76ff4f61 100644
--- a/src/racing/collision.c
+++ b/src/racing/collision.c
@@ -435,6 +435,11 @@ s8 get_surface_type(u16 index) {
}
s16 get_track_section_id(u16 index) {
+ if (index >= gCollisionMeshCount) {
+ // printf("[collision.c] [get_track_section_id] Warning: Trying to access a collision triangle index %d\n
+ // Which is overflows gCollisionMesh, as its total size is %d\n", index, gCollisionMeshCount);
+ return 0xFF;
+ }
CollisionTriangle* triangle = &gCollisionMesh[index];
return triangle->flags & 0xFF;
}
diff --git a/src/racing/math_util.c b/src/racing/math_util.c
index 55c953a1f..69d5c0cbc 100644
--- a/src/racing/math_util.c
+++ b/src/racing/math_util.c
@@ -252,7 +252,7 @@ void func_802B5564(Mat4 arg0, u16* arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5,
}
}
- if (arg1 != 0) {
+ if (arg1 != NULL) {
if ((arg4 + arg5) <= 2.0) {
*arg1 = 0xFFFF;
} else {
diff --git a/src/racing/memory.c b/src/racing/memory.c
index a3c3bf6b3..002492f41 100644
--- a/src/racing/memory.c
+++ b/src/racing/memory.c
@@ -19,7 +19,7 @@
#include "courses/all_course_offsets.h"
#include "defines.h"
-#include <course_offsets.h>
+#include "course_offsets.h"
#include "engine/courses/Course.h"
@@ -30,7 +30,7 @@
s32 sGfxSeekPosition;
s32 sPackedSeekPosition;
-static u8 sMemoryPool[0xFFFFF]; // Stock memory pool size: 0xAB630
+static u8 sMemoryPool[0xFFFFFFF]; // Stock memory pool size: 0xAB630
uintptr_t sPoolEnd = sMemoryPool + sizeof(sMemoryPool);
uintptr_t sPoolFreeSpace;
@@ -154,6 +154,73 @@ Gfx* segmented_gfx_to_virtual(const void* addr) {
return (Gfx*) ((gSegmentTable[segment] + offset));
}
+static uintptr_t get_texture2(size_t offset, const course_texture* textures) {
+ if (!(offset & 0x5000000)) {
+ return NULL;
+ }
+ size_t totalOffset = 0x5000000;
+
+ while (textures->addr) {
+ if (totalOffset == offset) {
+ return (uintptr_t) (textures->addr);
+ }
+ totalOffset += textures->data_size;
+ textures++;
+ }
+
+ printf("memory.c: get_texture()\n TEXTURE NOT FOUND DURING DISPLAYLIST EXTRACT\n");
+ printf(" offset: 0x%X\n", offset);
+ return NULL;
+}
+
+// Finds texture calls and replaces hard-coded addresses with direct pointers to the o2r texture.
+void replace_segmented_textures_with_o2r_textures(Gfx* gfx, const course_texture* textures) {
+ char* name = NULL;
+ if (GameEngine_OTRSigCheck((char*) gfx)) {
+ name = (char*) gfx;
+ gfx = (Gfx*) LOAD_ASSET_RAW(gfx);
+ }
+ Gfx* iterator = gfx;
+ int i = 0;
+ u8 opcode;
+ while ((opcode = (iterator->words.w0 >> 24)) != (u8) G_ENDDL) {
+ if (opcode == G_DL) {
+ uintptr_t addr = iterator->words.w1;
+ if (!(addr & 0x400000000)) { // avoid segment address
+ replace_segmented_textures_with_o2r_textures((Gfx*) addr, textures);
+ }
+ } else if (opcode == G_DL_OTR_FILEPATH) {
+ char* fileName = (char*) iterator->words.w1;
+ Gfx* gfx2 = (Gfx*) ResourceGetDataByName((const char*) fileName);
+ if (((iterator->words.w0 >> (16)) & ((1U << 1) - 1)) == 0 && gfx2 != NULL) {
+ replace_segmented_textures_with_o2r_textures(gfx2, textures);
+ }
+ } else if (opcode == G_DL_OTR_HASH) {
+ if (((iterator->words.w0 >> (16)) & ((1U << 1) - 1)) == 0) {
+ iterator++;
+ Gfx* gfx2 = (Gfx*) ResourceGetDataByCrc(((uint64_t) iterator->words.w0 << 32) + iterator->words.w1);
+ if (gfx2 != NULL) {
+ replace_segmented_textures_with_o2r_textures(gfx2, textures);
+ }
+ }
+ } else if (opcode == G_SETTIMG) {
+ // If this is a texture command, we need to fix the texture segment pointer
+ uintptr_t tex = iterator->words.w1 & (~1);
+ uintptr_t addr = get_texture2(tex, textures);
+ if (addr != NULL) {
+ iterator->words.w1 = addr;
+ }
+ }
+
+ if (opcode == G_MARKER || opcode == G_MTX_OTR || opcode == G_VTX_OTR_FILEPATH || opcode == G_VTX_OTR_HASH) {
+ iterator++;
+ }
+ // Move to the next command in the display list
+ iterator++;
+ i++;
+ }
+}
+
void move_segment_table_to_dmem(void) {
s32 i;
@@ -489,7 +556,6 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) {
#ifdef TARGET_N64
temp_v0 = (u8*) gNextFreeMemoryAddress;
#else
- u8* tex = (u8*) LOAD_ASSET(texture);
temp_v0 = (u8*) allocate_memory(arg2);
#endif
@@ -504,7 +570,7 @@ u8* dma_textures(const char* texture, size_t arg1, size_t arg2) {
mio0decode((u8*) temp_a0, temp_v0);
gNextFreeMemoryAddress += arg2;
#else
- memcpy(temp_v0, tex, arg2);
+ strncpy(temp_v0, texture, arg2);
// strcpy(temp_v0, texture);
#endif
return temp_v0;
diff --git a/src/racing/memory.h b/src/racing/memory.h
index 8f4fbe2b5..557d9f02f 100644
--- a/src/racing/memory.h
+++ b/src/racing/memory.h
@@ -2,6 +2,7 @@
#define MEMORY_H
#include "common_structs.h"
+#include "course_offsets.h"
struct MainPoolBlock {
struct MainPoolBlock* prev;
@@ -52,6 +53,7 @@ void* segment_vtx_to_virtual(size_t offset);
void* segmented_texture_to_virtual(uintptr_t addr);
void* segmented_uintptr_t_to_virtual(uintptr_t);
Gfx* segmented_gfx_to_virtual(const void*);
+void replace_segmented_textures_with_o2r_textures(Gfx* gfx, const course_texture* textures);
void move_segment_table_to_dmem(void);
void initialize_memory_pool(void);
void* decompress_segments(u8*, u8*);
@@ -74,7 +76,7 @@ void func_802A81EC(void);
struct AllocOnlyPool* alloc_only_pool_init(uintptr_t, uintptr_t);
uintptr_t func_802A82AC(s32);
uintptr_t func_802A8348(s32, s32, s32);
-u8* dma_textures(const char*, size_t, size_t);
+u8* dma_textures(const char* texture, size_t arg1, size_t arg2);
uintptr_t MIO0_0F(u8*, uintptr_t, uintptr_t);
void func_802A8844(void);
void unpack_lights(Gfx*, u8*, s8);
diff --git a/src/racing/skybox_and_splitscreen.c b/src/racing/skybox_and_splitscreen.c
index eecac8375..aa65f1e75 100644
--- a/src/racing/skybox_and_splitscreen.c
+++ b/src/racing/skybox_and_splitscreen.c
@@ -2,6 +2,7 @@
#include <macros.h>
#include <libultra/gbi.h>
#include <mk64.h>
+#include <stdio.h>
#include "skybox_and_splitscreen.h"
#include "code_800029B0.h"
@@ -382,6 +383,7 @@ void func_802A450C(Vtx* skybox) {
skybox[3].v.cn[1] = prop->TopLeft.g;
skybox[3].v.cn[2] = prop->TopLeft.b;
+ // Floor
skybox[4].v.cn[0] = prop->FloorTopRight.r;
skybox[4].v.cn[1] = prop->FloorTopRight.g;
skybox[4].v.cn[2] = prop->FloorTopRight.b;
@@ -422,18 +424,15 @@ void func_802A487C(Vtx* arg0, UNUSED struct UnkStruct_800DC5EC* arg1, UNUSED s32
}
void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, UNUSED s32 arg3, UNUSED f32* arg4) {
- //! @todo Confirm if this crash still happens and fix if so
- s32 id = arg1 - D_8015F480;
- arg1->camera = &cameras[id]; // bad fix of bowser castle crash where camera get an invalid value
Camera* camera = arg1->camera;
s16 temp_t5;
f32 temp_f0;
UNUSED s32 pad[2];
UNUSED u16 pad2;
u16 sp128;
- Mat4 matrix1;
- Mat4 matrix2;
- Mat4 matrix3;
+ Mat4 matrix1 = { 0 };
+ Mat4 matrix2 = { 0 };
+ Mat4 matrix3 = { 0 };
Vec3f sp5C;
f32 sp58;
@@ -443,6 +442,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U
vtx[1].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH);
vtx[2].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0);
vtx[3].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0);
+
vtx[4].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH);
vtx[5].v.ob[0] = OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH);
vtx[6].v.ob[0] = OTRGetRectDimensionFromLeftEdge(0);
@@ -468,7 +468,7 @@ void func_802A4A0C(Vtx* vtx, struct UnkStruct_800DC5EC* arg1, UNUSED s32 arg2, U
sp5C[0] *= 160.0f;
sp5C[1] *= 120.0f;
- temp_t5 = 120 - (s16) sp5C[1];
+ temp_t5 = 120 - (s32) sp5C[1];
arg1->cameraHeight = temp_t5;
vtx[1].v.ob[1] = temp_t5;
vtx[2].v.ob[1] = temp_t5;