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
This commit is contained in:
MegaMech
2025-12-18 19:03:43 -07:00
committed by GitHub
parent 509a8f4259
commit 7d64601d85
4 changed files with 85 additions and 28 deletions
+2 -2
View File
@@ -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);
+23
View File
@@ -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
+16
View File
@@ -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
+44 -26
View File
@@ -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);