mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
loading screen (#495)
* loading screen * fix compile error * Fix animation comparisons after character anim commit * Cleaned up character sound/anim lookup code * hopefully fix problems with queued mods * use dj's changes * fix compile errors due to upstream merge
This commit is contained in:
parent
e8b6a8cffa
commit
b12b479d70
29 changed files with 427 additions and 66 deletions
|
|
@ -25,6 +25,7 @@ bool dynos_warp_exit_level(s32 aDelay);
|
||||||
bool dynos_warp_to_castle(s32 aLevel);
|
bool dynos_warp_to_castle(s32 aLevel);
|
||||||
|
|
||||||
// -- dynos packs -- //
|
// -- dynos packs -- //
|
||||||
|
void dynos_gfx_init(void);
|
||||||
void dynos_packs_init(void);
|
void dynos_packs_init(void);
|
||||||
int dynos_pack_get_count(void);
|
int dynos_pack_get_count(void);
|
||||||
const char* dynos_pack_get_name(s32 index);
|
const char* dynos_pack_get_name(s32 index);
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,11 @@ bool dynos_warp_to_castle(s32 aLevel) {
|
||||||
|
|
||||||
// -- dynos packs -- //
|
// -- dynos packs -- //
|
||||||
|
|
||||||
void dynos_packs_init(void) {
|
void dynos_gfx_init(void) {
|
||||||
DynOS_Gfx_Init();
|
DynOS_Gfx_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynos_packs_init(void) {
|
||||||
DynOS_Pack_Init();
|
DynOS_Pack_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
#include "dynos.cpp.h"
|
#include "dynos.cpp.h"
|
||||||
|
#include "src/pc/loading.h"
|
||||||
|
|
||||||
void DynOS_Gfx_GeneratePacks(const char* directory) {
|
void DynOS_Gfx_GeneratePacks(const char* directory) {
|
||||||
DIR *modsDir = opendir(directory);
|
DIR *modsDir = opendir(directory);
|
||||||
if (!modsDir) { return; }
|
if (!modsDir) { return; }
|
||||||
|
|
||||||
struct dirent *dir = NULL;
|
struct dirent *dir = NULL;
|
||||||
while ((dir = readdir(modsDir)) != NULL) {
|
DIR* d = opendir(directory);
|
||||||
|
u32 pathCount = 0;
|
||||||
|
while ((dir = readdir(d)) != NULL) pathCount++;
|
||||||
|
closedir(d);
|
||||||
|
|
||||||
|
for (u32 i = 0; (dir = readdir(modsDir)) != NULL; ++i) {
|
||||||
// Skip . and ..
|
// Skip . and ..
|
||||||
if (SysPath(dir->d_name) == ".") continue;
|
if (SysPath(dir->d_name) == ".") continue;
|
||||||
if (SysPath(dir->d_name) == "..") continue;
|
if (SysPath(dir->d_name) == "..") continue;
|
||||||
|
|
@ -15,21 +21,24 @@ void DynOS_Gfx_GeneratePacks(const char* directory) {
|
||||||
if (fs_sys_dir_exists(_LevelPackFolder.c_str())) {
|
if (fs_sys_dir_exists(_LevelPackFolder.c_str())) {
|
||||||
DynOS_Lvl_GeneratePack(_LevelPackFolder);
|
DynOS_Lvl_GeneratePack(_LevelPackFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
SysPath _ActorPackFolder = fstring("%s/%s/actors", directory, dir->d_name);
|
SysPath _ActorPackFolder = fstring("%s/%s/actors", directory, dir->d_name);
|
||||||
if (fs_sys_dir_exists(_ActorPackFolder.c_str())) {
|
if (fs_sys_dir_exists(_ActorPackFolder.c_str())) {
|
||||||
DynOS_Actor_GeneratePack(_ActorPackFolder);
|
DynOS_Actor_GeneratePack(_ActorPackFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
SysPath _BehaviorPackFolder = fstring("%s/%s/data", directory, dir->d_name);
|
SysPath _BehaviorPackFolder = fstring("%s/%s/data", directory, dir->d_name);
|
||||||
if (fs_sys_dir_exists(_BehaviorPackFolder.c_str())) {
|
if (fs_sys_dir_exists(_BehaviorPackFolder.c_str())) {
|
||||||
DynOS_Bhv_GeneratePack(_BehaviorPackFolder);
|
DynOS_Bhv_GeneratePack(_BehaviorPackFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
SysPath _TexturePackFolder = fstring("%s/%s", directory, dir->d_name);
|
SysPath _TexturePackFolder = fstring("%s/%s", directory, dir->d_name);
|
||||||
SysPath _TexturePackOutputFolder = fstring("%s/%s/textures", directory, dir->d_name);
|
SysPath _TexturePackOutputFolder = fstring("%s/%s/textures", directory, dir->d_name);
|
||||||
if (fs_sys_dir_exists(_TexturePackFolder.c_str())) {
|
if (fs_sys_dir_exists(_TexturePackFolder.c_str())) {
|
||||||
DynOS_Tex_GeneratePack(_TexturePackFolder, _TexturePackOutputFolder, true);
|
DynOS_Tex_GeneratePack(_TexturePackFolder, _TexturePackOutputFolder, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gIsThreaded) REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / (f32) pathCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(modsDir);
|
closedir(modsDir);
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "Obnovování..."
|
||||||
ENTER_PASSWORD = "Zadejte heslo soukromé hry:"
|
ENTER_PASSWORD = "Zadejte heslo soukromé hry:"
|
||||||
SEARCH = "Hledat"
|
SEARCH = "Hledat"
|
||||||
NONE_FOUND = "Nebyly nalezeny žádné hry."
|
NONE_FOUND = "Nebyly nalezeny žádné hry."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Načítání"
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "herladen..."
|
||||||
ENTER_PASSWORD = "Typ het wachtwoord van de privé lobby:"
|
ENTER_PASSWORD = "Typ het wachtwoord van de privé lobby:"
|
||||||
SEARCH = "Zoek"
|
SEARCH = "Zoek"
|
||||||
NONE_FOUND = "Er zijn geen lobby's gevonden."
|
NONE_FOUND = "Er zijn geen lobby's gevonden."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Bezig met laden"
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "Refreshing..."
|
||||||
ENTER_PASSWORD = "Enter the private lobby's password:"
|
ENTER_PASSWORD = "Enter the private lobby's password:"
|
||||||
SEARCH = "Search"
|
SEARCH = "Search"
|
||||||
NONE_FOUND = "No lobbies were found."
|
NONE_FOUND = "No lobbies were found."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Loading"
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "Actualisation..."
|
||||||
ENTER_PASSWORD = "Entrez le mot de passe de la partie:"
|
ENTER_PASSWORD = "Entrez le mot de passe de la partie:"
|
||||||
SEARCH = "Rechercher"
|
SEARCH = "Rechercher"
|
||||||
NONE_FOUND = "Aucune partie n'a été trouvée."
|
NONE_FOUND = "Aucune partie n'a été trouvée."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Chargement"
|
||||||
|
|
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "Aktualisiere..."
|
||||||
ENTER_PASSWORD = "Gib das Passwort für die Lobby ein:"
|
ENTER_PASSWORD = "Gib das Passwort für die Lobby ein:"
|
||||||
SEARCH = "Suchen"
|
SEARCH = "Suchen"
|
||||||
NONE_FOUND = "Keine Lobbys gefunden."
|
NONE_FOUND = "Keine Lobbys gefunden."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Wird geladen"
|
||||||
|
|
|
||||||
|
|
@ -371,3 +371,6 @@ REFRESHING = "Refreshing..."
|
||||||
ENTER_PASSWORD = "Enter the private lobby's password:"
|
ENTER_PASSWORD = "Enter the private lobby's password:"
|
||||||
SEARCH = "Search"
|
SEARCH = "Search"
|
||||||
NONE_FOUND = "No lobbies were found."
|
NONE_FOUND = "No lobbies were found."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Caricamento"
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ UNKNOWN = "desconhecido"
|
||||||
LOBBY_HOST = "o host da partida"
|
LOBBY_HOST = "o host da partida"
|
||||||
|
|
||||||
[CHAT]
|
[CHAT]
|
||||||
KICKING = "Expulso '@'!"
|
KICKING = "Expulso '@'!"
|
||||||
BANNING = "Banindo '@'!"
|
BANNING = "Banindo '@'!"
|
||||||
SERVER_ONLY = "Apenas o servidor pode usar este comando."
|
SERVER_ONLY = "Apenas o servidor pode usar este comando."
|
||||||
PERM_BANNING = "'@' permanentemente banido!"
|
PERM_BANNING = "'@' permanentemente banido!"
|
||||||
|
|
@ -374,3 +374,6 @@ REFRESHING = "Recarregando..."
|
||||||
ENTER_PASSWORD = "Coloque a senha para a partida privada:"
|
ENTER_PASSWORD = "Coloque a senha para a partida privada:"
|
||||||
SEARCH = "Pesquisar"
|
SEARCH = "Pesquisar"
|
||||||
NONE_FOUND = "Nenhuma partida foi encontrada."
|
NONE_FOUND = "Nenhuma partida foi encontrada."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Carregando"
|
||||||
|
|
|
||||||
|
|
@ -372,4 +372,7 @@ REFRESH = "Обновить"
|
||||||
REFRESHING = "Обновление..."
|
REFRESHING = "Обновление..."
|
||||||
ENTER_PASSWORD = "Введите пароль закрытой группы:"
|
ENTER_PASSWORD = "Введите пароль закрытой группы:"
|
||||||
SEARCH = "Поиск"
|
SEARCH = "Поиск"
|
||||||
NONE_FOUND = "Группы не найдены."
|
NONE_FOUND = "Группы не найдены."
|
||||||
|
|
||||||
|
[LOADING_SCREEN]
|
||||||
|
LOADING = "Загрузка"
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ struct Character gCharacters[CT_MAX] = {
|
||||||
.torsoRotMult = 1.0f,
|
.torsoRotMult = 1.0f,
|
||||||
// anim
|
// anim
|
||||||
.animOffsetEnabled = false,
|
.animOffsetEnabled = false,
|
||||||
|
|
||||||
// character anims
|
// character anims
|
||||||
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
||||||
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
||||||
|
|
@ -601,7 +601,7 @@ struct Character gCharacters[CT_MAX] = {
|
||||||
.torsoRotMult = 1.0f,
|
.torsoRotMult = 1.0f,
|
||||||
// anim
|
// anim
|
||||||
.animOffsetEnabled = false,
|
.animOffsetEnabled = false,
|
||||||
|
|
||||||
// character anims
|
// character anims
|
||||||
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
||||||
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
||||||
|
|
@ -881,7 +881,7 @@ struct Character gCharacters[CT_MAX] = {
|
||||||
.animOffsetLowYPoint = 11,
|
.animOffsetLowYPoint = 11,
|
||||||
.animOffsetFeet = 25,
|
.animOffsetFeet = 25,
|
||||||
.animOffsetHand = -10,
|
.animOffsetHand = -10,
|
||||||
|
|
||||||
// character anims
|
// character anims
|
||||||
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
||||||
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
||||||
|
|
@ -1158,7 +1158,7 @@ struct Character gCharacters[CT_MAX] = {
|
||||||
.torsoRotMult = 1.0f,
|
.torsoRotMult = 1.0f,
|
||||||
// anim
|
// anim
|
||||||
.animOffsetEnabled = true,
|
.animOffsetEnabled = true,
|
||||||
|
|
||||||
// character anims
|
// character anims
|
||||||
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
.animSlowLedgeGrab = MARIO_ANIM_SLOW_LEDGE_GRAB,
|
||||||
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
.animFallOverBackwards = MARIO_ANIM_FALL_OVER_BACKWARDS,
|
||||||
|
|
@ -1521,7 +1521,7 @@ struct Character* get_character(struct MarioState* m) {
|
||||||
|
|
||||||
static s32 get_character_sound(struct MarioState* m, enum CharacterSound characterSound) {
|
static s32 get_character_sound(struct MarioState* m, enum CharacterSound characterSound) {
|
||||||
if (m == NULL || m->marioObj == NULL) { return 0; }
|
if (m == NULL || m->marioObj == NULL) { return 0; }
|
||||||
|
|
||||||
s32 override = 0;
|
s32 override = 0;
|
||||||
if (smlua_call_event_hooks_mario_character_sound_param_ret_int(HOOK_CHARACTER_SOUND, m, characterSound, &override)) {
|
if (smlua_call_event_hooks_mario_character_sound_param_ret_int(HOOK_CHARACTER_SOUND, m, characterSound, &override)) {
|
||||||
return override;
|
return override;
|
||||||
|
|
@ -1612,7 +1612,7 @@ void update_character_anim_offset(struct MarioState* m) {
|
||||||
|
|
||||||
s32 get_character_anim(struct MarioState* m, enum CharacterAnimID characterAnim) {
|
s32 get_character_anim(struct MarioState* m, enum CharacterAnimID characterAnim) {
|
||||||
if (m == NULL || m->marioObj == NULL) { return 0; }
|
if (m == NULL || m->marioObj == NULL) { return 0; }
|
||||||
|
|
||||||
struct Character* character = ((m == NULL || m->character == NULL) ? &gCharacters[CT_MARIO] : m->character);
|
struct Character* character = ((m == NULL || m->character == NULL) ? &gCharacters[CT_MARIO] : m->character);
|
||||||
if (!character || characterAnim < 0 || characterAnim >= CHAR_ANIM_MAX) { return 0; }
|
if (!character || characterAnim < 0 || characterAnim >= CHAR_ANIM_MAX) { return 0; }
|
||||||
return character->anims[characterAnim];
|
return character->anims[characterAnim];
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ static inline int arg_uint(UNUSED const char *name, const char *value, unsigned
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void parse_cli_opts(int argc, char* argv[]) {
|
bool parse_cli_opts(int argc, char* argv[]) {
|
||||||
|
|
||||||
// Initialize options with false values.
|
// Initialize options with false values.
|
||||||
memset(&gCLIOpts, 0, sizeof(gCLIOpts));
|
memset(&gCLIOpts, 0, sizeof(gCLIOpts));
|
||||||
|
|
||||||
|
|
@ -88,7 +89,9 @@ inline void parse_cli_opts(int argc, char* argv[]) {
|
||||||
// Print help
|
// Print help
|
||||||
else if (strcmp(argv[i], "--help") == 0) {
|
else if (strcmp(argv[i], "--help") == 0) {
|
||||||
print_help();
|
print_help();
|
||||||
game_exit();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,6 @@ struct PCCLIOptions {
|
||||||
|
|
||||||
extern struct PCCLIOptions gCLIOpts;
|
extern struct PCCLIOptions gCLIOpts;
|
||||||
|
|
||||||
void parse_cli_opts(int argc, char* argv[]);
|
bool parse_cli_opts(int argc, char* argv[]);
|
||||||
|
|
||||||
#endif // _CLIOPTS_H
|
#endif // _CLIOPTS_H
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,23 @@ static const struct ConfigOption options[] = {
|
||||||
|
|
||||||
// FunctionConfigOption functions
|
// FunctionConfigOption functions
|
||||||
|
|
||||||
|
struct QueuedMods {
|
||||||
|
char* path;
|
||||||
|
struct QueuedMods *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct QueuedMods *sQueuedEnableModsHead = NULL;
|
||||||
|
|
||||||
|
void enable_queued_mods() {
|
||||||
|
while (sQueuedEnableModsHead) {
|
||||||
|
struct QueuedMods *next = sQueuedEnableModsHead->next;
|
||||||
|
mods_enable(sQueuedEnableModsHead->path);
|
||||||
|
free(sQueuedEnableModsHead->path);
|
||||||
|
free(sQueuedEnableModsHead);
|
||||||
|
sQueuedEnableModsHead = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void enable_mod_read(char** tokens, UNUSED int numTokens) {
|
static void enable_mod_read(char** tokens, UNUSED int numTokens) {
|
||||||
char combined[256] = { 0 };
|
char combined[256] = { 0 };
|
||||||
for (int i = 1; i < numTokens; i++) {
|
for (int i = 1; i < numTokens; i++) {
|
||||||
|
|
@ -286,7 +303,16 @@ static void enable_mod_read(char** tokens, UNUSED int numTokens) {
|
||||||
strncat(combined, tokens[i], 255);
|
strncat(combined, tokens[i], 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
mods_enable(combined);
|
struct QueuedMods* queued = malloc(sizeof(struct QueuedMods));
|
||||||
|
queued->path = strdup(combined);
|
||||||
|
queued->next = NULL;
|
||||||
|
if (!sQueuedEnableModsHead) {
|
||||||
|
sQueuedEnableModsHead = queued;
|
||||||
|
} else {
|
||||||
|
struct QueuedMods* tail = sQueuedEnableModsHead;
|
||||||
|
while (tail->next) { tail = tail->next; }
|
||||||
|
tail->next = queued;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_mod_write(FILE* file) {
|
static void enable_mod_write(FILE* file) {
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ extern bool configFadeoutDistantSounds;
|
||||||
extern unsigned int configDjuiTheme;
|
extern unsigned int configDjuiTheme;
|
||||||
extern bool configCoopCompatibility;
|
extern bool configCoopCompatibility;
|
||||||
|
|
||||||
|
void enable_queued_mods();
|
||||||
void configfile_load(void);
|
void configfile_load(void);
|
||||||
void configfile_save(const char *filename);
|
void configfile_save(const char *filename);
|
||||||
const char *configfile_name(void);
|
const char *configfile_name(void);
|
||||||
|
|
|
||||||
|
|
@ -275,8 +275,7 @@ static void crash_handler_produce_one_frame(void) {
|
||||||
// Render frame
|
// Render frame
|
||||||
end_master_display_list();
|
end_master_display_list();
|
||||||
alloc_display_list(0);
|
alloc_display_list(0);
|
||||||
extern void send_display_list(struct SPTask *spTask);
|
gfx_run((Gfx*) gGfxSPTask->task.t.data_ptr); // send_display_list
|
||||||
send_display_list(&gGfxPool->spTask);
|
|
||||||
display_and_vsync();
|
display_and_vsync();
|
||||||
gfx_end_frame();
|
gfx_end_frame();
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +301,7 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) {
|
||||||
#elif __linux__
|
#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, ucontext_t *context) {
|
||||||
#endif
|
#endif
|
||||||
LOG_INFO("game crashed! preparing crash screen...");
|
printf("game crashed! preparing crash screen...\n");
|
||||||
memset(sCrashHandlerText, 0, sizeof(sCrashHandlerText));
|
memset(sCrashHandlerText, 0, sizeof(sCrashHandlerText));
|
||||||
CrashHandlerText *pText = &sCrashHandlerText[0];
|
CrashHandlerText *pText = &sCrashHandlerText[0];
|
||||||
gDjuiDisabled = true;
|
gDjuiDisabled = true;
|
||||||
|
|
@ -658,6 +657,11 @@ static void crash_handler(const int signalNum, siginfo_t *info, ucontext_t *cont
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Incase it crashed before the game window opened
|
||||||
|
if (!gGfxInited) gfx_init(&WAPI, &RAPI, TITLE);
|
||||||
|
djui_init();
|
||||||
|
djui_unicode_init();
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (true) {
|
while (true) {
|
||||||
WAPI.main_loop(crash_handler_produce_one_frame);
|
WAPI.main_loop(crash_handler_produce_one_frame);
|
||||||
|
|
@ -670,17 +674,17 @@ AT_STARTUP static void init_crash_handler(void) {
|
||||||
// Windows
|
// Windows
|
||||||
SetUnhandledExceptionFilter(crash_handler);
|
SetUnhandledExceptionFilter(crash_handler);
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
|
|
||||||
// Linux
|
// Linux
|
||||||
struct sigaction linux_crash_handler;
|
struct sigaction linuxCrashHandler;
|
||||||
|
linuxCrashHandler.sa_handler = (void*) &crash_handler;
|
||||||
|
sigemptyset(&linuxCrashHandler.sa_mask);
|
||||||
|
linuxCrashHandler.sa_flags = SA_SIGINFO; // Get extra info about the crash
|
||||||
|
|
||||||
linux_crash_handler.sa_handler = (void *)crash_handler;
|
sigaction(SIGBUS, &linuxCrashHandler, NULL);
|
||||||
sigemptyset(&linux_crash_handler.sa_mask);
|
sigaction(SIGFPE, &linuxCrashHandler, NULL);
|
||||||
linux_crash_handler.sa_flags = SA_SIGINFO; // Get extra info about the crash
|
sigaction(SIGILL, &linuxCrashHandler, NULL);
|
||||||
|
sigaction(SIGSEGV, &linuxCrashHandler, NULL);
|
||||||
sigaction(SIGBUS, &linux_crash_handler, NULL);
|
|
||||||
sigaction(SIGFPE, &linux_crash_handler, NULL);
|
|
||||||
sigaction(SIGILL, &linux_crash_handler, NULL);
|
|
||||||
sigaction(SIGSEGV, &linux_crash_handler, NULL);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#define CTX_BEGIN(_ctx) debug_context_begin(_ctx)
|
#define CTX_BEGIN(_ctx) debug_context_begin(_ctx)
|
||||||
#define CTX_END(_ctx) debug_context_end(_ctx)
|
#define CTX_END(_ctx) debug_context_end(_ctx)
|
||||||
#define CTX_WITHIN(_ctx) debug_context_within(_ctx)
|
#define CTX_WITHIN(_ctx) debug_context_within(_ctx)
|
||||||
#define CTX_EXTENT(__ctx, __func) CTX_BEGIN(__ctx); __func(); CTX_END(__ctx);
|
#define CTX_EXTENT(_ctx, _f) { CTX_BEGIN(_ctx); _f(); CTX_END(_ctx); }
|
||||||
|
|
||||||
enum DebugContext {
|
enum DebugContext {
|
||||||
CTX_NONE,
|
CTX_NONE,
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,26 @@ static u32 sDjuiLuaErrorTimeout = 0;
|
||||||
bool gDjuiInMainMenu = true;
|
bool gDjuiInMainMenu = true;
|
||||||
bool gDjuiDisabled = false;
|
bool gDjuiDisabled = false;
|
||||||
bool gDjuiRenderBehindHud = false;
|
bool gDjuiRenderBehindHud = false;
|
||||||
|
static bool sDjuiInited = false;
|
||||||
|
|
||||||
bool sDjuiRendered60fps = false;
|
bool sDjuiRendered60fps = false;
|
||||||
|
|
||||||
|
void reset_djui_text(void);
|
||||||
|
|
||||||
|
void reset_djui(void) {
|
||||||
|
sSavedDisplayListHead = NULL;
|
||||||
|
sDjuiPauseOptions = NULL;
|
||||||
|
sDjuiLuaError = NULL;
|
||||||
|
sDjuiLuaErrorTimeout = 0;
|
||||||
|
if (gDjuiRoot) djui_base_destroy(&gDjuiRoot->base);
|
||||||
|
|
||||||
|
if (gDjuiConsole) djui_base_destroy(&gDjuiConsole->panel->base);
|
||||||
|
extern u32 sDjuiConsoleMessages;
|
||||||
|
sDjuiConsoleMessages = 0;
|
||||||
|
|
||||||
|
sDjuiInited = false;
|
||||||
|
}
|
||||||
|
|
||||||
void patch_djui_before(void) {
|
void patch_djui_before(void) {
|
||||||
sDjuiRendered60fps = false;
|
sDjuiRendered60fps = false;
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +85,7 @@ void djui_init(void) {
|
||||||
djui_panel_playerlist_create(NULL);
|
djui_panel_playerlist_create(NULL);
|
||||||
|
|
||||||
djui_console_create();
|
djui_console_create();
|
||||||
|
sDjuiInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void djui_init_late(void) {
|
void djui_init_late(void) {
|
||||||
|
|
@ -91,6 +109,7 @@ void djui_connect_menu_open(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void djui_lua_error(char* text) {
|
void djui_lua_error(char* text) {
|
||||||
|
if (!sDjuiLuaError) { return; }
|
||||||
djui_text_set_text(sDjuiLuaError, text);
|
djui_text_set_text(sDjuiLuaError, text);
|
||||||
djui_base_set_visible(&sDjuiLuaError->base, true);
|
djui_base_set_visible(&sDjuiLuaError->base, true);
|
||||||
sDjuiLuaErrorTimeout = 30 * 5;
|
sDjuiLuaErrorTimeout = 30 * 5;
|
||||||
|
|
@ -105,7 +124,7 @@ void djui_reset_hud_params(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void djui_render(void) {
|
void djui_render(void) {
|
||||||
if (gDjuiDisabled) { return; }
|
if (!sDjuiInited || gDjuiDisabled) { return; }
|
||||||
djui_reset_hud_params();
|
djui_reset_hud_params();
|
||||||
|
|
||||||
sSavedDisplayListHead = gDisplayListHead;
|
sSavedDisplayListHead = gDisplayListHead;
|
||||||
|
|
|
||||||
|
|
@ -46,3 +46,5 @@ void djui_connect_menu_open(void);
|
||||||
void djui_lua_error(char* text);
|
void djui_lua_error(char* text);
|
||||||
void djui_render(void);
|
void djui_render(void);
|
||||||
void djui_reset_hud_params(void);
|
void djui_reset_hud_params(void);
|
||||||
|
|
||||||
|
void reset_djui(void);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
#include "../configfile.h"
|
#include "../configfile.h"
|
||||||
#include "../fs/fs.h"
|
#include "../fs/fs.h"
|
||||||
|
#include "../pc_main.h"
|
||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
|
@ -1779,6 +1780,8 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
|
||||||
gfx_rapi->init();
|
gfx_rapi->init();
|
||||||
|
|
||||||
gfx_cc_precomp();
|
gfx_cc_precomp();
|
||||||
|
|
||||||
|
gGfxInited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GfxRenderingAPI *gfx_get_current_rendering_api(void) {
|
struct GfxRenderingAPI *gfx_get_current_rendering_api(void) {
|
||||||
|
|
|
||||||
193
src/pc/loading.c
Normal file
193
src/pc/loading.c
Normal file
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include "gfx_dimensions.h"
|
||||||
|
#include "game/segment2.h"
|
||||||
|
|
||||||
|
#include "djui/djui.h"
|
||||||
|
#include "pc/djui/djui_unicode.h"
|
||||||
|
|
||||||
|
#include "controller/controller_keyboard.h"
|
||||||
|
|
||||||
|
#include "pc_main.h"
|
||||||
|
#include "loading.h"
|
||||||
|
#include "pc/utils/misc.h"
|
||||||
|
|
||||||
|
struct LoadingSegment gCurrLoadingSegment = { "", 0 };
|
||||||
|
|
||||||
|
struct LoadingScreen {
|
||||||
|
struct DjuiBase base;
|
||||||
|
struct DjuiText* splashText;
|
||||||
|
struct DjuiText* loadingText;
|
||||||
|
struct DjuiText* loadingDesc;
|
||||||
|
struct DjuiProgressBar *loadingBar;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoadingScreen* sLoading = NULL;
|
||||||
|
pthread_t gLoadingThreadId;
|
||||||
|
pthread_mutex_t gLoadingThreadMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
bool gIsThreaded = false;
|
||||||
|
|
||||||
|
extern Vp D_8032CF00;
|
||||||
|
extern u8 gRenderingInterpolated;
|
||||||
|
|
||||||
|
static void loading_screen_produce_one_frame() {
|
||||||
|
|
||||||
|
// Start frame
|
||||||
|
gfx_start_frame();
|
||||||
|
config_gfx_pool();
|
||||||
|
init_render_image();
|
||||||
|
create_dl_ortho_matrix();
|
||||||
|
djui_gfx_displaylist_begin();
|
||||||
|
|
||||||
|
// Fix scaling issues
|
||||||
|
gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(&D_8032CF00));
|
||||||
|
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, 0, BORDER_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - BORDER_HEIGHT);
|
||||||
|
|
||||||
|
// Clear screen
|
||||||
|
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 240.f, 0.f);
|
||||||
|
create_dl_scale_matrix(MENU_MTX_NOPUSH, (GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT) / 130.f, 3.f, 1.f);
|
||||||
|
gDPSetEnvColor(gDisplayListHead++, 0x00, 0x00, 0x00, 0xFF);
|
||||||
|
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
||||||
|
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||||
|
|
||||||
|
// Render loading screen elements
|
||||||
|
if (sLoading) { djui_base_render(&sLoading->base); }
|
||||||
|
|
||||||
|
// Render frame
|
||||||
|
djui_gfx_displaylist_end();
|
||||||
|
end_master_display_list();
|
||||||
|
alloc_display_list(0);
|
||||||
|
gfx_run((Gfx*) gGfxSPTask->task.t.data_ptr); // send_display_list
|
||||||
|
display_and_vsync();
|
||||||
|
gfx_end_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool loading_screen_on_render(struct DjuiBase* base) {
|
||||||
|
pthread_mutex_lock(&gLoadingThreadMutex);
|
||||||
|
|
||||||
|
u32 windowWidth, windowHeight;
|
||||||
|
WAPI.get_dimensions(&windowWidth, &windowHeight);
|
||||||
|
f32 scale = djui_gfx_get_scale();
|
||||||
|
windowWidth /= scale;
|
||||||
|
windowHeight /= scale;
|
||||||
|
|
||||||
|
// Fill the screen
|
||||||
|
djui_base_set_size(base, windowWidth, windowHeight);
|
||||||
|
|
||||||
|
// Splash text
|
||||||
|
djui_base_set_location(&sLoading->splashText->base, (windowWidth / 2) - 416, 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Loading... text
|
||||||
|
char* loadingStr = DLANG(LOADING_SCREEN, LOADING);
|
||||||
|
char tmp[20] = "";
|
||||||
|
switch ((u8) floor(clock_elapsed()) % 3) {
|
||||||
|
case 0: snprintf(tmp, 20, "%s...", loadingStr); break;
|
||||||
|
case 1: snprintf(tmp, 20, "%s.", loadingStr); break;
|
||||||
|
default: snprintf(tmp, 20, "%s..", loadingStr); break;
|
||||||
|
}
|
||||||
|
djui_text_set_text(sLoading->loadingText, tmp);
|
||||||
|
djui_base_set_visible(&sLoading->loadingText->base, sLoading->loadingText->base.y.value + 50 < sLoading->loadingDesc->base.y.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Loading text description
|
||||||
|
char buffer[256] = "";
|
||||||
|
if (strlen(gCurrLoadingSegment.str) > 0) {
|
||||||
|
if (gCurrLoadingSegment.percentage > 0) {
|
||||||
|
snprintf(buffer, 256, "%s... %d%%", gCurrLoadingSegment.str, (u8) floor(gCurrLoadingSegment.percentage * 100));
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, 256, "%s...", gCurrLoadingSegment.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
djui_text_set_text(sLoading->loadingDesc, buffer);
|
||||||
|
djui_base_set_location(&sLoading->loadingDesc->base, 0, windowHeight - 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loading bar
|
||||||
|
djui_base_set_location(&sLoading->loadingBar->base, windowWidth / 4, windowHeight - 100);
|
||||||
|
djui_base_set_visible(&sLoading->loadingBar->base, gCurrLoadingSegment.percentage > 0 && strlen(gCurrLoadingSegment.str) > 0);
|
||||||
|
|
||||||
|
djui_base_compute(base);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&gLoadingThreadMutex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loading_screen_destroy(struct DjuiBase* base) {
|
||||||
|
struct LoadingScreen* load = (struct LoadingScreen*)base;
|
||||||
|
free(load);
|
||||||
|
sLoading = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_loading_screen() {
|
||||||
|
struct LoadingScreen* load = malloc(sizeof(struct LoadingScreen));
|
||||||
|
struct DjuiBase* base = &load->base;
|
||||||
|
|
||||||
|
djui_base_init(NULL, base, loading_screen_on_render, loading_screen_destroy);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Splash text
|
||||||
|
struct DjuiText* splashDjuiText = djui_text_create(base, "\\#ff0800\\SM\\#1be700\\64\\#00b3ff\\EX\\#ffef00\\COOP");
|
||||||
|
djui_text_set_font(splashDjuiText, gDjuiFonts[1]);
|
||||||
|
djui_text_set_font_scale(splashDjuiText, gDjuiFonts[1]->defaultFontScale * 4);
|
||||||
|
djui_text_set_alignment(splashDjuiText, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||||
|
djui_base_set_size(&splashDjuiText->base, 800, 800);
|
||||||
|
|
||||||
|
load->splashText = splashDjuiText;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// "Loading..." text
|
||||||
|
struct DjuiText *text = djui_text_create(base, "");
|
||||||
|
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&text->base, 1.0f, 32 * 4);
|
||||||
|
djui_base_set_color(&text->base, 200, 200, 200, 255);
|
||||||
|
djui_base_set_location(&text->base, 0, 400);
|
||||||
|
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_CENTER);
|
||||||
|
djui_text_set_font(text, gDjuiFonts[0]);
|
||||||
|
djui_text_set_font_scale(text, gDjuiFonts[0]->defaultFontScale * 2);
|
||||||
|
|
||||||
|
load->loadingText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Current loading stage text
|
||||||
|
struct DjuiText *text = djui_text_create(base, "");
|
||||||
|
djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
|
djui_base_set_size(&text->base, 1.0f, 32 * 4);
|
||||||
|
djui_base_set_color(&text->base, 200, 200, 200, 255);
|
||||||
|
djui_text_set_alignment(text, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP);
|
||||||
|
djui_text_set_font(text, gDjuiFonts[0]);
|
||||||
|
djui_text_set_font_scale(text, gDjuiFonts[0]->defaultFontScale * 2);
|
||||||
|
|
||||||
|
load->loadingDesc = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Loading bar
|
||||||
|
struct DjuiProgressBar *progressBar = djui_progress_bar_create(base, &gCurrLoadingSegment.percentage, 0.0f, 1.0f, false);
|
||||||
|
djui_base_set_visible(&progressBar->base, false);
|
||||||
|
progressBar->base.width.value = 0.5;
|
||||||
|
|
||||||
|
load->loadingBar = progressBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
sLoading = load;
|
||||||
|
|
||||||
|
// Loading screen loop
|
||||||
|
while (!gGameInited) {
|
||||||
|
WAPI.main_loop(loading_screen_produce_one_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_join(gLoadingThreadId, NULL);
|
||||||
|
|
||||||
|
// Reset some things after rendering the loading screen
|
||||||
|
reset_djui();
|
||||||
|
alloc_display_list_reset();
|
||||||
|
gDisplayListHead = NULL;
|
||||||
|
djui_init();
|
||||||
|
djui_unicode_init();
|
||||||
|
rendering_init();
|
||||||
|
configWindow.settings_changed = true;
|
||||||
|
}
|
||||||
25
src/pc/loading.h
Normal file
25
src/pc/loading.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef LOADING_HEADER
|
||||||
|
#define LOADING_HEADER
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
struct LoadingSegment {
|
||||||
|
char str[256];
|
||||||
|
f32 percentage;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct LoadingSegment gCurrLoadingSegment;
|
||||||
|
|
||||||
|
#define REFRESH_MUTEX(...) \
|
||||||
|
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();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -10,10 +10,7 @@
|
||||||
#include "pc/crash_handler.h"
|
#include "pc/crash_handler.h"
|
||||||
#include "src/game/hud.h"
|
#include "src/game/hud.h"
|
||||||
#include "pc/debug_context.h"
|
#include "pc/debug_context.h"
|
||||||
#include "pc/network/network.h"
|
#include "pc/pc_main.h"
|
||||||
#include "pc/network/network_player.h"
|
|
||||||
#include "pc/network/socket/socket.h"
|
|
||||||
#include "pc/chat_commands.h"
|
|
||||||
|
|
||||||
#if defined(DEVELOPMENT)
|
#if defined(DEVELOPMENT)
|
||||||
#include "../mods/mods.h"
|
#include "../mods/mods.h"
|
||||||
|
|
@ -92,6 +89,8 @@ struct LuaHookedEvent {
|
||||||
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
|
static struct LuaHookedEvent sHookedEvents[HOOK_MAX] = { 0 };
|
||||||
|
|
||||||
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod) {
|
int smlua_call_hook(lua_State* L, int nargs, int nresults, int errfunc, struct Mod* activeMod) {
|
||||||
|
if (!gGameInited) { return 0; } // Don't call hooks while the game is booting
|
||||||
|
|
||||||
struct Mod* prev = gLuaActiveMod;
|
struct Mod* prev = gLuaActiveMod;
|
||||||
gLuaActiveMod = activeMod;
|
gLuaActiveMod = activeMod;
|
||||||
gLuaLastHookMod = activeMod;
|
gLuaLastHookMod = activeMod;
|
||||||
|
|
|
||||||
|
|
@ -322,7 +322,7 @@ static bool mod_load_files(struct Mod* mod, char* modName, char* fullPath) {
|
||||||
const char* fileTypes[] = { ".bin", ".col", NULL };
|
const char* fileTypes[] = { ".bin", ".col", NULL };
|
||||||
if (!mod_load_files_dir(mod, fullPath, "actors", fileTypes)) { return false; }
|
if (!mod_load_files_dir(mod, fullPath, "actors", fileTypes)) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// deal with behaviors directory
|
// deal with behaviors directory
|
||||||
{
|
{
|
||||||
const char* fileTypes[] = { ".bhv", NULL };
|
const char* fileTypes[] = { ".bhv", NULL };
|
||||||
|
|
@ -525,11 +525,11 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// print
|
// print
|
||||||
LOG_INFO(" %s", mod->name);
|
// LOG_INFO(" %s", mod->name);
|
||||||
for (int i = 0; i < mod->fileCount; i++) {
|
for (int i = 0; i < mod->fileCount; i++) {
|
||||||
struct ModFile* file = &mod->files[i];
|
struct ModFile* file = &mod->files[i];
|
||||||
mod_cache_add(mod, file, true);
|
mod_cache_add(mod, file, true);
|
||||||
LOG_INFO(" - %s", file->relativePath);
|
// LOG_INFO(" - %s", file->relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ bool mod_import_file(char* path) {
|
||||||
djui_language_replace(DLANG(NOTIF, IMPORT_MOD_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
djui_language_replace(DLANG(NOTIF, IMPORT_MOD_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
||||||
djui_popup_create(msg, 2);
|
djui_popup_create(msg, 2);
|
||||||
} else if (isDynos) {
|
} else if (isDynos) {
|
||||||
|
dynos_gfx_init();
|
||||||
dynos_packs_init();
|
dynos_packs_init();
|
||||||
djui_language_replace(DLANG(NOTIF, IMPORT_DYNOS_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
djui_language_replace(DLANG(NOTIF, IMPORT_DYNOS_SUCCESS), msg, SYS_MAX_PATH, '@', basename);
|
||||||
djui_popup_create(msg, 2);
|
djui_popup_create(msg, 2);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "mod_cache.h"
|
#include "mod_cache.h"
|
||||||
#include "data/dynos.c.h"
|
#include "data/dynos.c.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
#include "pc/pc_main.h"
|
#include "pc/loading.h"
|
||||||
|
|
||||||
#define MAX_SESSION_CHARS 7
|
#define MAX_SESSION_CHARS 7
|
||||||
|
|
||||||
|
|
@ -147,7 +147,18 @@ static void mods_sort(struct Mods* mods) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mods_load(struct Mods* mods, char* modsBasePath) {
|
static u32 mods_count_directory(char* modsBasePath) {
|
||||||
|
struct dirent* dir = NULL;
|
||||||
|
DIR* d = opendir(modsBasePath);
|
||||||
|
u32 pathCount = 0;
|
||||||
|
while ((dir = readdir(d)) != NULL) pathCount++;
|
||||||
|
closedir(d);
|
||||||
|
return pathCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (%s)", isUserModPath ? "user" : "local", modsBasePath)); }
|
||||||
|
|
||||||
// generate bins
|
// generate bins
|
||||||
dynos_generate_packs(modsBasePath);
|
dynos_generate_packs(modsBasePath);
|
||||||
|
|
||||||
|
|
@ -174,10 +185,13 @@ static void mods_load(struct Mods* mods, char* modsBasePath) {
|
||||||
LOG_ERROR("Could not open directory '%s'", modsBasePath);
|
LOG_ERROR("Could not open directory '%s'", modsBasePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
f32 count = (f32) mods_count_directory(modsBasePath);
|
||||||
|
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Loading Mods in %s mod path (%s)", isUserModPath ? "user" : "local", modsBasePath)); }
|
||||||
|
|
||||||
// iterate
|
// iterate
|
||||||
char path[SYS_MAX_PATH] = { 0 };
|
char path[SYS_MAX_PATH] = { 0 };
|
||||||
while ((dir = readdir(d)) != NULL) {
|
for (u32 i = 0; (dir = readdir(d)) != NULL; ++i) {
|
||||||
|
|
||||||
// sanity check / fill path[]
|
// sanity check / fill path[]
|
||||||
if (!directory_sanity_check(dir, modsBasePath, path)) { continue; }
|
if (!directory_sanity_check(dir, modsBasePath, path)) { continue; }
|
||||||
|
|
||||||
|
|
@ -185,10 +199,11 @@ static void mods_load(struct Mods* mods, char* modsBasePath) {
|
||||||
if (!mod_load(mods, modsBasePath, dir->d_name)) {
|
if (!mod_load(mods, modsBasePath, dir->d_name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (gIsThreaded) { REFRESH_MUTEX(gCurrLoadingSegment.percentage = (f32) i / count); }
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(d);
|
closedir(d);
|
||||||
|
if (gIsThreaded) { REFRESH_MUTEX(gCurrLoadingSegment.percentage = 1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void mods_refresh_local(void) {
|
void mods_refresh_local(void) {
|
||||||
|
|
@ -208,13 +223,13 @@ void mods_refresh_local(void) {
|
||||||
mods_clear(&gLocalMods);
|
mods_clear(&gLocalMods);
|
||||||
|
|
||||||
// load mods
|
// load mods
|
||||||
if (hasUserPath) { mods_load(&gLocalMods, userModPath); }
|
if (hasUserPath) { mods_load(&gLocalMods, userModPath, true); }
|
||||||
|
|
||||||
const char* exePath = path_to_executable();
|
const char* exePath = path_to_executable();
|
||||||
char defaultModsPath[SYS_MAX_PATH] = { 0 };
|
char defaultModsPath[SYS_MAX_PATH] = { 0 };
|
||||||
path_get_folder((char*)exePath, defaultModsPath);
|
path_get_folder((char*)exePath, defaultModsPath);
|
||||||
strncat(defaultModsPath, MOD_DIRECTORY, SYS_MAX_PATH-1);
|
strncat(defaultModsPath, MOD_DIRECTORY, SYS_MAX_PATH-1);
|
||||||
mods_load(&gLocalMods, defaultModsPath);
|
mods_load(&gLocalMods, defaultModsPath, false);
|
||||||
|
|
||||||
// sort
|
// sort
|
||||||
mods_sort(&gLocalMods);
|
mods_sort(&gLocalMods);
|
||||||
|
|
@ -242,6 +257,8 @@ void mods_enable(char* relativePath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mods_init(void) {
|
void mods_init(void) {
|
||||||
|
if (gIsThreaded) { REFRESH_MUTEX(snprintf(gCurrLoadingSegment.str, 256, "Caching mods")); }
|
||||||
|
|
||||||
// load mod cache
|
// load mod cache
|
||||||
mod_cache_load();
|
mod_cache_load();
|
||||||
mods_refresh_local();
|
mods_refresh_local();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "audio/audio_null.h"
|
#include "audio/audio_null.h"
|
||||||
|
|
||||||
#include "pc_main.h"
|
#include "pc_main.h"
|
||||||
|
#include "loading.h"
|
||||||
#include "cliopts.h"
|
#include "cliopts.h"
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
#include "controller/controller_api.h"
|
#include "controller/controller_api.h"
|
||||||
|
|
@ -238,8 +239,10 @@ void audio_shutdown(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_deinit(void) {
|
void game_deinit(void) {
|
||||||
smlua_call_event_hooks(HOOK_ON_EXIT);
|
if (gGameInited) {
|
||||||
configfile_save(configfile_name());
|
smlua_call_event_hooks(HOOK_ON_EXIT);
|
||||||
|
configfile_save(configfile_name());
|
||||||
|
}
|
||||||
controller_shutdown();
|
controller_shutdown();
|
||||||
audio_custom_shutdown();
|
audio_custom_shutdown();
|
||||||
audio_shutdown();
|
audio_shutdown();
|
||||||
|
|
@ -256,24 +259,28 @@ void game_exit(void) {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_func(void) {
|
void *main_game_init(void*) {
|
||||||
const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR;
|
const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR;
|
||||||
const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path();
|
const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path();
|
||||||
fs_init(sys_ropaths, gamedir, userpath);
|
fs_init(sys_ropaths, gamedir, userpath);
|
||||||
|
|
||||||
sync_objects_init_system();
|
dynos_gfx_init();
|
||||||
djui_unicode_init();
|
|
||||||
djui_init();
|
|
||||||
dynos_packs_init();
|
|
||||||
mods_init();
|
|
||||||
|
|
||||||
// load config
|
// load config
|
||||||
configfile_load();
|
configfile_load();
|
||||||
if (!djui_language_init(configLanguage)) {
|
configWindow.settings_changed = true;
|
||||||
snprintf(configLanguage, MAX_CONFIG_STRING, "%s", "");
|
if (!djui_language_init(configLanguage)) { snprintf(configLanguage, MAX_CONFIG_STRING, "%s", ""); }
|
||||||
}
|
dynos_packs_init();
|
||||||
|
sync_objects_init_system();
|
||||||
|
|
||||||
dynos_pack_init();
|
mods_init();
|
||||||
|
enable_queued_mods();
|
||||||
|
if (gIsThreaded) {
|
||||||
|
REFRESH_MUTEX(
|
||||||
|
gCurrLoadingSegment.percentage = 0;
|
||||||
|
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)
|
// 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
|
// But if no preset is found, that means the current palette is a custom palette
|
||||||
|
|
@ -292,7 +299,6 @@ void main_func(void) {
|
||||||
if (gCLIOpts.FullScreen == 1) { configWindow.fullscreen = true; }
|
if (gCLIOpts.FullScreen == 1) { configWindow.fullscreen = true; }
|
||||||
else if (gCLIOpts.FullScreen == 2) { configWindow.fullscreen = false; }
|
else if (gCLIOpts.FullScreen == 2) { configWindow.fullscreen = false; }
|
||||||
|
|
||||||
// incase the loading screen failed, or is disabled
|
|
||||||
if (!gGfxInited) {
|
if (!gGfxInited) {
|
||||||
gfx_init(&WAPI, &RAPI, TITLE);
|
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);
|
WAPI.set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up, keyboard_on_text_input);
|
||||||
|
|
@ -310,9 +316,36 @@ void main_func(void) {
|
||||||
|
|
||||||
thread5_game_loop(NULL);
|
thread5_game_loop(NULL);
|
||||||
|
|
||||||
|
gGameInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
// Handle terminal arguments
|
||||||
|
if (!parse_cli_opts(argc, argv)) { return 0; }
|
||||||
|
|
||||||
|
// Create the window straight away
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the thread for setting up the game
|
||||||
|
if (pthread_mutex_init(&gLoadingThreadMutex, NULL) == 0 && pthread_create(&gLoadingThreadId, NULL, main_game_init, (void*) 1) == 0) {
|
||||||
|
gIsThreaded = true;
|
||||||
|
render_loading_screen(); // Render the loading screen while the game is setup
|
||||||
|
gIsThreaded = false;
|
||||||
|
} else {
|
||||||
|
main_game_init(NULL); // Failsafe incase threading doesn't work
|
||||||
|
}
|
||||||
|
pthread_mutex_destroy(&gLoadingThreadMutex);
|
||||||
|
|
||||||
|
// Initialize djui
|
||||||
|
djui_init();
|
||||||
|
djui_unicode_init();
|
||||||
djui_init_late();
|
djui_init_late();
|
||||||
|
|
||||||
// init network
|
// Init network
|
||||||
if (gCLIOpts.Network == NT_CLIENT) {
|
if (gCLIOpts.Network == NT_CLIENT) {
|
||||||
network_set_system(NS_SOCKET);
|
network_set_system(NS_SOCKET);
|
||||||
snprintf(gGetHostName, MAX_CONFIG_STRING, "%s", gCLIOpts.JoinIp);
|
snprintf(gGetHostName, MAX_CONFIG_STRING, "%s", gCLIOpts.JoinIp);
|
||||||
|
|
@ -322,6 +355,12 @@ void main_func(void) {
|
||||||
} else if (gCLIOpts.Network == NT_SERVER) {
|
} else if (gCLIOpts.Network == NT_SERVER) {
|
||||||
network_set_system(NS_SOCKET);
|
network_set_system(NS_SOCKET);
|
||||||
configHostPort = gCLIOpts.NetworkPort;
|
configHostPort = gCLIOpts.NetworkPort;
|
||||||
|
|
||||||
|
// Horrible, hacky fix for mods that access marioObj straight away
|
||||||
|
// best fix: host with the standard main menu method
|
||||||
|
static struct Object sHackyObject = { 0 };
|
||||||
|
gMarioStates[0].marioObj = &sHackyObject;
|
||||||
|
|
||||||
network_init(NT_SERVER, false);
|
network_init(NT_SERVER, false);
|
||||||
djui_panel_shutdown();
|
djui_panel_shutdown();
|
||||||
djui_panel_modlist_create(NULL);
|
djui_panel_modlist_create(NULL);
|
||||||
|
|
@ -329,8 +368,7 @@ void main_func(void) {
|
||||||
network_init(NT_NONE, false);
|
network_init(NT_NONE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
gGameInited = true;
|
// Main loop
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
debug_context_reset();
|
debug_context_reset();
|
||||||
CTX_BEGIN(CTX_FRAME);
|
CTX_BEGIN(CTX_FRAME);
|
||||||
|
|
@ -346,10 +384,5 @@ void main_func(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bassh_deinit();
|
bassh_deinit();
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
parse_cli_opts(argc, argv);
|
|
||||||
main_func();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ extern bool gCoopCompatibility;
|
||||||
#define TITLE "sm64coopdx"
|
#define TITLE "sm64coopdx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOAD_STEPS 6
|
|
||||||
|
|
||||||
#define AT_STARTUP __attribute__((constructor))
|
#define AT_STARTUP __attribute__((constructor))
|
||||||
|
|
||||||
extern bool gGameInited;
|
extern bool gGameInited;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue