size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param) { if (!buffer || !maxlen) { return 0; } int arg; int args = params[0]; char *buf_p; char ch; int flags; int width; int prec; int n; char sign; const char *fmt; size_t llen = maxlen - 1; buf_p = buffer; arg = *param; fmt = format; while (true) { // run through the format string until we hit a '%' or '\0' for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++) { *buf_p++ = ch; llen--; } if ((ch == '\0') || (llen <= 0)) { goto done; } // skip over the '%' fmt++; // reset formatting state flags = 0; width = 0; prec = -1; sign = '\0'; rflag: ch = *fmt++; reswitch: switch(ch) { case '-': { flags |= LADJUST; goto rflag; } case '.': { n = 0; while(is_digit((ch = *fmt++))) { n = 10 * n + (ch - '0'); } prec = (n < 0) ? -1 : n; goto reswitch; } case '0': { flags |= ZEROPAD; goto rflag; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { n = 0; do { n = 10 * n + (ch - '0'); ch = *fmt++; } while(is_digit(ch)); width = n; goto reswitch; } case 'c': { CHECK_ARGS(0); if (!llen) { goto done; } char *c; pCtx->LocalToString(params[arg], &c); *buf_p++ = *c; llen--; arg++; break; } case 'b': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); AddBinary(&buf_p, llen, *value, width, flags); arg++; break; } case 'd': case 'i': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); AddInt(&buf_p, llen, static_cast<int>(*value), width, flags); arg++; break; } case 'u': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); AddUInt(&buf_p, llen, static_cast<unsigned int>(*value), width, flags); arg++; break; } case 'f': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); AddFloat(&buf_p, llen, sp_ctof(*value), width, prec, flags); arg++; break; } case 'L': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); char buffer[255]; if (*value) { CPlayer *player = g_Players.GetPlayerByIndex(*value); if (!player || !player->IsConnected()) { return pCtx->ThrowNativeError("Client index %d is invalid", *value); } const char *auth = player->GetAuthString(); if (!auth || auth[0] == '\0') { auth = "STEAM_ID_PENDING"; } int userid = engine->GetPlayerUserId(player->GetEdict()); UTIL_Format(buffer, sizeof(buffer), "%s<%d><%s><>", player->GetName(), userid, auth); } else { UTIL_Format(buffer, sizeof(buffer), "Console<0><Console><Console>"); } AddString(&buf_p, llen, buffer, width, prec); arg++; break; } case 'N': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); const char *name = "Console"; if (*value) { CPlayer *player = g_Players.GetPlayerByIndex(*value); if (!player || !player->IsConnected()) { return pCtx->ThrowNativeError("Client index %d is invalid", *value); } name = player->GetName(); } AddString(&buf_p, llen, name, width, prec); arg++; break; } case 's': { CHECK_ARGS(0); char *str; int err; if ((err=pCtx->LocalToString(params[arg], &str)) != SP_ERROR_NONE) { pCtx->ThrowNativeErrorEx(err, "Could not deference string"); return 0; } AddString(&buf_p, llen, str, width, prec); arg++; break; } case 'T': { CHECK_ARGS(1); char *key; bool error; size_t res; cell_t *target; pCtx->LocalToString(params[arg++], &key); pCtx->LocalToPhysAddr(params[arg++], &target); res = Translate(buf_p, llen, pCtx, key, *target, params, &arg, &error); if (error) { return 0; } buf_p += res; llen -= res; break; } case 't': { CHECK_ARGS(0); char *key; bool error; size_t res; cell_t target = g_SourceMod.GetGlobalTarget(); pCtx->LocalToString(params[arg++], &key); res = Translate(buf_p, llen, pCtx, key, target, params, &arg, &error); if (error) { return 0; } buf_p += res; llen -= res; break; } case 'X': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); flags |= UPPERDIGITS; AddHex(&buf_p, llen, static_cast<unsigned int>(*value), width, flags); arg++; break; } case 'x': { CHECK_ARGS(0); cell_t *value; pCtx->LocalToPhysAddr(params[arg], &value); AddHex(&buf_p, llen, static_cast<unsigned int>(*value), width, flags); arg++; break; } case '%': { if (!llen) { goto done; } *buf_p++ = ch; llen--; break; } case '\0': { if (!llen) { goto done; } *buf_p++ = '%'; llen--; goto done; } default: { if (!llen) { goto done; } *buf_p++ = ch; llen--; break; } } } done: *buf_p = '\0'; *param = arg; return (maxlen - llen - 1); }
size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args) { if (!buffer || !maxlen) { return 0; } int arg = 0; char *buf_p; char ch; int flags; int width; int prec; int n; char sign; const char *fmt; size_t llen = maxlen - 1; buf_p = buffer; fmt = format; while (true) { // run through the format string until we hit a '%' or '\0' for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++) { *buf_p++ = ch; llen--; } if ((ch == '\0') || (llen <= 0)) { goto done; } // skip over the '%' fmt++; // reset formatting state flags = 0; width = 0; prec = -1; sign = '\0'; rflag: ch = *fmt++; reswitch: switch(ch) { case '-': { flags |= LADJUST; goto rflag; } case '.': { n = 0; while(is_digit((ch = *fmt++))) { n = 10 * n + (ch - '0'); } prec = (n < 0) ? -1 : n; goto reswitch; } case '0': { flags |= ZEROPAD; goto rflag; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { n = 0; do { n = 10 * n + (ch - '0'); ch = *fmt++; } while(is_digit(ch)); width = n; goto reswitch; } case 'c': { if (!llen) { goto done; } char *c = (char *)args[arg]; *buf_p++ = *c; llen--; arg++; break; } case 'b': { int *value = (int *)args[arg]; AddBinary(&buf_p, llen, *value, width, flags); arg++; break; } case 'd': case 'i': { int *value = (int *)args[arg]; AddInt(&buf_p, llen, *value, width, flags); arg++; break; } case 'u': { unsigned int *value = (unsigned int *)args[arg]; AddUInt(&buf_p, llen, *value, width, flags); arg++; break; } case 'f': { float *value = (float *)args[arg]; AddFloat(&buf_p, llen, *value, width, prec, flags); arg++; break; } case 's': { const char *str = (const char *)args[arg]; AddString(&buf_p, llen, str, width, prec); arg++; break; } case 'X': { unsigned int *value = (unsigned int *)args[arg]; flags |= UPPERDIGITS; AddHex(&buf_p, llen, *value, width, flags); arg++; break; } case 'x': { unsigned int *value = (unsigned int *)args[arg]; AddHex(&buf_p, llen, *value, width, flags); arg++; break; } case '%': { if (!llen) { goto done; } *buf_p++ = ch; llen--; break; } case '\0': { if (!llen) { goto done; } *buf_p++ = '%'; llen--; goto done; } default: { if (!llen) { goto done; } *buf_p++ = ch; llen--; break; } } } done: *buf_p = '\0'; return (maxlen - llen - 1); }
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param) { int arg; int args = params[0] / sizeof(cell); D *buf_p; D ch; int flags; int width; int prec; int n; //char sign; const S *fmt; size_t llen = maxlen; buf_p = buffer; arg = *param; fmt = format; while (true) { // run through the format string until we hit a '%' or '\0' for (ch = static_cast<D>(*fmt); llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%'); fmt++) { *buf_p++ = static_cast<D>(ch); llen--; } if (ch == '\0' || llen <= 0) goto done; // skip over the '%' fmt++; // reset formatting state flags = 0; width = 0; prec = -1; //sign = '\0'; rflag: ch = static_cast<D>(*fmt++); reswitch: switch(ch) { case '-': flags |= LADJUST; goto rflag; case '.': n = 0; while( is_digit( ( ch = static_cast<D>(*fmt++)) ) ) n = 10 * n + ( ch - '0' ); prec = n < 0 ? -1 : n; goto reswitch; case '0': flags |= ZEROPAD; goto rflag; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; do { n = 10 * n + ( ch - '0' ); ch = static_cast<D>(*fmt++); } while( is_digit( ch ) ); width = n; goto reswitch; case 'c': CHECK_ARGS(0); *buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg])); llen--; arg++; break; case 'b': CHECK_ARGS(0); AddBinary(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags); arg++; break; case 'd': case 'i': CHECK_ARGS(0); AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags); arg++; break; case 'u': CHECK_ARGS(0); AddUInt(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags); arg++; break; case 'f': CHECK_ARGS(0); AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec, flags); arg++; break; case 'X': CHECK_ARGS(0); flags |= UPPERDIGITS; AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags); arg++; break; case 'x': CHECK_ARGS(0); AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags); arg++; break; case 'a': { CHECK_ARGS(0); // %a is passed a pointer directly to a cell string. cell* ptr=reinterpret_cast<cell*>(*get_amxaddr(amx, params[arg])); if (!ptr) { LogError(amx, AMX_ERR_NATIVE, "Invalid vector string handle provided (%d)", *get_amxaddr(amx, params[arg])); return 0; } AddString(&buf_p, llen, ptr, width, prec); arg++; break; } case 's': CHECK_ARGS(0); AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec); arg++; break; case 'L': case 'l': { const char *lang; int len; if (ch == 'L') { CHECK_ARGS(1); auto currParam = params[arg++]; lang = playerlang(*get_amxaddr(amx, currParam)); if (!lang) lang = get_amxstring(amx, currParam, 2, len); } else { CHECK_ARGS(0); lang = playerlang(g_langMngr.GetDefLang()); } const char *key = get_amxstring(amx, params[arg++], 3, len); const char *def = translate(amx, lang, key); if (!def) { static char buf[255]; ke::SafeSprintf(buf, sizeof(buf), "ML_NOTFOUND: %s", key); def = buf; } size_t written = atcprintf(buf_p, llen, def, amx, params, &arg); buf_p += written; llen -= written; break; } case 'N': { CHECK_ARGS(0); cell *addr = get_amxaddr(amx, params[arg]); char buffer[255]; if (*addr) { CPlayer *player = NULL; if (*addr >= 1 && *addr <= gpGlobals->maxClients) { player = GET_PLAYER_POINTER_I(*addr); } if (!player || !player->initialized) { LogError(amx, AMX_ERR_NATIVE, "Client index %d is invalid", *addr); return 0; } const char *auth = GETPLAYERAUTHID(player->pEdict); if (!auth || auth[0] == '\0') { auth = "STEAM_ID_PENDING"; } int userid = GETPLAYERUSERID(player->pEdict); ke::SafeSprintf(buffer, sizeof(buffer), "%s<%d><%s><%s>", player->name.chars(), userid, auth, player->team.chars()); } else { ke::SafeSprintf(buffer, sizeof(buffer), "Console<0><Console><Console>"); } AddString(&buf_p, llen, buffer, width, prec); arg++; break; } case 'n': { CHECK_ARGS(0); cell *addr = get_amxaddr(amx, params[arg]); const char *name = "Console"; if (*addr) { CPlayer *player = NULL; if (*addr >= 1 && *addr <= gpGlobals->maxClients) { player = GET_PLAYER_POINTER_I(*addr); } if (!player || !player->initialized) { LogError(amx, AMX_ERR_NATIVE, "Client index %d is invalid", *addr); return 0; } name = player->name.chars(); } AddString(&buf_p, llen, name, width, prec); arg++; break; } case '%': *buf_p++ = static_cast<D>(ch); if (!llen) goto done; llen--; break; case '\0': *buf_p++ = static_cast<D>('%'); if (!llen) goto done; llen--; goto done; break; default: *buf_p++ = static_cast<D>(ch); if (!llen) goto done; llen--; break; } } done: *buf_p = static_cast<D>(0); *param = arg; /* if max buffer length consumed, make sure we don't truncate a multi-byte character */ if (llen <= 0 && *(buf_p - 1) & 1 << 7) { llen += UTIL_CheckValidChar(buf_p - 1); *(buf_p - llen) = static_cast<D>(0); } return maxlen-llen; }
// 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 }
LWorkItem& LWorkItem::operator<<(unsigned int unData) { AddUInt(unData); return *this; }