cleanup and bug fixes
This commit is contained in:
parent
5f81a88edd
commit
f07b74c3d2
3
Makefile
3
Makefile
|
@ -868,8 +868,9 @@ else
|
|||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm $(BACKEND_LDFLAGS) -no-pie -lpthread
|
||||
endif
|
||||
|
||||
# used by crash handler and loading screen on linux
|
||||
ifeq ($(WINDOWS_BUILD),0)
|
||||
LDFLAGS += -rdynamic
|
||||
LDFLAGS += -rdynamic -ldl -pthread
|
||||
endif
|
||||
|
||||
# icon
|
||||
|
|
|
@ -581,7 +581,7 @@ const BehaviorScript* get_behavior_from_id(enum BehaviorId id) {
|
|||
|
||||
const char* get_behavior_name_from_id(enum BehaviorId id) {
|
||||
if (id < 0 || id >= id_bhv_max_count) {
|
||||
return NULL;
|
||||
return smlua_get_name_from_hooked_behavior_id(id);
|
||||
}
|
||||
|
||||
return gBehaviorTable[id].name;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "src/pc/loading.h"
|
||||
|
||||
void DynOS_Gfx_GeneratePacks(const char* directory) {
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In Path:\n\\#808080\\%s", directory)); }
|
||||
snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In Path:\n\\#808080\\%s", directory);
|
||||
|
||||
DIR *modsDir = opendir(directory);
|
||||
if (!modsDir) { return; }
|
||||
|
@ -40,7 +40,7 @@ void DynOS_Gfx_GeneratePacks(const char* directory) {
|
|||
DynOS_Tex_GeneratePack(_TexturePackFolder, _TexturePackOutputFolder, true);
|
||||
}
|
||||
|
||||
if (gIsThreaded) REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / (f32) pathCount);
|
||||
REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / (f32) pathCount);
|
||||
}
|
||||
|
||||
closedir(modsDir);
|
||||
|
|
|
@ -588,6 +588,8 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
play_music(SEQ_PLAYER_SFX, SEQUENCE_ARGS(0, SEQ_SOUND_PLAYER), 0);
|
||||
set_sound_mode(save_file_get_sound_mode());
|
||||
|
||||
thread6_rumble_loop(NULL);
|
||||
|
||||
gGlobalTimer++;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "pc/lua/smlua_hooks.h"
|
||||
#include "game/camera.h"
|
||||
#include "level_info.h"
|
||||
#include "pc/lua/utils/smlua_text_utils.h"
|
||||
#include "pc/lua/utils/smlua_math_utils.h"
|
||||
|
||||
u16 gDialogColorFadeTimer;
|
||||
s8 gLastDialogLineNum;
|
||||
|
@ -2513,8 +2515,9 @@ void render_pause_my_score_coins(void) {
|
|||
|
||||
u8 strCourseNum[4];
|
||||
u8 courseIndex = gCurrCourseNum - 1;
|
||||
u8 starIndex = clamp(gDialogCourseActNum, 1, MAX_ACTS);
|
||||
u8 *courseName = (u8*) get_level_name_sm64(gCurrCourseNum, gCurrLevelNum, gCurrAreaIndex, 1);
|
||||
u8 *actName = (u8*) get_star_name_sm64(gCurrCourseNum, gDialogCourseActNum, 1);
|
||||
u8 *actName = (u8*) get_star_name_sm64(gCurrCourseNum, starIndex, 1);
|
||||
u8 starFlags;
|
||||
|
||||
starFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
|
||||
|
@ -2549,7 +2552,7 @@ void render_pause_my_score_coins(void) {
|
|||
print_generic_string(CRS_NUM_X1, 157, strCourseNum);
|
||||
#endif
|
||||
|
||||
if (starFlags & (1 << (gDialogCourseActNum - 1))) {
|
||||
if (starFlags & (1 << (starIndex - 1))) {
|
||||
print_generic_string(TXT_STAR_X, 140, textStar);
|
||||
} else {
|
||||
print_generic_string(TXT_STAR_X, 140, textUnfilledStar);
|
||||
|
|
|
@ -956,11 +956,8 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O
|
|||
}
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < MAX_PLAYERS; i++) {
|
||||
struct MarioState* marioState = &gMarioStates[i];
|
||||
if (!is_player_active(marioState)) { continue; }
|
||||
if (marioState->marioObj == NULL) { continue; }
|
||||
spawn_object(marioState->marioObj, MODEL_NONE, bhvStarKeyCollectionPuffSpawner);
|
||||
if (m->marioObj != NULL) {
|
||||
spawn_object(m->marioObj, MODEL_NONE, bhvStarKeyCollectionPuffSpawner);
|
||||
}
|
||||
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
|
|
|
@ -60,6 +60,7 @@ s16 gChangeLevel = -1;
|
|||
s16 gChangeLevelTransition = -1;
|
||||
s16 gChangeActNum = -1;
|
||||
|
||||
static bool sCancelNextActSelector = true; // Cancel the act selector after the main menu
|
||||
static bool sFirstCastleGroundsMenu = true;
|
||||
bool gIsDemoActive = false;
|
||||
bool gInPlayerMenu = false;
|
||||
|
@ -1637,6 +1638,7 @@ s32 update_level(void) {
|
|||
if (gDjuiInMainMenu) {
|
||||
update_menu_level();
|
||||
}
|
||||
sCancelNextActSelector = gDjuiInMainMenu;
|
||||
|
||||
if (gFanFareDebounce > 0) { gFanFareDebounce--; }
|
||||
|
||||
|
@ -1917,6 +1919,11 @@ s32 lvl_set_current_level(UNUSED s16 arg0, s32 levelNum) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (sCancelNextActSelector) {
|
||||
sCancelNextActSelector = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -287,10 +287,7 @@ void bhv_mario_update(void) {
|
|||
|
||||
smlua_call_event_hooks_mario_param(HOOK_BEFORE_MARIO_UPDATE, gMarioState);
|
||||
|
||||
u32 particleFlags = 0;
|
||||
s32 i;
|
||||
|
||||
particleFlags = execute_mario_action(gCurrentObject);
|
||||
u32 particleFlags = execute_mario_action(gCurrentObject);
|
||||
smlua_call_event_hooks_mario_param(HOOK_MARIO_UPDATE, gMarioState);
|
||||
particleFlags |= gMarioState->particleFlags;
|
||||
gCurrentObject->oMarioParticleFlags = particleFlags;
|
||||
|
@ -320,14 +317,10 @@ void bhv_mario_update(void) {
|
|||
// to sync it with the Mario object
|
||||
copy_mario_state_to_object(gMarioState);
|
||||
|
||||
i = 0;
|
||||
while (sParticleTypes[i].particleFlag != 0) {
|
||||
for (s32 i = 0; sParticleTypes[i].particleFlag != 0; i++) {
|
||||
if (particleFlags & sParticleTypes[i].particleFlag) {
|
||||
spawn_particle(sParticleTypes[i].activeParticleFlag, sParticleTypes[i].model,
|
||||
sParticleTypes[i].behavior);
|
||||
spawn_particle(sParticleTypes[i].activeParticleFlag, sParticleTypes[i].model, sParticleTypes[i].behavior);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
update_character_anim_offset(gMarioState);
|
||||
|
|
|
@ -469,6 +469,9 @@ s32 lvl_update_obj_and_load_act_button_actions(UNUSED s32 arg, UNUSED s32 unused
|
|||
sReceivedLoadedActNum = 0;
|
||||
}
|
||||
|
||||
// Cancel the act selector while on the main menu
|
||||
if (gDjuiInMainMenu) { return 1; }
|
||||
|
||||
area_update_objects();
|
||||
sActSelectorMenuTimer++;
|
||||
return sLoadedActNum;
|
||||
|
|
|
@ -42,6 +42,8 @@ static CrashHandlerText sCrashHandlerText[128 + 256 + 4];
|
|||
#define MEMNEW(typ, cnt) calloc(sizeof(typ), cnt)
|
||||
#define STRING(str, size, fmt, ...) char str[size]; snprintf(str, size, fmt, __VA_ARGS__);
|
||||
|
||||
#define BACK_TRACE_SIZE 15
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define OS_NAME "Windows"
|
||||
|
@ -207,6 +209,7 @@ static void crash_handler_produce_one_frame(void) {
|
|||
gfx_start_frame();
|
||||
config_gfx_pool();
|
||||
init_render_image();
|
||||
create_dl_ortho_matrix();
|
||||
|
||||
float minAspectRatio = 1.743468f;
|
||||
float aspectScale = 1.0f;
|
||||
|
@ -306,7 +309,7 @@ static void crash_handler_add_info_int(CrashHandlerText** pTextP, f32 x, f32 y,
|
|||
#ifdef _WIN32
|
||||
static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||
#elif __linux__
|
||||
static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *context) {
|
||||
static void crash_handler(const int signalNum, siginfo_t *info, UNUSED ucontext_t *context) {
|
||||
#endif
|
||||
printf("Game crashed! preparing crash screen...\n");
|
||||
memset(sCrashHandlerText, 0, sizeof(sCrashHandlerText));
|
||||
|
@ -352,8 +355,10 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
char segFaultStr[255] = "";
|
||||
if (info->si_code == SEGV_MAPERR) {
|
||||
snprintf(segFaultStr, 255, "The game tried to read unmapped memory at address %p", info->si_addr);
|
||||
#ifdef __x86_64__
|
||||
} else if (info->si_code == SEGV_ACCERR) {
|
||||
snprintf(segFaultStr, 255, "The game tried to %s at address %016llX", ((context->uc_mcontext.gregs[REG_ERR] & 0x2) != 0 ? "write" : "read"), (u64) info->si_addr);
|
||||
#endif
|
||||
} else {
|
||||
snprintf(segFaultStr, 255, "Unknown segmentation fault at address %p", info->si_addr);
|
||||
}
|
||||
|
@ -373,6 +378,7 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
|
||||
// Registers
|
||||
crash_handler_set_text(8, 22, 0xFF, 0xFF, 0xFF, "%s", "Registers:");
|
||||
#if defined(_WIN32) || (defined(__linux__) && defined(__x86_64__))
|
||||
#ifdef _WIN32
|
||||
if (ExceptionInfo && ExceptionInfo->ContextRecord) {
|
||||
PCONTEXT cr = ExceptionInfo->ContextRecord;
|
||||
|
@ -456,6 +462,9 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
} else {
|
||||
crash_handler_set_text(8, 30, 0x80, 0x80, 0x80, "%s", "Unable to access the registers.");
|
||||
}
|
||||
#else
|
||||
crash_handler_set_text(8, 30, 0x80, 0x80, 0x80, "%s", "Cannot access the registers on this system.");
|
||||
#endif
|
||||
|
||||
// Stack trace
|
||||
crash_handler_set_text(8, 72, 0xFF, 0xFF, 0xFF, "%s", "Stack trace:");
|
||||
|
@ -542,7 +551,7 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
#else
|
||||
s32 frames = CaptureStackWalkBackTrace(ExceptionInfo->ContextRecord, 0, 64, stack);
|
||||
#endif
|
||||
for (s32 i = 1, j = 0; i < frames && j < 15; ++i) {
|
||||
for (s32 i = 1, j = 0; i < frames && j < BACK_TRACE_SIZE; ++i) {
|
||||
s32 y = 80 + j++ * 8;
|
||||
crash_handler_set_text( 8, y, 0xFF, 0xFF, 0x00, "0x%016llX", (PTR) stack[i]);
|
||||
crash_handler_set_text(-1, y, 0xFF, 0xFF, 0xFF, "%s", ": ");
|
||||
|
@ -563,13 +572,12 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
}
|
||||
}
|
||||
#elif __linux__
|
||||
void *trace[15];
|
||||
int traceSize = backtrace(trace, 15);
|
||||
|
||||
void *trace[BACK_TRACE_SIZE];
|
||||
u8 traceSize = backtrace(trace, BACK_TRACE_SIZE);
|
||||
if (traceSize > 0) {
|
||||
// Unwind and print call stack
|
||||
char **messages = backtrace_symbols(trace, traceSize);
|
||||
for (s32 i = 1, j = 0; i < traceSize && j < 15; ++i) {
|
||||
for (s32 i = 1, j = 0; i < traceSize && j < BACK_TRACE_SIZE; ++i) {
|
||||
s32 y = 80 + j++ * 8;
|
||||
crash_handler_set_text( 8, y, 0xFF, 0xFF, 0x00, "0x%016llX", (u64) strtoul(strstr(messages[i], "[") + 1, NULL, 16));
|
||||
crash_handler_set_text(-1, y, 0xFF, 0xFF, 0xFF, "%s", ": ");
|
||||
|
@ -595,9 +603,11 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
crash_handler_add_info_int(&pText, 315, -4 + (8 * 3), "Players", network_player_connected_count());
|
||||
|
||||
s32 syncObjects = 0;
|
||||
if (gGameInited) {
|
||||
for (struct SyncObject* so = sync_object_get_first(); so != NULL; so = sync_object_get_next()) {
|
||||
if (so->o != NULL) { syncObjects++; }
|
||||
}
|
||||
}
|
||||
crash_handler_add_info_int(&pText, 315, -4 + (8 * 4), "SyncObj", syncObjects);
|
||||
|
||||
crash_handler_add_info_int(&pText, 380, -4 + (8 * 0), "Id", (int)gPcDebug.id & 0xFF);
|
||||
|
@ -664,10 +674,9 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
|||
}
|
||||
#endif
|
||||
|
||||
// Incase it crashed before the game window opened
|
||||
// In case the game crashed before the game window opened
|
||||
if (!gGfxInited) gfx_init(&WAPI, &RAPI, TITLE);
|
||||
djui_init();
|
||||
djui_unicode_init();
|
||||
if (!gGameInited) djui_unicode_init();
|
||||
|
||||
// Main loop
|
||||
while (true) {
|
||||
|
|
|
@ -28,19 +28,28 @@ static bool sDjuiInited = false;
|
|||
|
||||
bool sDjuiRendered60fps = false;
|
||||
|
||||
void reset_djui_text(void);
|
||||
|
||||
void reset_djui(void) {
|
||||
void djui_shutdown(void) {
|
||||
sSavedDisplayListHead = NULL;
|
||||
if (sDjuiPauseOptions) djui_base_destroy(&sDjuiPauseOptions->base);
|
||||
if (sDjuiLuaError) djui_base_destroy(&sDjuiLuaError->base);
|
||||
sDjuiPauseOptions = NULL;
|
||||
sDjuiLuaError = NULL;
|
||||
sDjuiLuaErrorTimeout = 0;
|
||||
if (gDjuiRoot) djui_base_destroy(&gDjuiRoot->base);
|
||||
|
||||
if (gDjuiConsole) djui_base_destroy(&gDjuiConsole->base);
|
||||
if (gDjuiConsole) {
|
||||
djui_base_destroy(&gDjuiConsole->base);
|
||||
free(gDjuiConsole);
|
||||
gDjuiConsole = NULL;
|
||||
}
|
||||
extern u32 sDjuiConsoleMessages;
|
||||
sDjuiConsoleMessages = 0;
|
||||
|
||||
if (gDjuiRoot) {
|
||||
djui_base_destroy(&gDjuiRoot->base);
|
||||
}
|
||||
|
||||
djui_fps_display_destroy();
|
||||
|
||||
sDjuiInited = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,4 +47,4 @@ void djui_lua_error(char* text);
|
|||
void djui_render(void);
|
||||
void djui_reset_hud_params(void);
|
||||
|
||||
void reset_djui(void);
|
||||
void djui_shutdown(void);
|
||||
|
|
|
@ -161,6 +161,7 @@ void djui_console_message_create(const char* message, enum ConsoleMessageLevel l
|
|||
struct DjuiConsole* djui_console_create(void) {
|
||||
if (gDjuiConsole != NULL) {
|
||||
djui_base_destroy(&gDjuiConsole->base);
|
||||
free(gDjuiConsole);
|
||||
gDjuiConsole = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ static void djui_cursor_base_hover_location(struct DjuiBase* base, f32* x, f32*
|
|||
}
|
||||
|
||||
void djui_cursor_input_controlled_center(struct DjuiBase* base) {
|
||||
if (!sCursorMouseControlled) {
|
||||
if (!sCursorMouseControlled && (!base || (base && base->interactable && base->interactable->enabled))) {
|
||||
sInputControlledBase = base;
|
||||
djui_cursor_set_visible(base != NULL);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ static f32 djui_cursor_base_distance(struct DjuiBase* base, f32 xScale, f32 ySca
|
|||
static void djui_cursor_move_check(s8 xDir, s8 yDir, struct DjuiBase** pick, struct DjuiBase* base) {
|
||||
if (!base->visible) { return; }
|
||||
|
||||
if (base->interactable != NULL) {
|
||||
if (base->interactable != NULL && base->interactable->enabled) {
|
||||
f32 x1, y1, x2, y2;
|
||||
x1 = base->elem.x;
|
||||
y1 = base->elem.y;
|
||||
|
|
|
@ -23,10 +23,14 @@ void djui_fps_display_render(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void djui_fps_display_on_destroy(UNUSED struct DjuiBase* base) {
|
||||
free(sFpsDisplay);
|
||||
}
|
||||
|
||||
void djui_fps_display_create(void) {
|
||||
struct DjuiFpsDisplay *fpsDisplay = malloc(sizeof(struct DjuiFpsDisplay));
|
||||
struct DjuiFpsDisplay *fpsDisplay = calloc(1, sizeof(struct DjuiFpsDisplay));
|
||||
struct DjuiBase* base = &fpsDisplay->base;
|
||||
djui_base_init(NULL, base, NULL, NULL);
|
||||
djui_base_init(NULL, base, NULL, djui_fps_display_on_destroy);
|
||||
djui_base_set_size(base, 150, 50);
|
||||
djui_base_set_color(base, 0, 0, 0, 240);
|
||||
djui_base_set_border_color(base, 0, 0, 0, 200);
|
||||
|
@ -46,3 +50,9 @@ void djui_fps_display_create(void) {
|
|||
|
||||
sFpsDisplay = fpsDisplay;
|
||||
}
|
||||
|
||||
void djui_fps_display_destroy(void) {
|
||||
if (sFpsDisplay) {
|
||||
djui_base_destroy(&sFpsDisplay->base);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
void djui_fps_display_update(s16 fps);
|
||||
void djui_fps_display_render(void);
|
||||
void djui_fps_display_create(void);
|
||||
void djui_fps_display_destroy(void);
|
||||
|
|
|
@ -18,7 +18,7 @@ bool djui_panel_is_active(void) {
|
|||
return (sPanelList != NULL);
|
||||
}
|
||||
|
||||
struct DjuiBase* djui_panel_find_first_interactable(struct DjuiBaseChild* child) {
|
||||
static struct DjuiBase* djui_panel_find_first_interactable(struct DjuiBaseChild* child) {
|
||||
while (child) {
|
||||
if (child->base->interactable && child->base->interactable->enabled) {
|
||||
return child->base;
|
||||
|
|
|
@ -48,23 +48,19 @@ static void djui_panel_language_destroy(UNUSED struct DjuiBase* caller) {
|
|||
snprintf(configLanguage, MAX_CONFIG_STRING, "%s", "");
|
||||
}
|
||||
|
||||
if (gPanelLanguageOnStartup) {
|
||||
djui_panel_shutdown();
|
||||
if (gPanelLanguageOnStartup) {
|
||||
gDjuiInMainMenu = true;
|
||||
djui_panel_main_create(NULL);
|
||||
} else if (gDjuiInMainMenu) {
|
||||
djui_panel_shutdown();
|
||||
gDjuiInMainMenu = true;
|
||||
djui_panel_main_create(NULL);
|
||||
djui_panel_options_create(NULL);
|
||||
djui_panel_misc_create(NULL);
|
||||
} else if (gDjuiPanelPauseCreated) {
|
||||
djui_panel_shutdown();
|
||||
djui_panel_pause_create(NULL);
|
||||
djui_panel_options_create(NULL);
|
||||
djui_panel_misc_create(NULL);
|
||||
} else {
|
||||
djui_panel_shutdown();
|
||||
}
|
||||
}
|
||||
if (configLanguage[0] == '\0') {
|
||||
|
|
|
@ -34,7 +34,7 @@ void djui_panel_pause_disconnect_key_update(int scancode) {
|
|||
}
|
||||
|
||||
static void djui_panel_pause_quit(struct DjuiBase* caller) {
|
||||
if (find_object_with_behavior(bhvActSelector) != NULL || gMarioStates[0].action == ACT_PUSHING_DOOR || gMarioStates[0].action == ACT_PULLING_DOOR) { return; }
|
||||
if (gMarioStates[0].action == ACT_PUSHING_DOOR || gMarioStates[0].action == ACT_PULLING_DOOR) { return; }
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
djui_panel_confirm_create(caller,
|
||||
|
|
|
@ -20,7 +20,7 @@ struct LoadingScreen {
|
|||
struct DjuiProgressBar *loadingBar;
|
||||
};
|
||||
|
||||
struct LoadingScreen* sLoading = NULL;
|
||||
static struct LoadingScreen* sLoading = NULL;
|
||||
pthread_t gLoadingThreadId;
|
||||
pthread_mutex_t gLoadingThreadMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -77,7 +77,7 @@ static bool loading_screen_on_render(struct DjuiBase* base) {
|
|||
u32 length = strlen(gCurrLoadingSegment.str);
|
||||
if (length > 0) {
|
||||
if (gCurrLoadingSegment.percentage > 0) {
|
||||
snprintf(buffer, 256, "%s\n\\#c8c8c8\\%d%%", gCurrLoadingSegment.str, (u8)floor(gCurrLoadingSegment.percentage * 100));
|
||||
snprintf(buffer, 256, "%s\n\\#dcdcdc\\%d%%", gCurrLoadingSegment.str, (u8)floor(gCurrLoadingSegment.percentage * 100));
|
||||
} else {
|
||||
snprintf(buffer, 256, "%s...", gCurrLoadingSegment.str);
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ static void loading_screen_destroy(struct DjuiBase* base) {
|
|||
}
|
||||
|
||||
void render_loading_screen(void) {
|
||||
struct LoadingScreen* load = malloc(sizeof(struct LoadingScreen));
|
||||
struct LoadingScreen* load = calloc(1, sizeof(struct LoadingScreen));
|
||||
struct DjuiBase* base = &load->base;
|
||||
|
||||
djui_base_init(NULL, base, loading_screen_on_render, loading_screen_destroy);
|
||||
|
@ -156,13 +156,13 @@ void render_loading_screen(void) {
|
|||
}
|
||||
|
||||
pthread_join(gLoadingThreadId, NULL);
|
||||
gIsThreaded = false;
|
||||
|
||||
// reset some things after rendering the loading screen
|
||||
reset_djui();
|
||||
djui_base_destroy(base);
|
||||
djui_shutdown();
|
||||
alloc_display_list_reset();
|
||||
gDisplayListHead = NULL;
|
||||
djui_init();
|
||||
djui_unicode_init();
|
||||
rendering_init();
|
||||
configWindow.settings_changed = true;
|
||||
}
|
||||
|
|
|
@ -10,16 +10,18 @@ struct LoadingSegment {
|
|||
|
||||
extern struct LoadingSegment gCurrLoadingSegment;
|
||||
|
||||
extern bool gIsThreaded;
|
||||
|
||||
#define REFRESH_MUTEX(...) \
|
||||
if (gIsThreaded) { \
|
||||
pthread_mutex_lock(&gLoadingThreadMutex); \
|
||||
__VA_ARGS__; \
|
||||
pthread_mutex_unlock(&gLoadingThreadMutex); \
|
||||
} \
|
||||
|
||||
extern pthread_t gLoadingThreadId;
|
||||
extern pthread_mutex_t gLoadingThreadMutex;
|
||||
|
||||
extern bool gIsThreaded;
|
||||
|
||||
void render_loading_screen(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1175,6 +1175,7 @@ struct LuaHookedBehavior {
|
|||
u32 originalId;
|
||||
BehaviorScript *behavior;
|
||||
const BehaviorScript* originalBehavior;
|
||||
const char* bhvName;
|
||||
int initReference;
|
||||
int loopReference;
|
||||
bool replace;
|
||||
|
@ -1235,6 +1236,15 @@ bool smlua_is_behavior_hooked(const BehaviorScript *behavior) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id) {
|
||||
for (int i = 0; i < sHookedBehaviorsCount; i++) {
|
||||
struct LuaHookedBehavior *hooked = &sHookedBehaviors[i];
|
||||
if (hooked->behaviorId != id && hooked->overrideId != id) { continue; }
|
||||
return hooked->bhvName;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int smlua_hook_custom_bhv(BehaviorScript *bhvScript, const char *bhvName) {
|
||||
if (sHookedBehaviorsCount >= MAX_HOOKED_BEHAVIORS) {
|
||||
LOG_ERROR("Hooked behaviors exceeded maximum references!");
|
||||
|
@ -1392,6 +1402,7 @@ int smlua_hook_behavior(lua_State* L) {
|
|||
hooked->overrideId = noOverrideId ? customBehaviorId : overrideBehaviorId;
|
||||
hooked->originalId = customBehaviorId; // For LUA behaviors. The only behavior id they have IS their custom one.
|
||||
hooked->originalBehavior = originalBehavior ? originalBehavior : hooked->behavior;
|
||||
hooked->bhvName = bhvName;
|
||||
hooked->initReference = initReference;
|
||||
hooked->loopReference = loopReference;
|
||||
hooked->replace = replaceBehavior;
|
||||
|
|
|
@ -152,6 +152,7 @@ enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
|
|||
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);
|
||||
const BehaviorScript* smlua_get_hooked_behavior_from_id(enum BehaviorId id, bool returnOriginal);
|
||||
bool smlua_is_behavior_hooked(const BehaviorScript *behavior);
|
||||
const char* smlua_get_name_from_hooked_behavior_id(enum BehaviorId id);
|
||||
bool smlua_call_behavior_hook(const BehaviorScript** behavior, struct Object* object, bool before);
|
||||
|
||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod);
|
||||
|
|
|
@ -193,7 +193,7 @@ static u32 mods_count_directory(char* modsBasePath) {
|
|||
}
|
||||
|
||||
static void mods_load(struct Mods* mods, char* modsBasePath, bool isUserModPath) {
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In %s Mod Path:\n\\#808080\\%s", isUserModPath ? "User" : "Local", modsBasePath)); }
|
||||
REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Generating DynOS Packs In %s Mod Path:\n\\#808080\\%s", isUserModPath ? "User" : "Local", modsBasePath));
|
||||
|
||||
// generate bins
|
||||
dynos_generate_packs(modsBasePath);
|
||||
|
@ -223,7 +223,7 @@ static void mods_load(struct Mods* mods, char* modsBasePath, bool isUserModPath)
|
|||
}
|
||||
f32 count = (f32) mods_count_directory(modsBasePath);
|
||||
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading Mods In %s Mod Path:\n\\#808080\\%s", isUserModPath ? "User" : "Local", modsBasePath)); }
|
||||
REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading Mods In %s Mod Path:\n\\#808080\\%s", isUserModPath ? "User" : "Local", modsBasePath));
|
||||
|
||||
// iterate
|
||||
char path[SYS_MAX_PATH] = { 0 };
|
||||
|
@ -232,18 +232,18 @@ static void mods_load(struct Mods* mods, char* modsBasePath, bool isUserModPath)
|
|||
// sanity check / fill path[]
|
||||
if (!directory_sanity_check(dir, modsBasePath, path)) { continue; }
|
||||
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading Mod:\n\\#808080\\%s/%s", modsBasePath, dir->d_name)); }
|
||||
REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading Mod:\n\\#808080\\%s/%s", modsBasePath, dir->d_name));
|
||||
|
||||
// load the mod
|
||||
if (!mod_load(mods, modsBasePath, dir->d_name)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (gIsThreaded) { REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / count); }
|
||||
REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / count);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
if (gIsThreaded) { REFRESH_MUTEX(gCurrLoadingSegment.percentage = 1); }
|
||||
REFRESH_MUTEX(gCurrLoadingSegment.percentage = 1);
|
||||
}
|
||||
|
||||
void mods_refresh_local(void) {
|
||||
|
@ -297,7 +297,7 @@ void mods_enable(char* relativePath) {
|
|||
}
|
||||
|
||||
void mods_init(void) {
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Caching Mods")); }
|
||||
REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Caching Mods"));
|
||||
|
||||
// load mod cache
|
||||
mod_cache_load();
|
||||
|
|
|
@ -683,11 +683,6 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
|
|||
mods_clear(&gActiveMods);
|
||||
mods_clear(&gRemoteMods);
|
||||
smlua_shutdown();
|
||||
extern s16 gChangeLevel;
|
||||
gChangeLevel = LEVEL_CASTLE_GROUNDS;
|
||||
if (gSkipInterpolationTitleScreen || find_object_with_behavior(bhvActSelector) != NULL) {
|
||||
dynos_warp_to_level(LEVEL_CASTLE_GROUNDS, 1, 0);
|
||||
}
|
||||
network_player_init();
|
||||
camera_set_use_course_specific_settings(true);
|
||||
free_vtx_scroll_targets();
|
||||
|
|
|
@ -258,6 +258,7 @@ void game_deinit(void) {
|
|||
network_shutdown(true, true, false, false);
|
||||
smlua_shutdown();
|
||||
mods_shutdown();
|
||||
djui_shutdown();
|
||||
gGameInited = false;
|
||||
}
|
||||
|
||||
|
@ -267,11 +268,13 @@ void game_exit(void) {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
void* main_game_init(UNUSED void* arg) {
|
||||
void* main_game_init(void* isThreaded) {
|
||||
gIsThreaded = isThreaded != NULL;
|
||||
|
||||
const char *userpath = gCLIOpts.savePath[0] ? gCLIOpts.savePath : sys_user_path();
|
||||
fs_init(sys_ropaths, FS_BASEDIR, userpath);
|
||||
|
||||
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading")); }
|
||||
REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading"));
|
||||
dynos_gfx_init();
|
||||
|
||||
// load config
|
||||
|
@ -288,12 +291,10 @@ void* main_game_init(UNUSED void* arg) {
|
|||
|
||||
mods_init();
|
||||
enable_queued_mods();
|
||||
if (gIsThreaded) {
|
||||
REFRESH_MUTEX(
|
||||
gCurrLoadingSegment.percentage = 0;
|
||||
snprintf(gCurrLoadingSegment.str, 256, "Starting Game");
|
||||
snprintf(gCurrLoadingSegment.str, 256, "Starting game");
|
||||
);
|
||||
}
|
||||
|
||||
// If coop_custom_palette_* values are not found in sm64config.txt, the custom palette config will use the default values (Mario's palette)
|
||||
// But if no preset is found, that means the current palette is a custom palette
|
||||
|
@ -308,20 +309,11 @@ void* main_game_init(UNUSED void* arg) {
|
|||
if (gCLIOpts.fullscreen == 1) { configWindow.fullscreen = true; }
|
||||
else if (gCLIOpts.fullscreen == 2) { configWindow.fullscreen = false; }
|
||||
|
||||
if (gCLIOpts.playerName[0] != '\0') {
|
||||
snprintf(configPlayerName, MAX_PLAYER_STRING, "%s", gCLIOpts.playerName);
|
||||
}
|
||||
|
||||
if (!gGfxInited) {
|
||||
gfx_init(&WAPI, &RAPI, TITLE);
|
||||
WAPI.set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input);
|
||||
}
|
||||
|
||||
#if defined(AAPI_SDL1) || defined(AAPI_SDL2)
|
||||
if (audio_api == NULL && audio_sdl.init()) { audio_api = &audio_sdl; }
|
||||
#endif
|
||||
if (audio_api == NULL) { audio_api = &audio_null; }
|
||||
|
||||
audio_init();
|
||||
sound_init();
|
||||
bassh_init();
|
||||
|
@ -352,21 +344,29 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Start the thread for setting up the game
|
||||
#ifndef WAPI_DXGI
|
||||
if (pthread_mutex_init(&gLoadingThreadMutex, NULL) == 0 && pthread_create(&gLoadingThreadId, NULL, main_game_init, (void*) 1) == 0) {
|
||||
gIsThreaded = true;
|
||||
bool threadSuccess = false;
|
||||
if (pthread_mutex_init(&gLoadingThreadMutex, NULL) == 0) {
|
||||
if (pthread_create(&gLoadingThreadId, NULL, main_game_init, (void*) 1) == 0) {
|
||||
render_loading_screen(); // Render the loading screen while the game is setup
|
||||
gIsThreaded = false;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
main_game_init(NULL); // Failsafe incase threading doesn't work
|
||||
threadSuccess = true;
|
||||
}
|
||||
pthread_mutex_destroy(&gLoadingThreadMutex);
|
||||
}
|
||||
if (!threadSuccess)
|
||||
#endif
|
||||
{
|
||||
main_game_init(NULL); // Failsafe incase threading doesn't work
|
||||
}
|
||||
|
||||
// initialize sm64 data and controllers
|
||||
thread5_game_loop(NULL);
|
||||
|
||||
// Initialize sound outside threads
|
||||
#if defined(AAPI_SDL1) || defined(AAPI_SDL2)
|
||||
if (!audio_api && audio_sdl.init()) { audio_api = &audio_sdl; }
|
||||
#endif
|
||||
if (!audio_api) { audio_api = &audio_null; }
|
||||
|
||||
// Initialize djui
|
||||
djui_init();
|
||||
djui_unicode_init();
|
||||
|
|
Loading…
Reference in New Issue