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) {
printf("sm64coopdx\n");
#if defined(_WIN32) || defined(_WIN64)
printf("--console Enables the Windows console.\n");
printf("--console Enables the Windows console.\n");
#endif
printf("--savepath SAVEPATH Overrides the default save/config path ('!' expands to executable path).\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("--no-discord Disables discord integration.\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) {
@ -112,6 +113,8 @@ bool parse_cli_opts(int argc, char* argv[]) {
gCLIOpts.enableMods = realloc(gCLIOpts.enableMods, sizeof(char*) * gCLIOpts.enabledModsCount);
}
gCLIOpts.enableMods[gCLIOpts.enabledModsCount - 1] = strdup(argv[++i]);
} else if (!strcmp(argv[i], "--headless")) {
gCLIOpts.headless = true;
} else if (!strcmp(argv[i], "--help")) {
print_help();
return false;

View file

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

View file

@ -49,7 +49,7 @@ static void _debuglog_print_log(const char* logType, char* filename) {
#define LOG_ERROR(...)
#else
#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)
#endif
#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
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
@ -247,5 +245,4 @@ struct GfxRenderingAPI gfx_dummy_renderer_api = {
gfx_dummy_renderer_end_frame,
gfx_dummy_renderer_finish_render,
gfx_dummy_renderer_shutdown
};
#endif
};

View file

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

View file

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