/* AppleWin : An Apple //e emulator for Windows Copyright (C) 1994-1996, Michael O'Brien Copyright (C) 1999-2001, Oliver Schmidt Copyright (C) 2002-2005, Tom Charlesworth Copyright (C) 2006-2014, Tom Charlesworth, Michael Pohoreski AppleWin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. AppleWin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with AppleWin; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Description: main * * Author: Various */ #include "StdAfx.h" #include "CmdLine.h" #include "Log.h" #include "Core.h" #include "Memory.h" #include "LanguageCard.h" #include "Keyboard.h" #include "Joystick.h" #include "SoundCore.h" #include "SNESMAX.h" #include "Interface.h" #include "Harddisk.h" CmdLine g_cmdLine; std::string g_sConfigFile; // INI file to use instead of Registry bool g_bCapturePrintScreenKey = true; bool g_bRegisterFileTypes = true; bool g_bHookSystemKey = true; bool g_bHookAltTab = false; bool g_bHookAltGrControl = false; static LPSTR GetCurrArg(LPSTR lpCmdLine) { if (*lpCmdLine == '\"') lpCmdLine++; return lpCmdLine; } static LPSTR GetNextArg(LPSTR lpCmdLine) { int bInQuotes = 0; while (*lpCmdLine) { if (*lpCmdLine == '\"') { bInQuotes ^= 1; if(!bInQuotes) { *lpCmdLine++ = 0x00; // Assume end-quote is end of this arg continue; } } if ((*lpCmdLine == ' ') && !bInQuotes) { *lpCmdLine++ = 0x00; while (*lpCmdLine == ' ') // Skip multiple spaces between args lpCmdLine++; break; } lpCmdLine++; } return lpCmdLine; } //--------------------------------------------------------------------------- bool ProcessCmdLine(LPSTR lpCmdLine) { const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput std::string strUnsupported; // If 1st param looks like an abs pathname then assume that an associated filetype has been double-clicked // NB. Handled by WM_DDE_INITIATE & WM_DDE_EXECUTE msgs if ((lpCmdLine[0] >= '\"' && lpCmdLine[1] >= 'A' && lpCmdLine[1] <= 'Z' && lpCmdLine[2] == ':') // always in quotes || strncmp("\\\\?\\", lpCmdLine, 4) == 0) return true; while (*lpCmdLine) { LPSTR lpNextArg = GetNextArg(lpCmdLine); if (((strcmp(lpCmdLine, "-l") == 0) || (strcmp(lpCmdLine, "-log") == 0)) && (g_fh == NULL)) { LogInit(); } else if (strcmp(lpCmdLine, "-noreg") == 0) { g_bRegisterFileTypes = false; } else if (strcmp(lpCmdLine, "-conf") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); char buf[MAX_PATH]; DWORD res = GetFullPathName(lpCmdLine, MAX_PATH, buf, NULL); if (res == 0) LogFileOutput("Failed to open configuration file: %s\n", lpCmdLine); else g_sConfigFile = buf; } else if (strcmp(lpCmdLine, "-d1") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_drive[SLOT6][DRIVE_1] = lpCmdLine; } else if (strcmp(lpCmdLine, "-d2") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_drive[SLOT6][DRIVE_2] = lpCmdLine; } else if (strcmp(lpCmdLine, "-d1-disconnected") == 0) { g_cmdLine.driveConnected[SLOT6][DRIVE_1] = false; } else if (strcmp(lpCmdLine, "-d2-disconnected") == 0) { g_cmdLine.driveConnected[SLOT6][DRIVE_2] = false; } else if (strcmp(lpCmdLine, "-h1") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_harddisk[SLOT7][HARDDISK_1] = lpCmdLine; } else if (strcmp(lpCmdLine, "-h2") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_harddisk[SLOT7][HARDDISK_2] = lpCmdLine; } else if (strcmp(lpCmdLine, "-s0") == 0) // Language Card options for Apple II/II+ { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0) g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks; else if (strcmp(lpCmdLine, "saturn64") == 0) g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks / 2; else if (strcmp(lpCmdLine, "languagecard") == 0 || strcmp(lpCmdLine, "lc") == 0) g_cmdLine.bSlot0LanguageCard = true; } else if (lpCmdLine[0] == '-' && lpCmdLine[1] == 's' && lpCmdLine[2] >= '1' && lpCmdLine[2] <= '7') { const UINT slot = lpCmdLine[2] - '0'; if (lpCmdLine[3] == 0) // -s[1..7] { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (strcmp(lpCmdLine, "empty") == 0) g_cmdLine.bSlotEmpty[slot] = true; if (strcmp(lpCmdLine, "diskii") == 0) g_cmdLine.slotInsert[slot] = CT_Disk2; if (strcmp(lpCmdLine, "diskii13") == 0) { g_cmdLine.slotInsert[slot] = CT_Disk2; g_cmdLine.slotInfo[slot].isDiskII13 = true; } if (strcmp(lpCmdLine, "hdc") == 0) g_cmdLine.slotInsert[slot] = CT_GenericHDD; if (strcmp(lpCmdLine, "hdc-sp") == 0) { g_cmdLine.slotInsert[slot] = CT_GenericHDD; g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcSmartPort; } if (strcmp(lpCmdLine, "hdc-bm2") == 0) { g_cmdLine.slotInsert[slot] = CT_GenericHDD; g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcBlockMode2Devices; } if (strcmp(lpCmdLine, "hdc-bm4") == 0) { g_cmdLine.slotInsert[slot] = CT_GenericHDD; g_cmdLine.slotInfo[slot].useHdcFirmwareMode = HdcBlockMode4Devices; } if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0) // Support Saturn128 card in slot 1-7 too (GH#1279) g_cmdLine.slotInsert[slot] = CT_Saturn128K; if (strcmp(lpCmdLine, "megaaudio") == 0) { g_cmdLine.slotInsert[slot] = CT_MegaAudio; g_cmdLine.supportExtraMBCardTypes = true; } if (strcmp(lpCmdLine, "sdmusic") == 0) { g_cmdLine.slotInsert[slot] = CT_SDMusic; g_cmdLine.supportExtraMBCardTypes = true; } if (strcmp(lpCmdLine, "parallel") == 0) { if (slot == SLOT1) g_cmdLine.slotInsert[slot] = CT_GenericPrinter; else LogFileOutput("Parallel Printer card currently only supported in slot 1\n"); } if (strcmp(lpCmdLine, "ssc") == 0) { if (slot == SLOT2) g_cmdLine.slotInsert[slot] = CT_SSC; else LogFileOutput("SSC currently only supported in slot 2\n"); } if (strcmp(lpCmdLine, "vidhd") == 0) { if (slot == SLOT3) g_cmdLine.slotInsert[slot] = CT_VidHD; else LogFileOutput("VidHD currently only supported in slot 3\n"); } } else if (lpCmdLine[3] == 'd' && (lpCmdLine[4] == '1' || lpCmdLine[4] == '2')) // -s[1..7]d[1|2] { const UINT drive = lpCmdLine[4] == '1' ? DRIVE_1 : DRIVE_2; if (slot != SLOT5 && slot != SLOT6) { LogFileOutput("Unsupported arg: %s\n", lpCmdLine); } else { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_drive[slot][drive] = lpCmdLine; } } else if (lpCmdLine[3] == 'h' && (lpCmdLine[4] >= '1' || lpCmdLine[4] <= '8')) // -s[1..7]h[1|2|...|8] { const UINT drive = lpCmdLine[4] - '1'; bool badDrive = drive >= NUM_HARDDISKS; if (badDrive || (slot != SLOT5 && slot != SLOT7)) { LogFileOutput("Unsupported arg: %s\n", lpCmdLine); } else { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szImageName_harddisk[slot][drive] = lpCmdLine; } } else if (strcmp(lpCmdLine, "-s7-empty-on-exit") == 0) { g_cmdLine.bSlot7EmptyOnExit = true; } else { LogFileOutput("Unsupported arg: %s\n", lpCmdLine); } } else if (strcmp(lpCmdLine, "-harddisknumblocks") == 0) // number of blocks to report for ProDOS { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.uHarddiskNumBlocks = atoi(lpCmdLine); if (g_cmdLine.uHarddiskNumBlocks > kHarddiskMaxNumBlocks) { g_cmdLine.uHarddiskNumBlocks = kHarddiskMaxNumBlocks; } else { if (g_cmdLine.uHarddiskNumBlocks < 0) g_cmdLine.uHarddiskNumBlocks = 0; } } else if (strcmp(lpCmdLine, "-load-state") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.szSnapshotName = lpCmdLine; } else if (strcmp(lpCmdLine, "-f") == 0 || strcmp(lpCmdLine, "-full-screen") == 0) { g_cmdLine.setFullScreen = 1; } else if (strcmp(lpCmdLine, "-no-full-screen") == 0) { g_cmdLine.setFullScreen = 0; } #define CMD_FS_WIDTH "-fs-width=" else if (strncmp(lpCmdLine, CMD_FS_WIDTH, sizeof(CMD_FS_WIDTH)-1) == 0) { if (g_cmdLine.setFullScreen < 0) // Not yet been specified on cmd line? g_cmdLine.setFullScreen = 1; // Implicity set full-screen. NB. Can be overridden by "-no-full-screen" LPSTR lpTmp = lpCmdLine + sizeof(CMD_FS_WIDTH)-1; { g_cmdLine.userSpecifiedWidth = atoi(lpTmp); if (!g_cmdLine.userSpecifiedWidth) LogFileOutput("Invalid cmd-line parameter for -fs-width=x switch\n"); } } #define CMD_FS_HEIGHT "-fs-height=" else if (strncmp(lpCmdLine, CMD_FS_HEIGHT, sizeof(CMD_FS_HEIGHT)-1) == 0) { if (g_cmdLine.setFullScreen < 0) // Not yet been specified on cmd line? g_cmdLine.setFullScreen = 1; // Implicity set full-screen. NB. Can be overridden by "-no-full-screen" LPSTR lpTmp = lpCmdLine + sizeof(CMD_FS_HEIGHT)-1; if (strcmp(lpTmp, "best") == 0) { g_cmdLine.bestFullScreenResolution = true; } else { g_cmdLine.userSpecifiedHeight = atoi(lpTmp); if (!g_cmdLine.userSpecifiedHeight) LogFileOutput("Invalid cmd-line parameter for -fs-height=x switch\n"); } } else if (strcmp(lpCmdLine, "-no-di") == 0) { g_bDisableDirectInput = true; } else if (strcmp(lpCmdLine, "-m") == 0) { g_bDisableDirectSound = true; } else if (strcmp(lpCmdLine, "-no-mb") == 0) { g_bDisableDirectSoundMockingboard = true; } else if (strcmp(lpCmdLine, "-memclear") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_nMemoryClearType = atoi(lpCmdLine); if (g_nMemoryClearType < 0) g_nMemoryClearType = 0; else if (g_nMemoryClearType >= NUM_MIP) g_nMemoryClearType = NUM_MIP - 1; } #ifdef RAMWORKS else if (strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..127] { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.uRamWorksExPages = atoi(lpCmdLine); if (g_cmdLine.uRamWorksExPages > kMaxExMemoryBanks) g_cmdLine.uRamWorksExPages = kMaxExMemoryBanks; else if (g_cmdLine.uRamWorksExPages < 1) g_cmdLine.uRamWorksExPages = 1; } #endif else if (strcmp(lpCmdLine, "-f8rom") == 0) // Use custom 2K ROM at [$F800..$FFFF] { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) // Stop resource leak if -f8rom is specified twice! CloseHandle(g_hCustomRomF8); g_hCustomRomF8 = CreateFile(lpCmdLine, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if ((g_hCustomRomF8 == INVALID_HANDLE_VALUE) || (GetFileSize(g_hCustomRomF8, NULL) != 0x800)) g_bCustomRomF8Failed = true; } else if (strcmp(lpCmdLine, "-rom") == 0) // Use custom 16K at [$C000..$FFFF] or 12K ROM at [$D000..$FFFF] { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (g_hCustomRom != INVALID_HANDLE_VALUE) // Stop resource leak if -rom is specified twice! CloseHandle(g_hCustomRom); g_hCustomRom = CreateFile(lpCmdLine, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if ((g_hCustomRom == INVALID_HANDLE_VALUE) || ((GetFileSize(g_hCustomRom, NULL) != 0x4000) && (GetFileSize(g_hCustomRom, NULL) != 0x3000))) g_bCustomRomFailed = true; } else if (strcmp(lpCmdLine, "-videorom") == 0) // Use 2K (for II/II+). Use 4K,8K or 16K video ROM (for Enhanced //e) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (!GetVideo().ReadVideoRomFile(lpCmdLine)) { std::string msg = "Failed to load video rom (not found or not exactly 2/4/8/16KiB)\n"; LogFileOutput("%s", msg.c_str()); GetFrame().FrameMessageBox(msg.c_str(), TEXT("AppleWin Error"), MB_OK); } else { GetVideo().SetVideoRomRockerSwitch(true); // Use PAL char set } } else if (strcmp(lpCmdLine, "-printscreen") == 0) // Turn on display of the last filename print screen was saved to { GetFrame().SetDisplayPrintScreenFileName(true); } else if (strcmp(lpCmdLine, "-no-printscreen-key") == 0) // Don't try to capture PrintScreen key GH#469 { g_bCapturePrintScreenKey = false; } else if (strcmp(lpCmdLine, "-no-printscreen-dlg") == 0) // Turn off the PrintScreen warning message dialog (if PrintScreen key can't be grabbed) { GetFrame().SetShowPrintScreenWarningDialog(false); } else if (strcmp(lpCmdLine, "-no-hook-system-key") == 0) // Don't hook the System keys (eg. Left-ALT+ESC/SPACE/TAB) GH#556 { g_bHookSystemKey = false; } else if (strcmp(lpCmdLine, "-hook-alt-tab") == 0) // GH#556 { g_bHookAltTab = true; } else if (strcmp(lpCmdLine, "-hook-altgr-control") == 0) // GH#556 { g_bHookAltGrControl = true; } else if (strcmp(lpCmdLine, "-altgr-sends-wmchar") == 0) // GH#625 { KeybSetAltGrSendsWM_CHAR(true); } else if (strcmp(lpCmdLine, "-capslock=off") == 0) // GH#1187 { KeybSetCapsLock(false); } else if (strcmp(lpCmdLine, "-no-hook-alt") == 0) // GH#583 { JoySetHookAltKeys(false); } else if (strcmp(lpCmdLine, "-left-alt-control-buttons") == 0) // GH#743 { JoySetButtonVirtualKey(0, VK_CONTROL); JoySetButtonVirtualKey(1, VK_MENU); } else if (strcmp(lpCmdLine, "-right-alt-control-buttons") == 0) // GH#743 { JoySetButtonVirtualKey(0, VK_MENU | KF_EXTENDED); JoySetButtonVirtualKey(1, VK_CONTROL | KF_EXTENDED); } else if (strcmp(lpCmdLine, "-swap-buttons") == 0) { g_cmdLine.bSwapButtons0and1 = true; } else if (strcmp(lpCmdLine, "-spkr-inc") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); const int nErrorInc = atoi(lpCmdLine); SoundCore_SetErrorInc( nErrorInc ); } else if (strcmp(lpCmdLine, "-spkr-max") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); const int nErrorMax = atoi(lpCmdLine); SoundCore_SetErrorMax( nErrorMax ); } else if (strcmp(lpCmdLine, "-use-real-printer") == 0) // Enable control in Advanced config to allow dumping to a real printer { g_cmdLine.enableDumpToRealPrinter = true; } else if (strcmp(lpCmdLine, "-speech") == 0) { g_bEnableSpeech = true; } else if (strcmp(lpCmdLine, "-multimon") == 0) { GetFrame().g_bMultiMon = true; } else if ((strcmp(lpCmdLine, "-dcd") == 0) || (strcmp(lpCmdLine, "-modem") == 0)) // GH#386 { g_cmdLine.supportDCD = true; } else if (strcmp(lpCmdLine, "-alt-enter=toggle-full-screen") == 0) // GH#556 { GetFrame().SetAltEnterToggleFullScreen(true); } else if (strcmp(lpCmdLine, "-alt-enter=open-apple-enter") == 0) // GH#556 { GetFrame().SetAltEnterToggleFullScreen(false); } else if (strcmp(lpCmdLine, "-video-mode=idealized") == 0) // GH#616 { g_cmdLine.newVideoType = VT_COLOR_IDEALIZED; } else if (strcmp(lpCmdLine, "-video-mode=rgb-videocard") == 0) { g_cmdLine.newVideoType = VT_COLOR_VIDEOCARD_RGB; } else if (strcmp(lpCmdLine, "-video-mode=composite-monitor") == 0) // GH#763 { g_cmdLine.newVideoType = VT_COLOR_MONITOR_NTSC; } else if (strcmp(lpCmdLine, "-video-style=vertical-blend") == 0) // GH#616 { g_cmdLine.newVideoStyleEnableMask = VS_COLOR_VERTICAL_BLEND; } else if (strcmp(lpCmdLine, "-video-style=no-vertical-blend") == 0) // GH#616 { g_cmdLine.newVideoStyleDisableMask = VS_COLOR_VERTICAL_BLEND; } else if (strcmp(lpCmdLine, "-rgb-card-invert-bit7") == 0) // GH#633 { RGB_SetInvertBit7(true); } else if (strcmp(lpCmdLine, "-mac-lc-card-dlgr") == 0) // GH#1258 { RGB_SetMacLCCardDLGR(true); } else if (strcmp(lpCmdLine, "-screenshot-and-exit") == 0) // GH#616: For testing - Use in combination with -load-state { g_cmdLine.szScreenshotFilename = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); } else if (strcmp(lpCmdLine, "-clock-multiplier") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.clockMultiplier = atof(lpCmdLine); } else if (strcmp(lpCmdLine, "-model") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (strcmp(lpCmdLine, "apple2") == 0) g_cmdLine.model = A2TYPE_APPLE2; else if (strcmp(lpCmdLine, "apple2p") == 0) g_cmdLine.model = A2TYPE_APPLE2PLUS; else if (strcmp(lpCmdLine, "apple2jp") == 0) g_cmdLine.model = A2TYPE_APPLE2JPLUS; else if (strcmp(lpCmdLine, "apple2e") == 0) g_cmdLine.model = A2TYPE_APPLE2E; else if (strcmp(lpCmdLine, "apple2ee") == 0) g_cmdLine.model = A2TYPE_APPLE2EENHANCED; else LogFileOutput("-model: unsupported type: %s\n", lpCmdLine); } else if (_stricmp(lpCmdLine, "-50hz") == 0) // (case-insensitive) { g_cmdLine.newVideoRefreshRate = VR_50HZ; } else if (_stricmp(lpCmdLine, "-60hz") == 0) // (case-insensitive) { g_cmdLine.newVideoRefreshRate = VR_60HZ; } else if (strcmp(lpCmdLine, "-rgb-card-type") == 0) { // RGB video card valid types are: "apple", "sl7", "eve", "feline" lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); if (strcmp(lpCmdLine, "apple") == 0) // Just an alias for SL7 g_cmdLine.rgbCard = RGB_Videocard_e::Apple; else if (strcmp(lpCmdLine, "sl7") == 0) g_cmdLine.rgbCard = RGB_Videocard_e::Video7_SL7; else if (strcmp(lpCmdLine, "eve") == 0) g_cmdLine.rgbCard = RGB_Videocard_e::LeChatMauve_EVE; else if (strcmp(lpCmdLine, "feline") == 0) g_cmdLine.rgbCard = RGB_Videocard_e::LeChatMauve_Feline; else LogFileOutput("-rgb-card-type: unsupported type: %s\n", lpCmdLine); } else if (strcmp(lpCmdLine, "-rgb-card-foreground") == 0) { // Default hardware-defined Text foreground color, for Video-7's RGB-SL7 card only lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.rgbCardForegroundColor = atoi(lpCmdLine); } else if (strcmp(lpCmdLine, "-rgb-card-background") == 0) { // Default hardware-defined Text background color, for Video-7's RGB-SL7 card only lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.rgbCardBackgroundColor = atoi(lpCmdLine); } else if (strcmp(lpCmdLine, "-power-on") == 0) { g_cmdLine.bBoot = true; } else if (strcmp(lpCmdLine, "-current-dir") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.strCurrentDir = lpCmdLine; } else if (strcmp(lpCmdLine, "-no-nsc") == 0) { g_cmdLine.bRemoveNoSlotClock = true; } else if (strcmp(lpCmdLine, "-snes-max-alt-joy1") == 0) { g_cmdLine.snesMaxAltControllerType[0] = true; } else if (strcmp(lpCmdLine, "-snes-max-alt-joy2") == 0) { g_cmdLine.snesMaxAltControllerType[1] = true; } else if (strcmp(lpCmdLine, "-snes-max-user-joy1") == 0 || strcmp(lpCmdLine, "-snes-max-user-joy2") == 0) { const unsigned int joyNum = (strcmp(lpCmdLine, "-snes-max-user-joy1") == 0) ? 0 : 1; lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); std::string errorMsg; if (!SNESMAXCard::ParseControllerMappingFile(joyNum, lpCmdLine, errorMsg)) { LogFileOutput("%s", errorMsg.c_str()); GetFrame().FrameMessageBox(errorMsg.c_str(), TEXT("AppleWin Error"), MB_OK); } } else if (strcmp(lpCmdLine, "-wav-speaker") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.wavFileSpeaker = lpCmdLine; } else if (strcmp(lpCmdLine, "-wav-mockingboard") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.wavFileMockingboard = lpCmdLine; } else if (strcmp(lpCmdLine, "-mb-audit") == 0) // enable selection of additional sound cards, eg. for mb-audit { g_cmdLine.supportExtraMBCardTypes = true; } else if (strcmp(lpCmdLine, "-no-disk2-stepper-defer") == 0) // a debug switch added at 1.30.11 / GH#1110 (likely to be removed in a future version) { g_cmdLine.noDisk2StepperDefer = true; } else if (strcmp(lpCmdLine, "-hdc-firmware-v1") == 0) // a debug switch added at 1.30.18 / GH#1277 (likely to be removed in a future version) { g_cmdLine.useHdcFirmwareV1 = true; } else if (strcmp(lpCmdLine, "-hdc-firmware-v2") == 0) { g_cmdLine.useHdcFirmwareV2 = true; } else // unsupported { LogFileOutput("Unsupported arg: %s\n", lpCmdLine); strUnsupported += lpCmdLine; strUnsupported += "\n"; } lpCmdLine = lpNextArg; } LogFileOutput("CmdLine: %s\n", strCmdLine.c_str()); bool ok = true; if (!strUnsupported.empty()) { std::string msg("Unsupported commands:\n\n"); msg += strUnsupported; msg += "\n"; msg += "Continue running AppleWin?"; int res = GetFrame().FrameMessageBox( msg.c_str(), "AppleWin Command Line", MB_ICONSTOP | MB_SETFOREGROUND | MB_YESNO); ok = (res != IDNO); } return ok; }