mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
* Shadow overhaul round 2: PCSS, dynamic cascades, cockpit/instanced shadows Squashed snapshot of lafiel/shadow_overhaul_2's continuation work (d3922aa87..010f9d2d9), which has no separate upstream PR of its own. * Add Vulkan rendering backend Squashed snapshot of the Vulkan backend as vendored into this branch (ce2d1e85f..6ce539463, authored by Mara van der Laan with build/CI fixes by Taylor Richards). This work has its own upstream PR #7553 (notimaginative:vulkan-pr-new) and is not otherwise original to true-hdr. * Add true HDR output, RT shadows, and PCSS shadows for Vulkan Squashed snapshot of true-hdr's own integration work: true HDR framebuffer output, wiring the shadow overhaul into the Vulkan backend (raytraced + cascaded shadow maps), logging refactors, log filter UI, and CI/build fixes. * refactor: update Vulkan logging calls to use `nprintf` for scoped logging * fix: correct shadow cascade count in Vulkan logging calls * fix: fall back to PATH-resolved ccache when CCACHE_PATH is stale CI hardcodes /usr/local/bin/ccache, but macOS runners on Apple Silicon hosts install Homebrew (and ccache) under /opt/homebrew instead, causing all four Mac configs to fail with "No such file or directory". * Fix vulkan texture readback to correctly handle transparent pipelines * Put the pixel swizzles into a util file * OOB safety check * Fix fog handling * Fix MSAA in Vulkan * fix: enable SMAA for vulkan * adapt the post-processing AA shaders to hdr * fix clang-tidy warnings: concatenate nested namespaces, static methods pixel_swizzle.{h,cpp}: collapse `namespace graphics { namespace util {` into `namespace graphics::util {` (modernize-concat-nested-namespaces). VulkanState.h/VulkanDraw.h: getClearColor()/setClearColor() only touch gr_screen and other globals, no instance state, so make them static (readability-convert-member-functions-to-static) and drop the top-level const on getClearColor()'s return type (readability-const-return-type). * fix clang-tidy warning * Extend raytraced shadows to all directional lights RT shadows previously only shadowed the first directional light in the scene, even though multi-sun missions push more than one directional light into the engine. The TLAS raytraced shadows query against is already light-agnostic, so this extends both the deferred lighting pass and the forward MODEL shader to shadow every directional light (capped by a new Max Raytraced Shadow Lights option, configurable via the in-game Options menu or the Lab's Scene rendering options). Cascaded shadow maps are untouched: they're built for a single light only, so the deferred pass still limits itself to one shadowed directional light whenever CSM (not raytracing) is the active method. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_016DA6JHJ3twz2oHGQcZ1Udc * refactor: improve shader flag handling and render target finalization in Vulkan backend - Consolidate shader flag setup logic in VulkanPostProcessingLighting to simplify configuration. - Fix dead field usage in VulkanDraw by ensuring correct image view selection for environment maps. - Add mip chain regeneration in VulkanRenderer::endRenderTarget to ensure correct mip levels for cubemaps. * fix: ensure correct mip chain initialization in cubemap rendering - Add mip chain generation to VulkanDraw for cubemaps with multiple mip levels. - Fix potential issue with uninitialized mip levels above level 0 in deferred-f.sdr sampling paths. * fix: don't crash on startup when environment locale is unavailable std::locale("") pulls in the process's environment locale categories (LC_CTYPE, LC_MONETARY, LC_PAPER, etc.), and throws std::runtime_error if any of them names a locale not installed on the host (e.g. mismatched regional-format overrides). Since SCP_default_locale is constructed during static initialization, before main() and before any of our own exception handling exists, an uncaught throw here aborted the whole process before the game even started. Fall back to the classic "C" locale instead, which is sufficient since this locale is only ever used for ASCII case-folding (SCP_toupper/tolower/isdigit). Co-Authored-By: Claude Sonnet 5 <[email protected]> * `feat: add raytraced shadows for local lights and optimize TLAS management` * Make the Commandline authoritative for -res and -vulkan / -opengl * address BMagnu's comments on the original PR * update prebuilt version hash to 62c89ef6 * refactor: standardize graphics API handling and document Vulkan limitations in qtFRED - Updated `AboutDialogModel.cpp` to use `GraphicsAPI` enum for better clarity. - Ensured qtFRED falls back to OpenGL when Vulkan is requested. - Added detailed documentation in `qtfred/README.md` regarding Vulkan backend limitations and requirements. * chore: include cmdline library in main and mission management modules * docs: add known issue for blank render viewport under Wayland in README.md * fix CI issues * chore: add `GR_DEBUG_SCOPE` markers across Vulkan post-processing and rendering paths for improved debugging * feat: improve Vulkan HDR pipeline with separate encode paths for SDR and HDR10 - Added an HDR10-specific output encode pass in `VulkanRenderer` and `VulkanPostProcessor` that applies PQ/BT.2020 transfer. - Introduced an optimized SDR fallback path with direct blit support for devices that can skip shader draws. - Updated `m_sceneLdrCompressed` to provide [0,1]-clamped proxies for HDR edge detection. - Refactored `copyImageToImage` and added `blitImageToImage` to allow format conversions and optimized transfers. - Replaced `hdr_mode` with explicit HDR10 flags and data structures for clearer state handling. * refactor: encapsulate SMAA processing and refactor VulkanPostProcessor - Moved SMAA-specific logic into `VulkanSMAA` class for better separation of concerns. - Simplified `initSMAA`, `shutdownSMAA`, and `executeSMAA` logic by leveraging `VulkanLDR` and `PostProcessContext` abstractions. - Improved initialization and cleanup code with clearer resource lifecycle management. - Updated debug markers and messages to reference `VulkanSMAA`. - Enhanced flexibility of fullscreen triangle rendering API with additional parameters (`sampleCount`, `bindGlobalSet`). * Update Vulkan porting credits in AboutDialogModel * fix CI issues again * fix: correct Y-flip in viewport setup for Vulkan light volumes - Adjusted viewport height to negative value to account for G-buffer render pass's negative Y-axis convention. - Ensured proper alignment of point and tube light volumes with actual light positions. * feat: add user-adjustable gamma correction to SDR and HDR10 output paths - Added gamma correction to HDR10 path, applying user settings before PQ/BT.2020 encode. - Replaced the SDR blit-only path with an encode pass that applies gamma correction, ensuring consistent behavior across devices. - Refactored VulkanPostProcessor and associated shaders to support gamma slider adjustments for both SDR and HDR output. * fix: ensure proper uniform and cull mode setup for Vulkan sphere rendering - Added uniform buffer setup and default material uniforms in `vulkan_draw_sphere`. - Disabled face culling in material definition for sphere rendering to align behavior with OpenGL. * Ensure memory flushes after UBO updates and add explicit pipeline barrier for MoltenVK compatibility. * fix: add clear pass for SMAA edge detection to prevent persistent artifacts * feat: add Vulkan debug-utils messenger, opt-in sync validation, frame diagnostics Groundwork for the renderer-review fix series (.agents/plans/ vulkan-renderer-review-fixes.md, Phase 0): - Register a VK_EXT_debug_utils messenger (preferred) instead of only the deprecated VK_EXT_debug_report callback, which is kept as a fallback for loaders without debug-utils. The messenger config is also chained into instance creation so vkCreateInstance-time messages are captured. Validation errors/warnings now go to the main log via mprintf. - New -gr_sync_validation cmdline flag (implies -gr_debug): chains VkValidationFeaturesEXT with synchronization validation into instance creation when VK_LAYER_KHRONOS_validation is available. This is the regression net for the synchronization fixes in the following commits. - Frame stats now report descriptor sets/writes allocated per frame and the total pipeline count (descriptor-manager counters; DescriptorWriter::flush moved out-of-line to report into the manager). Co-Authored-By: Claude Fable 5 <[email protected]> * refactor: unify Vulkan render-pass begins, clamp in-pass clears, add per-frame UBO ring Phase 1 of the renderer-review fix series: shared helpers that the correctness fixes build on. - New VulkanRenderer::beginTrackedRenderPass(PassBeginDesc): every render-pass begin on the frame command buffer now records vkCmdBeginRenderPass and updates the state tracker (pass, color attachment count, sample count, render area, viewport) in one place. Converted: setupFrame, beginSceneRendering (both branches), resumeSceneRendering, endSceneRendering, beginRenderTarget (viewport kept for gr_set_viewport), resumeSwapChainPass, plus new resumeScenePassAfterCopy() shared by copyEffectTexture/copySceneDepthForParticles and rebeginSwapChainPassAfterReadback() shared by both readbackFramebuffer exits (~200 lines of duplicated begin/clear/viewport blocks removed). - The state tracker records the active render area; all four vkCmdClearAttachments sites clamp their rects against it and skip empty results. Previously gr_screen-sized clear rects could exceed a smaller off-screen render target's render area, which is invalid API usage. - New PerFrameUboRing utility (VulkanPerFrameUbo.h/.cpp): a persistently mapped uniform buffer with one slot region per frame in flight and a self-flushing alloc(). Used by the next commit to fix the cross-frame UBO races. Deliberate behavior deltas (all safe-direction): the helper always sets colorAttachmentCount/sampleCount (some sites previously inherited stale values), and resumeSwapChainPass/resumeSceneRendering now also reset the standard flipped viewport instead of leaving the previous one. Co-Authored-By: Claude Fable 5 <[email protected]> * fix: eliminate Vulkan cross-frame UBO/buffer races, make gr_sync honest Phase 2 of the renderer-review fix series: with two frames in flight, several host-visible resources were rewritten by the CPU while the previous frame's GPU work could still be reading them. - The post-processing scratch UBO is now a PerFrameUboRing (per-frame-in- flight slot regions, persistently mapped, self-flushing alloc). All the per-pass map/unmap/cursor bookkeeping in bloom/LDR/fog/SMAA is deleted; the cursor resets exactly once per frame via the new VulkanPostProcessor::beginFrame() hook in setupFrame. This also fixes two latent bugs: (a) fog consumed scratch slots mid-scene and bloom's later same-frame cursor reset overwrote them before submission whenever fog+bloom were both active; (b) volumetric_fog_data (288 bytes) overflowed the 256-byte slots - the memcpy spilled into the neighboring slot and the shader's bound range ended before the aspect/fov/noise fields. Slots are now 512 bytes (static_assert at the fog call site) and the per-frame budget is 32 slots. - The dedicated tonemap, output-encode, and MSAA-resolve UBOs (each a single instance rewritten per frame, i.e. racy; the MSAA one also never flushed) are deleted entirely - those passes build their structs on the stack and allocate from the scratch ring. - Static-buffer rewrites orphan instead of racing: getVkBuffer() stamps a last-used frame number, and a full-content updateBufferData() on a Static buffer used within the last MAX_FRAMES_IN_FLIGHT frames defers the old VkBuffer to the deletion queue and writes a fresh one. Offset writes (GPU-heap appends to fresh regions) and PersistentMapping buffers (the engine holds their mapped pointer and syncs via gr_sync) are exempt. - gr_sync_wait now honors its contract: VulkanRenderFrame::waitForFinish takes a timeout and reports expiry without consuming the fence; VulkanRenderer::waitForFrame returns false for fences taken during the still-recording frame (previously it waited on a stale or idle slot and reported success) and resolves the frame->slot mapping correctly. This makes UniformBufferManager's segment-fence throttling actually protective on Vulkan for the first time. Co-Authored-By: Claude Fable 5 <[email protected]> * Refactor framebuffer and target lifecycle: centralized creation/resizing logic, improved resource management across Vulkan post-processing subsystems. * Improve Vulkan cross-frame sync with explicit access masks and validation updates - Unified Vulkan validation flag handling in setup, separating engine debug output from synchronization validation. - Specified access masks and stage flags to address cross-frame WRITE_AFTER_WRITE vulnerabilities, notably in G-buffer, post-processing, and MSAA resolve paths. - Adjusted subpass dependencies and image layout transitions to prevent read-after-write and write-after-write hazards, detected using `-gr_sync_validation`. - Fixed uniform buffer and barrier transitions to ensure proper ordering in render passes across frames. * Refactor Vulkan render-pass dependencies and sync stages for clarity and future testing - Clarified dependency logic for cross-pass and cross-frame synchronization, ensuring explicit stage and access flag comments match observed behavior. - Adjusted subpass dependencies to decouple render-pass compatibility definitions from dependency assumptions. - Highlighted MoltenVK-specific issues and retained workarounds with notes for re-testing on macOS hardware. - Updated synchronization barriers and validation notes to address historical inconsistencies across platforms. * Remove transfer queue support; consolidate all operations into the graphics queue - Removed transfer queue handling, simplifying buffer and queue logic to use the graphics queue for all transfer operations. - Updated buffer sharing modes and removed related code paths and parameters for transfer queue families. - Introduced exclusive buffer access, noting async transfer and queue ownership transfers are future work. - Limited enabled device features to only those actively used by the renderer, reducing unnecessary feature requests (e.g., robustBufferAccess). * Refactor frame advancement and descriptor management in VulkanRenderer - Removed `endFrame()` from `VulkanDescriptorManager`, replacing it with `setCurrentFrame(frameIndex)` for explicit frame synchronization. - Centralized frame index advancement within `VulkanRenderer` to ensure consistency across components. - Invalidated cached descriptor set bindings at render-pass boundaries to handle raw recorder staleness correctly. - Optimized pipeline descriptor rebind logic by removing redundant clears during pipeline changes. * Refactor `PipelineConfig::hash` and Global descriptor set management for improved hashing and memoization efficiency - Replaced inefficient shift-based hashing in `PipelineConfig::hash` with a robust `hashCombine` strategy to minimize bucket collisions. - Introduced `maskBits` helper to streamline bitmask creation for boolean fields. - Implemented memoization for Global (Set 0) descriptor sets, reducing redundant rebuilds across frames and improving performance. - Added dirty state tracking (`m_globalSetDirty`) and invalidation logic for Global set updates following relevant input changes (e.g., TLAS or UBO modifications). * Refactor Vulkan post-processing output logic: extracted shared `encodeToSwapChainPass` method to streamline HDR and SDR output paths. * Optimize Vulkan descriptor set management with per-frame memoization - Added memoization for Material (Set 1) and PerDraw (Set 2) descriptor sets to reuse cached sets across frames if inputs remain unchanged. - Implemented precise input tracking for Material and PerDraw descriptor sets to detect and rebuild only when necessary. - Reduced redundant Vulkan descriptor allocations and writes, improving performance on repeated or batched draw calls. * Fix Vulkan access masks for G-buffer and scene pass transitions - Added `eColorAttachmentRead` to access masks in multiple barriers to ensure proper synchronization for load operations (e.g., `loadOp=eLoad`) across render passes. - Prevented `READ_AFTER_WRITE` synchronization validation issues in deferred and multi-pass rendering scenarios. - Updated comments to clarify the reasoning behind the access mask changes and load dependencies. * Refactor Vulkan resource management and indexed draw logic - Consolidated destruction queue methods in `VulkanDeletionQueue` using a shared `queueHandle` template to reduce redundancy. - Introduced `ModelDrawParams` structure and `computeModelDrawParams` function to unify indexed draw parameters for models and shadows. - Simplified draw logic by eliminating repeated calculation of indexed draw parameters and improving code reuse. * Add `releaseAnimationSlotRef` for ref-count handling of shared animation texture arrays - Introduced `releaseAnimationSlotRef` to manage reference counting for shared animation texture-array slots, preventing premature destruction of shared resources. - Updated `flushTextures` and related methods to integrate `releaseAnimationSlotRef` for shared slot cleanup. - Refactored staging buffer creation into `createStagingBuffer` for 3D texture uploads and shared path consistency. - Enhanced texture upload logic with improved tracking and logging for re-upload cases, aiding preloading gap analysis. - Added instrumentation for on-demand mid-frame texture uploads in `FrameStats`. * Refactor Vulkan resource and texture management, extend debug logging - Updated smart pointer usage for consistency across Vulkan resource managers (`std::make_unique`). - Removed redundant `cubeImageView` member and related cleanup logic; unified sampling view management. - Added per-instance debug log counters (avoiding static state) for Vulkan texture uploads and bindings, improving visibility during initialization and run-time. - Optimized `VulkanRenderer` property/feature getters by caching physical device properties and features during device creation. - Improved memory region flushing logic for out-of-date offsets, aligning with Vulkan Memory Allocator behavior. - Refactored render pass state tracking to reapply dynamic state reliably after mid-frame render passes. - Enhanced validation and error handling for mismatched update texture formats. * fix CI build warning * Fix on-demand YUV texture locking and set alpha uniform for movie rendering in Vulkan - Corrected bitmap lock type from `BMP_TEX_OTHER` to `BMP_AABITMAP` for YUV textures during on-demand loading. - Updated movie rendering to bind alpha from the `MovieData` UBO (set 2, binding 4) for Vulkan, aligning behavior with OpenGL implementation. * revert inadvertent changes introduced by a squash commit * address ci issues * remove wip stuff from code comments that make no sense to people who aren't me * Remove unused LD_LIBRARY_PATH export and fix shader shadow map sampling. * Refactor batched rendering uniform setup in Vulkan - Removed unused fields from `genericData` uniform block, simplifying shader definitions. - Updated Vulkan material uniform handling to align with OpenGL's batched rendering logic. - Introduced `batched_data` struct for streamlined UBO updates, improving maintainability and clarity. * Add `-hdr` command-line option for HDR nits configuration - Introduced `-hdr` parameter to set paper white and peak luminance in nits, overriding in-game HDR settings. - Added input validation with error feedback for incorrect format. * Remove unused `MODEL_SDR_FLAG_SHADOW_MAP` macro from shader flags * clean up unrelated changes * Invalidate Vulkan state tracker bindings after external command buffer modifications - Added `invalidateExternalBindings()` to `VulkanStateTracker` to handle stale pipelines, descriptors, and dynamic states caused by external Vulkan commands (e.g., ImGui renders mid-pass). - Updated ImGui rendering flow to call `invalidateExternalBindings()` post-draw, ensuring consistent pipeline state for subsequent engine renders. - Adjusted image usage flags to account for `eTransferSrc` in texture readbacks. - Fixed barrier `dstAccessMask` and pipeline stage flags to ensure proper synchronization for image transitions. * Add a few more generically useful lines to the log * Simplify Qt deployment logic and improve handling for system-installed Qt on Linux * add cmdline headers to make qtFred compile * use VK_KHR_synchronization2 for sync and barrier purposes * Simplify and clean up Qt deployment logic in CMake for qtfred * update get_bitmap_from_texture to match the new API * Enhance `-hdr` command-line option to force HDR output and support optional nits configuration with improved input validation and overrides. * Improve Vulkan robustness, add device feature checks, and refine memory/logging. - Added depth clamping support gated by device feature checks, with fallback where unsupported. - Improved deferred lighting UBO overflow handling with user-accessible warnings and buffer size adjustments. - Enhanced Vulkan logging for validation, allocation, and debugging: - Automatic logging for descriptor pool exhaustion/fragmentation. - Vertex format and resource destruction checks. - Notifications for generic layout transitions and volumetric texture uploads. - Consolidated shader logic to ensure Vulkan and OpenGL parity. * Remove HDR10 encode shader and consolidate gamma correction logic for SDR and HDR10. Replace `Verify` assertions with `Assert` * Add braces to conditional in object lighting logic for clarity * Refine Vulkan memory allocation checks with `Verification` for improved error handling and messaging. * Refine VulkanBuffer resize logic to preserve contents with CPU-side copy and add safeguards for non-coherent memory scenarios. * Add detailed comments explaining descriptor array capacity constants in VulkanDescriptorManager * Gate shadow support on depth clamp feature availability and clarify its necessity with improved comments. --------- Co-authored-by: BMagnu <[email protected]> Co-authored-by: Mara van der Laan <[email protected]> Co-authored-by: Claude <[email protected]>
2485 lines
88 KiB
C++
2485 lines
88 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
#include "cmdline/cmdline.h"
|
|
#include "camera/camera.h" //VIEWER_ZOOM_DEFAULT
|
|
#include "cfile/cfilesystem.h"
|
|
#include "fireball/fireballs.h"
|
|
#include "globalincs/linklist.h"
|
|
#include "globalincs/pstypes.h"
|
|
#include "globalincs/systemvars.h"
|
|
#include "globalincs/version.h"
|
|
#include "graphics/openxr.h"
|
|
#include "graphics/shadows.h"
|
|
#include "hud/hudconfig.h"
|
|
#include "io/joy.h"
|
|
#include "network/multi.h"
|
|
#include "network/multi_log.h"
|
|
#include "options/OptionsManager.h"
|
|
#include "osapi/osapi.h"
|
|
#include "osapi/dialogs.h"
|
|
#include "parse/sexp.h"
|
|
#include "scripting/scripting.h"
|
|
#include "sound/openal.h"
|
|
#include "sound/speech.h"
|
|
#include "starfield/starfield.h"
|
|
|
|
#ifdef _WIN32
|
|
#include <io.h>
|
|
#include <direct.h>
|
|
#elif defined(APPLE_APP)
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#endif
|
|
|
|
#ifdef SCP_UNIX
|
|
#include "osapi/osapi.h"
|
|
#include <dirent.h>
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <sstream>
|
|
|
|
#include <jansson.h>
|
|
|
|
// Stupid windows workaround...
|
|
#ifdef MessageBox
|
|
#undef MessageBox
|
|
#endif
|
|
|
|
enum cmdline_arg_type
|
|
{
|
|
AT_NONE =0,
|
|
AT_INT,
|
|
AT_FLOAT,
|
|
AT_STRING
|
|
};
|
|
// values and order MUST match cmdline_arg_type
|
|
const char *cmdline_arg_types[] =
|
|
{
|
|
"NONE",
|
|
"INT",
|
|
"FLOAT",
|
|
"STRING",
|
|
};
|
|
|
|
enum class flag_output_type {
|
|
Binary,
|
|
Json_V1,
|
|
};
|
|
|
|
// variables
|
|
class cmdline_parm {
|
|
public:
|
|
cmdline_parm *next, *prev;
|
|
const char *name; // name of parameter, must start with '-' char
|
|
const char *help; // help text for this parameter
|
|
const bool stacks; // whether this arg stacks with each use or is replaced by newest use (should only be used for strings!!)
|
|
char *args; // string value for parameter arguments (NULL if no arguments)
|
|
int name_found; // true if parameter on command line, otherwise false
|
|
const int arg_type; // from enum cmdline_arg_type; used for help
|
|
|
|
cmdline_parm(const char *name, const char *help, const int arg_type, const bool stacks = false) noexcept;
|
|
~cmdline_parm() noexcept;
|
|
int found();
|
|
int get_int();
|
|
float get_float();
|
|
char *str();
|
|
bool check_if_args_is_valid();
|
|
bool has_param();
|
|
};
|
|
|
|
static cmdline_parm Parm_list(NULL, NULL, AT_NONE);
|
|
static int Parm_list_inited = 0;
|
|
|
|
extern int Show_framerate; // from freespace.cpp
|
|
|
|
enum
|
|
{
|
|
// DO NOT CHANGE ANYTHING ABOUT THESE FIRST TWO OR WILL MESS UP THE LAUNCHER
|
|
EASY_DEFAULT = 1 << 1, // Default FS2 (All features off)
|
|
EASY_ALL_ON = 1 << 2, // All features on
|
|
|
|
EASY_HI_MEM_ON = 1 << 3, // High memory usage features on
|
|
EASY_HI_MEM_OFF = 1 << 4, // High memory usage features off
|
|
|
|
// Add new flags here
|
|
};
|
|
|
|
enum BuildCaps
|
|
{
|
|
BUILD_CAPS_OPENAL = (1<<0),
|
|
BUILD_CAPS_NO_D3D = (1<<1),
|
|
BUILD_CAPS_NEW_SND = (1<<2),
|
|
BUILD_CAPS_SDL = (1<<3)
|
|
};
|
|
|
|
#define PARSE_COMMAND_LINE_STRING "-parse_cmdline_only"
|
|
#define GET_FLAGS_STRING "-get_flags"
|
|
|
|
typedef struct
|
|
{
|
|
// DO NOT CHANGE THE SIZE OF THIS AT_STRING!
|
|
char name[32];
|
|
|
|
} EasyFlag;
|
|
|
|
EasyFlag easy_flags[] =
|
|
{
|
|
{ "Custom" },
|
|
{ "Default FS2 (All features off)" },
|
|
{ "All features on" },
|
|
{ "High memory usage features on" },
|
|
{ "High memory usage features off" }
|
|
};
|
|
|
|
// DO NOT CHANGE **ANYTHING** ABOUT THIS STRUCTURE AND ITS CONTENT
|
|
typedef struct
|
|
{
|
|
char name[20]; // The actual flag
|
|
char desc[40]; // The text that will appear in the launcher (unless its blank, other name is shown)
|
|
bool fso_only; // true if this is a fs2_open only feature
|
|
int on_flags; // "Easy setting" which will turn this option on
|
|
int off_flags; // "Easy setting" which will turn this option off
|
|
char type[16]; // Launcher uses this to put flags under different headings
|
|
char web_url[256]; // Link to documentation of feature (please use wiki or somewhere constant)
|
|
|
|
} Flag;
|
|
|
|
// clang-format off
|
|
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
|
|
Flag exe_params[] =
|
|
{
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-nospec", "Disable specular", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nospec", },
|
|
{ "-noglow", "Disable glow maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noglow", },
|
|
{ "-noenv", "Disable environment maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noenv", },
|
|
{ "-nonormal", "Disable normal maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nonormal" },
|
|
{ "-emissive_light", "Enable emissive light from ships", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-emissive_light" },
|
|
{ "-noheight", "Disable height/parallax maps", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noheight" },
|
|
{ "-no_post_process", "Disable post-processing", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_post_process" },
|
|
{ "-soft_particles", "Enable soft particles", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-soft_particles" },
|
|
{ "-aa", "Enable Post-process anti-aliasing", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-aa" },
|
|
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
|
|
{ "-fb_thrusters", "Enable Framebuffer Thrusters", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_thrusters", },
|
|
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT | EASY_HI_MEM_OFF, EASY_ALL_ON | EASY_HI_MEM_ON, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
|
|
{ "-enable_shadows", "Enable Shadows", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-enable_shadows"},
|
|
{ "-deferred_cockpit", "Enable Deferred Lighting for Cockpits", true, EASY_ALL_ON | EASY_HI_MEM_ON, EASY_DEFAULT | EASY_HI_MEM_OFF, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-deferred_cockpit"},
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
|
|
{ "-dualscanlines", "Add another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
|
|
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
|
|
{ "-orbradar", "Enable 3D radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
|
|
{ "-rearm_timer", "Enable rearm/repair completion timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
|
|
{ "-ballistic_gauge", "Enable analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
|
|
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fullscreen_window", },
|
|
{ "-capture_mouse", "Capture the mouse within the window", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-capture_mouse", },
|
|
{ "-stretch_menu", "Stretch interface to fill screen", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stretch_menu", },
|
|
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
|
|
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
|
|
{ "-vr", "Enable Virtual Reality Mode", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-vr", },
|
|
{ "-no_unfocused_pause","Don't pause if the window isn't focused", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_unfocused_pause", },
|
|
{ "-orig_speedx_range", "Restrict speedup/slowdown (1x to 4x)", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orig_speedx_range", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-nosound", "Disable all sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
|
|
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
|
|
{ "-no_enhanced_sound", "Disable enhanced sound", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_enhanced_sound", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-portable_mode", "Store config in portable location", false, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-portable_mode", },
|
|
{ "-joy_info", "Outputs SDL joystick info", true, 0, EASY_DEFAULT, "Launcher", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-joy_info",},
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-standalone", "Run as standalone server", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-standalone", },
|
|
{ "-startgame", "Skip mainhall and start hosting", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-startgame", },
|
|
{ "-closed", "Start hosted server as closed", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-closed", },
|
|
{ "-restricted", "Host confirms join requests", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-restricted", },
|
|
{ "-multilog", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-multilog", },
|
|
{ "-clientdamage", "", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-clientdamage", },
|
|
{ "-mpnoreturn", "Disable flight deck option", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mpnoreturn", },
|
|
{ "-gateway_ip", "Set gateway IP address", false, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gateway_ip", },
|
|
{ "-ingame_join", "Disable in-game joining", true, 0, EASY_DEFAULT, "Multiplayer", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
|
|
{ "-no_ingame_options", "Disable using ingame options", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ingame_options", },
|
|
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
|
|
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
|
|
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
|
|
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_fbo", },
|
|
{ "-disable_pbo", "Disable OpenGL Pixel Buffer Objects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-disable_pbo", },
|
|
{ "-ati_swap", "Fix colour issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ati_swap", },
|
|
{ "-no_3d_sound", "Use only 2D/stereo for sound effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_3d_sound", },
|
|
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT | EASY_HI_MEM_OFF, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
|
|
{ "-use_gldrawelements","Don't use glDrawRangeElements", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-use_gldrawelements", },
|
|
{ "-gl_finish", "Fix input lag on some ATI+Linux systems", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gl_finish", },
|
|
{ "-no_geo_effects", "Disable geometry shader for effects", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_geo_effects", },
|
|
{ "-set_cpu_affinity", "Sets processor affinity to config value", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-set_cpu_affinity", },
|
|
{ "-nograb", "Disables mouse grabbing", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
|
|
{ "-noshadercache", "Disables the shader cache", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noshadercache", },
|
|
{ "-prefer_ipv4", "Prefer IPv4 DNS lookups", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-prefer_ipv4", },
|
|
{ "-prefer_ipv6", "Prefer IPv6 DNS lookups", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-prefer_ipv6", },
|
|
{ "-log_multi_packet", "Log multi packet types ", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-log_multi_packet",},
|
|
{ "-no_bsp_align", "Disable pof BSP data alignment", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_bsp_align", },
|
|
{ "-no_large_shaders", "Split large shader into smaller shaders", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_large_shaders", },
|
|
|
|
#ifdef WIN32
|
|
{ "-fix_registry", "Use a different registry path", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fix_registry", },
|
|
#endif
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-voicer", "Enable voice recognition", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-voicer", },
|
|
|
|
//flag launcher text FSO on_flags off_flags category reference URL
|
|
{ "-override_data", "Enable override directory", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-override_data", },
|
|
{ "-bmpmanusage", "Show how many BMPMAN slots are in use", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-bmpmanusage", },
|
|
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
|
|
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
|
|
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
|
|
{ "-pofspew", "Dump model information to pofspew.txt", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
|
|
{ "-weaponspew", "Dump weapon stats and spreadsheets", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weaponspew", },
|
|
{ "-tablecrcs", "Dump table CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
|
|
{ "-missioncrcs", "Dump mission CRCs for multi validation", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
|
|
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
|
|
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
|
|
{ "-output_sexps", "Output SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
|
|
{ "-output_scripting", "Output scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
|
|
{ "-output_script_json", "Output scripting doc to scripting.json", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_script_json", },
|
|
{ "-output_script_lua", "Output scripting doc to scripting.lua", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_script_luastub", },
|
|
{ "-controlconfig_tbl", "Save control presets to table", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-controlconfig_tbl", },
|
|
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-save_render_target", },
|
|
{ "-verify_vps", "Spew VP CRCs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-verify_vps", },
|
|
{ "-reparse_mainhall", "Reparse mainhall.tbl when loading halls", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-reparse_mainhall", },
|
|
{ "-noninteractive", "Disables interactive dialogs", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noninteractive", },
|
|
{ "-benchmark_mode", "Puts the game into benchmark mode", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-benchmark_mode", },
|
|
{ "-profile_frame_time","Profile frame time", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_frame_time", },
|
|
{ "-profile_write_file", "Write profiling information to file", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-profile_write_file", },
|
|
{ "-json_profiling", "Generate JSON profiling output", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-json_profiling", },
|
|
{ "-debug_window", "Enable the debug window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-debug_window", },
|
|
{ "-gr_debug", "Output graphics debug information", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-gr_debug", },
|
|
{ "-stdout_log", "Output log file to stdout", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stdout_log", },
|
|
{ "-slow_frames_ok", "Don't adjust timestamps for slow frames", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-slow_frames_ok", },
|
|
{ "-imgui_debug", "Show imgui debug/demo window in the lab", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-imgui_debug", },
|
|
{ "-luadev", "Make lua errors non-fatal", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-luadev", },
|
|
{"-vulkan", "Use vulkan render backend", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-vulkan", },
|
|
};
|
|
// clang-format on
|
|
|
|
// forward declaration
|
|
const char * get_param_desc(const char *flag_name);
|
|
|
|
// here are the command line parameters that we will be using for FreeSpace
|
|
|
|
// RETAIL options ----------------------------------------------
|
|
cmdline_parm connect_arg("-connect", "Automatically connect to multiplayer IP:PORT", AT_STRING); // Cmdline_connect_addr
|
|
cmdline_parm gamename_arg("-gamename", "Set multiplayer game name", AT_STRING); // Cmdline_game_name
|
|
cmdline_parm gamepassword_arg("-password", "Set multiplayer game password", AT_STRING); // Cmdline_game_password
|
|
cmdline_parm allowabove_arg("-allowabove", "Ranks above this can join multi", AT_STRING); // Cmdline_rank_above
|
|
cmdline_parm allowbelow_arg("-allowbelow", "Ranks below this can join multi", AT_STRING); // Cmdline_rank_below
|
|
cmdline_parm standalone_arg("-standalone", NULL, AT_NONE);
|
|
cmdline_parm nosound_arg("-nosound", NULL, AT_NONE); // Cmdline_freespace_no_sound
|
|
cmdline_parm nomusic_arg("-nomusic", NULL, AT_NONE); // Cmdline_freespace_no_music
|
|
cmdline_parm noenhancedsound_arg("-no_enhanced_sound", NULL, AT_NONE); // Cmdline_no_enhanced_sound
|
|
cmdline_parm startgame_arg("-startgame", NULL, AT_NONE); // Cmdline_start_netgame
|
|
cmdline_parm gameclosed_arg("-closed", NULL, AT_NONE); // Cmdline_closed_game
|
|
cmdline_parm gamerestricted_arg("-restricted", NULL, AT_NONE); // Cmdline_restricted_game
|
|
cmdline_parm port_arg("-port", "Multiplayer network port", AT_INT);
|
|
cmdline_parm multilog_arg("-multilog", NULL, AT_NONE); // Cmdline_multi_log
|
|
cmdline_parm pof_spew("-pofspew", NULL, AT_NONE); // Cmdline_spew_pof_info
|
|
cmdline_parm weapon_spew("-weaponspew", nullptr, AT_STRING); // Cmdline_spew_weapon_stats
|
|
cmdline_parm mouse_coords("-coords", NULL, AT_NONE); // Cmdline_mouse_coords
|
|
cmdline_parm timeout("-timeout", "Multiplayer network timeout (secs)", AT_INT); // Cmdline_timeout
|
|
cmdline_parm bit32_arg("-32bit", "Deprecated", AT_NONE); // (only here for retail compatibility reasons, doesn't actually do anything)
|
|
|
|
char *Cmdline_connect_addr = NULL;
|
|
char *Cmdline_game_name = NULL;
|
|
char *Cmdline_game_password = NULL;
|
|
char *Cmdline_rank_above = NULL;
|
|
char *Cmdline_rank_below = NULL;
|
|
int Cmdline_cd_check = 1;
|
|
int Cmdline_closed_game = 0;
|
|
int Cmdline_freespace_no_music = 0;
|
|
int Cmdline_freespace_no_sound = 0;
|
|
int Cmdline_mouse_coords = 0;
|
|
int Cmdline_multi_log = 0;
|
|
int Cmdline_multi_stream_chat_to_file = 0;
|
|
int Cmdline_network_port = -1;
|
|
int Cmdline_restricted_game = 0;
|
|
int Cmdline_spew_pof_info = 0;
|
|
WeaponSpewType Cmdline_spew_weapon_stats = WeaponSpewType::NONE;
|
|
int Cmdline_start_netgame = 0;
|
|
int Cmdline_timeout = -1;
|
|
int Cmdline_use_last_pilot = 0;
|
|
|
|
|
|
// FSO options -------------------------------------------------
|
|
|
|
// Graphics related
|
|
cmdline_parm fov_arg("-fov", "Vertical field-of-view factor", AT_FLOAT); // Cmdline_fov -- comand line FOV -Bobboau
|
|
cmdline_parm fov_cockpit_arg("-fov_cockpit", "Vertical field-of-view factor for Cockpits", AT_FLOAT);
|
|
cmdline_parm ambient_power_arg("-ambient", "Multiplies the brightness of all ambient light", AT_FLOAT);
|
|
cmdline_parm light_power_arg("-light", "Multiplies the brightness of all light", AT_FLOAT);
|
|
cmdline_parm emissive_power_arg("-emissive", "Multiplies the brightness of all ambient light", AT_FLOAT);
|
|
cmdline_parm emissive_arg("-emissive_light", "Enable emissive light from ships", AT_NONE); // semi-deprecated but still functional
|
|
cmdline_parm env("-noenv", NULL, AT_NONE); // Cmdline_env
|
|
cmdline_parm glow_arg("-noglow", NULL, AT_NONE); // Cmdline_glow -- use Bobs glow code
|
|
cmdline_parm noscalevid_arg("-noscalevid", NULL, AT_NONE); // Cmdline_noscalevid -- disable video scaling that fits to window
|
|
cmdline_parm spec_arg("-nospec", NULL, AT_NONE); // Cmdline_spec --
|
|
cmdline_parm normal_arg("-nonormal", NULL, AT_NONE); // Cmdline_normal -- disable normal mapping
|
|
cmdline_parm height_arg("-noheight", NULL, AT_NONE); // Cmdline_height -- enable support for parallax mapping
|
|
cmdline_parm softparticles_arg("-soft_particles", NULL, AT_NONE);
|
|
cmdline_parm no_postprocess_arg("-no_post_process", "Disables post-processing", AT_NONE);
|
|
cmdline_parm post_process_aa_arg("-aa", "Enables post-process antialiasing", AT_NONE);
|
|
cmdline_parm post_process_aa_preset_arg("-aa_preset", "Sets the AA effect to use. See the wiki for details", AT_INT);
|
|
cmdline_parm deprecated_fxaa_arg("-fxaa", nullptr, AT_NONE);
|
|
cmdline_parm deprecated_fxaa_preset_arg("-fxaa_preset", "FXAA quality (0-2), requires post-processing and -fxaa", AT_INT);
|
|
cmdline_parm deprecated_smaa_arg("-smaa", nullptr, AT_NONE);
|
|
cmdline_parm deprecated_smaa_preset_arg("-smaa_preset", "SMAA quality (0-3), requires post-processing and -smaa", AT_INT);
|
|
cmdline_parm msaa_enabled_arg("-msaa", nullptr, AT_INT);
|
|
cmdline_parm fb_explosions_arg("-fb_explosions", NULL, AT_NONE);
|
|
cmdline_parm fb_thrusters_arg("-fb_thrusters", NULL, AT_NONE);
|
|
cmdline_parm shadow_quality_arg("-shadow_quality", NULL, AT_INT);
|
|
cmdline_parm enable_shadows_arg("-enable_shadows", NULL, AT_NONE);
|
|
cmdline_parm rt_shadows_arg("-rt_shadows", nullptr, AT_NONE);
|
|
cmdline_parm no_deferred_lighting_arg("-no_deferred", NULL, AT_NONE); // Cmdline_no_deferred
|
|
cmdline_parm deferred_lighting_cockpit_arg("-deferred_cockpit", nullptr, AT_NONE);
|
|
cmdline_parm anisotropy_level_arg("-anisotropic_filter", NULL, AT_INT);
|
|
|
|
float Cmdline_ambient_power = 1.0f;
|
|
float Cmdline_emissive_power = 0.0f;
|
|
float Cmdline_light_power = 1.0f;
|
|
int Cmdline_env = 1;
|
|
int Cmdline_mipmap = 0;
|
|
int Cmdline_glow = 1;
|
|
int Cmdline_noscalevid = 0;
|
|
int Cmdline_spec = 1;
|
|
int Cmdline_emissive = 0;
|
|
int Cmdline_normal = 1;
|
|
int Cmdline_height = 1;
|
|
int Cmdline_softparticles = 0;
|
|
int Cmdline_no_deferred_lighting = 0;
|
|
bool Cmdline_deferred_lighting_cockpit = false;
|
|
int Cmdline_aniso_level = 0;
|
|
int Cmdline_msaa_enabled = 0;
|
|
|
|
// Game Speed related
|
|
cmdline_parm no_fpscap("-no_fps_capping", "Don't limit frames-per-second", AT_NONE); // Cmdline_NoFPSCap
|
|
cmdline_parm no_vsync_arg("-no_vsync", NULL, AT_NONE); // Cmdline_no_vsync
|
|
|
|
int Cmdline_NoFPSCap = 0; // Disable FPS capping - kazan
|
|
bool Cmdline_no_vsync = false;
|
|
|
|
// HUD related
|
|
cmdline_parm ballistic_gauge("-ballistic_gauge", NULL, AT_NONE); // Cmdline_ballistic_gauge
|
|
cmdline_parm dualscanlines_arg("-dualscanlines", NULL, AT_NONE); // Cmdline_dualscanlines -- Change to phreaks options including new targeting code; semi-deprecated but still functional
|
|
cmdline_parm orb_radar("-orbradar", NULL, AT_NONE); // Cmdline_orb_radar
|
|
cmdline_parm rearm_timer_arg("-rearm_timer", NULL, AT_NONE); // Cmdline_rearm_timer; semi-deprecated but still functional-Mjn
|
|
cmdline_parm targetinfo_arg("-targetinfo", NULL, AT_NONE); // Cmdline_targetinfo -- Adds ship name/class to right of target box -C; semi-deprecated but still functional-Mjn
|
|
|
|
int Cmdline_ballistic_gauge = 0; // WMCoolmon's gauge thingy
|
|
int Cmdline_dualscanlines = 0;
|
|
int Cmdline_orb_radar = 0;
|
|
int Cmdline_rearm_timer = 0;
|
|
|
|
// Gameplay related
|
|
cmdline_parm allow_autpilot_interrupt("-no_ap_interrupt", nullptr, AT_NONE);
|
|
cmdline_parm stretch_menu("-stretch_menu", nullptr, AT_NONE); // Cmdline_stretch_menu
|
|
cmdline_parm capture_mouse("-capture_mouse", nullptr, AT_NONE); // Cmdline_capture_mouse
|
|
cmdline_parm vr("-vr", nullptr, AT_NONE);
|
|
cmdline_parm deadzone("-deadzone",
|
|
"Sets the joystick deadzone. Integer value from 0 to 100 as a percentage of the joystick's range (100% would make the stick do nothing). Disables deadzone slider in the in-game Options menu.", AT_INT); //Cmdline_deadzone
|
|
|
|
int Cmdline_autopilot_interruptable = 1;
|
|
bool Cmdline_stretch_menu = false;
|
|
bool Cmdline_capture_mouse = false;
|
|
int Cmdline_deadzone = -1;
|
|
bool Cmdline_enable_vr = false;
|
|
|
|
// Audio related
|
|
cmdline_parm voice_recognition_arg("-voicer", NULL, AT_NONE); // Cmdline_voice_recognition
|
|
|
|
int Cmdline_voice_recognition = 0;
|
|
int Cmdline_no_enhanced_sound = 0;
|
|
|
|
// MOD related
|
|
cmdline_parm mod_arg("-mod", "List of folders to overwrite/add-to the default data", AT_STRING, true); // Cmdline_mod -- DTP modsupport
|
|
cmdline_parm campaign_arg("-campaign", "Set current campaign", AT_STRING); // Cmdline_campaign
|
|
|
|
char *Cmdline_mod = NULL; //DTP for mod argument
|
|
char *Cmdline_campaign = nullptr; // for campaign argument
|
|
|
|
// Multiplayer/Network related
|
|
cmdline_parm almission_arg("-almission", "Autoload multiplayer mission", AT_STRING); // Cmdline_almission -- DTP for autoload Multi mission
|
|
cmdline_parm ingamejoin_arg("-ingame_join", NULL, AT_NONE); // Cmdline_ingamejoin
|
|
cmdline_parm mpnoreturn_arg("-mpnoreturn", NULL, AT_NONE); // Cmdline_mpnoreturn -- Removes 'Return to Flight Deck' in respawn dialog -C
|
|
cmdline_parm objupd_arg("-cap_object_update", "Multiplayer object update cap (0-3)", AT_INT);
|
|
cmdline_parm gateway_ip_arg("-gateway_ip", "Set gateway IP address", AT_STRING);
|
|
|
|
char *Cmdline_almission = nullptr; //DTP for autoload multi mission.
|
|
int Cmdline_ingamejoin = 1;
|
|
int Cmdline_mpnoreturn = 0;
|
|
int Cmdline_objupd = 3; // client object updates on LAN by default
|
|
char *Cmdline_gateway_ip = nullptr;
|
|
|
|
// Launcher related options
|
|
cmdline_parm portable_mode("-portable_mode", NULL, AT_NONE);
|
|
cmdline_parm joy_info("-joy_info", "Outputs SDL joystick info", AT_NONE);
|
|
cmdline_parm lang_arg("-language", "Language name as defined in strings.tbl", AT_STRING);
|
|
|
|
bool Cmdline_portable_mode = false;
|
|
SCP_string Cmdline_lang;
|
|
|
|
// Troubleshooting
|
|
cmdline_parm loadallweapons_arg("-loadallweps", NULL, AT_NONE); // Cmdline_load_all_weapons
|
|
cmdline_parm nomovies_arg("-nomovies", NULL, AT_NONE); // Cmdline_nomovies -- Allows video streaming
|
|
cmdline_parm no_set_gamma_arg("-no_set_gamma", NULL, AT_NONE); // Cmdline_no_set_gamma
|
|
cmdline_parm no_ingame_options_arg("-no_ingame_options", NULL, AT_NONE); // Cmdline_no_ingame_options
|
|
cmdline_parm no_fbo_arg("-disable_fbo", NULL, AT_NONE); // Cmdline_no_fbo
|
|
cmdline_parm no_pbo_arg("-disable_pbo", NULL, AT_NONE); // Cmdline_no_pbo
|
|
cmdline_parm mipmap_arg("-mipmap", NULL, AT_NONE); // Cmdline_mipmap
|
|
cmdline_parm atiswap_arg("-ati_swap", NULL, AT_NONE); // Cmdline_atiswap - Fix ATI color swap issue for screenshots.
|
|
cmdline_parm no3dsound_arg("-no_3d_sound", NULL, AT_NONE); // Cmdline_no_3d_sound - Disable use of full 3D sounds
|
|
cmdline_parm no_drawrangeelements("-use_gldrawelements", NULL, AT_NONE); // Cmdline_drawelements -- Uses glDrawElements instead of glDrawRangeElements
|
|
cmdline_parm keyboard_layout("-keyboard_layout", "Specify keyboard layout (qwertz or azerty)", AT_STRING);
|
|
cmdline_parm gl_finish ("-gl_finish", NULL, AT_NONE);
|
|
cmdline_parm no_geo_sdr_effects("-no_geo_effects", NULL, AT_NONE);
|
|
cmdline_parm set_cpu_affinity("-set_cpu_affinity", NULL, AT_NONE);
|
|
cmdline_parm nograb_arg("-nograb", NULL, AT_NONE);
|
|
cmdline_parm noshadercache_arg("-noshadercache", NULL, AT_NONE);
|
|
cmdline_parm prefer_ipv4_arg("-prefer_ipv4", nullptr, AT_NONE);
|
|
cmdline_parm prefer_ipv6_arg("-prefer_ipv6", nullptr, AT_NONE);
|
|
cmdline_parm log_multi_packet_arg("-log_multi_packet", nullptr, AT_NONE);
|
|
cmdline_parm no_bsp_align_arg("-no_bsp_align", nullptr, AT_NONE);
|
|
cmdline_parm no_large_shaders("-no_large_shaders", NULL, AT_NONE);
|
|
#ifdef WIN32
|
|
cmdline_parm fix_registry("-fix_registry", NULL, AT_NONE);
|
|
#endif
|
|
|
|
int Cmdline_load_all_weapons = 0;
|
|
int Cmdline_nomovies = 0;
|
|
int Cmdline_no_set_gamma = 0;
|
|
bool Cmdline_no_ingame_options = false;
|
|
int Cmdline_no_fbo = 0;
|
|
int Cmdline_no_pbo = 0;
|
|
int Cmdline_ati_color_swap = 0;
|
|
int Cmdline_no_3d_sound = 0;
|
|
int Cmdline_drawelements = 0;
|
|
char* Cmdline_keyboard_layout = NULL;
|
|
bool Cmdline_gl_finish = false;
|
|
bool Cmdline_no_geo_sdr_effects = false;
|
|
bool Cmdline_set_cpu_affinity = false;
|
|
bool Cmdline_nograb = false;
|
|
bool Cmdline_noshadercache = false;
|
|
bool Cmdline_prefer_ipv4 = false;
|
|
bool Cmdline_prefer_ipv6 = false;
|
|
bool Cmdline_dump_packet_type = false;
|
|
bool Cmdline_no_bsp_align = false;
|
|
bool Cmdline_no_large_shaders = false;
|
|
#ifdef WIN32
|
|
bool Cmdline_alternate_registry_path = false;
|
|
#endif
|
|
uint Cmdline_rng_seed = 0;
|
|
bool Cmdline_reuse_rng_seed = false;
|
|
|
|
// Developer/Testing related
|
|
cmdline_parm start_mission_arg("-start_mission", "Skip mainhall and run this mission", AT_STRING); // Cmdline_start_mission
|
|
cmdline_parm dis_collisions("-dis_collisions", NULL, AT_NONE); // Cmdline_dis_collisions
|
|
cmdline_parm dis_weapons("-dis_weapons", NULL, AT_NONE); // Cmdline_dis_weapons
|
|
cmdline_parm noparseerrors_arg("-noparseerrors", NULL, AT_NONE); // Cmdline_noparseerrors -- turns off parsing errors -C
|
|
cmdline_parm extra_warn_arg("-extra_warn", "Enable 'extra' warnings", AT_NONE); // Cmdline_extra_warn
|
|
cmdline_parm fps_arg("-fps", NULL, AT_NONE); // Cmdline_show_fps
|
|
cmdline_parm bmpmanusage_arg("-bmpmanusage", NULL, AT_NONE); // Cmdline_bmpman_usage
|
|
cmdline_parm pos_arg("-pos", NULL, AT_NONE); // Cmdline_show_pos
|
|
cmdline_parm stats_arg("-stats", NULL, AT_NONE); // Cmdline_show_stats
|
|
cmdline_parm save_render_targets_arg("-save_render_target", NULL, AT_NONE); // Cmdline_save_render_targets
|
|
cmdline_parm window_arg("-window", NULL, AT_NONE); // Cmdline_window
|
|
cmdline_parm fullscreen_window_arg("-fullscreen_window", "Fullscreen/borderless window (Windows only)", AT_NONE);
|
|
cmdline_parm deprecated_res_arg("-res", "Deprecated, resolution, formatted like 1600x900", AT_STRING);
|
|
cmdline_parm render_res_arg("-render_res", "Resolution, formatted like 1600x900", AT_STRING);
|
|
cmdline_parm window_res_arg("-window_res", "Window resolution, formatted like 1600x900.", AT_STRING);
|
|
cmdline_parm center_res_arg("-center_res", "Resolution of center monitor, formatted like 1600x900", AT_STRING);
|
|
cmdline_parm hdr_nits_arg("-hdr", "Forces HDR output on, overriding the in-game HDR setting. Optionally takes paper white and peak luminance in nits, formatted like 400,1500, overriding the in-game HDR nits settings.", AT_STRING);
|
|
cmdline_parm verify_vps_arg("-verify_vps", NULL, AT_NONE); // Cmdline_verify_vps -- spew VP crcs to vp_crcs.txt
|
|
cmdline_parm parse_cmdline_only(PARSE_COMMAND_LINE_STRING, "Ignore any cmdline_fso.cfg files", AT_NONE);
|
|
cmdline_parm reparse_mainhall_arg("-reparse_mainhall", NULL, AT_NONE); //Cmdline_reparse_mainhall
|
|
cmdline_parm frame_profile_write_file("-profile_write_file", NULL, AT_NONE); // Cmdline_profile_write_file
|
|
cmdline_parm no_unfocused_pause_arg("-no_unfocused_pause", NULL, AT_NONE); //Cmdline_no_unfocus_pause
|
|
cmdline_parm retail_time_compression_range_arg("-orig_speedx_range", NULL, AT_NONE); //Cmdline_retail_time_compression_range
|
|
cmdline_parm benchmark_mode_arg("-benchmark_mode", NULL, AT_NONE); //Cmdline_benchmark_mode
|
|
cmdline_parm pilot_arg("-pilot", nullptr, AT_STRING); //Cmdline_pilot
|
|
cmdline_parm noninteractive_arg("-noninteractive", NULL, AT_NONE); //Cmdline_noninteractive
|
|
cmdline_parm json_profiling("-json_profiling", NULL, AT_NONE); //Cmdline_json_profiling
|
|
cmdline_parm show_video_info("-show_video_info", NULL, AT_NONE); //Cmdline_show_video_info
|
|
cmdline_parm frame_profile_arg("-profile_frame_time", NULL, AT_NONE); //Cmdline_frame_profile
|
|
cmdline_parm debug_window_arg("-debug_window", NULL, AT_NONE); // Cmdline_debug_window
|
|
cmdline_parm graphics_debug_output_arg("-gr_debug", nullptr, AT_NONE); // Cmdline_graphics_debug_output
|
|
cmdline_parm gr_sync_validation_arg("-gr_sync_validation", nullptr, AT_NONE); // Cmdline_gr_sync_validation (implies -gr_debug)
|
|
cmdline_parm log_to_stdout_arg("-stdout_log", nullptr, AT_NONE); // Cmdline_log_to_stdout
|
|
cmdline_parm slow_frames_ok_arg("-slow_frames_ok", nullptr, AT_NONE); // Cmdline_slow_frames_ok
|
|
cmdline_parm fixed_seed_rand("-seed", nullptr, AT_INT); // Cmdline_rng_seed,Cmdline_reuse_rng_seed;
|
|
cmdline_parm luadev_arg("-luadev", "Make lua errors non-fatal", AT_NONE); // Cmdline_lua_devmode
|
|
cmdline_parm override_arg("-override_data", "Enable override directory", AT_NONE); // Cmdline_override_data
|
|
cmdline_parm imgui_debug_arg("-imgui_debug", nullptr, AT_NONE);
|
|
cmdline_parm vulkan("-vulkan", nullptr, AT_NONE);
|
|
cmdline_parm opengl("-opengl", nullptr, AT_NONE);
|
|
cmdline_parm multithreading("-threads", nullptr, AT_INT);
|
|
|
|
char *Cmdline_start_mission = NULL;
|
|
int Cmdline_dis_collisions = 0;
|
|
int Cmdline_dis_weapons = 0;
|
|
bool Cmdline_output_sexp_info = false;
|
|
int Cmdline_noparseerrors = 0;
|
|
#ifdef Allow_NoWarn
|
|
int Cmdline_nowarn = 0; // turn warnings off in FRED
|
|
#endif
|
|
int Cmdline_extra_warn = 0;
|
|
int Cmdline_bmpman_usage = 0;
|
|
int Cmdline_show_pos = 0;
|
|
int Cmdline_show_stats = 0;
|
|
int Cmdline_save_render_targets = 0;
|
|
bool Cmdline_window = false;
|
|
bool Cmdline_fullscreen_window = false;
|
|
std::optional<std::pair<uint16_t, uint16_t>>Cmdline_window_res = std::nullopt;
|
|
char *Cmdline_res = 0;
|
|
char *Cmdline_center_res = 0;
|
|
int Cmdline_verify_vps = 0;
|
|
int Cmdline_reparse_mainhall = 0;
|
|
bool Cmdline_profile_write_file = false;
|
|
bool Cmdline_no_unfocus_pause = false;
|
|
bool Cmdline_retail_time_compression_range = false;
|
|
bool Cmdline_benchmark_mode = false;
|
|
const char *Cmdline_pilot = nullptr;
|
|
bool Cmdline_noninteractive = false;
|
|
bool Cmdline_json_profiling = false;
|
|
bool Cmdline_frame_profile = false;
|
|
bool Cmdline_show_video_info = false;
|
|
bool Cmdline_debug_window = false;
|
|
bool Cmdline_graphics_debug_output = false;
|
|
bool Cmdline_gr_sync_validation = false;
|
|
bool Cmdline_log_to_stdout = false;
|
|
bool Cmdline_slow_frames_ok = false;
|
|
bool Cmdline_lua_devmode = false;
|
|
bool Cmdline_override_data = false;
|
|
bool Cmdline_show_imgui_debug = false;
|
|
GraphicsAPI Cmdline_graphics_api = GraphicsAPI::Default;
|
|
int Cmdline_multithreading = 1;
|
|
|
|
// Other
|
|
cmdline_parm get_flags_arg(GET_FLAGS_STRING, "Output the launcher flags file", AT_STRING);
|
|
cmdline_parm output_sexp_arg("-output_sexps", NULL, AT_NONE); //WMC - outputs all SEXPs to sexps.html
|
|
cmdline_parm output_scripting_arg("-output_scripting", NULL, AT_NONE); //WMC
|
|
cmdline_parm output_script_json_arg("-output_script_json", nullptr, AT_NONE); // m!m
|
|
cmdline_parm output_script_luastub_arg("-output_script_lua", nullptr, AT_NONE); // mjnmixael
|
|
cmdline_parm generate_controlconfig_arg("-controlconfig_tbl", nullptr, AT_NONE);
|
|
|
|
// Deprecated flags - CommanderDJ
|
|
cmdline_parm deprecated_spec_arg("-spec", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_glow_arg("-glow", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_normal_arg("-normal", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_env_arg("-env", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_tbp_arg("-tbp", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_jpgtga_arg("-jpgtga", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_htl_arg("-nohtl", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_brieflighting_arg("-brief_lighting", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_sndpreload_arg("-snd_preload", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_missile_lighting_arg("-missile_lighting", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_cache_bitmaps_arg("-cache_bitmaps", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_no_emissive_arg("-no_emissive_light", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_postprocess_arg("-post_process", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_spec_static_arg("-spec_static", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_spec_point_arg("-spec_point", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_spec_tube_arg("-spec_tube", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_ambient_factor_arg("-ambient_factor", "Deprecated", AT_NONE); //
|
|
cmdline_parm deprecated_ship_choice_3d_arg("-ship_choice_3d", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_weapon_choice_3d_arg("-weapon_choice_3d", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_no_screenshake("-no_screenshake", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_bloom_intensity_arg("-bloom_intensity", "Deprecated", AT_INT);
|
|
cmdline_parm deprecated_nomotiondebris_arg("-nomotiondebris", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_flightshaftsoff_arg("-nolightshafts", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_use_warp_flash("-warp_flash", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_use_3dwarp("-3dwarp", "Deprecated", AT_NONE);
|
|
cmdline_parm deprecated_enable_3d_shockwave_arg("-3dshockwave", "Deprecated", AT_NONE);
|
|
|
|
#ifndef NDEBUG
|
|
// NOTE: this assumes that os_init() has already been called but isn't a fatal error if it hasn't
|
|
void cmdline_debug_print_cmdline()
|
|
{
|
|
cmdline_parm *parmp;
|
|
int found = 0;
|
|
mprintf(("Passed cmdline options:"));
|
|
|
|
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
|
|
if ( parmp->name_found ) {
|
|
if ( parmp->args != NULL ) {
|
|
mprintf(("\n %s %s", parmp->name, parmp->args));
|
|
} else {
|
|
mprintf(("\n %s", parmp->name));
|
|
}
|
|
found++;
|
|
}
|
|
}
|
|
|
|
if ( !found )
|
|
mprintf(("\n <none>"));
|
|
|
|
mprintf(("\n"));
|
|
|
|
//Print log messages about any deprecated flags we found - CommanderDJ
|
|
//Do it programmatically, rather than enumerating them by hand - MageKing17
|
|
for (parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
|
|
if (parmp->name_found && !stricmp("deprecated", parmp->help)) {
|
|
mprintf(("Deprecated flag '%s' found. Please remove from your cmdline.\n", parmp->name));
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// builds simple cmdline
|
|
SCP_string cmdline_build_string()
|
|
{
|
|
cmdline_parm *parmp;
|
|
int found = 0;
|
|
std::ostringstream cmdline;
|
|
|
|
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
|
|
if ( parmp->name_found ) {
|
|
cmdline << " " << parmp->name;
|
|
|
|
if (parmp->args) {
|
|
cmdline << " " << parmp->args;
|
|
}
|
|
|
|
found++;
|
|
}
|
|
}
|
|
|
|
if ( !found ) {
|
|
return "";
|
|
}
|
|
|
|
return cmdline.str();
|
|
}
|
|
|
|
// prints simple cmdline to multi.log
|
|
void cmdline_print_cmdline_multi()
|
|
{
|
|
auto str = cmdline_build_string();
|
|
|
|
ml_printf("Command line:%s", str.empty() ? " <none>" : str.c_str());
|
|
}
|
|
|
|
// Return true if this character is an extra char (white space and quotes)
|
|
int is_extra_space(char ch)
|
|
{
|
|
return ((ch == ' ') || (ch == '\t') || (ch == 0x0a) || (ch == '\'') || (ch == '\"'));
|
|
}
|
|
|
|
// eliminates all leading and trailing extra chars from a string. Returns pointer passed in.
|
|
char *drop_extra_chars(char *str)
|
|
{
|
|
size_t s;
|
|
size_t e;
|
|
|
|
s = 0;
|
|
while (str[s] && is_extra_space(str[s]))
|
|
s++;
|
|
|
|
e = strlen(str);
|
|
|
|
if (e > 0) {
|
|
// we already account for NULL later on, so the -1 is here to make
|
|
// sure we do our math without taking it into consideration
|
|
e -= 1;
|
|
}
|
|
|
|
while (e > s) {
|
|
if (!is_extra_space(str[e])){
|
|
break;
|
|
}
|
|
|
|
e--;
|
|
}
|
|
|
|
if (e >= s && e !=0 ){
|
|
memmove(str, str + s, e - s + 1);
|
|
}
|
|
|
|
str[e - s + 1] = 0;
|
|
return str;
|
|
}
|
|
|
|
|
|
/*
|
|
* @brief Processes one argument for the given parameter
|
|
*
|
|
* @param param The parameter to check
|
|
* @param argc The argument count
|
|
* @param argc The argument values
|
|
* @param argc The current index
|
|
* @return @c true when an extra parameter was found, @c false otherwise
|
|
*/
|
|
bool parm_stuff_args(cmdline_parm *parm, int argc, char *argv[], int index)
|
|
{
|
|
Assert(index < argc);
|
|
|
|
if (index + 1 < argc)
|
|
{
|
|
char* value = argv[index + 1];
|
|
if (value[0] == '-')
|
|
{
|
|
// Found another argument, just return
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
char* saved_args = NULL;
|
|
|
|
if (parm->args != NULL) {
|
|
if (parm->stacks) {
|
|
saved_args = parm->args;
|
|
}
|
|
else {
|
|
delete[] parm->args;
|
|
}
|
|
|
|
parm->args = NULL;
|
|
}
|
|
|
|
size_t argsize = strlen(argv[index + 1]);
|
|
size_t buffersize = argsize;
|
|
|
|
if (saved_args != NULL)
|
|
{
|
|
// Add one for the , separating args
|
|
buffersize += strlen(saved_args) + 1;
|
|
}
|
|
|
|
buffersize += 1; // Null-terminator
|
|
|
|
parm->args = new char[buffersize];
|
|
memset(parm->args, 0, buffersize);
|
|
|
|
if (saved_args != NULL)
|
|
{
|
|
// saved args go first, then new arg
|
|
strcpy_s(parm->args, buffersize, saved_args);
|
|
// add a separator too, so that we can tell the args apart
|
|
strcat_s(parm->args, buffersize, ",");
|
|
// now the new arg
|
|
strcat_s(parm->args, buffersize, argv[index + 1]);
|
|
|
|
delete[] saved_args;
|
|
}
|
|
else
|
|
{
|
|
strcpy_s(parm->args, buffersize, argv[index + 1]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Last argument, can't have any values
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// internal function - parse the command line, extracting parameter arguments if they exist
|
|
// cmdline - command line string passed to the application
|
|
void os_parse_parms(int argc, char *argv[])
|
|
{
|
|
// locate command line parameters
|
|
cmdline_parm *parmp;
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
{
|
|
// On OS X this gets passed if the application was launched by double-clicking in the Finder
|
|
if (i == 1 && strncmp(argv[i], "-psn", 4) == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
|
|
if (!stricmp(parmp->name, argv[i]))
|
|
{
|
|
parmp->name_found = 1;
|
|
if (parm_stuff_args(parmp, argc, argv, i))
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// validate the command line parameters. Display an error if an unrecognized parameter is located.
|
|
void os_validate_parms(int argc, char *argv[])
|
|
{
|
|
cmdline_parm *parmp;
|
|
char *token;
|
|
int parm_found;
|
|
|
|
for (int i = 0; i < argc; i++)
|
|
{
|
|
token = argv[i];
|
|
|
|
// On OS X this gets passed if the application was launched by double-clicking in the Finder
|
|
if (i == 1 && strncmp(token, "-psn", 4) == 0) {
|
|
continue;
|
|
}
|
|
|
|
if (token[0] == '-') {
|
|
parm_found = 0;
|
|
|
|
for (parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
|
|
if (!stricmp(parmp->name, token)) {
|
|
parm_found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (parm_found == 0) {
|
|
// if we got a -help, --help, -h, or -? then show the help text, otherwise show unknown option
|
|
if (!stricmp(token, "-help") || !stricmp(token, "--help") || !stricmp(token, "-h") || !stricmp(token, "-?")) {
|
|
printf("FreeSpace 2 Open, version %s\n", FS_VERSION_FULL);
|
|
printf("Website: https://scp.indiegames.us\n");
|
|
printf("Github (bug reporting): https://github.com/scp-fs2open/fs2open.github.com/issues\n\n");
|
|
printf("Usage: fs2_open [options]\n");
|
|
|
|
// not the prettiest thing but the job gets done
|
|
static const int STR_SIZE = 25; // max len of exe_params.name + 5 spaces
|
|
const int AT_SIZE = 8; // max len of cmdline_arg_types[] + 2 spaces
|
|
size_t atp = 0;
|
|
size_t sp = 0;
|
|
for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
|
|
// don't output deprecated flags
|
|
if (stricmp("deprecated", parmp->help) != 0) {
|
|
sp = strlen(parmp->name);
|
|
if (parmp->arg_type != AT_NONE) {
|
|
atp = strlen(cmdline_arg_types[parmp->arg_type]);
|
|
printf(" [ %s ]%*s[ %s ]%*s- %s\n", parmp->name, (int)(STR_SIZE - sp -1), NOX(" "), cmdline_arg_types[parmp->arg_type], (int)(AT_SIZE-atp), NOX(" "), parmp->help);
|
|
} else {
|
|
printf(" [ %s ]%*s- %s\n", parmp->name, (int)(STR_SIZE - sp -1 +AT_SIZE+4), NOX(" "), parmp->help);
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
exit(0);
|
|
}
|
|
else {
|
|
char buffer[128];
|
|
sprintf(buffer, "Unrecognized command line parameter %s.", token);
|
|
|
|
os::dialogs::Message(os::dialogs::MESSAGEBOX_INFORMATION, buffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int parse_cmdline_string(char* cmdline, char** argv)
|
|
{
|
|
size_t length = strlen(cmdline);
|
|
|
|
bool start_found = false;
|
|
bool quoted = false;
|
|
|
|
size_t argc = 0;
|
|
char* current_argv = NULL;
|
|
for (size_t i = 0; i < length; i++)
|
|
{
|
|
if (!start_found && !isspace(cmdline[i]))
|
|
{
|
|
start_found = true;
|
|
current_argv = (cmdline + i);
|
|
}
|
|
else if (start_found)
|
|
{
|
|
if (cmdline[i] == '"')
|
|
{
|
|
quoted = !quoted;
|
|
|
|
if (!quoted && current_argv != NULL)
|
|
{
|
|
if (argv != NULL)
|
|
{
|
|
// Terminate string at quote
|
|
cmdline[i] = '\0';
|
|
argv[argc] = current_argv;
|
|
current_argv = NULL;
|
|
}
|
|
|
|
argc++;
|
|
}
|
|
}
|
|
else if (isspace(cmdline[i]) && !quoted)
|
|
{
|
|
// Parameter terminated by space
|
|
if (current_argv != NULL) // == NULL means that we currently don't have a parameter
|
|
{
|
|
if (argv != NULL)
|
|
{
|
|
// Terminate string at quote
|
|
cmdline[i] = '\0';
|
|
argv[argc] = current_argv;
|
|
current_argv = NULL;
|
|
}
|
|
|
|
argc++;
|
|
}
|
|
}
|
|
else if (current_argv == NULL)
|
|
{
|
|
current_argv = cmdline + i;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (current_argv != NULL)
|
|
{
|
|
if (argv != NULL)
|
|
{
|
|
// Terminate string at quote
|
|
argv[argc] = current_argv;
|
|
current_argv = NULL;
|
|
}
|
|
|
|
argc++;
|
|
}
|
|
|
|
return (int)argc;
|
|
}
|
|
|
|
void os_process_cmdline(char* cmdline)
|
|
{
|
|
int argc = parse_cmdline_string(cmdline, NULL);
|
|
|
|
char** argv = new char*[argc];
|
|
|
|
argc = parse_cmdline_string(cmdline, argv);
|
|
|
|
os_parse_parms(argc, argv);
|
|
os_validate_parms(argc, argv);
|
|
|
|
delete[] argv;
|
|
}
|
|
|
|
bool has_cmdline_only_or_get_flags(int argc, char *argv[])
|
|
{
|
|
for (int i = 0; i < argc; ++i)
|
|
{
|
|
if (!strcmp(argv[i], PARSE_COMMAND_LINE_STRING) || !strcmp(argv[i], GET_FLAGS_STRING))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// remove old parms - needed for tests
|
|
static void reset_cmdline_parms()
|
|
{
|
|
for (cmdline_parm *parmp = GET_FIRST(&Parm_list); parmp != END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp)) {
|
|
if (parmp->args != NULL) {
|
|
delete[] parmp->args;
|
|
parmp->args = NULL;
|
|
}
|
|
parmp->name_found = 0;
|
|
}
|
|
}
|
|
|
|
// Call once to initialize the command line system
|
|
//
|
|
// cmdline - command line string passed to the application
|
|
void os_init_cmdline(int argc, char *argv[])
|
|
{
|
|
// Tests call this multiple times, so reset the params here.
|
|
// Otherwise e.g. the modlist just grows and grows...
|
|
reset_cmdline_parms();
|
|
|
|
FILE *fp;
|
|
|
|
// Don't parse any command-line config files if we specified PARSE_COMMAND_LINE_STRING (to explicitly prevent it),
|
|
// or GET_FLAGS_STRING (because the engine is going to do a quick exit and for GitHub issue #1221)
|
|
if (!has_cmdline_only_or_get_flags(argc, argv)) {
|
|
// Only parse the config file in the current directory if we are in legacy config mode
|
|
if (os_is_legacy_mode()) {
|
|
// read the cmdline_fso.cfg file from the data folder, and pass the command line arguments to
|
|
// the the parse_parms and validate_parms line. Read these first so anything actually on
|
|
// the command line will take precedence
|
|
#ifdef APPLE_APP
|
|
char resolved_path[MAX_PATH], data_path[MAX_PATH_LEN];
|
|
|
|
getcwd(data_path, sizeof(data_path));
|
|
snprintf(resolved_path, MAX_PATH, "%s/data/cmdline_fso.cfg", data_path);
|
|
|
|
fp = fopen(resolved_path, "rt");
|
|
#else
|
|
fp = fopen("data" DIR_SEPARATOR_STR "cmdline_fso.cfg", "rt");
|
|
#endif
|
|
// if the file exists, get a single line, and deal with it
|
|
if (fp) {
|
|
char *buf, *p;
|
|
|
|
auto len = static_cast<int>(filelength(fileno(fp))) + 2;
|
|
buf = new char[len];
|
|
|
|
if (fgets(buf, len - 1, fp) != nullptr)
|
|
{
|
|
// replace the newline character with a NULL
|
|
if ((p = strrchr(buf, '\n')) != NULL) {
|
|
*p = '\0';
|
|
}
|
|
#ifdef SCP_UNIX
|
|
// append a space for the os_parse_parms() check
|
|
strcat_s(buf, len, " ");
|
|
#endif
|
|
os_process_cmdline(buf);
|
|
}
|
|
delete[] buf;
|
|
fclose(fp);
|
|
}
|
|
} else {
|
|
// parse user specific cmdline_fso config file (will supersede options in global file)
|
|
fp = fopen(os_get_config_path("data/cmdline_fso.cfg").c_str(), "rt");
|
|
|
|
// if the file exists, get a single line, and deal with it
|
|
if ( fp ) {
|
|
char *buf, *p;
|
|
|
|
auto len = static_cast<int>(filelength( fileno(fp) )) + 2;
|
|
buf = new char [len];
|
|
|
|
if (fgets(buf, len-1, fp) != nullptr)
|
|
{
|
|
// replace the newline character with a NULL
|
|
if ( (p = strrchr(buf, '\n')) != NULL ) {
|
|
*p = '\0';
|
|
}
|
|
|
|
// append a space for the os_parse_parms() check
|
|
strcat_s(buf, len, " ");
|
|
|
|
os_process_cmdline(buf);
|
|
}
|
|
delete [] buf;
|
|
fclose(fp);
|
|
}
|
|
}
|
|
} // If cmdline included PARSE_COMMAND_LINE_STRING or GET_FLAGS_STRING
|
|
|
|
// By parsing cmdline last, anything actually on the command line will take precedence.
|
|
os_parse_parms(argc, argv);
|
|
os_validate_parms(argc, argv);
|
|
}
|
|
|
|
|
|
/*
|
|
* arg constructor
|
|
*
|
|
* @param name_ name of the parameter, must start with '-' character
|
|
* @param help_ help text for this parameter
|
|
* @param arg_type_ parameters arguement type (if any)
|
|
* @param stacks_ can the parameter be stacked
|
|
*/
|
|
cmdline_parm::cmdline_parm(const char *name_, const char *help_, const int arg_type_, const bool stacks_) noexcept:
|
|
name(name_), help(help_), stacks(stacks_), arg_type(arg_type_)
|
|
{
|
|
args = NULL;
|
|
name_found = 0;
|
|
|
|
if (Parm_list_inited == 0) {
|
|
Assertion(&Parm_list == this, "Coding error! 1st initialised cmdline_parm must be static Parm_list\n");
|
|
list_init(this);
|
|
Parm_list_inited = 1;
|
|
} else {
|
|
Assertion(name, "Coding error! cmdline_parm's must have a non-NULL name\n");
|
|
Assertion(name[0] == '-', "Coding error! cmdline_parm's must start with a '-'\n");
|
|
// not in the static Parm_list init, so lookup the NULL help args
|
|
if (help == NULL) {
|
|
help = get_param_desc(name);
|
|
}
|
|
list_append(&Parm_list, this);
|
|
}
|
|
}
|
|
|
|
|
|
// destructor - frees any allocated memory
|
|
cmdline_parm::~cmdline_parm() noexcept
|
|
{
|
|
#ifndef FRED
|
|
if (args) {
|
|
delete [] args;
|
|
args = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// checks if the objects args variable is valid
|
|
// returns true if it is, shows an error box and returns false if not valid.
|
|
bool cmdline_parm::check_if_args_is_valid() {
|
|
if ( args == NULL ) {
|
|
Error(__FILE__, __LINE__,
|
|
"Command line flag passed that requires an argument, but the argument is missing!\r\n"
|
|
"The flag is '%s', make sure that you have an argument that follows it.\r\n"
|
|
"You may need to close your launcher and remove the flag manually from %s/data/cmdline_fso.cfg\r\n",
|
|
name, "<Freespace directory>");
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
// returns - true if the parameter exists on the command line, otherwise false
|
|
int cmdline_parm::found()
|
|
{
|
|
return name_found;
|
|
}
|
|
|
|
// returns - the interger representation for the parameter argument
|
|
int cmdline_parm::get_int()
|
|
{
|
|
Assertion(arg_type == AT_INT, "Coding error! Cmdline arg (%s) called cmdline_parm::get_int() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
|
|
check_if_args_is_valid();
|
|
|
|
size_t offset = 0;
|
|
|
|
if (stacks) {
|
|
// first off, DON'T STACK NON-STRINGS!!
|
|
Int3();
|
|
|
|
// secondly, we still need to get it right for the user's sake...
|
|
char *moron = strstr(args, ",");
|
|
|
|
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
|
|
// we get the last arg, since it's the newest one
|
|
offset = strlen(args) - strlen(moron) + 1;
|
|
}
|
|
}
|
|
|
|
return atoi(args+offset);
|
|
}
|
|
|
|
|
|
// returns - the float representation for the parameter argument
|
|
float cmdline_parm::get_float()
|
|
{
|
|
Assertion(arg_type == AT_FLOAT, "Coding error! Cmdline arg (%s) called cmdline_parm::get_float() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
|
|
check_if_args_is_valid();
|
|
|
|
size_t offset = 0;
|
|
|
|
if (stacks) {
|
|
// first off, DON'T STACK NON-STRINGS!!
|
|
Int3();
|
|
|
|
// secondly, we still need to get it right for the user's sake
|
|
char *moron = strstr(args, ",");
|
|
|
|
if ( moron && ((strlen(moron) + 1) < strlen(args)) ) {
|
|
// we get the last arg, since it's the newest one
|
|
offset = strlen(args) - strlen(moron) + 1;
|
|
}
|
|
}
|
|
|
|
return (float)atof(args+offset);
|
|
}
|
|
|
|
|
|
// returns - the string value for the parameter argument
|
|
char *cmdline_parm::str()
|
|
{
|
|
Assertion(arg_type == AT_STRING, "Coding error! Cmdline arg (%s) called cmdline_parm::str() with invalid arg_type (%s)", name, cmdline_arg_types[arg_type]);
|
|
check_if_args_is_valid();
|
|
|
|
return args;
|
|
}
|
|
bool cmdline_parm::has_param() {
|
|
return args != nullptr;
|
|
}
|
|
|
|
#ifdef SCP_UNIX
|
|
extern void normalize_directory_separators(SCP_string &str);
|
|
|
|
static SCP_string get_real_mod_path(const char *mod)
|
|
{
|
|
DIR *dirp;
|
|
SCP_string fullpath;
|
|
SCP_string mod_path = mod;
|
|
|
|
normalize_directory_separators(mod_path);
|
|
|
|
fullpath = SCP_string(".") + DIR_SEPARATOR_STR;
|
|
fullpath += mod_path;
|
|
|
|
// check if path already exists
|
|
dirp = opendir(fullpath.c_str());
|
|
|
|
if (dirp) {
|
|
// found it, return unchanged
|
|
closedir(dirp);
|
|
|
|
return mod_path;
|
|
}
|
|
|
|
// not found, check for a difference in case
|
|
SCP_string new_mod_path;
|
|
SCP_string part;
|
|
struct dirent *dir;
|
|
SCP_string::size_type separator;
|
|
SCP_string::size_type offset = 0;
|
|
|
|
fullpath = SCP_string(".") + DIR_SEPARATOR_STR;
|
|
|
|
do {
|
|
separator = mod_path.find(DIR_SEPARATOR_CHAR, offset);
|
|
|
|
if (separator != SCP_string::npos) {
|
|
part = mod_path.substr(offset, separator-offset);
|
|
offset += separator-offset + 1;
|
|
} else {
|
|
part = mod_path.substr(offset);
|
|
offset += part.length();
|
|
}
|
|
|
|
dirp = opendir(fullpath.c_str());
|
|
|
|
if ( !dirp ) {
|
|
break;
|
|
}
|
|
|
|
while ((dir = readdir(dirp)) != nullptr) {
|
|
if (stricmp(dir->d_name, part.c_str())) {
|
|
continue;
|
|
}
|
|
|
|
SCP_string fn = fullpath + dir->d_name;
|
|
|
|
// make sure it accessible and a directory
|
|
struct stat buf;
|
|
|
|
if (stat(fn.c_str(), &buf) == -1) {
|
|
continue;
|
|
}
|
|
|
|
if ( !S_ISDIR(buf.st_mode) ) {
|
|
continue;
|
|
}
|
|
|
|
if ( !new_mod_path.empty() ) {
|
|
new_mod_path += DIR_SEPARATOR_STR;
|
|
}
|
|
|
|
new_mod_path += dir->d_name;
|
|
|
|
fullpath += dir->d_name;
|
|
fullpath += DIR_SEPARATOR_STR;
|
|
|
|
break;
|
|
}
|
|
|
|
if (dirp) {
|
|
closedir(dirp);
|
|
}
|
|
} while (offset < mod_path.length());
|
|
|
|
// Append anything left from mod_path onto the new path. This will catch trailing separators
|
|
// as well as mod folders which don't exist so that the mod string remains unchanged except
|
|
// for the directory name case.
|
|
if (new_mod_path.length() != mod_path.length()) {
|
|
new_mod_path += mod_path.substr(new_mod_path.length());
|
|
}
|
|
|
|
return new_mod_path;
|
|
}
|
|
|
|
// For case sensitive filesystems (e.g. Linux/BSD) perform case-insensitive dir matches.
|
|
//
|
|
// NOTE: Aside from change in case no alterations should be made to the modlist. Missing
|
|
// mod folders should be left in place and no errors or warnings should be generated.
|
|
// There should be no difference between Windows and non-Windows modlist handling.
|
|
static void handle_unix_modlist(char **modlist, size_t *len)
|
|
{
|
|
// search filesystem for given paths
|
|
SCP_vector<SCP_string> mod_paths;
|
|
|
|
for (char *cur_mod = strtok(*modlist, ","); cur_mod != NULL; cur_mod = strtok(NULL, ",")) {
|
|
SCP_string path = get_real_mod_path(cur_mod);
|
|
mod_paths.push_back(std::move(path));
|
|
}
|
|
|
|
// create new char[] to replace modlist
|
|
size_t total_len = 0;
|
|
|
|
for (auto &path : mod_paths) {
|
|
total_len += path.length() + 1;
|
|
}
|
|
|
|
char *new_modlist = new char[total_len + 1];
|
|
memset(new_modlist, 0, total_len + 1);
|
|
|
|
for (auto &path : mod_paths) {
|
|
strcat_s(new_modlist, total_len + 1, path.c_str());
|
|
strcat_s(new_modlist, total_len + 1, ",");
|
|
}
|
|
|
|
// remove trailing comma
|
|
new_modlist[total_len-1] = '\0';
|
|
|
|
// make the rest of the modlist manipulation unaware that anything happened here
|
|
delete [] *modlist;
|
|
*modlist = new_modlist;
|
|
*len = total_len;
|
|
}
|
|
#endif /* SCP_UNIX */
|
|
|
|
// external entry point into this modules
|
|
|
|
static json_t* json_get_v1() {
|
|
auto root = json_object();
|
|
|
|
{
|
|
auto version_obj = json_object();
|
|
|
|
json_object_set_new(version_obj, "full", json_string(FS_VERSION_FULL));
|
|
json_object_set_new(version_obj, "major", json_integer(FS_VERSION_MAJOR));
|
|
json_object_set_new(version_obj, "minor", json_integer(FS_VERSION_MINOR));
|
|
json_object_set_new(version_obj, "build", json_integer(FS_VERSION_BUILD));
|
|
|
|
json_object_set_new(version_obj, "has_revision", json_boolean(FS_VERSION_HAS_REVIS));
|
|
json_object_set_new(version_obj, "revision", json_integer(FS_VERSION_REVIS));
|
|
json_object_set_new(version_obj, "revision_str", json_string(FS_VERSION_REVIS_STR));
|
|
|
|
json_object_set_new(root, "version", version_obj);
|
|
}
|
|
{
|
|
auto easy_array = json_array();
|
|
|
|
for (auto& easy_flag : easy_flags) {
|
|
json_array_append_new(easy_array, json_string(easy_flag.name));
|
|
}
|
|
|
|
json_object_set_new(root, "easy_flags", easy_array);
|
|
}
|
|
{
|
|
auto flags_array = json_array();
|
|
|
|
for (auto& flag : exe_params) {
|
|
auto flag_obj = json_object();
|
|
|
|
json_object_set_new(flag_obj, "name", json_string(flag.name));
|
|
json_object_set_new(flag_obj, "description", json_string(flag.desc));
|
|
json_object_set_new(flag_obj, "fso_only", json_boolean(flag.fso_only));
|
|
json_object_set_new(flag_obj, "on_flags", json_integer(flag.on_flags));
|
|
json_object_set_new(flag_obj, "off_flags", json_integer(flag.off_flags));
|
|
json_object_set_new(flag_obj, "type", json_string(flag.type));
|
|
json_object_set_new(flag_obj, "web_url", json_string(flag.web_url));
|
|
|
|
json_array_append_new(flags_array, flag_obj);
|
|
}
|
|
|
|
json_object_set_new(root, "flags", flags_array);
|
|
}
|
|
{
|
|
auto caps_array = json_array();
|
|
|
|
json_array_append_new(caps_array, json_string("OpenAL"));
|
|
json_array_append_new(caps_array, json_string("No D3D"));
|
|
json_array_append_new(caps_array, json_string("New Sound"));
|
|
json_array_append_new(caps_array, json_string("SDL"));
|
|
json_array_append_new(caps_array, json_string("Multijoy"));
|
|
|
|
json_object_set_new(root, "caps", caps_array);
|
|
}
|
|
{
|
|
auto voices_array = json_array();
|
|
|
|
auto voices = speech_enumerate_voices();
|
|
|
|
for (auto& voice : voices) {
|
|
json_array_append_new(voices_array, json_string(voice.second.c_str()));
|
|
}
|
|
|
|
json_object_set_new(root, "voices", voices_array);
|
|
}
|
|
{
|
|
auto resolution_array = json_array();
|
|
|
|
auto displays = gr_enumerate_displays();
|
|
|
|
for (auto& display : displays) {
|
|
auto display_obj = json_object();
|
|
|
|
json_object_set_new(display_obj, "index", json_integer(display.index));
|
|
json_object_set_new(display_obj, "name", json_string(display.name.c_str()));
|
|
|
|
json_object_set_new(display_obj, "x", json_integer(display.x));
|
|
json_object_set_new(display_obj, "y", json_integer(display.y));
|
|
json_object_set_new(display_obj, "width", json_integer(display.width));
|
|
json_object_set_new(display_obj, "height", json_integer(display.height));
|
|
|
|
auto modes_array = json_array();
|
|
|
|
for (auto& mode : display.video_modes) {
|
|
auto mode_obj = json_object();
|
|
|
|
json_object_set_new(mode_obj, "x", json_integer(mode.width));
|
|
json_object_set_new(mode_obj, "y", json_integer(mode.height));
|
|
json_object_set_new(mode_obj, "bits", json_integer(mode.bit_depth));
|
|
|
|
json_array_append_new(modes_array, mode_obj);
|
|
}
|
|
|
|
json_object_set_new(display_obj, "modes", modes_array);
|
|
|
|
json_array_append_new(resolution_array, display_obj);
|
|
}
|
|
|
|
json_object_set_new(root, "displays", resolution_array);
|
|
}
|
|
{
|
|
auto openal_obj = json_object();
|
|
|
|
auto openal_info = openal_get_platform_information();
|
|
|
|
json_object_set_new(openal_obj, "version_major", json_integer(openal_info.version_major));
|
|
json_object_set_new(openal_obj, "version_minor", json_integer(openal_info.version_minor));
|
|
|
|
json_object_set(openal_obj, "default_playback", json_string(openal_info.default_playback_device.c_str()));
|
|
json_object_set(openal_obj, "default_capture", json_string(openal_info.default_capture_device.c_str()));
|
|
|
|
{
|
|
auto playback_array = json_array();
|
|
|
|
for (auto& device : openal_info.playback_devices) {
|
|
json_array_append_new(playback_array, json_string(device.c_str()));
|
|
}
|
|
|
|
json_object_set_new(openal_obj, "playback_devices", playback_array);
|
|
}
|
|
{
|
|
auto capture_array = json_array();
|
|
|
|
for (auto& device : openal_info.capture_devices) {
|
|
json_array_append_new(capture_array, json_string(device.c_str()));
|
|
}
|
|
|
|
json_object_set_new(openal_obj, "capture_devices", capture_array);
|
|
}
|
|
{
|
|
auto efx_support_obj = json_object();
|
|
|
|
for (auto& pair : openal_info.efx_support) {
|
|
json_object_set_new(efx_support_obj, pair.first.c_str(), json_boolean(pair.second));
|
|
}
|
|
|
|
json_object_set_new(openal_obj, "efx_support", efx_support_obj);
|
|
}
|
|
|
|
json_object_set_new(root, "openal", openal_obj);
|
|
}
|
|
{
|
|
auto joystick_array = io::joystick::getJsonArray();
|
|
|
|
json_object_set_new(root, "joysticks", joystick_array);
|
|
}
|
|
{
|
|
json_object_set_new(root, "pref_path", json_string(os_get_config_path().c_str()));
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
static void write_flags_file() {
|
|
FILE *fp = fopen("flags.lch","w");
|
|
|
|
if (fp == NULL) {
|
|
os::dialogs::Message(os::dialogs::MESSAGEBOX_ERROR, "Error creating flag list for launcher");
|
|
return;
|
|
}
|
|
|
|
int easy_flag_size = sizeof(EasyFlag);
|
|
int flag_size = sizeof(Flag);
|
|
|
|
int num_easy_flags = sizeof(easy_flags) / easy_flag_size;
|
|
int num_flags = sizeof(exe_params) / flag_size;
|
|
|
|
// Launcher will check its using structures of the same size
|
|
fwrite(&easy_flag_size, sizeof(int), 1, fp);
|
|
fwrite(&flag_size, sizeof(int), 1, fp);
|
|
|
|
fwrite(&num_easy_flags, sizeof(int), 1, fp);
|
|
fwrite(&easy_flags, sizeof(easy_flags), 1, fp);
|
|
|
|
fwrite(&num_flags, sizeof(int), 1, fp);
|
|
fwrite(&exe_params, sizeof(exe_params), 1, fp);
|
|
|
|
{
|
|
// cheap and bastardly cap check for builds
|
|
// (needs to be compatible with older Launchers, which means having
|
|
// this implies an OpenAL build for old Launchers)
|
|
ubyte build_caps = 0;
|
|
|
|
/* portej05 defined this always */
|
|
build_caps |= BUILD_CAPS_OPENAL;
|
|
build_caps |= BUILD_CAPS_NO_D3D;
|
|
build_caps |= BUILD_CAPS_NEW_SND;
|
|
build_caps |= BUILD_CAPS_SDL;
|
|
|
|
fwrite(&build_caps, 1, 1, fp);
|
|
}
|
|
|
|
fflush(fp);
|
|
fclose(fp);
|
|
}
|
|
|
|
static flag_output_type get_flags_output_type() {
|
|
Assertion(get_flags_arg.found(), "This function is only valid if " GET_FLAGS_STRING " is present!");
|
|
|
|
if (!get_flags_arg.has_param()) {
|
|
// Default to binary mode
|
|
return flag_output_type::Binary;
|
|
}
|
|
|
|
SCP_string type(get_flags_arg.str());
|
|
|
|
if (type == "binary") {
|
|
return flag_output_type::Binary;
|
|
} else if (type == "json_v1") {
|
|
return flag_output_type::Json_V1;
|
|
} else {
|
|
// This is supposed to make it easy for the launcher to recognize an unsupported type
|
|
printf("OUTPUT TYPE NOT SUPPORTED!\n");
|
|
// Default to json in this case so that no flags.lch file is created
|
|
return flag_output_type::Json_V1;
|
|
}
|
|
}
|
|
|
|
static void write_flags() {
|
|
auto type = get_flags_output_type();
|
|
switch(type) {
|
|
case flag_output_type::Binary:
|
|
write_flags_file();
|
|
break;
|
|
case flag_output_type::Json_V1:
|
|
json_t* root = json_get_v1();
|
|
|
|
json_dumpf(root, stdout, JSON_INDENT(4));
|
|
json_decref(root);
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool SetCmdlineParams()
|
|
// Sets externed variables used for communication cmdline information
|
|
{
|
|
//getcwd(FreeSpace_Directory, 256); // set the directory to our fs2 root
|
|
|
|
// DO THIS BEFORE get_flags, as portable_mode can change the value of pref_path printed in the json
|
|
if (portable_mode.found())
|
|
{
|
|
Cmdline_portable_mode = true;
|
|
}
|
|
|
|
// DO THIS FIRST to avoid unrecognized flag warnings when just getting flag file
|
|
if ( get_flags_arg.found() ) {
|
|
write_flags();
|
|
|
|
return false;
|
|
}
|
|
|
|
if (joy_info.found()) {
|
|
io::joystick::printJoyJSON();
|
|
return false;
|
|
}
|
|
|
|
if (no_fpscap.found())
|
|
{
|
|
Cmdline_NoFPSCap = 1;
|
|
}
|
|
|
|
if(loadallweapons_arg.found())
|
|
{
|
|
Cmdline_load_all_weapons = 1;
|
|
}
|
|
|
|
if(voice_recognition_arg.found())
|
|
{
|
|
Cmdline_voice_recognition = 1;
|
|
}
|
|
|
|
#ifdef Allow_NoWarn
|
|
if (nowarn_arg.found())
|
|
{
|
|
Cmdline_nowarn = 1;
|
|
}
|
|
#endif
|
|
|
|
if (extra_warn_arg.found())
|
|
{
|
|
Cmdline_extra_warn = 1;
|
|
}
|
|
|
|
if (!Fred_running) { //There is no standalone FRED
|
|
// is this a standalone server??
|
|
if (standalone_arg.found()) {
|
|
Is_standalone = 1;
|
|
|
|
// also enable non-interactive by default here
|
|
Cmdline_noninteractive = true;
|
|
}
|
|
}
|
|
|
|
// object update control
|
|
if(objupd_arg.found()){
|
|
Cmdline_objupd = objupd_arg.get_int();
|
|
if (Cmdline_objupd < 0)
|
|
{
|
|
Cmdline_objupd = 0;
|
|
}
|
|
if (Cmdline_objupd > 3)
|
|
{
|
|
Cmdline_objupd = 3;
|
|
}
|
|
}
|
|
|
|
if(mpnoreturn_arg.found()) {
|
|
Cmdline_mpnoreturn = 1;
|
|
}
|
|
|
|
// run with no sound
|
|
if ( nosound_arg.found() ) {
|
|
Cmdline_freespace_no_sound = 1;
|
|
// and since music is automatically unusable...
|
|
Cmdline_freespace_no_music = 1;
|
|
}
|
|
|
|
// run with no music
|
|
if ( nomusic_arg.found() ) {
|
|
Cmdline_freespace_no_music = 1;
|
|
}
|
|
|
|
// Disable enhanced sound
|
|
if (noenhancedsound_arg.found()) {
|
|
Cmdline_no_enhanced_sound = 1;
|
|
}
|
|
|
|
// should we start a network game
|
|
if ( startgame_arg.found() ) {
|
|
Cmdline_use_last_pilot = 1;
|
|
Cmdline_start_netgame = 1;
|
|
}
|
|
|
|
// closed network game
|
|
if ( gameclosed_arg.found() ) {
|
|
Cmdline_closed_game = 1;
|
|
}
|
|
|
|
// restircted network game
|
|
if ( gamerestricted_arg.found() ) {
|
|
Cmdline_restricted_game = 1;
|
|
}
|
|
|
|
// get the name of the network game
|
|
if ( gamename_arg.found() ) {
|
|
Cmdline_game_name = gamename_arg.str();
|
|
|
|
// be sure that this string fits in our limits
|
|
if ( strlen(Cmdline_game_name) >= MAX_GAMENAME_LEN ) {
|
|
Cmdline_game_name[MAX_GAMENAME_LEN-1] = '\0';
|
|
}
|
|
}
|
|
|
|
// get the password for a pssword game
|
|
if ( gamepassword_arg.found() ) {
|
|
Cmdline_game_password = gamepassword_arg.str();
|
|
|
|
// be sure that this string fits in our limits
|
|
if ( strlen(Cmdline_game_password) >= MAX_PASSWD_LEN ) {
|
|
ReleaseWarning(LOCATION, "Multi game password is longer than max of %d characters and will be trimmed to fit!", MAX_PASSWD_LEN-1);
|
|
Cmdline_game_password[MAX_PASSWD_LEN-1] = '\0';
|
|
}
|
|
}
|
|
|
|
// set the rank above/below arguments
|
|
if ( allowabove_arg.found() ) {
|
|
Cmdline_rank_above = allowabove_arg.str();
|
|
}
|
|
if ( allowbelow_arg.found() ) {
|
|
Cmdline_rank_below = allowbelow_arg.str();
|
|
}
|
|
|
|
// get the port number for games
|
|
if ( port_arg.found() ) {
|
|
Cmdline_network_port = port_arg.get_int();
|
|
}
|
|
|
|
// get IP address of gateway, for auto port forwarding
|
|
if ( gateway_ip_arg.found() ) {
|
|
Cmdline_gateway_ip = gateway_ip_arg.str();
|
|
}
|
|
|
|
// the connect argument specifies to join a game at this particular address
|
|
if ( connect_arg.found() ) {
|
|
Cmdline_use_last_pilot = 1;
|
|
Cmdline_connect_addr = connect_arg.str();
|
|
}
|
|
|
|
// see if the multilog flag was set
|
|
if ( multilog_arg.found() ){
|
|
Cmdline_multi_log = 1;
|
|
}
|
|
|
|
// spew pof info
|
|
if(pof_spew.found()){
|
|
Cmdline_spew_pof_info = 1;
|
|
}
|
|
|
|
// spew weapon stats
|
|
if (weapon_spew.found()) {
|
|
Cmdline_spew_weapon_stats = WeaponSpewType::STANDARD;
|
|
|
|
// currently just one argument
|
|
if (weapon_spew.has_param()) {
|
|
if (!stricmp(weapon_spew.str(), "all")) {
|
|
Cmdline_spew_weapon_stats = WeaponSpewType::ALL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// mouse coords
|
|
if(mouse_coords.found()){
|
|
Cmdline_mouse_coords = 1;
|
|
}
|
|
|
|
// net timeout
|
|
if(timeout.found()){
|
|
Cmdline_timeout = timeout.get_int();
|
|
}
|
|
|
|
// d3d windowed
|
|
if(window_arg.found()) {
|
|
// We need to set both values since we don't know if we are going to use the new config system
|
|
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "0");
|
|
Cmdline_window = true;
|
|
}
|
|
|
|
if ( fullscreen_window_arg.found( ) )
|
|
{
|
|
//options::OptionsManager::instance()->setOverride("Graphics.WindowMode", "1");
|
|
Cmdline_fullscreen_window = true;
|
|
Cmdline_window = false; /* Make sure no-one sets both */
|
|
}
|
|
|
|
if(render_res_arg.found() || deprecated_res_arg.found()){
|
|
if (render_res_arg.found()) {
|
|
Cmdline_res = render_res_arg.str();
|
|
}
|
|
else {
|
|
Cmdline_res = deprecated_res_arg.str();
|
|
mprintf(("Deprecated -res argument. Use -render_res instead...\n"));
|
|
}
|
|
|
|
/*int width = 0;
|
|
int height = 0;
|
|
|
|
if (sscanf(Cmdline_res, "%dx%d", &width, &height) == 2) {
|
|
SCP_string override;
|
|
sprintf(override, "{\"width\":%d,\"height\":%d}", width, height);
|
|
options::OptionsManager::instance()->setOverride("Graphics.Resolution", override);
|
|
} else {
|
|
Warning(LOCATION, "Failed to parse -res parameter \"%s\". Must be in format \"<width>x<height>\".\n", Cmdline_res);
|
|
}*/
|
|
}
|
|
if(window_res_arg.found()){
|
|
int width = 0;
|
|
int height = 0;
|
|
|
|
if ( sscanf(window_res_arg.str(), "%dx%d", &width, &height) == 2 ) {
|
|
Cmdline_window_res.emplace(static_cast<uint16_t>(width), static_cast<uint16_t>(height));
|
|
} else {
|
|
Warning(LOCATION, "Failed to parse -window_res parameter \"%s\". Must be in format \"<width>x<height>\".\n", window_res_arg.str());
|
|
}
|
|
}
|
|
|
|
if(center_res_arg.found()){
|
|
Cmdline_center_res = center_res_arg.str();
|
|
}
|
|
if (hdr_nits_arg.found()) {
|
|
// presence of the flag alone forces HDR output on, overriding the in-game HDR setting
|
|
options::OptionsManager::instance()->setOverride("Graphics.HDR", "true");
|
|
|
|
if (hdr_nits_arg.has_param()) {
|
|
float paperwhite_nits = 0.0f, peak_nits = 0.0f;
|
|
if (sscanf(hdr_nits_arg.str(), "%f,%f", &paperwhite_nits, &peak_nits) == 2 && paperwhite_nits > 0.0f && peak_nits > 0.0f) {
|
|
// std::to_string always includes a decimal point, so this is a valid JSON real
|
|
// (json_unpack's "f" format rejects a bare integer like "400")
|
|
options::OptionsManager::instance()->setOverride("Graphics.HDRPaperWhite", std::to_string(paperwhite_nits));
|
|
options::OptionsManager::instance()->setOverride("Graphics.HDRPeakLuminance", std::to_string(peak_nits));
|
|
} else {
|
|
Warning(LOCATION, "Failed to parse -hdr parameter \"%s\". Must be in format \"<paperwhite_nits>,<peak_nits>\".\n", hdr_nits_arg.str());
|
|
}
|
|
}
|
|
}
|
|
if(almission_arg.found()){//DTP for autoload mission // developer oritentated
|
|
Cmdline_almission = almission_arg.str();
|
|
Cmdline_use_last_pilot = 1;
|
|
Cmdline_start_netgame = 1;
|
|
}
|
|
|
|
if(dualscanlines_arg.found() ) {
|
|
Cmdline_dualscanlines = 1;
|
|
}
|
|
|
|
if(targetinfo_arg.found())
|
|
{
|
|
Extra_target_info = true;
|
|
}
|
|
|
|
if(nomovies_arg.found() ) {
|
|
Cmdline_nomovies = 1;
|
|
}
|
|
|
|
if ( noscalevid_arg.found() ) {
|
|
Cmdline_noscalevid = 1;
|
|
}
|
|
|
|
if(noparseerrors_arg.found()) {
|
|
Cmdline_noparseerrors = 1;
|
|
}
|
|
|
|
|
|
if(mod_arg.found() ) {
|
|
Cmdline_mod = mod_arg.str();
|
|
|
|
// strip off blank space if it's there
|
|
if ( Cmdline_mod[strlen(Cmdline_mod)-1] == ' ' ) {
|
|
Cmdline_mod[strlen(Cmdline_mod)-1] = '\0';
|
|
}
|
|
|
|
// Ok - mod stacking support
|
|
size_t len = strlen(Cmdline_mod);
|
|
char *modlist = new char[len+2];
|
|
memset( modlist, 0, len + 2 );
|
|
strcpy_s(modlist, len+2, Cmdline_mod);
|
|
|
|
#ifdef SCP_UNIX
|
|
// handle case-insensitive searching
|
|
handle_unix_modlist(&modlist, &len);
|
|
#endif
|
|
|
|
// null terminate each individual
|
|
for (size_t i = 0; i < len; i++)
|
|
{
|
|
if (modlist[i] == ',')
|
|
modlist[i] = '\0';
|
|
}
|
|
|
|
//copy over - we don't have to delete[] Cmdline_mod because it's a pointer to an automatic global char*
|
|
Cmdline_mod = modlist;
|
|
}
|
|
|
|
if(campaign_arg.found()) {
|
|
Cmdline_campaign = campaign_arg.str();
|
|
|
|
// strip off blank space if it's there
|
|
if ( Cmdline_campaign[strlen(Cmdline_campaign)-1] == ' ' ) {
|
|
Cmdline_campaign[strlen(Cmdline_campaign)-1] = '\0';
|
|
}
|
|
}
|
|
|
|
if (fps_arg.found())
|
|
{
|
|
Show_framerate = 1;
|
|
}
|
|
|
|
if (bmpmanusage_arg.found())
|
|
{
|
|
Cmdline_bmpman_usage = 1;
|
|
}
|
|
|
|
if(pos_arg.found())
|
|
{
|
|
Cmdline_show_pos = 1;
|
|
}
|
|
|
|
if( mipmap_arg.found() ) {
|
|
Cmdline_mipmap = 1;
|
|
}
|
|
|
|
if( stats_arg.found() ) {
|
|
Cmdline_show_stats = 1;
|
|
}
|
|
|
|
if ( fov_arg.found() ) {
|
|
auto val = fov_arg.get_float();
|
|
if (val > 0.1) {
|
|
VIEWER_ZOOM_DEFAULT = val;
|
|
} else {
|
|
VIEWER_ZOOM_DEFAULT = DEFAULT_FOV;
|
|
}
|
|
}
|
|
|
|
if ( fov_cockpit_arg.found() ) {
|
|
auto val = fov_cockpit_arg.get_float();
|
|
if (val > 0.1) {
|
|
COCKPIT_ZOOM_DEFAULT = val;
|
|
}
|
|
else {
|
|
COCKPIT_ZOOM_DEFAULT = VIEWER_ZOOM_DEFAULT;
|
|
}
|
|
}
|
|
|
|
if (vr.found()) {
|
|
Cmdline_enable_vr = true;
|
|
if (fov_arg.found() || fov_cockpit_arg.found()) {
|
|
Warning(LOCATION, "FoV Command line settings found. VR-Mode will override these with the HMD's native FoV...");
|
|
}
|
|
|
|
// enable other settings to allow VR to work more seamlessly
|
|
mprintf(("VR-Mode enabled, so forcing on the following settings: capture_mouse, window_res 1000x1000, window, no_vsync \n"));
|
|
|
|
// ensure ingame resolution is set to sensible values in VR mode,
|
|
// which will exceed the resolution otherwise shown and is not dependent on the monitor resolution
|
|
Cmdline_capture_mouse = true;
|
|
Cmdline_window_res.emplace(static_cast<uint16_t>(1000), static_cast<uint16_t>(1000));
|
|
|
|
Cmdline_fullscreen_window = false;
|
|
Cmdline_window = true; /* Make sure no-one sets both */
|
|
removeWindowModeOption();
|
|
|
|
// Turn off VSync, since we definitely don't want to be capped by the main monitor
|
|
// the OpenXR runtime should have a buffered wait which will behave, effectively,
|
|
// as a VSync to VR goggle driver
|
|
Gr_enable_vsync = false;
|
|
removeVSyncOption();
|
|
|
|
openxr_prepare();
|
|
}
|
|
|
|
if (orb_radar.found())
|
|
{
|
|
Cmdline_orb_radar = 1;
|
|
}
|
|
|
|
if ( allow_autpilot_interrupt.found() ) {
|
|
Cmdline_autopilot_interruptable = 0;
|
|
}
|
|
|
|
if ( deadzone.found() ) {
|
|
Cmdline_deadzone = deadzone.get_int();
|
|
}
|
|
|
|
if ( stretch_menu.found() ) {
|
|
Cmdline_stretch_menu = true;
|
|
}
|
|
|
|
if ( capture_mouse.found() ) {
|
|
Cmdline_capture_mouse = true;
|
|
}
|
|
// new lighting lines
|
|
if ( ambient_power_arg.found() )
|
|
Cmdline_ambient_power = ambient_power_arg.get_float();
|
|
|
|
if (emissive_power_arg.found() && emissive_power_arg.has_param()) {
|
|
Cmdline_emissive_power = emissive_power_arg.get_float();
|
|
} else if (emissive_arg.found() || emissive_power_arg.found()) {
|
|
// for legacy support no argument param defaults to the old emissive value
|
|
Cmdline_emissive_power = 0.30f;
|
|
}
|
|
|
|
if (light_power_arg.found())
|
|
Cmdline_light_power = light_power_arg.get_float();
|
|
|
|
if (spec_arg.found()) {
|
|
Cmdline_spec = 0;
|
|
}
|
|
|
|
if( no_set_gamma_arg.found() )
|
|
{
|
|
Cmdline_no_set_gamma = 1;
|
|
}
|
|
|
|
if (no_ingame_options_arg.found()) {
|
|
Cmdline_no_ingame_options = true;
|
|
}
|
|
|
|
if(no_vsync_arg.found() )
|
|
{
|
|
Gr_enable_vsync = false;
|
|
}
|
|
|
|
if ( normal_arg.found() ) {
|
|
Cmdline_normal = 0;
|
|
}
|
|
|
|
if ( height_arg.found() ) {
|
|
Cmdline_height = 0;
|
|
}
|
|
|
|
if (post_process_aa_arg.found() || post_process_aa_preset_arg.found()) {
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Low;
|
|
|
|
if (post_process_aa_preset_arg.found()) {
|
|
switch (post_process_aa_preset_arg.get_int()) {
|
|
case 0:
|
|
Gr_aa_mode = AntiAliasMode::FXAA_Low;
|
|
break;
|
|
case 1:
|
|
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
|
|
break;
|
|
case 2:
|
|
Gr_aa_mode = AntiAliasMode::FXAA_High;
|
|
break;
|
|
case 3:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Low;
|
|
break;
|
|
case 4:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
|
|
break;
|
|
case 5:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_High;
|
|
break;
|
|
case 6:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (msaa_enabled_arg.found()) {
|
|
Cmdline_msaa_enabled = msaa_enabled_arg.get_int();
|
|
switch (Cmdline_msaa_enabled) {
|
|
case 0:
|
|
case 4:
|
|
case 8:
|
|
case 16:
|
|
break;
|
|
default:
|
|
Warning(LOCATION, "Requested illegal MSAA sample count %d. Allowed are: 0, 4, 8, 16. Setting to 0.", Cmdline_msaa_enabled);
|
|
Cmdline_msaa_enabled = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( glow_arg.found() )
|
|
Cmdline_glow = 0;
|
|
|
|
if (ingamejoin_arg.found() )
|
|
Cmdline_ingamejoin = 0;
|
|
|
|
if ( start_mission_arg.found() ) {
|
|
Cmdline_start_mission = start_mission_arg.str();
|
|
}
|
|
|
|
if ( output_scripting_arg.found() )
|
|
Output_scripting_meta = true;
|
|
|
|
if (output_script_json_arg.found() )
|
|
Output_scripting_json = true;
|
|
|
|
if (output_script_luastub_arg.found())
|
|
Output_scripting_luastub = true;
|
|
|
|
if (output_sexp_arg.found() ) {
|
|
Cmdline_output_sexp_info = true;
|
|
}
|
|
|
|
if (generate_controlconfig_arg.found())
|
|
Generate_controlconfig_table = true;
|
|
|
|
if ( no_pbo_arg.found() )
|
|
{
|
|
Cmdline_no_pbo = 1;
|
|
}
|
|
|
|
if ( no_drawrangeelements.found() )
|
|
{
|
|
Cmdline_drawelements = 1;
|
|
}
|
|
|
|
if( keyboard_layout.found())
|
|
{
|
|
Cmdline_keyboard_layout = keyboard_layout.str();
|
|
}
|
|
|
|
if (gl_finish.found())
|
|
{
|
|
Cmdline_gl_finish = true;
|
|
}
|
|
|
|
if ( no_geo_sdr_effects.found() )
|
|
{
|
|
Cmdline_no_geo_sdr_effects = true;
|
|
}
|
|
|
|
if (set_cpu_affinity.found())
|
|
{
|
|
Cmdline_set_cpu_affinity = true;
|
|
}
|
|
|
|
if (nograb_arg.found())
|
|
{
|
|
Cmdline_nograb = true;
|
|
}
|
|
|
|
if (noshadercache_arg.found())
|
|
{
|
|
Cmdline_noshadercache = true;
|
|
}
|
|
|
|
if (lang_arg.found())
|
|
{
|
|
Cmdline_lang = lang_arg.str();
|
|
}
|
|
|
|
if (no_bsp_align_arg.found()) {
|
|
Cmdline_no_bsp_align = true;
|
|
}
|
|
|
|
if (no_large_shaders.found()) {
|
|
Cmdline_no_large_shaders = true;
|
|
}
|
|
|
|
#ifdef WIN32
|
|
if (fix_registry.found()) {
|
|
Cmdline_alternate_registry_path = true;
|
|
}
|
|
#endif
|
|
|
|
if ( env.found() ) {
|
|
Cmdline_env = 0;
|
|
}
|
|
|
|
if ( ballistic_gauge.found() ) {
|
|
Cmdline_ballistic_gauge = 1;
|
|
}
|
|
|
|
if(dis_collisions.found())
|
|
Cmdline_dis_collisions = 1;
|
|
|
|
if(dis_weapons.found())
|
|
Cmdline_dis_weapons = 1;
|
|
|
|
if ( no_fbo_arg.found() ) {
|
|
Cmdline_no_fbo = 1;
|
|
}
|
|
|
|
if ( rearm_timer_arg.found() )
|
|
Cmdline_rearm_timer = 1;
|
|
|
|
if ( save_render_targets_arg.found() )
|
|
Cmdline_save_render_targets = 1;
|
|
|
|
if ( verify_vps_arg.found() )
|
|
Cmdline_verify_vps = 1;
|
|
|
|
if ( no3dsound_arg.found() )
|
|
Cmdline_no_3d_sound = 1;
|
|
|
|
if ( atiswap_arg.found() )
|
|
{
|
|
Cmdline_ati_color_swap = 1;
|
|
}
|
|
|
|
if ( softparticles_arg.found() )
|
|
{
|
|
Cmdline_softparticles = 1;
|
|
}
|
|
|
|
if ( fb_explosions_arg.found() )
|
|
{
|
|
Gr_framebuffer_effects.set(FramebufferEffects::Shockwaves, true);
|
|
}
|
|
|
|
if (fb_thrusters_arg.found())
|
|
{
|
|
Gr_framebuffer_effects.set(FramebufferEffects::Thrusters, true);
|
|
}
|
|
|
|
if ( no_postprocess_arg.found() )
|
|
{
|
|
Gr_post_processing_enabled = false;
|
|
}
|
|
|
|
if( reparse_mainhall_arg.found() )
|
|
{
|
|
Cmdline_reparse_mainhall = 1;
|
|
}
|
|
|
|
if( enable_shadows_arg.found() )
|
|
{
|
|
// if only using `enable_shadows` then default quality level can be overriden in mod_settings.tbl --wookieejedi
|
|
Shadow_quality_uses_mod_option = true;
|
|
|
|
Shadow_quality = ShadowQuality::Medium;
|
|
}
|
|
|
|
if( shadow_quality_arg.found() )
|
|
{
|
|
// set that we are not using default shadow quality level --wookieejedi
|
|
Shadow_quality_uses_mod_option = false;
|
|
|
|
switch (shadow_quality_arg.get_int()) {
|
|
case 0:
|
|
Shadow_quality = ShadowQuality::Disabled;
|
|
break;
|
|
case 1:
|
|
Shadow_quality = ShadowQuality::Low;
|
|
break;
|
|
case 2:
|
|
Shadow_quality = ShadowQuality::Medium;
|
|
break;
|
|
case 3:
|
|
Shadow_quality = ShadowQuality::High;
|
|
break;
|
|
case 4:
|
|
Shadow_quality = ShadowQuality::Ultra;
|
|
break;
|
|
default:
|
|
mprintf(("Invalid shadow quality %d. Disabling shadows...\n", shadow_quality_arg.get_int()));
|
|
Shadow_quality = ShadowQuality::Disabled;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( rt_shadows_arg.found() )
|
|
{
|
|
// Equivalent to picking "Raytraced" in the Shadow Method option. Silently
|
|
// has no effect if the renderer/hardware doesn't support
|
|
// CAPABILITY_RAYTRACED_SHADOWS -- the CSM path is used either way.
|
|
Shadow_render_method = ShadowRenderMethod::Raytraced;
|
|
}
|
|
|
|
if( no_deferred_lighting_arg.found() )
|
|
{
|
|
Cmdline_no_deferred_lighting = 1;
|
|
}
|
|
|
|
if( deferred_lighting_cockpit_arg.found() )
|
|
{
|
|
Cmdline_deferred_lighting_cockpit = true;
|
|
}
|
|
|
|
if (anisotropy_level_arg.found())
|
|
{
|
|
Cmdline_aniso_level = anisotropy_level_arg.get_int();
|
|
}
|
|
|
|
if (frame_profile_write_file.found())
|
|
{
|
|
Cmdline_profile_write_file = true;
|
|
}
|
|
|
|
if (no_unfocused_pause_arg.found())
|
|
{
|
|
Cmdline_no_unfocus_pause = true;
|
|
}
|
|
|
|
if (retail_time_compression_range_arg.found())
|
|
{
|
|
Cmdline_retail_time_compression_range = true;
|
|
}
|
|
|
|
if (benchmark_mode_arg.found())
|
|
{
|
|
Cmdline_benchmark_mode = true;
|
|
}
|
|
|
|
if (pilot_arg.found())
|
|
{
|
|
Cmdline_pilot = pilot_arg.str();
|
|
}
|
|
|
|
if (noninteractive_arg.found())
|
|
{
|
|
Cmdline_noninteractive = true;
|
|
}
|
|
|
|
if (json_profiling.found())
|
|
{
|
|
Cmdline_json_profiling = true;
|
|
}
|
|
|
|
if (frame_profile_arg.found() )
|
|
{
|
|
Cmdline_frame_profile = true;
|
|
}
|
|
|
|
if (debug_window_arg.found()) {
|
|
Cmdline_debug_window = true;
|
|
}
|
|
|
|
if (graphics_debug_output_arg.found()) {
|
|
Cmdline_graphics_debug_output = true;
|
|
}
|
|
|
|
if (gr_sync_validation_arg.found()) {
|
|
// Enables the Vulkan validation layer + debug messenger + synchronization
|
|
// validation feature (see VulkanRenderer::initializeInstance), but NOT the
|
|
// engine-level graphics debug output: -gr_debug additionally draws debug
|
|
// overlays (e.g. output_uniform_debug_data), which are unrelated to GPU
|
|
// sync validation and would otherwise appear as spurious on-screen
|
|
// artifacts. Keep this a pure GPU-validation switch.
|
|
Cmdline_gr_sync_validation = true;
|
|
}
|
|
|
|
if (log_to_stdout_arg.found()) {
|
|
Cmdline_log_to_stdout = true;
|
|
}
|
|
|
|
if (slow_frames_ok_arg.found()) {
|
|
Cmdline_slow_frames_ok = true;
|
|
}
|
|
if ( luadev_arg.found()) {
|
|
Cmdline_lua_devmode = true;
|
|
}
|
|
|
|
if ( override_arg.found()) {
|
|
Cmdline_override_data = true;
|
|
}
|
|
|
|
if (imgui_debug_arg.found()) {
|
|
Cmdline_show_imgui_debug = true;
|
|
}
|
|
|
|
if (show_video_info.found())
|
|
{
|
|
Cmdline_show_video_info = true;
|
|
}
|
|
|
|
if (vulkan.found()) {
|
|
Cmdline_graphics_api = GraphicsAPI::Vulkan;
|
|
}
|
|
else if (opengl.found()) {
|
|
Cmdline_graphics_api = GraphicsAPI::OpenGL;
|
|
}
|
|
|
|
//Deprecated flags - CommanderDJ
|
|
if (deprecated_no_emissive_arg.found()) {
|
|
Cmdline_emissive = 0;
|
|
}
|
|
|
|
if (deprecated_fxaa_arg.found() ) {
|
|
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
|
|
|
|
if (deprecated_fxaa_preset_arg.found()) {
|
|
auto val = deprecated_fxaa_preset_arg.get_int();
|
|
if (val > 6) {
|
|
Gr_aa_mode = AntiAliasMode::FXAA_High;
|
|
} else if (val > 3) {
|
|
Gr_aa_mode = AntiAliasMode::FXAA_Medium;
|
|
} else {
|
|
Gr_aa_mode = AntiAliasMode::FXAA_Low;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (deprecated_smaa_arg.found()) {
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
|
|
|
|
if (deprecated_smaa_preset_arg.found()) {
|
|
switch (deprecated_smaa_preset_arg.get_int()) {
|
|
case 0:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Low;
|
|
break;
|
|
case 1:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Medium;
|
|
break;
|
|
case 2:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_High;
|
|
break;
|
|
case 3:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
|
|
break;
|
|
default:
|
|
Gr_aa_mode = AntiAliasMode::SMAA_Ultra;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (prefer_ipv4_arg.found()) {
|
|
Cmdline_prefer_ipv4 = true;
|
|
}
|
|
|
|
if (prefer_ipv6_arg.found()) {
|
|
Cmdline_prefer_ipv6 = true;
|
|
|
|
// Rule 2: Not both
|
|
if (Cmdline_prefer_ipv4) {
|
|
ReleaseWarning(LOCATION, "Cannot set preference for both IPv4 and IPv6! Reverting to default behavior...\n");
|
|
|
|
Cmdline_prefer_ipv4 = false;
|
|
Cmdline_prefer_ipv6 = false;
|
|
}
|
|
}
|
|
|
|
if (log_multi_packet_arg.found()) {
|
|
Cmdline_dump_packet_type = true;
|
|
}
|
|
|
|
if (fixed_seed_rand.found()) {
|
|
Cmdline_rng_seed = abs(fixed_seed_rand.get_int());
|
|
if (Cmdline_rng_seed>0) {
|
|
Cmdline_reuse_rng_seed = true;
|
|
}
|
|
else {
|
|
Warning(LOCATION,"-seed must be an integer greater than 0. Invalid input seed will be disregarded.");
|
|
}
|
|
}
|
|
|
|
if (multithreading.found()) {
|
|
Cmdline_multithreading = abs(multithreading.get_int());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int parse_cmdline(int argc, char *argv[])
|
|
{
|
|
// mprintf(("I got to parse_cmdline()!!\n"));
|
|
|
|
os_init_cmdline(argc, argv);
|
|
|
|
// --------------- Kazan -------------
|
|
// If you're looking for the list of if (someparam.found()) { cmdline_someparam = something; } look above at this function
|
|
// I did this because of fred2_parse_cmdline()
|
|
return SetCmdlineParams();
|
|
}
|
|
|
|
const char * get_param_desc(const char *flag_name)
|
|
{
|
|
int i;
|
|
int flag_size = sizeof(Flag);
|
|
int num_flags = sizeof(exe_params) / flag_size;
|
|
for (i = 0; i < num_flags; ++i) {
|
|
if (!strcmp(flag_name, exe_params[i].name)) {
|
|
return exe_params[i].desc;
|
|
}
|
|
}
|
|
return "UNKNOWN - FIXME!";
|
|
}
|