From 76f19c6de33e1220997a70cf300b499f9c6ea2b7 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 27 Aug 2024 21:00:44 -0600 Subject: [PATCH] Networking Update & Fix (#66) * Update start_game.c * Update networking.c * Update networking.h * Create MultiplayerWindow.cpp * Create MultiplayerWindow.h * Update start_game.c * Update render_player.c --- src/networking/networking.c | 6 +- src/networking/networking.h | 8 +- src/networking/start_game.c | 120 ++++++++++++----------- src/port/ui/MultiplayerWindow.cpp | 155 ++++++++++++++++++++++++++++++ src/port/ui/MultiplayerWindow.h | 16 +++ src/render_player.c | 8 +- 6 files changed, 250 insertions(+), 63 deletions(-) create mode 100644 src/port/ui/MultiplayerWindow.cpp create mode 100644 src/port/ui/MultiplayerWindow.h diff --git a/src/networking/networking.c b/src/networking/networking.c index 0c0ffd777..54f5fd585 100644 --- a/src/networking/networking.c +++ b/src/networking/networking.c @@ -200,7 +200,7 @@ void handleReceivedData(const char* buffer, size_t bufSize) { case PACKET_PLAYER: replicate_player(data); break; - case PACKET_COURSE: + case PACKET_SET_COURSE: set_course(data); break; case PACKET_PLAYER_ASSIGN_SLOTS: @@ -223,3 +223,7 @@ void networking_cleanup(SDLNet_SocketSet socketSet) { SDLNet_Quit(); SDL_Quit; } + +void networking_disconnect(void) { + networking_cleanup(gNetwork.tcpSocket); +} diff --git a/src/networking/networking.h b/src/networking/networking.h index 95de42002..2a7634d66 100644 --- a/src/networking/networking.h +++ b/src/networking/networking.h @@ -15,7 +15,8 @@ enum { PACKET_LOADED, PACKET_READY_UP, PACKET_SET_CHARACTER, - PACKET_COURSE, + PACKET_COURSE_VOTE, + PACKET_SET_COURSE, PACKET_PLAYER_ASSIGN_SLOTS, PACKET_START_SESSION, PACKET_PLAYER, @@ -32,6 +33,8 @@ typedef struct { bool loaded; bool playersLoaded; // Are all players loaded? bool gameStarted; + uint32_t cupVote; + uint32_t character; } Network; extern Network gNetwork; @@ -58,6 +61,9 @@ void networking_cleanup(SDLNet_SocketSet); int networking_loop(void*); void handleReceivedData(const char*, size_t); void set_username(const char* username); +void network_character_vote(uint32_t course); +void network_cup_vote(uint32_t course); +void networking_disconnect(void); /* Start Game */ void spawn_network_players(f32*, f32*, f32); diff --git a/src/networking/start_game.c b/src/networking/start_game.c index 483b2b80f..6fc7dbb3d 100644 --- a/src/networking/start_game.c +++ b/src/networking/start_game.c @@ -25,6 +25,11 @@ void assign_player_control_types(void) { if (clients[i].isAI) { gPlayers[playerIndex].nControlFlags = 0; } else if (clients[i].hasAuthority) { + //printf("PLAYER SLOT %d, INDEX %d\n", clients[i].slot, clients[i].character); + + // Set player to the camera + //cameras[0].playerId = clients[i].slot; + //D_800DC5EC->player = &gPlayers[clients[i].slot]; // printf("PLAYER SLOT %d, INDEX %d\n", clients[i].slot, clients[i].character); gPlayers[playerIndex].nControlFlags = PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE; // Requires server replication to move. @@ -37,9 +42,19 @@ void assign_player_control_types(void) { // gNetwork.localPlayer = &gPlayers[i]; } +void network_character_vote(uint32_t course) { + send_int_packet(gNetwork.tcpSocket, PACKET_SET_CHARACTER, course, sizeof(uint32_t)); +} + +void network_cup_vote(uint32_t course) { + send_int_packet(gNetwork.tcpSocket, PACKET_COURSE_VOTE, course, sizeof(uint32_t)); +} + + void set_course(const char* data) { if (data != NULL) { - gCurrentCourseId = 8; //*(s16 *) data; + gCupSelection = data[0]; + gCurrentCourseId = gCupCourseOrder[gCupSelection][CUP_COURSE_ONE]; } } @@ -106,12 +121,12 @@ void networking_start_session(const char* data) { gGotoMode = RACING; // Enter race state gGamestateNext = RACING; gCCSelection = CC_150; - gCupSelection = FLOWER_CUP; - gCupCourseSelection = CUP_COURSE_FOUR; + //gCupSelection = FLOWER_CUP; + gCupCourseSelection = CUP_COURSE_ONE; gScreenModeSelection = SCREEN_MODE_1P; gModeSelection = GRAND_PRIX; gPlayerCount = 1; - gCurrentCourseId = 8; + //gCurrentCourseId = 8; gDebugMenuSelection = DEBUG_MENU_EXITED; func_8009E1C0(); func_800CA330(0x19); @@ -150,64 +165,55 @@ void spawn_network_players(f32* arg0, f32* arg1, f32 arg2) { u32 pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; printf("----- Spawn Players ------\n"); - // for (size_t i = 0; i < NETWORK_MAX_PLAYERS; i++) { - // s32 playerIndex = clients[i].slot; - // printf("Spawned %s, in slot %d as char %d with flags 0x%X", clients[i].username, clients[i].slot, - // gPlayers[playerIndex].nCharacter, gPlayers[playerIndex].nControlFlags); + //for (size_t i = 0; i < NETWORK_MAX_PLAYERS; i++) { + //s32 playerIndex = clients[i].slot; + //printf("Spawned %s, in slot %d as char %d with flags 0x%X", clients[i].username, clients[i].slot, gPlayers[playerIndex].nCharacter, gPlayers[playerIndex].nControlFlags); - // if (gPlayers[playerIndex].nCharacter == -1) { - // printf("\n\nCORRUPT PLAYER DATA\n\n"); - // } else { - // printf(" X: %d, Z: %d\n", arg0[D_80165270[posX[playerIndex]]], arg1[D_80165270[posZ[playerIndex]]] + 250.0f) ; - // spawn_player(&gPlayers[clients[i].slot], clients[i].slot, arg0[D_80165270[posX[clients[i].slot]]], - // arg1[D_80165270[posZ[clients[i].slot]]] + 250.0f, arg2, 32768.0f, clients[i].character, - // gPlayers[playerIndex].nControlFlags); - // } - // This index isn't right like this ^ + + //if (gPlayers[playerIndex].nCharacter == -1) { + // printf("\n\nCORRUPT PLAYER DATA\n\n"); + //} else { + //printf(" X: %d, Z: %d\n", arg0[D_80165270[posX[playerIndex]]], arg1[D_80165270[posZ[playerIndex]]] + 250.0f) ; + //spawn_player(&gPlayers[clients[i].slot], clients[i].slot, arg0[D_80165270[posX[clients[i].slot]]], arg1[D_80165270[posZ[clients[i].slot]]] + 250.0f, arg2, 32768.0f, clients[i].character, gPlayers[playerIndex].nControlFlags); + //} + // This index isn't right like this ^ - // if localClient.Slots + //if localClient.Slots - spawn_player(&gPlayers[clients[0].slot], clients[0].slot, arg0[D_80165270[0]], arg1[D_80165270[0]] + 250.0f, arg2, - 32768.0f, clients[0].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_HUMAN); - spawn_player(&gPlayers[clients[1].slot], clients[1].slot, arg0[D_80165270[1]], arg1[D_80165270[1]] + 250.0f, arg2, - 32768.0f, clients[1].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[2].slot], clients[2].slot, arg0[D_80165270[3]], arg1[D_80165270[2]] + 250.0f, arg2, - 32768.0f, clients[2].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[3].slot], clients[3].slot, arg0[D_80165270[2]], arg1[D_80165270[3]] + 250.0f, arg2, - 32768.0f, clients[3].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[4].slot], clients[4].slot, arg0[D_80165270[5]], arg1[D_80165270[4]] + 250.0f, arg2, - 32768.0f, clients[4].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[5].slot], clients[5].slot, arg0[D_80165270[4]], arg1[D_80165270[5]] + 250.0f, arg2, - 32768.0f, clients[5].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[6].slot], clients[6].slot, arg0[D_80165270[7]], arg1[D_80165270[6]] + 250.0f, arg2, - 32768.0f, clients[6].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - spawn_player(&gPlayers[clients[7].slot], clients[7].slot, arg0[D_80165270[6]], arg1[D_80165270[7]] + 250.0f, arg2, - 32768.0f, clients[7].character, - PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + for (size_t i = 0; i < 8; i++) { + printf("a %d, %d\n", clients[i].slot, clients[i].character); + } + + for (size_t i = 0; i < NETWORK_MAX_PLAYERS; i++) { + if (clients[i].hasAuthority) { + spawn_player(&gPlayers[0], i, arg0[clients[i].slot], arg1[clients[i].slot] + 250.0f, arg2, 32768.0f, clients[i].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_HUMAN); + } + } + + for (size_t i = 0; i < NETWORK_MAX_PLAYERS - 1; i++) { + if (!clients[i].hasAuthority) { + spawn_player(&gPlayers[clients[i].slot], i, arg0[clients[i].slot], arg1[clients[i].slot] + 250.0f, arg2, 32768.0f, clients[i].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + } + } + + // spawn_player(&gPlayers[clients[0].slot], 0, arg0[clients[0].slot], arg1[clients[0].slot] + 250.0f, arg2, 32768.0f, clients[0].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_HUMAN); + // spawn_player(&gPlayers[clients[1].slot], 1, arg0[clients[1].slot], arg1[clients[1].slot] + 250.0f, arg2, 32768.0f, clients[1].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[2].slot], 2, arg0[clients[2].slot], arg1[clients[2].slot] + 250.0f, arg2, 32768.0f, clients[2].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[3].slot], 3, arg0[clients[3].slot], arg1[clients[3].slot] + 250.0f, arg2, 32768.0f, clients[3].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[4].slot], 4, arg0[clients[4].slot], arg1[clients[4].slot] + 250.0f, arg2, 32768.0f, clients[4].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[5].slot], 5, arg0[clients[5].slot], arg1[clients[5].slot] + 250.0f, arg2, 32768.0f, clients[5].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[6].slot], 6, arg0[clients[6].slot], arg1[clients[6].slot] + 250.0f, arg2, 32768.0f, clients[6].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[7].slot], 7, arg0[clients[7].slot], arg1[clients[7].slot] + 250.0f, arg2, 32768.0f, clients[7].character, PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); //} printf("--------------------------\n"); // gPlayers[i].nControlFlags - // spawn_player(&gPlayers[clients[0].slot], clients[0].slot, arg0[D_80165270[0]], arg1[D_80165270[0]] + 250.0f, - // arg2, 32768.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_HUMAN); - // spawn_player(&gPlayers[clients[1].slot], clients[1].slot, arg0[D_80165270[1]], arg1[D_80165270[1]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[0], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[2].slot], clients[2].slot, arg0[D_80165270[3]], arg1[D_80165270[2]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[1], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[3].slot], clients[3].slot, arg0[D_80165270[2]], arg1[D_80165270[3]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[2], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[4].slot], clients[4].slot, arg0[D_80165270[5]], arg1[D_80165270[4]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[3], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[5].slot], clients[5].slot, arg0[D_80165270[4]], arg1[D_80165270[5]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[4], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[6].slot], clients[6].slot, arg0[D_80165270[7]], arg1[D_80165270[6]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[5], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); - // spawn_player(&gPlayers[clients[7].slot], clients[7].slot, arg0[D_80165270[6]], arg1[D_80165270[7]] + 250.0f, - // arg2, 32768.0f, chooseKartAIPlayers[6], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[0].slot], clients[0].slot, arg0[D_80165270[0]], arg1[D_80165270[0]] + 250.0f, arg2, 32768.0f, gCharacterSelections[0], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_HUMAN); + // spawn_player(&gPlayers[clients[1].slot], clients[1].slot, arg0[D_80165270[1]], arg1[D_80165270[1]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[0], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[2].slot], clients[2].slot, arg0[D_80165270[3]], arg1[D_80165270[2]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[1], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[3].slot], clients[3].slot, arg0[D_80165270[2]], arg1[D_80165270[3]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[2], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[4].slot], clients[4].slot, arg0[D_80165270[5]], arg1[D_80165270[4]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[3], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[5].slot], clients[5].slot, arg0[D_80165270[4]], arg1[D_80165270[5]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[4], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[6].slot], clients[6].slot, arg0[D_80165270[7]], arg1[D_80165270[6]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[5], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); + // spawn_player(&gPlayers[clients[7].slot], clients[7].slot, arg0[D_80165270[6]], arg1[D_80165270[7]] + 250.0f, arg2, 32768.0f, chooseKartAIPlayers[6], PLAYER_EXISTS | PLAYER_STAGING | PLAYER_START_SEQUENCE | PLAYER_KART_AI); } diff --git a/src/port/ui/MultiplayerWindow.cpp b/src/port/ui/MultiplayerWindow.cpp new file mode 100644 index 000000000..70ec541f7 --- /dev/null +++ b/src/port/ui/MultiplayerWindow.cpp @@ -0,0 +1,155 @@ +#include "MultiplayerWindow.h" +#include "UIWidgets.h" +#include "libultraship/src/Context.h" + +#include +#include +#include "spdlog/spdlog.h" +#include +#include + +extern "C" { +#include "../../../src/main.h" +#include "networking/networking.h" +#include "actor_types.h" +#include "code_800029B0.h" +struct Actor gActorList[]; +extern char *gCourseNames[]; +extern char *gCupNames[]; +extern char* D_800E76A8[]; +extern Network gNetwork; +extern Camera cameras[]; +extern UnkStruct_800DC5EC *D_800DC5EC; +} + +namespace Multiplayer { +MultiplayerWindow::~MultiplayerWindow() { + SPDLOG_TRACE("destruct multiplayer window"); +} + +void MultiplayerWindow::InitElement() { +} + +static s32 sConnectedBool = false; +static s32 sReadyUpBool = false; +static s32 sCharacter = 0; +static s32 sCup = 0; + +void MultiplayerWindow::DrawElement() { + const float framerate = ImGui::GetIO().Framerate; + const float deltatime = ImGui::GetIO().DeltaTime; + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + + if (!gNetwork.isConnected) { + + static char username[NETWORK_USERNAME_LENGTH] = "TestUser"; + + ImGui::Text("Username:"); + ImGui::InputText("##edit", username, IM_ARRAYSIZE(username)); + + static char address[32] = "127.0.0.1:64010"; + static char addressCopy[32]; + strncpy(addressCopy, address, sizeof(addressCopy)); + addressCopy[sizeof(addressCopy) - 1] = '\0'; // Ensure null termination + + ImGui::Text("Host:"); + ImGui::InputText("##edit3", addressCopy, IM_ARRAYSIZE(addressCopy)); + + if (ImGui::Button("Connect!")) { + char* ip = NULL; + uint16_t port = 0; + + char* token = strtok(addressCopy, ":"); + ip = token; + + token = strtok(NULL, ":"); + if (token != NULL) { + port = (uint16_t)atoi(token); + } + + gNetwork.enabled = true; + ConnectToServer(ip, port, username); + } + + } else { + + ImGui::Spacing(); + ImGui::Text("Select Character:"); + ImGui::Spacing(); + + for (size_t i = 0; i < NUM_PLAYERS; i++) { + if (D_800E76A8[i] == NULL || D_800E76A8[i] == "ーーーー") { + break; + } + ImGui::SameLine(); + if (ImGui::Button(D_800E76A8[i])) { + network_character_vote(i); + sCharacter = i; + } + } + ImGui::Spacing(); + ImGui::Text("-- %s --", D_800E76A8[sCharacter]); + + ImGui::Spacing(); + ImGui::Spacing(); + ImGui::Text("Course Vote:"); + + for (size_t i = 0; i < NUM_CUPS - 1; i++) { + if (ImGui::Button(gCupNames[i])) { + network_cup_vote(i); + sCup = i; + } + ImGui::SameLine(); + } + ImGui::Spacing(); + ImGui::Text("-- %s --", gCupNames[sCup]); + + + if (ImGui::Button("test", ImVec2(-1, 0))) { + // Add disconnect logic here + cameras[0].playerId = 2; + D_800DC5EC->player = &gPlayers[2]; + } + + for (size_t i = 0; i < NETWORK_MAX_PLAYERS; i++) { + ImGui::Text("Slot %d: char: %d, hasAuthority: %d", clients[i].slot, clients[i].character, gPlayers[i].nHasAuthority); + } + + + /* Stick UI to the bottom of the panel */ + + float windowHeight = ImGui::GetWindowHeight(); + + // Move the cursor to a position relative to the bottom of the window + ImGui::SetCursorPosY(windowHeight - ImGui::GetFrameHeightWithSpacing() * 2); // Adjust Y position for two buttons + + char buttonLabel[32]; + + if (sReadyUpBool) { + strcpy(buttonLabel, "Lets Go!"); + } else { + strcpy(buttonLabel, "Ready Up!"); + } + + // First button (Ready Up / Let's Go) + if (ImGui::Button(buttonLabel, ImVec2(-1, 0))) { + sReadyUpBool = !sReadyUpBool; + networking_ready_up(sReadyUpBool); + } + + // Add some vertical spacing between the buttons + ImGui::Spacing(); + + // Second button (Disconnect) + if (ImGui::Button("Disconnect", ImVec2(-1, 0))) { + // Add disconnect logic here + networking_disconnect(); + } + } + + ImGui::PopStyleColor(); +} + +void MultiplayerWindow::UpdateElement() { +} +} // namespace GameInfo diff --git a/src/port/ui/MultiplayerWindow.h b/src/port/ui/MultiplayerWindow.h new file mode 100644 index 000000000..c7c6553c8 --- /dev/null +++ b/src/port/ui/MultiplayerWindow.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace Multiplayer { +class MultiplayerWindow : public Ship::GuiWindow { + public: + using Ship::GuiWindow::GuiWindow; + ~MultiplayerWindow(); + + private: + void InitElement() override; + void DrawElement() override; + void UpdateElement() override; +}; +} // namespace GameInfo diff --git a/src/render_player.c b/src/render_player.c index 7e8e868b3..17d04c016 100644 --- a/src/render_player.c +++ b/src/render_player.c @@ -1706,7 +1706,7 @@ void render_kart(Player* player, s8 playerId, s8 arg2, s8 arg3) { // Render karts u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1784,7 +1784,7 @@ void render_ghost(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1829,7 +1829,7 @@ void func_80025DE8(Player* player, s8 playerId, s8 screenId, s8 arg3) { gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0); @@ -1874,7 +1874,7 @@ void render_player_ice_reflection(Player* player, s8 playerId, s8 screenId, s8 a gSPDisplayList(gDisplayListHead++, common_square_plain_render); u8* test = (u8*) LOAD_ASSET(sKartUpperTexture); - gDPLoadTextureBlock(gDisplayListHead++, test + 0x7C0, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, + gDPLoadTextureBlock(gDisplayListHead++, test + 0x800, G_IM_FMT_CI, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); gSPVertex(gDisplayListHead++, &D_800DDBB4[playerId][arg3 + 4], 4, 0);