summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMegaMech <MegaMech@users.noreply.github.com>2025-12-18 19:03:43 -0700
committerGitHub <noreply@github.com>2025-12-18 19:03:43 -0700
commit7d64601d85f4b3cf19baf6504dea0476725f184f (patch)
treee83da783c8ba11dbce2e6f28327fee3aa04120dd /src
parent509a8f4259e93a4783d8599e0ca1c2556281924a (diff)
Fix Camera nullptr (#599)
* Update spawn_players.c * Update spawn_players.c * Update code_80280000.c * Update Game.cpp * Add CM_ThrowRuntimeError function declaration * Update spawn_players.c * Modify CM_ThrowRuntimeError for improved error handling Increased the buffer size for error messages and added a crash description. * Update Game.cpp * Update Game.cpp * Update Game.h * Update Game.h * Update Game.h
Diffstat (limited to 'src')
-rw-r--r--src/ending/code_80280000.c4
-rw-r--r--src/port/Game.cpp23
-rw-r--r--src/port/Game.h16
-rw-r--r--src/spawn_players.c70
4 files changed, 85 insertions, 28 deletions
diff --git a/src/ending/code_80280000.c b/src/ending/code_80280000.c
index 815f1b229..467bf62bd 100644
--- a/src/ending/code_80280000.c
+++ b/src/ending/code_80280000.c
@@ -137,8 +137,8 @@ void load_credits(void) {
CM_CleanCameras();
Vec3f spawn = {0.0f, 0.0f, 0.0f};
Camera* camera = CM_AddCamera(spawn, 0, 0);
- if (NULL == camera) {
- return;
+ if (!camera) {
+ CM_ThrowRuntimeError("[code_80280000] [load_credits] NULL camera while attempting to create camera for player one");
}
CM_AttachCamera(camera, PLAYER_ONE);
diff --git a/src/port/Game.cpp b/src/port/Game.cpp
index 8f50da220..4242815c1 100644
--- a/src/port/Game.cpp
+++ b/src/port/Game.cpp
@@ -906,6 +906,29 @@ void push_frame() {
// Graphics_ThreadUpdate();w
}
+void CM_ThrowRuntimeError(const char* fmt, ...) {
+ char error_mesg[2048];
+
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(error_mesg, sizeof(error_mesg), fmt, args);
+ va_end(args);
+
+ const char* crash_desc = "\nSpaghettiKart has crashed! Please upload the logs to the support channel in Discord.";
+ strncat(error_mesg, crash_desc, sizeof(error_mesg) - strlen(error_mesg) - 1);
+
+ SPDLOG_ERROR(error_mesg);
+
+ SDL_ShowSimpleMessageBox(
+ SDL_MESSAGEBOX_ERROR,
+ "You dropped your plate of Spaghetti!",
+ error_mesg,
+ NULL
+ );
+
+ exit(EXIT_FAILURE);
+}
+
#ifdef _WIN32
int SDL_main(int argc, char** argv) {
#else
diff --git a/src/port/Game.h b/src/port/Game.h
index dbf2a7cea..2fcda177d 100644
--- a/src/port/Game.h
+++ b/src/port/Game.h
@@ -228,6 +228,22 @@ void* GetCup();
void CM_RunGarbageCollector(void);
void CM_ResetAudio(void);
+// Add print formatting check attribute
+#if defined(__GNUC__) || defined(__clang__)
+__attribute__((format(printf, 1, 2)))
+#endif
+
+// Add noreturn attribute
+#if defined(_MSC_VER)
+ __declspec(noreturn)
+#elif defined(__APPLE__)
+#elif defined(__cplusplus) || (__STDC_VERSION__ >= 202311)
+ [[noreturn]]
+#elif defined(__GNUC__)
+ __attribute__((noreturn))
+#endif
+void CM_ThrowRuntimeError(const char* fmt, ...);
+
// NOLINTEND(readability-identifier-naming)
#ifdef __cplusplus
diff --git a/src/spawn_players.c b/src/spawn_players.c
index fd4ef174b..a5e5d739f 100644
--- a/src/spawn_players.c
+++ b/src/spawn_players.c
@@ -1241,8 +1241,10 @@ void spawn_players_and_cameras(void) {
// Add freecam, tourcam, and lookbehind cameras
Vec3f spawn = {player->pos[0], player->pos[1], player->pos[2]};
-
camera = CM_AddFreeCamera(spawn, player->rotation[1], 1);
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_players_and_cameras] NULL camera while attempting to create FreeCamera for player one");
+ }
gScreenContexts[PLAYER_ONE].freeCamera = camera;
if (CVarGetInteger("gFreecam", false) == true) {
@@ -1252,18 +1254,20 @@ void spawn_players_and_cameras(void) {
if ((CM_IsTourEnabled() == true) && (gModeSelection == GRAND_PRIX) && (Editor_IsPaused() == false)) {
camera = CM_AddTourCamera(spawn, player->rotation[1], 1);
- if (NULL != camera) {
- CM_AttachCamera(camera, PLAYER_ONE);
- gScreenContexts[PLAYER_ONE].camera = camera;
- gScreenContexts[PLAYER_ONE].pendingCamera = NULL;
- CM_CameraSetActive(0, false);
- CM_ActivateTourCamera(camera);
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_players_and_cameras] NULL camera while attempting to create TourCamera for player one");
}
+ CM_AttachCamera(camera, PLAYER_ONE);
+ gScreenContexts[PLAYER_ONE].camera = camera;
+ gScreenContexts[PLAYER_ONE].pendingCamera = NULL;
+ CM_CameraSetActive(0, false);
+ CM_ActivateTourCamera(camera);
}
}
void spawn_single_player_camera(u32 mode) {
Vec3f spawn = {gPlayerOne->pos[0], gPlayerOne->pos[1], gPlayerOne->pos[2]};
+ Vec3f spawn2 = {gPlayerTwo->pos[0], gPlayerTwo->pos[1], gPlayerTwo->pos[2]};
// Technically there should be a default case of mode 10 here. Except it never gets used.
if (gModeSelection == GRAND_PRIX && !gDemoMode) {
@@ -1278,17 +1282,28 @@ void spawn_single_player_camera(u32 mode) {
}
Camera* camera = CM_AddCamera(spawn, gPlayerOne->rotation[1], mode);
- if (camera) {
- CM_AttachCamera(camera, PLAYER_ONE);
- gScreenContexts[PLAYER_ONE].camera = camera;
- gScreenContexts[PLAYER_ONE].raceCamera = camera;
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_single_player_camera] NULL camera while attempting to create camera for player one");
}
+ CM_AttachCamera(camera, PLAYER_ONE);
+ gScreenContexts[PLAYER_ONE].camera = camera;
+ gScreenContexts[PLAYER_ONE].raceCamera = camera;
+
+ // For end of race scene
+ camera = CM_AddCamera(spawn2, gPlayerTwo->rotation[1], mode);
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_single_player_camera] NULL camera while attempting to create camera for player two");
+ }
+ CM_AttachCamera(camera, PLAYER_TWO);
+ gScreenContexts[PLAYER_TWO].camera = camera;
+ gScreenContexts[PLAYER_TWO].raceCamera = camera;
camera = CM_AddLookBehindCamera(spawn, gPlayerOne->rotation[1], mode);
- if (camera) {
- CM_AttachCamera(camera, PLAYER_ONE);
- gScreenContexts[PLAYER_ONE].lookBehindCamera = camera;
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_single_player_camera] NULL camera while attempting to create LookBehind camera for player one");
}
+ CM_AttachCamera(camera, PLAYER_ONE);
+ gScreenContexts[PLAYER_ONE].lookBehindCamera = camera;
}
void spawn_multiplayer_cameras(u32 mode) {
@@ -1309,21 +1324,22 @@ void spawn_multiplayer_cameras(u32 mode) {
for (size_t i = 0; i < screens; i++) {
Vec3f spawn = {gPlayers[i].pos[0], gPlayers[i].pos[1], gPlayers[i].pos[2]};
camera = CM_AddCamera(spawn, gPlayers[i].rotation[1], mode);
- if (camera) {
- CM_AttachCamera(camera, i);
- gScreenContexts[i].camera = camera;
- gScreenContexts[i].raceCamera = camera;
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_multiplayer_cameras] NULL camera while attempting to create camera for player %d", i);
}
-
+ CM_AttachCamera(camera, i);
+ gScreenContexts[i].camera = camera;
+ gScreenContexts[i].raceCamera = camera;
}
for (size_t i = 0; i < screens; i++) {
Vec3f spawn = {gPlayers[i].pos[0], gPlayers[i].pos[1], gPlayers[i].pos[2]};
camera = CM_AddLookBehindCamera(spawn, gPlayers[i].rotation[1], mode);
- if (camera) {
- CM_AttachCamera(camera, i);
- gScreenContexts[i].lookBehindCamera = camera;
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [spawn_multiplayer_cameras] NULL camera while attempting to create LookBehind camera for player %d", i);
}
+ CM_AttachCamera(camera, i);
+ gScreenContexts[i].lookBehindCamera = camera;
}
}
@@ -1362,13 +1378,15 @@ void func_8003DB5C(void) {
Vec3f spawn = {player->pos[0], player->pos[1], player->pos[2]};
camera = CM_AddCamera(spawn, player->rotation[1], 3);
- if (camera) {
- CM_AttachCamera(camera, PLAYER_ONE);
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [func_8003DB5C] NULL camera while attempting to create camera for player one");
}
+ CM_AttachCamera(camera, PLAYER_ONE);
camera = CM_AddCamera(spawn, player->rotation[1], 3);
- if (camera) {
- CM_AttachCamera(camera, PLAYER_ONE);
+ if (!camera) {
+ CM_ThrowRuntimeError("[spawn_players] [func_8003DB5C] NULL camera while attempting to create camera for player two");
}
+ CM_AttachCamera(camera, PLAYER_TWO);
for (playerId = 0; playerId < NUM_PLAYERS; playerId++, player++) {
load_kart_palette(player, playerId, 1, 0);