diff --git a/assets/Menu.singe b/assets/Menu.singe index 4aac9f5c4..3380dfa27 100644 --- a/assets/Menu.singe +++ b/assets/Menu.singe @@ -423,7 +423,7 @@ local function loadGamesDat(source, container) -- Packed game: the engine opens its files through the database, and so does the menu. value.CONTAINER = container for _, key in ipairs({ "CABINET", "MARQUEE", "ATTRACT" }) do - if value[key] then + if value[key] and value[key]:sub(1, 6):lower() ~= "singe/" then value[key] = container .. "/" .. value[key] end end diff --git a/src/main.c b/src/main.c index e962684de..da3babd1f 100644 --- a/src/main.c +++ b/src/main.c @@ -66,6 +66,7 @@ #define MIXER_CHANNELS 2 #define MIXER_CHUNK_SAMPLES "1024" // Device buffer, kept small so the audio queue and any error in measuring it stay small #define USAGE_OPTION_WIDTH 27 +#define USAGE_LINE_WIDTH 79 // Help text wraps so no line is wider than this #define CRASH_FRAMES_MAX 64 @@ -127,12 +128,12 @@ static const OptionT _options[] = { { 'm', "nomouse", ap_no, NULL, "disable mouse", false }, { 'n', "nocrosshair", ap_no, NULL, "request game not display gun crosshairs", false }, { 'o', "audio", ap_yes, "TRACK", "select default track for audio output", false }, - { 'P', "pack", ap_yes, "DIRECTORY", "pack a game DIRECTORY into the .game (or changed files into the .patch) named after the options", false }, + { 'P', "pack", ap_yes, "DIRECTORY", "pack the game in DIRECTORY into the .game named after the options, or changed files into a .patch", false }, { 'p', "program", ap_no, NULL, "trace Singe execution to screen and file", false }, { 's', "nosound", ap_no, NULL, "mutes all sound", false }, - { 'T', "patch", ap_yes, "DATABASE", "patch a game DATABASE from the directory or .patch named after the options", false }, + { 'T', "patch", ap_yes, "DATABASE", "patch the game DATABASE from the directory or .patch named after the options", false }, { 't', "trace", ap_no, NULL, "trace script execution to screen and file", false }, - { 'U', "unpack", ap_yes, "DATABASE", "unpack a game or patch DATABASE into the directory named after the options", false }, + { 'U', "unpack", ap_yes, "DATABASE", "unpack the game or patch DATABASE into the directory named after the options", false }, { 'u', "stretch", ap_no, NULL, "use ugly stretched video", false }, { 'v', "framefile", ap_yes, "FILENAME", "use an alternate video file", false }, { 'w', "fullscreen_window", ap_no, NULL, "run in windowed full screen mode", false }, @@ -898,8 +899,13 @@ static bool _runTool(const ConfigT *conf) { static void _showUsage(const char *name, const char *message) { - int32_t x = 0; - char *longForm = NULL; + const int32_t helpColumn = 6 + USAGE_OPTION_WIDTH; // " -x, " plus the padded long form + const int32_t helpWidth = USAGE_LINE_WIDTH - helpColumn; + const char *help = NULL; + const char *end = NULL; + const char *space = NULL; + int32_t x = 0; + char *longForm = NULL; _showHeader(); @@ -914,7 +920,28 @@ static void _showUsage(const char *name, const char *message) { } else { longForm = utilCreateString("--%s", _options[x].name); } - utilSay(" -%c, %-*s%s", _options[x].code, USAGE_OPTION_WIDTH, longForm, _options[x].help); + // Wrap the help at word boundaries; continuation lines start in the help column. + help = _options[x].help; + while (help != NULL) { + end = help + strlen(help); + if ((end - help) > helpWidth) { + end = help + helpWidth; + for (space = end; (space > help) && (*space != ' '); space--) { + } + if (space > help) { + end = space; + } + } + if (help == _options[x].help) { + utilSay(" -%c, %-*s%.*s", _options[x].code, USAGE_OPTION_WIDTH, longForm, (int)(end - help), help); + } else { + utilSay("%*s%.*s", helpColumn, "", (int)(end - help), help); + } + while (*end == ' ') { + end++; + } + help = (*end != 0) ? end : NULL; + } free(longForm); } utilNewline(); diff --git a/src/vfs.c b/src/vfs.c index 877b90c43..679207356 100644 --- a/src/vfs.c +++ b/src/vfs.c @@ -390,6 +390,13 @@ static bool _resolve(const char *name, TargetT *target) { inner = norm; } + // The engine's own files are never inside a game, however the name reached us. + if ((target->db != NULL) && _isEngineName(inner)) { + target->db = NULL; + target->path = strdup(inner); + free(norm); + return true; + } if (target->db == NULL) { target->path = strdup(name); free(norm);