Headless mode as a CLI option (#639)

This commit is contained in:
Cooliokid956 2025-01-27 18:19:38 -06:00 committed by GitHub
parent 6bdfe56f1e
commit 42e0051dda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 25 additions and 16 deletions

View file

@ -15,7 +15,7 @@ struct CLIOptions gCLIOpts;
static void print_help(void) { static void print_help(void) {
printf("sm64coopdx\n"); printf("sm64coopdx\n");
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
printf("--console Enables the Windows console.\n"); printf("--console Enables the Windows console.\n");
#endif #endif
printf("--savepath SAVEPATH Overrides the default save/config path ('!' expands to executable path).\n"); printf("--savepath SAVEPATH Overrides the default save/config path ('!' expands to executable path).\n");
printf("--configfile CONFIGNAME Saves the configuration file as CONFIGNAME.\n"); printf("--configfile CONFIGNAME Saves the configuration file as CONFIGNAME.\n");
@ -33,7 +33,8 @@ static void print_help(void) {
printf("--skip-update-check Skips the update check when loading the game.\n"); printf("--skip-update-check Skips the update check when loading the game.\n");
printf("--no-discord Disables discord integration.\n"); printf("--no-discord Disables discord integration.\n");
printf("--disable-mods Disables all mods that are already enabled.\n"); printf("--disable-mods Disables all mods that are already enabled.\n");
printf("--enable-mod MODNAME Enables a mod."); printf("--enable-mod MODNAME Enables a mod.\n");
printf("--headless Enable Headless mode.");
} }
static inline int arg_string(const char *name, const char *value, char *target, int maxLength) { static inline int arg_string(const char *name, const char *value, char *target, int maxLength) {
@ -112,6 +113,8 @@ bool parse_cli_opts(int argc, char* argv[]) {
gCLIOpts.enableMods = realloc(gCLIOpts.enableMods, sizeof(char*) * gCLIOpts.enabledModsCount); gCLIOpts.enableMods = realloc(gCLIOpts.enableMods, sizeof(char*) * gCLIOpts.enabledModsCount);
} }
gCLIOpts.enableMods[gCLIOpts.enabledModsCount - 1] = strdup(argv[++i]); gCLIOpts.enableMods[gCLIOpts.enabledModsCount - 1] = strdup(argv[++i]);
} else if (!strcmp(argv[i], "--headless")) {
gCLIOpts.headless = true;
} else if (!strcmp(argv[i], "--help")) { } else if (!strcmp(argv[i], "--help")) {
print_help(); print_help();
return false; return false;

View file

@ -36,6 +36,7 @@ struct CLIOptions {
bool disableMods; bool disableMods;
int enabledModsCount; int enabledModsCount;
char** enableMods; char** enableMods;
bool headless;
}; };
extern struct CLIOptions gCLIOpts; extern struct CLIOptions gCLIOpts;

View file

@ -49,7 +49,7 @@ static void _debuglog_print_log(const char* logType, char* filename) {
#define LOG_ERROR(...) #define LOG_ERROR(...)
#else #else
#define LOG_DEBUG(...) (configDebugPrint ? ( _debuglog_print_log("DEBUG", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_DEBUG(...) (configDebugPrint ? ( _debuglog_print_log("DEBUG", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#define LOG_INFO(...) (configDebugInfo ? ( _debuglog_print_log("INFO", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_INFO(...) ((configDebugInfo || gCLIOpts.headless) ? ( _debuglog_print_log("INFO", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#define LOG_ERROR(...) (configDebugError ? ( _debuglog_print_log("ERROR", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0) #define LOG_ERROR(...) (configDebugError ? ( _debuglog_print_log("ERROR", __FILE__), printf(__VA_ARGS__), printf("\n") ) : 0)
#endif #endif
#define LOG_CONSOLE(...) { snprintf(gDjuiConsoleTmpBuffer, CONSOLE_MAX_TMP_BUFFER, __VA_ARGS__), djui_console_message_create(gDjuiConsoleTmpBuffer, CONSOLE_MESSAGE_INFO); } #define LOG_CONSOLE(...) { snprintf(gDjuiConsoleTmpBuffer, CONSOLE_MAX_TMP_BUFFER, __VA_ARGS__), djui_console_message_create(gDjuiConsoleTmpBuffer, CONSOLE_MESSAGE_INFO); }

View file

@ -1,5 +1,3 @@
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L #elif _POSIX_C_SOURCE >= 199309L
@ -247,5 +245,4 @@ struct GfxRenderingAPI gfx_dummy_renderer_api = {
gfx_dummy_renderer_end_frame, gfx_dummy_renderer_end_frame,
gfx_dummy_renderer_finish_render, gfx_dummy_renderer_finish_render,
gfx_dummy_renderer_shutdown gfx_dummy_renderer_shutdown
}; };
#endif

View file

@ -132,11 +132,7 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) {
gServerSettings.maxPlayers = configAmountOfPlayers; gServerSettings.maxPlayers = configAmountOfPlayers;
gServerSettings.pauseAnywhere = configPauseAnywhere; gServerSettings.pauseAnywhere = configPauseAnywhere;
gServerSettings.pvpType = configPvpType; gServerSettings.pvpType = configPvpType;
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY) gServerSettings.headlessServer = gCLIOpts.headless && (inNetworkType == NT_SERVER);
gServerSettings.headlessServer = (inNetworkType == NT_SERVER);
#else
gServerSettings.headlessServer = 0;
#endif
gNametagsSettings.showHealth = false; gNametagsSettings.showHealth = false;
gNametagsSettings.showSelfTag = false; gNametagsSettings.showSelfTag = false;

View file

@ -411,9 +411,13 @@ int main(int argc, char *argv[]) {
// handle terminal arguments // handle terminal arguments
if (!parse_cli_opts(argc, argv)) { return 0; } if (!parse_cli_opts(argc, argv)) { return 0; }
#if defined(RAPI_DUMMY) || defined(WAPI_DUMMY)
gCLIOpts.headless = true;
#endif
#ifdef _WIN32 #ifdef _WIN32
// handle Windows console // handle Windows console
if (gCLIOpts.console) { if (gCLIOpts.console || gCLIOpts.headless) {
SetConsoleOutputCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);
} else { } else {
FreeConsole(); FreeConsole();
@ -433,6 +437,13 @@ int main(int argc, char *argv[]) {
fs_init(gCLIOpts.savePath[0] ? gCLIOpts.savePath : sys_user_path()); fs_init(gCLIOpts.savePath[0] ? gCLIOpts.savePath : sys_user_path());
#endif #endif
#if !defined(RAPI_DUMMY) && !defined(WAPI_DUMMY)
if (gCLIOpts.headless) {
memcpy(&WAPI, &gfx_dummy_wm_api, sizeof(struct GfxWindowManagerAPI));
memcpy(&RAPI, &gfx_dummy_renderer_api, sizeof(struct GfxRenderingAPI));
}
#endif
configfile_load(); configfile_load();
legacy_folder_handler(); legacy_folder_handler();
@ -460,7 +471,7 @@ int main(int argc, char *argv[]) {
// start the thread for setting up the game // start the thread for setting up the game
#ifdef LOADING_SCREEN_SUPPORTED #ifdef LOADING_SCREEN_SUPPORTED
bool threadSuccess = false; bool threadSuccess = false;
if (!gCLIOpts.hideLoadingScreen) { if (!gCLIOpts.hideLoadingScreen && !gCLIOpts.headless) {
if (init_thread_handle(&gLoadingThread, main_game_init, NULL, NULL, 0) == 0) { if (init_thread_handle(&gLoadingThread, main_game_init, NULL, NULL, 0) == 0) {
render_loading_screen(); // render the loading screen while the game is setup render_loading_screen(); // render the loading screen while the game is setup
threadSuccess = true; threadSuccess = true;
@ -477,10 +488,11 @@ int main(int argc, char *argv[]) {
thread5_game_loop(NULL); thread5_game_loop(NULL);
// initialize sound outside threads // initialize sound outside threads
if (gCLIOpts.headless) audio_api = &audio_null;
#if defined(AAPI_SDL1) || defined(AAPI_SDL2) #if defined(AAPI_SDL1) || defined(AAPI_SDL2)
if (!audio_api && audio_sdl.init()) { audio_api = &audio_sdl; } if (!audio_api && audio_sdl.init()) audio_api = &audio_sdl;
#endif #endif
if (!audio_api) { audio_api = &audio_null; } if (!audio_api) audio_api = &audio_null;
// Initialize the audio thread if possible. // Initialize the audio thread if possible.
// init_thread_handle(&gAudioThread, audio_thread, NULL, NULL, 0); // init_thread_handle(&gAudioThread, audio_thread, NULL, NULL, 0);