/* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: * Copyright (C) 2020 mjbudd77 * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include "Qt/main.h" #include "Qt/throttle.h" #include "Qt/config.h" #include "fceu.h" #include "ppu.h" #include "../common/cheat.h" #include "Qt/input.h" #include "Qt/dface.h" #include "Qt/sdl.h" #include "Qt/sdl-video.h" #include "Qt/unix-netplay.h" #ifdef WIN32 #include #endif //#include #include #include #include #include #include #ifdef WIN32 #include #else #include #include #include #endif extern bool force_grayscale; extern bool palupdate; extern int palnotch; extern int palsaturation; extern int palsharpness; extern int palcontrast; extern int palbrightness; int getHotKeyConfig( int i, const char **nameOut, const char **keySeqOut, const char **titleOut ) { const char *name = ""; const char *keySeq = ""; const char *title = NULL; switch ( i ) { case HK_OPEN_ROM: name = "OpenROM"; keySeq = "Ctrl+O"; title = "Open ROM"; break; case HK_CLOSE_ROM: name = "CloseROM"; keySeq = "Ctrl+C"; title = "Close ROM"; break; case HK_CHEAT_MENU: name = "CheatMenu"; keySeq = ""; title = "Open Cheat Window"; break; case HK_BIND_STATE: name = "BindState"; keySeq = ""; title = "Bind Save State to Movie"; break; case HK_LOAD_LUA: name = "LoadLua"; keySeq = "Ctrl+L"; break; case HK_TOGGLE_BG: name = "ToggleBG"; keySeq = ""; title = "Toggle Background Display"; break; case HK_TOGGLE_FG: name = "ToggleFG"; keySeq = ""; title = "Toggle Object Display"; break; // Save States case HK_SAVE_STATE: name = "SaveState"; keySeq = "I"; title = "Save State"; break; case HK_SAVE_STATE_0: name = "SaveState0"; keySeq = "Shift+F10"; title = "Save State to Slot 0"; break; case HK_SAVE_STATE_1: name = "SaveState1"; keySeq = "Shift+F1"; title = "Save State to Slot 1"; break; case HK_SAVE_STATE_2: name = "SaveState2"; keySeq = "Shift+F2"; title = "Save State to Slot 2"; break; case HK_SAVE_STATE_3: name = "SaveState3"; keySeq = "Shift+F3"; title = "Save State to Slot 3"; break; case HK_SAVE_STATE_4: name = "SaveState4"; keySeq = "Shift+F4"; title = "Save State to Slot 4"; break; case HK_SAVE_STATE_5: name = "SaveState5"; keySeq = "Shift+F5"; title = "Save State to Slot 5"; break; case HK_SAVE_STATE_6: name = "SaveState6"; keySeq = "Shift+F6"; title = "Save State to Slot 6"; break; case HK_SAVE_STATE_7: name = "SaveState7"; keySeq = "Shift+F7"; title = "Save State to Slot 7"; break; case HK_SAVE_STATE_8: name = "SaveState8"; keySeq = "Shift+F8"; title = "Save State to Slot 8"; break; case HK_SAVE_STATE_9: name = "SaveState9"; keySeq = "Shift+F9"; title = "Save State to Slot 9"; break; // Load States case HK_LOAD_STATE: name = "LoadState"; keySeq = "P"; title = "Load State"; break; case HK_LOAD_STATE_0: name = "LoadState0"; keySeq = "F10"; title = "Load State From Slot 0"; break; case HK_LOAD_STATE_1: name = "LoadState1"; keySeq = "F1"; title = "Load State From Slot 1"; break; case HK_LOAD_STATE_2: name = "LoadState2"; keySeq = "F2"; title = "Load State From Slot 2"; break; case HK_LOAD_STATE_3: name = "LoadState3"; keySeq = "F3"; title = "Load State From Slot 3"; break; case HK_LOAD_STATE_4: name = "LoadState4"; keySeq = "F4"; title = "Load State From Slot 4"; break; case HK_LOAD_STATE_5: name = "LoadState5"; keySeq = "F5"; title = "Load State From Slot 5"; break; case HK_LOAD_STATE_6: name = "LoadState6"; keySeq = "F6"; title = "Load State From Slot 6"; break; case HK_LOAD_STATE_7: name = "LoadState7"; keySeq = "F7"; title = "Load State From Slot 7"; break; case HK_LOAD_STATE_8: name = "LoadState8"; keySeq = "F8"; title = "Load State From Slot 8"; break; case HK_LOAD_STATE_9: name = "LoadState9"; keySeq = "F9"; title = "Load State From Slot 9"; break; case HK_FDS_SELECT: name = "FDSSelect"; keySeq = ""; title = "Switch FDS Disk Side"; break; case HK_FDS_EJECT: name = "FDSEject"; keySeq = ""; title = "Eject FDS Disk"; break; case HK_VS_INSERT_COIN: name = "VSInsertCoin"; keySeq = ""; title = "VS Insert Coin"; break; case HK_VS_TOGGLE_DIPSWITCH: name = "VSToggleDip"; keySeq = ""; title = "VS Toggle Dipswitch"; break; case HK_TOGGLE_FRAME_DISPLAY: name = "MovieToggleFrameDisplay"; keySeq = "."; title = "Toggle Frame Display"; break; case HK_TOGGLE_SUBTITLE: name = "SubtitleDisplay"; keySeq = ""; title = "Toggle Movie Subtitles"; break; case HK_POWER: name = "Power"; keySeq = ""; title = "Power"; break; case HK_RESET: name = "Reset"; keySeq = "Ctrl+R"; title = "Reset"; break; case HK_PAUSE: name = "Pause"; keySeq = "Pause"; title = "Pause"; break; case HK_QUIT: name = "Quit"; keySeq = "Ctrl+Q"; title = "Exit Application"; break; case HK_SCREENSHOT: name = "Screenshot"; keySeq = "F12"; break; case HK_DECREASE_SPEED: name = "DecreaseSpeed"; keySeq = "-"; break; case HK_INCREASE_SPEED: name = "IncreaseSpeed"; keySeq = "="; break; case HK_FRAME_ADVANCE: name = "FrameAdvance"; keySeq = "\\"; break; case HK_TURBO: name = "Turbo"; keySeq = "Tab"; break; case HK_TOGGLE_INPUT_DISPLAY: name = "ToggleInputDisplay"; keySeq = ","; break; case HK_MOVIE_TOGGLE_RW: name = "ToggleMovieRW"; keySeq = "Q"; break; case HK_PLAY_MOVIE_FROM: name = "PlayMovieFrom"; keySeq = ""; break; case HK_MOVIE_PLAY_RESTART: name = "PlayMovieFromBeginning"; keySeq = ""; break; case HK_RECORD_MOVIE_TO: name = "RecordMovieTo"; keySeq = ""; break; case HK_STOP_MOVIE: name = "StopMovie"; keySeq = ""; break; case HK_RECORD_AVI: name = "RecordAvi"; keySeq = ""; break; case HK_RECORD_AVI_TO: name = "RecordAviTo"; keySeq = ""; break; case HK_STOP_AVI: name = "StopAvi"; keySeq = ""; break; case HK_RECORD_WAV: name = "RecordWav"; keySeq = ""; break; case HK_RECORD_WAV_TO: name = "RecordWavTo"; keySeq = ""; break; case HK_STOP_WAV: name = "StopWav"; keySeq = ""; break; case HK_MUTE_CAPTURE: name = "MuteCapture"; keySeq = "'"; break; case HK_FA_LAG_SKIP: name = "FrameAdvanceLagSkip"; keySeq = "Delete"; break; case HK_LAG_COUNTER_DISPLAY: name = "LagCounterDisplay"; keySeq = "/"; break; case HK_SELECT_STATE_0: name = "SelectState0"; keySeq = "0"; title = "Select State Slot 0"; break; case HK_SELECT_STATE_1: name = "SelectState1"; keySeq = "1"; title = "Select State Slot 1"; break; case HK_SELECT_STATE_2: name = "SelectState2"; keySeq = "2"; title = "Select State Slot 2"; break; case HK_SELECT_STATE_3: name = "SelectState3"; keySeq = "3"; title = "Select State Slot 3"; break; case HK_SELECT_STATE_4: name = "SelectState4"; keySeq = "4"; title = "Select State Slot 4"; break; case HK_SELECT_STATE_5: name = "SelectState5"; keySeq = "5"; title = "Select State Slot 5"; break; case HK_SELECT_STATE_6: name = "SelectState6"; keySeq = "6"; title = "Select State Slot 6"; break; case HK_SELECT_STATE_7: name = "SelectState7"; keySeq = "7"; title = "Select State Slot 7"; break; case HK_SELECT_STATE_8: name = "SelectState8"; keySeq = "8"; title = "Select State Slot 8"; break; case HK_SELECT_STATE_9: name = "SelectState9"; keySeq = "9"; title = "Select State Slot 9"; break; case HK_SELECT_STATE_NEXT: name = "SelectStateNext"; keySeq = ""; title = "Select Next State Slot"; break; case HK_SELECT_STATE_PREV: name = "SelectStatePrev"; keySeq = ""; title = "Select Previous State Slot"; break; case HK_VOLUME_DOWN: name = "VolumeDown"; keySeq = ""; break; case HK_VOLUME_UP: name = "VolumeUp"; keySeq = ""; break; case HK_FKB_ENABLE: name = "FKB_Enable"; keySeq = "ScrollLock"; title = "Toggle Family Keyboard Enable"; break; case HK_FULLSCREEN: name = "FullScreen"; keySeq = "Alt+Return"; title = "Toggle Fullscreen View"; break; case HK_MAIN_MENU_HIDE: name = "MainMenuHide"; keySeq = "Alt+/"; title = "Toggle Main Menu Visibility"; break; default: case HK_MAX: name = ""; keySeq = ""; break; } if ( nameOut ) { *nameOut = name; } if ( keySeqOut ) { *keySeqOut = keySeq; } if ( titleOut ) { if ( title == NULL ) { title = name; } *titleOut = title; } return 0; } /** * Read a custom pallete from a file and load it into the core. */ int LoadCPalette(const std::string &file) { uint8 tmpp[192]; FILE *fp; if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) { char errorMsg[256]; strcpy(errorMsg, "Error loading custom palette from file: "); strcat(errorMsg, file.c_str()); FCEUD_PrintError(errorMsg); return 0; } size_t result = fread(tmpp, 1, 192, fp); if(result != 192) { char errorMsg[256]; strcpy(errorMsg, "Error loading custom palette from file: "); strcat(errorMsg, file.c_str()); FCEUD_PrintError(errorMsg); return 0; } FCEUI_SetUserPalette(tmpp, result/3); fclose(fp); return 1; } /** * Creates the subdirectories used for saving snapshots, movies, game * saves, etc. Hopefully obsolete with new configuration system. */ static void CreateDirs(const std::string &dir) { const char *subs[]={"fcs","snaps","gameinfo","sav","cheats","avi","wav","movies","input", NULL }; std::string subdir; int x=0; #if defined(WIN32) || defined(NEED_MINGW_HACKS) mkdir(dir.c_str()); chmod(dir.c_str(), 755); while ( subs[x] != NULL ) { subdir = dir + PSS + subs[x]; mkdir(subdir.c_str()); x++; } #else mkdir(dir.c_str(), S_IRWXU); while ( subs[x] != NULL ) { subdir = dir + PSS + subs[x]; mkdir(subdir.c_str(), S_IRWXU); x++; } #endif } /** * Attempts to locate FCEU's application directory. This will * hopefully become obsolete once the new configuration system is in * place. */ static void GetBaseDirectory(std::string &dir) { char *home = getenv("FCEUX_HOME"); #ifdef WIN32 // Windows users want base directory to be where executable resides. // Only way to override this behavior is to set an FCEUX_HOME // environment variable prior to starting the application. //if ( home == NULL ) //{ // home = getenv("USERPROFILE"); //} //if ( home == NULL ) //{ // home = getenv("HOMEPATH"); //} #else if ( home == NULL ) { home = getenv("HOME"); } #endif if (home) { dir = std::string(home) + "/.fceux"; } else { #ifdef WIN32 home = new char[MAX_PATH + 1]; GetModuleFileNameA(NULL, home, MAX_PATH + 1); char *lastBS = strrchr(home,'\\'); if(lastBS) { *lastBS = 0; } dir = std::string(home); delete[] home; #else dir = ""; #endif } } // returns a config structure with default options // also creates config base directory (ie: /home/user/.fceux as well as subdirs Config * InitConfig() { std::string dir, prefix, savPath, movPath; Config *config; GetBaseDirectory(dir); FCEUI_SetBaseDirectory(dir.c_str()); CreateDirs(dir); config = new Config(dir); // sound options config->addOption('s', "sound", "SDL.Sound", 1); config->addOption("volume", "SDL.Sound.Volume", 150); config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 255); config->addOption("square1vol", "SDL.Sound.Square1Volume", 255); config->addOption("square2vol", "SDL.Sound.Square2Volume", 255); config->addOption("noisevol", "SDL.Sound.NoiseVolume", 255); config->addOption("pcmvol", "SDL.Sound.PCMVolume", 255); config->addOption("soundrate", "SDL.Sound.Rate", 44100); config->addOption("soundq", "SDL.Sound.Quality", 1); config->addOption("soundrecord", "SDL.Sound.RecordFile", ""); config->addOption("soundbufsize", "SDL.Sound.BufSize", 128); config->addOption("lowpass", "SDL.Sound.LowPass", 0); config->addOption('g', "gamegenie", "SDL.GameGenie", 0); config->addOption("pal", "SDL.PAL", 0); config->addOption("autoPal", "SDL.AutoDetectPAL", 1); config->addOption("frameskip", "SDL.Frameskip", 0); config->addOption("clipsides", "SDL.ClipSides", 0); config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1); config->addOption("swapduty", "SDL.SwapDuty", 0); config->addOption("ramInit", "SDL.RamInitMethod", 0); // color control config->addOption('p', "palette", "SDL.Palette", ""); config->addOption("tint", "SDL.Tint", 56); config->addOption("hue", "SDL.Hue", 72); config->addOption("ntsccolor", "SDL.NTSCpalette", 0); config->addOption("SDL.ForceGrayScale", 0); config->addOption("SDL.DeempBitSwap", 0); config->addOption("SDL.PalNotch", 100); config->addOption("SDL.PalSaturation", 100); config->addOption("SDL.PalSharpness", 0); config->addOption("SDL.PalContrast", 100); config->addOption("SDL.PalBrightness", 50); // scanline settings config->addOption("SDL.ScanLineStartNTSC", 0+8); config->addOption("SDL.ScanLineEndNTSC", 239-8); config->addOption("SDL.ScanLineStartPAL", 0); config->addOption("SDL.ScanLineEndPAL", 239); // video controls config->addOption('f', "fullscreen", "SDL.Fullscreen", 0); config->addOption("videoDriver", "SDL.VideoDriver", 0); // set x/y res to 0 for automatic fullscreen resolution detection (no change) config->addOption('x', "xres", "SDL.XResolution", 0); config->addOption('y', "yres", "SDL.YResolution", 0); config->addOption("SDL.LastXRes", 0); config->addOption("SDL.LastYRes", 0); config->addOption("SDL.WinSizeX", 0); config->addOption("SDL.WinSizeY", 0); config->addOption("doublebuf", "SDL.DoubleBuffering", 1); config->addOption("autoscale", "SDL.AutoScale", 1); config->addOption("forceAspect", "SDL.ForceAspect", 1); config->addOption("aspectSelect", "SDL.AspectSelect", 0); config->addOption("aspectX", "SDL.AspectX", 1.000); config->addOption("aspectY", "SDL.AspectY", 1.000); config->addOption("xscale", "SDL.XScale", 2.000); config->addOption("yscale", "SDL.YScale", 2.000); config->addOption("xstretch", "SDL.XStretch", 0); config->addOption("ystretch", "SDL.YStretch", 0); config->addOption("noframe", "SDL.NoFrame", 0); config->addOption("special", "SDL.SpecialFilter", 0); config->addOption("showfps", "SDL.ShowFPS", 0); config->addOption("togglemenu", "SDL.ToggleMenu", 0); config->addOption("cursorType", "SDL.CursorType", 0); config->addOption("cursorVis" , "SDL.CursorVis", 1); config->addOption("SDL.DrawInputAids", 1); // OpenGL options config->addOption("opengl", "SDL.OpenGL", 1); config->addOption("openglip", "SDL.OpenGLip", 0); config->addOption("SDL.SpecialFilter", 0); config->addOption("SDL.SpecialFX", 0); config->addOption("SDL.Vsync", 1); // network play options - netplay is broken config->addOption("server", "SDL.NetworkIsServer", 0); config->addOption('n', "net", "SDL.NetworkIP", ""); config->addOption('u', "user", "SDL.NetworkUsername", ""); config->addOption('w', "pass", "SDL.NetworkPassword", ""); config->addOption('k', "netkey", "SDL.NetworkGameKey", ""); config->addOption("port", "SDL.NetworkPort", 4046); config->addOption("players", "SDL.NetworkPlayers", 1); // input configuration options config->addOption("input1", "SDL.Input.0", "GamePad.0"); config->addOption("input2", "SDL.Input.1", "GamePad.1"); config->addOption("input3", "SDL.Input.2", "Gamepad.2"); config->addOption("input4", "SDL.Input.3", "Gamepad.3"); config->addOption("autoInputPreset", "SDL.AutoInputPreset", 0); config->addOption("SDL.AutofireOnFrames" , 1); config->addOption("SDL.AutofireOffFrames", 1); config->addOption("SDL.AutofireCustomOnFrames" , 1); config->addOption("SDL.AutofireCustomOffFrames", 1); // display input config->addOption("inputdisplay", "SDL.InputDisplay", 0); // enable / disable opposite directionals (left + right or up + down simultaneously) config->addOption("opposite-directionals", "SDL.Input.EnableOppositeDirectionals", 1); // pause movie playback at frame x config->addOption("pauseframe", "SDL.PauseFrame", 0); config->addOption("recordhud", "SDL.RecordHUD", 1); config->addOption("moviemsg", "SDL.MovieMsg", 1); config->addOption("SDL.AviVideoFormat", 0); // Hex Editor Options config->addOption("hexEditBgColor", "SDL.HexEditBgColor", "#000000"); config->addOption("hexEditFgColor", "SDL.HexEditFgColor", "#FFFFFF"); config->addOption("SDL.HexEditCursorColorRC", "#000080"); config->addOption("SDL.HexEditAltColColor" , "#545454"); config->addOption("SDL.HexEditFont" , ""); config->addOption("SDL.HexEditActivityHlgt", true); config->addOption("SDL.HexEditReverseVideo", true); config->addOption("SDL.HexEditRowColumnHlgt", false); config->addOption("SDL.HexEditAltnColumnColor", false); config->addOption("SDL.HexEditRefreshRate", 10); // Debugger Options config->addOption("autoLoadDebugFiles" , "SDL.AutoLoadDebugFiles", 1); config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0); config->addOption("debuggerPCPlacementMode", "SDL.DebuggerPCPlacement" , 0); config->addOption("debuggerPCDLineOffset" , "SDL.DebuggerPCLineOffset" , 0); config->addOption("SDL.DebuggerAsmFont" , ""); config->addOption("SDL.DebuggerStackFont" , ""); config->addOption("SDL.DebuggerCpuStatusFont" , ""); config->addOption("SDL.AsmSyntaxColorOpcode", ""); config->addOption("SDL.AsmSyntaxColorAddress", ""); config->addOption("SDL.AsmSyntaxColorImmediate", ""); config->addOption("SDL.AsmSyntaxColorLabel", ""); config->addOption("SDL.AsmSyntaxColorComment", ""); config->addOption("SDL.AsmSyntaxColorPC", ""); config->addOption("SDL.AsmShowByteCodes", 0); config->addOption("SDL.AsmShowRomOffsets", 0); config->addOption("SDL.DebuggerShowSymNames", 1); config->addOption("SDL.DebuggerShowRegNames", 1); config->addOption("SDL.DebuggerBreakOnBadOpcodes", 0); config->addOption("SDL.DebuggerBreakOnUnloggedCode", 0); config->addOption("SDL.DebuggerBreakOnUnloggedData", 0); // Code Data Logger Options config->addOption("autoSaveCDL" , "SDL.AutoSaveCDL", 1); config->addOption("autoLoadCDL" , "SDL.AutoLoadCDL", 1); config->addOption("autoResumeCDL", "SDL.AutoResumeCDL", 0); // Trace Logger Options config->addOption("SDL.TraceLogRegisterState", 1); config->addOption("SDL.TraceLogProcessorState", 1); config->addOption("SDL.TraceLogNewInstructions", 0); config->addOption("SDL.TraceLogNewData", 0); config->addOption("SDL.TraceLogFrameCount", 0); config->addOption("SDL.TraceLogCycleCount", 0); config->addOption("SDL.TraceLogInstructionCount", 0); config->addOption("SDL.TraceLogMessages", 1); config->addOption("SDL.TraceLogBreakpointHits", 1); config->addOption("SDL.TraceLogBankNumber", 0); config->addOption("SDL.TraceLogSymbolic", 0); config->addOption("SDL.TraceLogStackTabbing", 1); config->addOption("SDL.TraceLogLeftDisassembly", 1); // overwrite the config file? config->addOption("no-config", "SDL.NoConfig", 0); config->addOption("autoresume", "SDL.AutoResume", 0); // video playback config->addOption("playmov", "SDL.Movie", ""); config->addOption("subtitles", "SDL.SubtitleDisplay", 1); config->addOption("movielength", "SDL.MovieLength", 0); config->addOption("fourscore", "SDL.FourScore", 0); config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1); #ifdef _S9XLUA_H // load lua script config->addOption("loadlua", "SDL.LuaScript", ""); #endif #ifdef CREATE_AVI config->addOption("videolog", "SDL.VideoLog", ""); config->addOption("mute", "SDL.MuteCapture", 0); #endif // auto load/save on gameload/close config->addOption("loadstate", "SDL.AutoLoadState", INVALID_STATE); config->addOption("savestate", "SDL.AutoSaveState", INVALID_STATE); //TODO implement this config->addOption("periodicsaves", "SDL.PeriodicSaves", 0); savPath = dir + "/sav"; movPath = dir + "/movies"; // prefixed with _ because they are internal (not cli options) config->addOption("_lastopenfile", "SDL.LastOpenFile", dir); config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", savPath ); config->addOption("_lastopennsf", "SDL.LastOpenNSF", dir); config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", savPath ); config->addOption("_lastopenmovie", "SDL.LastOpenMovie", movPath); config->addOption("_lastloadlua", "SDL.LastLoadLua", ""); for (unsigned int i=0; i<10; i++) { char buf[128]; sprintf(buf, "SDL.RecentRom%02u", i); config->addOption( buf, ""); } config->addOption("_useNativeFileDialog", "SDL.UseNativeFileDialog", false); config->addOption("_useNativeMenuBar" , "SDL.UseNativeMenuBar", false); config->addOption("SDL.PauseOnMainMenuAccess", false); config->addOption("SDL.ContextMenuEnable", true); config->addOption("SDL.GuiStyle", ""); config->addOption("SDL.QtStyleSheet", ""); config->addOption("SDL.QPaletteFile", ""); config->addOption("SDL.UseCustomQss", 0); config->addOption("SDL.UseCustomQPal", 0); config->addOption("_setSchedParam" , "SDL.SetSchedParam" , 0); config->addOption("_emuSchedPolicy" , "SDL.EmuSchedPolicy", 0); config->addOption("_emuSchedNice" , "SDL.EmuSchedNice" , 0); config->addOption("_emuSchedPrioRt" , "SDL.EmuSchedPrioRt", 40); config->addOption("_guiSchedPolicy" , "SDL.GuiSchedPolicy", 0); config->addOption("_guiSchedNice" , "SDL.GuiSchedNice" , 0); config->addOption("_guiSchedPrioRt" , "SDL.GuiSchedPrioRt", 40); config->addOption("_emuTimingMech" , "SDL.EmuTimingMech" , 0); // fcm -> fm2 conversion config->addOption("fcmconvert", "SDL.FCMConvert", ""); // fm2 -> srt conversion config->addOption("ripsubs", "SDL.RipSubs", ""); // enable new PPU core config->addOption("newppu", "SDL.NewPPU", 0); // PPU Viewer Preferences config->addOption("SDL.NT_TileFocusPolicy", 0); config->addOption("SDL.PPU_TileFocusPolicy", 0); config->addOption("SDL.OAM_TileFocusPolicy", 0); config->addOption("SDL.PPU_MaskUnused", 0); config->addOption("SDL.PPU_InvertMask", 0); config->addOption("SDL.PPU_View1_8x16", 0); config->addOption("SDL.PPU_View2_8x16", 0); config->addOption("SDL.PPU_ViewScanLine", 0); config->addOption("SDL.PPU_ViewRefreshFrames", 1); config->addOption("SDL.NT_TileSelColor", "#FFFFFF"); config->addOption("SDL.NT_TileGridColor", "#FF0000"); config->addOption("SDL.NT_AttrGridColor", "#0000FF"); config->addOption("SDL.NT_ViewScanLine", 0); config->addOption("SDL.NT_DrawScrollLines", 1); config->addOption("SDL.NT_DrawTileGridLines", 1); config->addOption("SDL.NT_DrawAttrGridLines", 0); config->addOption("SDL.NT_DrawAttrbView", 0); config->addOption("SDL.NT_IgnoreHidePal", 0); config->addOption("SDL.NT_RefreshFrames", 1); config->addOption("SDL.PPU_TileSelColor0", "#FFFFFF"); config->addOption("SDL.PPU_TileGridColor0", "#7F7F7F"); config->addOption("SDL.PPU_TileSelColor1", "#FFFFFF"); config->addOption("SDL.PPU_TileGridColor1", "#7F7F7F"); config->addOption("SDL.PPU_TileShowGrid0", 1); config->addOption("SDL.PPU_TileShowGrid1", 1); config->addOption("SDL.OAM_TileShowGrid", 0); config->addOption("SDL.OAM_TileSelColor", "#FFFFFF"); config->addOption("SDL.OAM_TileGridColor", "#7F7F7F"); config->addOption("SDL.OAM_LocatorColor", "#7F7F7F"); config->addOption("SDL.OAM_ShowPosHex", 0); // quit when a+b+select+start is pressed config->addOption("4buttonexit", "SDL.ABStartSelectExit", 0); // GamePad 0 - 3 for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) { char buf[64]; snprintf(buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i); prefix = buf; config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]); config->addOption(prefix + "DeviceGUID", ""); config->addOption(prefix + "Profile" , ""); } // PowerPad 0 - 1 for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) { char buf[64]; snprintf(buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i); prefix = buf; config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) { config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]); } } // QuizKing prefix = "SDL.Input.QuizKing."; config->addOption(prefix + "DeviceType", DefaultQuizKingDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) { config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]); } // HyperShot prefix = "SDL.Input.HyperShot."; config->addOption(prefix + "DeviceType", DefaultHyperShotDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) { config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]); } // Mahjong prefix = "SDL.Input.Mahjong."; config->addOption(prefix + "DeviceType", DefaultMahjongDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) { config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]); } // TopRider prefix = "SDL.Input.TopRider."; config->addOption(prefix + "DeviceType", DefaultTopRiderDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) { config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]); } // FTrainer prefix = "SDL.Input.FTrainer."; config->addOption(prefix + "DeviceType", DefaultFTrainerDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) { config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]); } // FamilyKeyBoard prefix = "SDL.Input.FamilyKeyBoard."; config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice); config->addOption(prefix + "DeviceNum", 0); for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) { config->addOption(prefix + FamilyKeyBoardNames[j], DefaultFamilyKeyBoard[j]); } // for FAMICOM microphone in pad 2 pad 1 didn't have it // Takeshi no Chousenjou uses it for example. prefix = "SDL.Input.FamicomPad2."; config->addOption("rp2mic", prefix + "EnableMic", 0); // TODO: use a better data structure to store the hotkeys or something // improve this code overall in the future to make it // easier to maintain //const int Hotkeys[HK_MAX] = { // SDLK_F1, // cheat menu // SDLK_F2, // bind state // SDLK_F3, // load lua // SDLK_F4, // toggleBG // SDLK_F5, // save state // SDLK_F6, // fds select // SDLK_F7, // load state // SDLK_F8, // fds eject // SDLK_F6, // VS insert coin // SDLK_F8, // VS toggle dipswitch // SDLK_PERIOD, // toggle frame display // SDLK_F10, // toggle subtitle // SDLK_F11, // reset // SDLK_F12, // screenshot // SDLK_PAUSE, // pause // SDLK_MINUS, // speed++ // SDLK_EQUALS, // speed-- // SDLK_BACKSLASH, //frame advnace // SDLK_TAB, // turbo // SDLK_COMMA, // toggle input display // SDLK_q, // toggle movie RW // SDLK_QUOTE, // toggle mute capture // 0, // quit // edit 10/11/11 - don't map to escape, it causes ugly things to happen to sdl. can be manually appended to config // SDLK_DELETE, // frame advance lag skip // SDLK_SLASH, // lag counter display // SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, // SDLK_6, SDLK_7, SDLK_8, SDLK_9, // SDLK_PAGEUP, // select state next // SDLK_PAGEDOWN, // select state prev // 0, // Volume Down Internal // 0, // Volume Up Internal // SDLK_SCROLLLOCK }; // FKB Enable Toggle //Hotkeys[ HK_OPEN_ROM ].init( "OpenROM", QKeySequence(QKeySequence::Open) ); prefix = "SDL.Hotkeys."; for(int i=0; i < HK_MAX; i++) { const char *hotKeyName, *hotKeySeq; std::string nameText, keyText; getHotKeyConfig( i, &hotKeyName, &hotKeySeq ); //printf("Hot Key: '%s' = '%s' \n", hotKeyName, hotKeySeq ); //keyText.assign(" mod="); //sprintf( buf, " key=%s", SDL_GetKeyName( Hotkeys[i] ) ); if ( hotKeyName[0] != 0 ) { nameText.assign( hotKeyName ); keyText.assign( hotKeySeq ); config->addOption(prefix + nameText, keyText); Hotkeys[i].setConfigName( hotKeyName ); } } // All mouse devices config->addOption("SDL.OekaKids.0.DeviceType", "Mouse"); config->addOption("SDL.OekaKids.0.DeviceNum", 0); config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse"); config->addOption("SDL.Arkanoid.0.DeviceNum", 0); config->addOption("SDL.Shadow.0.DeviceType", "Mouse"); config->addOption("SDL.Shadow.0.DeviceNum", 0); config->addOption("SDL.Zapper.0.DeviceType", "Mouse"); config->addOption("SDL.Zapper.0.DeviceNum", 0); return config; } void UpdateEMUCore(Config *config) { int ntsccol, ntsctint, ntschue, flag, region; int startNTSC, endNTSC, startPAL, endPAL; std::string cpalette; config->getOption("SDL.NTSCpalette", &ntsccol); config->getOption("SDL.Tint", &ntsctint); config->getOption("SDL.Hue", &ntschue); FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue); config->getOption("SDL.ForceGrayScale", &force_grayscale); config->getOption("SDL.DeempBitSwap" , &paldeemphswap); config->getOption("SDL.PalNotch" , &palnotch); config->getOption("SDL.PalSaturation" , &palsaturation); config->getOption("SDL.PalSharpness" , &palsharpness); config->getOption("SDL.PalContrast" , &palcontrast); config->getOption("SDL.PalBrightness" , &palbrightness); palupdate = 1; config->getOption("SDL.Palette", &cpalette); if(cpalette.size()) { LoadCPalette(cpalette); } config->getOption("SDL.NewPPU", &newppu); config->getOption("SDL.PAL", ®ion); FCEUI_SetRegion(region); config->getOption("SDL.GameGenie", &flag); FCEUI_SetGameGenie(flag ? 1 : 0); config->getOption("SDL.Sound.LowPass", &flag); FCEUI_SetLowPass(flag ? 1 : 0); config->getOption("SDL.DisableSpriteLimit", &flag); FCEUI_DisableSpriteLimitation(flag ? 1 : 0); config->getOption("SDL.ScanLineStartNTSC", &startNTSC); config->getOption("SDL.ScanLineEndNTSC", &endNTSC); config->getOption("SDL.ScanLineStartPAL", &startPAL); config->getOption("SDL.ScanLineEndPAL", &endPAL); #if DOING_SCANLINE_CHECKS for(int i = 0; i < 2; x++) { if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0; if(erendlinev[x]239) erendlinev[x]=239; } #endif FCEUI_SetRenderedLines(startNTSC, endNTSC, startPAL, endPAL); }