// and now for the important part, // which determines what goes into and comes out of the config file: // add all of the things we want to save and load to a list // (but don't actually save or load anything yet) void WinRegisterConfigItems() { #define CATEGORY "Config" AddBool2C("NiceAlignment", niceAlignment, true, "on to line up the =, :, and # in each section of this config file"); AddBool2C("Comments", showComments, true, "on to keep comments such as this in this config file. To update/refresh all comments, set this to false and run Snes9x, then set it to true and run Snes9x again."); AddUIntC("Sort", configSort, 1, "ordering within sections: 0=allow reordering, 1=force default order, 2=sort alphabetically"); AddBoolC("Lock", readOnlyConfig, false, "if true, prevents Snes9x from editing this configuration file (or making it read-only while it is running)"); #undef CATEGORY #define CATEGORY "Display" AddBool2C("HiRes", Settings.SupportHiRes, true, "on to support the hi-res mode that a few games use, off to render them in low-res"); AddBool2("Transparency", Settings.Transparency, true); AddBoolC("MessagesInImage", Settings.AutoDisplayMessages, false, "true to draw text inside the SNES image (will get into AVIs, screenshots, and filters)"); AddBool2C("FrameRate", Settings.DisplayFrameRate, false, "on to display the framerate (will be inaccurate if AutoMaxSkipFrames is too small)"); AddBoolC("DisplayInput", Settings.DisplayPressedKeys, false, "true to show which buttons are pressed"); AddBoolC("DisplayFrameCount", Settings.DisplayMovieFrame, true, "true to show the frame count when a movie is playing"); #undef CATEGORY #define CATEGORY "Display\\Win" AddUIntC("OutputMethod", GUI.outputMethod, 0, "0=DirectDraw, 1=Direct3D, 2=OpenGL"); AddUIntC("FilterType", GUI.Scale, 0, filterString); AddUIntC("FilterHiRes", GUI.ScaleHiRes, 0, filterString2); AddBoolC("BlendHiRes", GUI.BlendHiRes, true, "true to horizontally blend Hi-Res images (better transparency effect on filters that do not account for this)"); AddBoolC("ShaderEnabled", GUI.shaderEnabled, false, "true to use pixel shader (if supported by output method)"); AddStringC("Direct3D:D3DShader", GUI.D3DshaderFileName, MAX_PATH, "", "shader filename for Direct3D mode (HLSL effect file or CG shader"); AddStringC("OpenGL:OGLShader", GUI.OGLshaderFileName, MAX_PATH, "", "shader filename for OpenGL mode (bsnes-style XML shader or CG shader)"); AddBoolC("OpenGL:DisablePBOs", GUI.OGLdisablePBOs, false, "do not use PBOs in OpenGL mode, even if the video card supports them"); AddBoolC("ExtendHeight", GUI.HeightExtend, false, "true to display an extra 15 pixels at the bottom, which few games use. Also increases AVI output size from 256x224 to 256x240."); AddBoolC("AlwaysCenterImage", GUI.AlwaysCenterImage,false, "true to center the image even if larger than window"); AddIntC("Window:Width", GUI.window_size.right, 512, "256=1x, 512=2x, 768=3x, 1024=4x, etc. (usually)"); AddIntC("Window:Height", GUI.window_size.bottom, 448, "224=1x, 448=2x, 672=3x, 896=4x, etc. (usually)"); AddIntC("Window:Left", GUI.window_size.left, 0, "in pixels from left edge of screen"); AddIntC("Window:Top", GUI.window_size.top, 0, "in pixels from top edge of screen"); AddBool("Window:Maximized", GUI.window_maximized, false); AddBoolC("Stretch:Enabled", GUI.Stretch, true, "true to stretch the game image to fill the window or screen"); AddBoolC("Stretch:MaintainAspectRatio", GUI.AspectRatio, true, "prevents stretching from changing the aspect ratio"); AddUIntC("Stretch:AspectRatioBaseWidth", GUI.AspectWidth, 256, "base width for aspect ratio calculation (AR=AspectRatioBaseWidth/224), default is 256 - set to 299 for 4:3 aspect ratio"); AddBoolC("Stretch:BilinearFilter", GUI.BilinearFilter, true, "allows bilinear filtering of stretching. Depending on your video card and the window size, this may result in a lower framerate."); AddBoolC("Stretch:LocalVidMem", GUI.LocalVidMem, true, "determines the location of video memory in DirectDraw mode. May increase or decrease rendering performance, depending on your setup and which filter and stretching options are active."); AddBool("Fullscreen:Enabled", GUI.FullScreen, false); AddUInt("Fullscreen:Width", GUI.FullscreenMode.width, 640); AddUInt("Fullscreen:Height", GUI.FullscreenMode.height, 480); AddUInt("Fullscreen:Depth", GUI.FullscreenMode.depth, 16); AddUInt("Fullscreen:RefreshRate", GUI.FullscreenMode.rate, 60); AddBool("Fullscreen:DoubleBuffered", GUI.DoubleBuffered, false); AddBoolC("Fullscreen:EmulateFullscreen", GUI.EmulateFullscreen, true,"true makes snes9x create a window that spans the entire screen when going fullscreen"); AddBoolC("HideMenu", GUI.HideMenu, false, "true to auto-hide the menu bar on startup."); AddBoolC("Vsync", GUI.Vsync, false, "true to enable Vsync"); #undef CATEGORY #define CATEGORY "Settings" AddUIntC("FrameSkip", Settings.SkipFrames, AUTO_FRAMERATE, "200=automatic (limits at 50/60 fps), 0=none, 1=skip every other, ..."); AddUIntC("AutoMaxSkipFramesAtOnce", Settings.AutoMaxSkipFrames, 0, "most frames to skip at once to maintain speed in automatic mode, don't set to more than 1 or 2 frames because the skipping algorithm isn't very smart"); AddUIntC("TurboFrameSkip", Settings.TurboSkipFrames, 15, "how many frames to skip when in fast-forward mode"); AddUInt("AutoSaveDelay", Settings.AutoSaveDelay, 30); AddBool("BlockInvalidVRAMAccess", Settings.BlockInvalidVRAMAccessMaster, true); AddBool2C("SnapshotScreenshots", Settings.SnapshotScreenshots, true, "on to save the screenshot in each snapshot, for loading-when-paused display"); AddBoolC("MovieTruncateAtEnd", Settings.MovieTruncate, true, "true to truncate any leftover data in the movie file after the current frame when recording stops"); AddBoolC("MovieNotifyIgnored", Settings.MovieNotifyIgnored, false, "true to display \"(ignored)\" in the frame counter when recording when the last frame of input was not used by the SNES (such as lag or loading frames)"); AddBool("DisplayWatchedAddresses", Settings.DisplayWatchedAddresses, true); AddBool2C("WrongMovieStateProtection", Settings.WrongMovieStateProtection, true, "off to allow states to be loaded for recording from a different movie than they were made in"); AddUIntC("MessageDisplayTime", Settings.InitialInfoStringTimeout, 120, "display length of messages, in frames. set to 0 to disable all message text"); #undef CATEGORY #define CATEGORY "Settings\\Win" AddUIntC("RewindBufferSize", GUI.rewindBufferSize, 0, "rewind buffer size in MB - 0 disables rewind support"); AddUIntC("RewindGranularity", GUI.rewindGranularity, 1, "rewind granularity - rewind takes a snapshot each x frames"); AddBoolC("PauseWhenInactive", GUI.InactivePause, TRUE, "true to pause Snes9x when it is not the active window"); AddBoolC("CustomRomOpenDialog", GUI.CustomRomOpen, false, "false to use standard Windows open dialog for the ROM open dialog"); AddBoolC("AVIHiRes", GUI.AVIHiRes, false, "true to record AVI in Hi-Res scale"); // AddUIntC("Language", GUI.Language, 0, "0=English, 1=Nederlands"); // NYI AddBoolC("FrameAdvanceSkipsNonInput", GUI.FASkipsNonInput, false, "causes frame advance to fast-forward past frames where the game is definitely not checking input, such as during lag or loading time. EXPERIMENTAL"); AddBool("MovieDefaultClearSRAM", GUI.MovieClearSRAM, false); AddBool("MovieDefaultStartFromReset", GUI.MovieStartFromReset, false); AddBool("MovieDefaultReadOnly", GUI.MovieReadOnly, true); AddUInt("CurrentSaveSlot", GUI.CurrentSaveSlot, 0); AddUIntC("MaxRecentGames", GUI.MaxRecentGames, 14, "max recent games to show in the recent games menu (must be <= 32)"); #undef CATEGORY #define CATEGORY "Settings\\Win\\Files" AddStringC("Dir:Roms", GUI.RomDir, _MAX_PATH, ".\\Roms", "directory where the Open ROM dialog will start"); AddStringC("Dir:Screenshots", GUI.ScreensDir, _MAX_PATH, ".\\Screenshots", "directory where screenshots will be saved"); AddStringC("Dir:Movies", GUI.MovieDir, _MAX_PATH, ".\\Movies", "the default directory for recorded movie (.smv) files"); AddStringC("Dir:SPCs", GUI.SPCDir, _MAX_PATH, ".\\SPCs", "directory where SPCs will be saved"); AddStringC("Dir:Savestates", GUI.FreezeFileDir, _MAX_PATH, ".\\Saves", "directory where savestates will be created and loaded from"); AddStringC("Dir:SRAM", GUI.SRAMFileDir, _MAX_PATH, ".\\Saves", "directory where battery saves will be created and loaded from"); AddStringC("Dir:Patches", GUI.PatchDir, _MAX_PATH, ".\\Cheats", "directory in which ROM patches (.ips files) and cheats (.cht files) will be looked for"); AddStringC("Dir:Bios", GUI.BiosDir, _MAX_PATH, ".\\BIOS", "directory where BIOS files (such as \"BS-X.bios\") will be located"); AddBoolC("Dir:Lock", GUI.LockDirectories, false, "true to prevent Snes9x from changing configured directories when you browse to a new location"); #define ADD(n) AddString("Rom:RecentGame" #n, GUI.RecentGames[n-1], MAX_PATH, "") ADD(1); ADD(2); ADD(3); ADD(4); ADD(5); ADD(6); ADD(7); ADD(8); ADD(9); ADD(10); ADD(11); ADD(12); ADD(13); ADD(14); ADD(15); ADD(16); ADD(17); ADD(18); ADD(19); ADD(20); ADD(21); ADD(22); ADD(23); ADD(24); ADD(25); ADD(26); ADD(27); ADD(28); ADD(29); ADD(30); ADD(31); ADD(32); assert(MAX_RECENT_GAMES_LIST_SIZE == 32); #undef ADD AddString("Rom:MultiCartA", multiRomA, _MAX_PATH, ""); AddString("Rom:MultiCartB", multiRomB, _MAX_PATH, ""); #undef CATEGORY #define CATEGORY "Sound" AddIntC("Sync", Settings.SoundSync, 1, "1 to sync emulation to sound output, 0 to disable."); AddBool2("Stereo", Settings.Stereo, true); AddBool("SixteenBitSound", Settings.SixteenBitSound, true); AddUIntC("Rate", Settings.SoundPlaybackRate, 32000, "sound playback quality, in Hz"); AddUIntC("InputRate", Settings.SoundInputRate, 31900, "for each 'Input rate' samples generated by the SNES, 'Playback rate' samples will produced. If you experience crackling you can try to lower this setting."); AddBoolC("ReverseStereo", Settings.ReverseStereo, false, "true to swap speaker outputs"); AddBoolC("Mute", GUI.Mute, false, "true to mute sound output (does not disable the sound CPU)"); #undef CATEGORY #define CATEGORY "Sound\\Win" AddUIntC("SoundDriver", GUI.SoundDriver, 4, "0=Snes9xDirectSound, 4=XAudio2 (recommended), 5=FMOD Default, 6=FMOD ASIO, 7=FMOD OpenAL"); AddUIntC("BufferSize", GUI.SoundBufferSize, 64, "sound buffer size in ms - determines the internal and output sound buffer sizes. actual mixing is done every SoundBufferSize/4 samples"); AddBoolC("MuteFrameAdvance", GUI.FAMute, false, "true to prevent Snes9x from outputting sound when the Frame Advance command is in use"); #undef CATEGORY #define CATEGORY "Controls" AddBoolC("AllowLeftRight", Settings.UpAndDown, false, "true to allow left+right and up+down"); #undef CATEGORY #define CATEGORY "ROM" AddBoolC("Cheat", Settings.ApplyCheats, true, "true to allow enabled cheats to be applied"); AddInvBoolC("Patch", Settings.NoPatch, true, "true to allow IPS/UPS patches to be applied (\"soft patching\")"); AddBoolC("BS", Settings.BS, false, "Broadcast Satellaview emulation"); AddStringC("Filename", rom_filename, MAX_PATH, "", "filename of ROM to run when Snes9x opens"); #undef CATEGORY #ifdef NETPLAY_SUPPORT #define CATEGORY "Netplay" AddUInt("Port", Settings.Port, NP_DEFAULT_PORT); AddString("Server", Settings.ServerName, 128, Settings.ServerName); AddBool2("SyncByReset", NPServer.SyncByReset, true); AddBool2("SendROMImageOnConnect", NPServer.SendROMImageOnConnect, false); AddUInt("MaxFrameSkip", NetPlay.MaxFrameSkip, 10); AddUInt("MaxBehindFrameCount", NetPlay.MaxBehindFrameCount, 10); AddBoolC("UseJoypad1", GUI.NetplayUseJoypad1, true, "if false, player 2 has to use their joypad #2 controls, etc."); #define ADD(n,d) AddString("RecentHost" #n, GUI.RecentHostNames[n-1], MAX_PATH, d) ADD(1,"localhost"); ADD(2,""); ADD(3,""); ADD(4,""); ADD(5,""); ADD(6,""); ADD(7,""); ADD(8,""); ADD(9,""); ADD(10,""); ADD(11,""); ADD(12,""); ADD(13,""); ADD(14,""); ADD(15,""); ADD(16,""); assert(MAX_RECENT_HOSTS_LIST_SIZE == 16); #undef ADD #undef CATEGORY #endif #define CATEGORY "Controls\\Win" #define ADD(n,x) AddVKey("Joypad" #n ":" #x, Joypad[n-1].x, Joypad[n-1].x) #define ADDN(n,x,n2) AddVKey("Joypad" #n ":" #n2, Joypad[n-1].x, Joypad[n-1].x) #define ADDB(n,x) AddBool("Joypad" #n ":" #x, Joypad[n-1].x, Joypad[n-1].x) #define ADD2(n) ADDB(n,Enabled); ADD(n,Up); ADD(n,Down); ADD(n,Left); ADD(n,Right); ADD(n,A); ADD(n,B); ADD(n,Y); ADD(n,X); ADD(n,L); ADD(n,R); ADD(n,Start); ADD(n,Select); ADDN(n,Left_Up,Left+Up); ADDN(n,Right_Up,Right+Up); ADDN(n,Right_Down,Right+Down); ADDN(n,Left_Down,Left+Down) #define ADDT(n,x) AddVKey("Joypad" #n "Turbo:" #x, Joypad[n-1+8].x, Joypad[n-1+8].x) #define ADDTN(n,x,n2) AddVKey("Joypad" #n "Turbo:" #n2, Joypad[n-1+8].x, Joypad[n-1+8].x) #define ADDT2(n) ADDTN(n,Down,AutoFire); ADDTN(n,Left,AutoHold); ADDTN(n,Up,TempTurbo); ADDTN(n,Right,ClearAll) #define ADDT3(n) ADDT(n,A); ADDT(n,B); ADDT(n,Y); ADDT(n,X); ADDT(n,L); ADDT(n,R); ADDT(n,Start); ADDT(n,Select) #define ADD2T2(n) ADD2(n); ADDT2(n) // NOTE: for now, the windows port doesn't actually allow 8 different controllers to be set configured, only 5 ADD2T2(1); ADD2T2(2); ADD2T2(3); ADD2T2(4); ADD2T2(5); ADD2T2(6); ADD2T2(7); ADD2T2(8); ADDT3(1); ADDT3(2); ADDT3(3); ADDT3(4); ADDT3(5); ADDT3(6); ADDT3(7); ADDT3(8); #undef ADD #undef ADD2 #undef ADDN #undef ADDB #undef ADDT #undef ADDT2 #undef ADDT3 #undef ADDTN #undef ADD2T2 AddBool2C("Input:Background", GUI.BackgroundInput, false, "on to detect game keypresses and hotkeys while window is inactive, if PauseWhenInactive = FALSE."); #undef CATEGORY #define CATEGORY "Controls\\Win\\Hotkeys" AddBool2C("Handler:Joystick", GUI.JoystickHotkeys, true, "on to detect game controller buttons assigned to hotkeys. May impact performance."); #define ADD(x) AddVKey("Key:" #x , CustomKeys.x.key, CustomKeys.x.key); AddVKMod("Mods:" #x, CustomKeys.x.modifiers, CustomKeys.x.modifiers) #define ADDN(x,n2) AddVKey("Key:" #n2, CustomKeys.x.key, CustomKeys.x.key); AddVKMod("Mods:" #n2, CustomKeys.x.modifiers, CustomKeys.x.modifiers) ADD(SpeedUp); ADD(SpeedDown); ADD(Pause); ADD(FrameAdvance); ADD(SkipUp); ADD(SkipDown); ADD(ScopeTurbo); ADD(ScopePause); ADD(FrameCount); ADD(ReadOnly); ADD(FastForward); ADD(FastForwardToggle); ADD(ShowPressed); ADDN(Save[0],SaveSlot0); ADDN(Save[1],SaveSlot1); ADDN(Save[2],SaveSlot2); ADDN(Save[3],SaveSlot3); ADDN(Save[4],SaveSlot4); ADDN(Save[5],SaveSlot5); ADDN(Save[6],SaveSlot6); ADDN(Save[7],SaveSlot7); ADDN(Save[8],SaveSlot8); ADDN(Save[9],SaveSlot9); ADDN(Load[0],LoadSlot0); ADDN(Load[1],LoadSlot1); ADDN(Load[2],LoadSlot2); ADDN(Load[3],LoadSlot3); ADDN(Load[4],LoadSlot4); ADDN(Load[5],LoadSlot5); ADDN(Load[6],LoadSlot6); ADDN(Load[7],LoadSlot7); ADDN(Load[8],LoadSlot8); ADDN(Load[9],LoadSlot9); ADDN(SelectSave[0],SelectSlot0); ADDN(SelectSave[1],SelectSlot1); ADDN(SelectSave[2],SelectSlot2); ADDN(SelectSave[3],SelectSlot3); ADDN(SelectSave[4],SelectSlot4); ADDN(SelectSave[5],SelectSlot5); ADDN(SelectSave[6],SelectSlot6); ADDN(SelectSave[7],SelectSlot7); ADDN(SelectSave[8],SelectSlot8); ADDN(SelectSave[9],SelectSlot9); ADD(SaveScreenShot); ADD(SlotPlus); ADD(SlotMinus); ADD(SlotSave); ADD(SlotLoad); ADD(BGL1); ADD(BGL2); ADD(BGL3); ADD(BGL4); ADD(BGL5); ADD(ClippingWindows); /*ADD(BGLHack);*/ ADD(Transparency); /*ADD(HDMA)*/; /*ADD(GLCube);*/ /*ADD(InterpMode7);*/ ADD(JoypadSwap); ADD(SwitchControllers); ADD(ResetGame); ADD(ToggleCheats); ADD(TurboA); ADD(TurboB); ADD(TurboY); ADD(TurboX); ADD(TurboL); ADD(TurboR); ADD(TurboStart); ADD(TurboSelect); ADD(TurboUp); ADD(TurboDown); ADD(TurboLeft); ADD(TurboRight); ADD(QuitS9X);ADD(Rewind); #undef ADD #undef ADDN #undef CATEGORY }
size_t strftime(char *s,size_t maxsize,const char *format,const struct tm *timeptr) { size_t size=0,tmp; while(*format) { if(*format=='%') { tmp=0; switch(*++format) { case 'a': ADDS(STR(ABDAY_1+timeptr->tm_wday)); case 'b': case 'h': ADDS(STR(ABMON_1+timeptr->tm_mon)); case 'c': ADDS("%m/%d/%y %H:%M:%S"); case 'd': ADDN(2,timeptr->tm_mday); case 'e': ADDN(-2,timeptr->tm_mday); case 'j': ADDN(3,timeptr->tm_yday+1); case 'k': ADDN(-2,timeptr->tm_hour); case 'l': ADDN(-2,timeptr->tm_hour%12+(timeptr->tm_hour%12==0)*12); case 'm': ADDN(2,timeptr->tm_mon+1); case 'p': ADDS(STR(AM_STR+(timeptr->tm_hour>=12))); case 'r': ADDS("%I:%M:%S %p"); case 'w': ADDN(1,timeptr->tm_wday); case 'x': ADDS("%m/%d/%y"); case 'y': ADDN(2,timeptr->tm_year%100); case 'A': ADDS(STR(DAY_1+timeptr->tm_wday)); case 'B': ADDS(STR(MON_1+timeptr->tm_mon)); case 'C': ADDS("%a %b %e %H:%M:%S %Y"); case 'D': ADDS("%m/%d/%y"); case 'H': ADDN(2,timeptr->tm_hour); case 'I': ADDN(2,timeptr->tm_hour%12+(timeptr->tm_hour%12==0)*12); case 'M': ADDN(2,timeptr->tm_min); case 'R': ADDS("%H:%M"); case 'S': ADDN(2,timeptr->tm_sec); case 'T': case 'X': ADDS("%H:%M:%S"); case 'U': ADDN(2,(timeptr->tm_yday+7-timeptr->tm_wday)/7); case 'W': ADDN(2,(timeptr->tm_yday+7-(6+timeptr->tm_wday)%7)/7); case 'Y': ADDN(4,timeptr->tm_year+1900); case 't': STOR('\t'); break; case 'n': STOR('\n'); break; case '%': STOR('%'); break; case '\0': format--; break; } size+=tmp; s+=tmp; } else STOR(*format); format++; } STOR('\0'); if(size>maxsize) { s-=size; if(maxsize) /* Don't know if this is necessary, therefore it's here ;-) */ s[maxsize-1]='\0'; size=1; } return size-1; }