Path: blob/master/RSDKv5/RSDK/User/Core/UserCore.cpp
1162 views
#include "RSDK/Core/RetroEngine.hpp"12#include "iniparser/iniparser.h"34// ====================5// API Cores6// ====================78namespace RSDK9{10namespace SKU11{12// Dummy API13#if RETRO_USERCORE_DUMMY14#include "RSDK/User/Dummy/DummyCore.cpp"15#endif1617// Steam API18#if RETRO_USERCORE_STEAM19#include "RSDK/User/Steam/SteamCore.cpp"20#endif2122// Epic Games API23#if RETRO_USERCORE_EOS24#include "RSDK/User/EOS/EOSCore.cpp"25#endif2627// Switch API28#if RETRO_USERCORE_NX29#include "RSDK/User/NX/NXCore.cpp"30#endif3132} // namespace SKU33} // namespace RSDK3435using namespace RSDK;3637#if RETRO_REV0238SKU::UserCore *RSDK::SKU::userCore = NULL;39#endif4041void RSDK::SKU::InitUserCore()42{43InitUserDirectory();4445#if RETRO_REV0246#if RETRO_USERCORE_DUMMY47if (dummyCore)48delete dummyCore;49dummyCore = InitDummyCore();50#endif5152// Initalize platform-specific subsystems here5354#if RETRO_USERCORE_STEAM55userCore = InitSteamCore();56#endif5758#if RETRO_USERCORE_EOS59userCore = InitEOSCore();60#endif6162#if RETRO_USERCORE_NX63userCore = InitNXCore();64#endif6566#if RETRO_USERCORE_DUMMY67if (!userCore) { // no platform core, so default to dummy funcs68userCore = dummyCore;69}70else if (dummyCore) {71delete dummyCore;72dummyCore = nullptr;73}74#endif7576if (!userDBStorage)77userDBStorage = new UserDBStorage;78#endif7980#if RETRO_REV0281curSKU.platform = userCore->GetUserPlatform();82curSKU.language = userCore->GetUserLanguage();83curSKU.region = userCore->GetUserRegion();84engine.confirmFlip = userCore->GetConfirmButtonFlip();85#else8687#if RETRO_PLATFORM == RETRO_PS488gameVerInfo.platform = PLATFORM_PS4;89#elif RETRO_PLATFORM == RETRO_XB190gameVerInfo.platform = PLATFORM_XB1;91#elif RETRO_PLATFORM == RETRO_SWITCH || RETRO_PLATFORM == RETRO_ANDROID92gameVerInfo.platform = PLATFORM_SWITCH;93#else94// default to PC (or dev if dev stuff is enabled)95gameVerInfo.platform = engine.devMenu ? PLATFORM_DEV : PLATFORM_PC;96#endif9798gameVerInfo.language = LANGUAGE_EN;99gameVerInfo.region = REGION_US;100engine.confirmFlip = false;101#endif102103#if !RETRO_USE_ORIGINAL_CODE104// Add achievements105achievementList.clear();106achievementStack.clear();107RegisterAchievement("ACH_GOLD_MEDAL", "No Way? No Way!", "Collect gold medallions in Blue Spheres Bonus stage");108RegisterAchievement("ACH_SILVER_MEDAL", "Full Medal Jacket", "Collect silver medallions in Blue Spheres Bonus stage");109RegisterAchievement("ACH_EMERALDS", "Magnificent Seven", "Collect all seven Chaos Emeralds");110RegisterAchievement("ACH_GAME_CLEARED", "See You Next Game", "Achieve any ending");111RegisterAchievement("ACH_STARPOST", "Superstar", "Spin the Star Post!");112RegisterAchievement("ACH_SIGNPOST", "That's a Two-fer", "Find the hidden item boxes at the end of the Zone");113RegisterAchievement("ACH_GHZ", "Now It Can't Hurt You Anymore", "What would happen if you cross a bridge with a fire shield?");114RegisterAchievement("ACH_CPZ", "Triple Trouble", "Try for a 3 chain combo!");115RegisterAchievement("ACH_SPZ", "The Most Famous Hedgehog in the World", "Have your photos taken in Studiopolis Zone");116RegisterAchievement("ACH_FBZ", "Window Shopping", "Let the wind take you through");117RegisterAchievement("ACH_PGZ", "Crate Expectations", "Wreak havoc at the propaganda factory");118RegisterAchievement("ACH_SSZ", "King of Speed", "Get through Stardust Speedway Zone as quickly as possible");119RegisterAchievement("ACH_HCZ", "Boat Enthusiast", "We really like boats");120RegisterAchievement("ACH_MSZ", "The Password is \"Special Stage\"", "Try pushing a barrel to see how far it goes");121RegisterAchievement("ACH_OOZ", "Secret Sub", "You might have to submerge to find it");122RegisterAchievement("ACH_LRZ", "Without a Trace", "Barrel through the lava, don't let anything stop you");123RegisterAchievement("ACH_MMZ", "Collect 'Em All", "Gotta gacha 'em all");124RegisterAchievement("ACH_TMZ", "Professional Hedgehog", "That elusive perfect run, only a professional can achieve");125126#if RETRO_USERCORE_DUMMY127int32 achievementsRAM[0x100];128memset(achievementsRAM, 0, 0x100 * sizeof(int32));129bool32 loaded = false;130loaded = LoadUserFile("Achievements.bin", achievementsRAM, 0x100 * sizeof(int32));131(void)loaded;132for (int32 i = 0; i < (int32)achievementList.size(); ++i) {133achievementList[i].achieved = achievementsRAM[i];134}135#endif136#endif137}138void RSDK::SKU::ReleaseUserCore()139{140SaveUserData();141142#if RETRO_REV02143144if (achievements)145delete achievements;146achievements = nullptr;147148if (leaderboards)149delete leaderboards;150leaderboards = nullptr;151152if (richPresence)153delete richPresence;154richPresence = nullptr;155156if (stats)157delete stats;158stats = nullptr;159160if (userStorage)161delete userStorage;162userStorage = nullptr;163164if (userDBStorage)165delete userDBStorage;166userDBStorage = nullptr;167168if (userCore) {169userCore->Shutdown();170delete userCore;171}172173#if RETRO_USERCORE_DUMMY174dummyCore = nullptr;175#endif176userCore = nullptr;177#endif178}179180void RSDK::SKU::SaveUserData()181{182#if RETRO_USERCORE_DUMMY183int32 achievementsRAM[0x100];184memset(achievementsRAM, 0, 0x100 * sizeof(int32));185for (int32 i = 0; i < (int32)achievementList.size(); ++i) {186achievementsRAM[i] = achievementList[i].achieved;187}188SaveUserFile("Achievements.bin", achievementsRAM, 0x100 * sizeof(int32));189#endif190}191192// Found this in Switch 1.00, doesn't seem to show up in rev02 variants but its neat nonetheless193bool32 RSDK::SKU::GetXYButtonFlip() { return engine.XYFlip; }194195#if RETRO_REV02196void RSDK::SKU::UserCore::StageLoad()197{198achievements->StageLoad();199leaderboards->StageLoad();200richPresence->StageLoad();201stats->StageLoad();202userStorage->StageLoad();203}204void RSDK::SKU::UserCore::FrameInit()205{206achievements->FrameInit();207leaderboards->FrameInit();208richPresence->FrameInit();209stats->FrameInit();210userStorage->FrameInit();211}212void RSDK::SKU::UserCore::OnUnknownEvent()213{214achievements->OnUnknownEvent();215leaderboards->OnUnknownEvent();216richPresence->OnUnknownEvent();217stats->OnUnknownEvent();218userStorage->OnUnknownEvent();219}220#else221bool32 RSDK::SKU::GetConfirmButtonFlip() { return engine.confirmFlip; }222void RSDK::SKU::LaunchManual()223{224// LaunchManual() just opens the mania manual URL, thats it225#if RETRO_RENDERDEVICE_SDL2226// SDL_OpenURL("http://www.sonicthehedgehog.com/mania/manual");227PrintLog(PRINT_NORMAL, "DUMMY LaunchManual()");228#else229PrintLog(PRINT_NORMAL, "EMPTY LaunchManual()");230#endif231}232void RSDK::SKU::ExitGame() { RenderDevice::isRunning = false; }233234int32 RSDK::SKU::GetDefaultGamepadType()235{236#if RETRO_REV02237int32 platform = curSKU.platform = PLATFORM_SWITCH;238#else239int32 platform = gameVerInfo.platform = PLATFORM_SWITCH;240#endif241242switch (platform) {243case PLATFORM_SWITCH: return (DEVICE_API_NONE << 16) | (DEVICE_TYPE_CONTROLLER << 8) | (DEVICE_SWITCH_HANDHELD << 0);244case PLATFORM_PC:245case PLATFORM_DEV:246default: return (DEVICE_API_NONE << 16) | (DEVICE_TYPE_CONTROLLER << 8) | (0 << 0); break;247}248}249250bool32 RSDK::SKU::ShowExtensionOverlay(uint8 overlay)251{252switch (overlay) {253default: PrintLog(PRINT_POPUP, "Show Extension Overlay: %d", overlay); break;254}255return false;256}257#endif258259#if RETRO_PLATFORM == RETRO_ANDROID260#include <jni.h>261#endif262263#if !RETRO_USE_ORIGINAL_CODE264CustomSettings RSDK::customSettings;265#endif266267char buttonNames[18][8] = { "U", "D", "L", "R", "START", "SELECT", "LSTICK", "RSTICK", "L1", "R1", "C", "Z", "A", "B", "X", "Y", "L2", "R2" };268269void RSDK::LoadSettingsINI()270{271videoSettings.screenCount = 1;272videoSettings.pixHeight = SCREEN_YSIZE;273videoSettings.windowState = WINDOWSTATE_UNINITIALIZED;274275int32 platform = PLATFORM_DEV;276#if RETRO_REV02277platform = SKU::curSKU.platform;278#else279platform = gameVerInfo.platform;280#endif281282// Consoles load the entire file and buffer it, while PC just io's the file when needed283bool32 useBuffer = !(platform == PLATFORM_PC || platform == PLATFORM_DEV);284285char pathBuffer[0x100];286sprintf_s(pathBuffer, sizeof(pathBuffer), "%sSettings.ini", SKU::userFileDir);287288dictionary *ini = iniparser_load(pathBuffer);289290int32 defaultKeyMaps[PLAYER_COUNT + 1][KEY_MAX] = {291{ KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING,292KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING },293294{ VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_A, VK_S, VK_D, VK_Q, VK_W, VK_E, VK_RETURN, VK_TAB },295{ VK_NUMPAD8, VK_NUMPAD5, VK_NUMPAD4, VK_NUMPAD6, VK_J, VK_K, KEYMAP_NO_MAPPING, VK_U, VK_I, KEYMAP_NO_MAPPING, VK_OEM_4, VK_OEM_6 },296297{ KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING,298KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING },299300{ KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING,301KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING, KEYMAP_NO_MAPPING }302};303304if (ini) {305#if RETRO_REV02306SKU::curSKU.language = iniparser_getint(ini, "Game:language", LANGUAGE_EN);307#else308gameVerInfo.language = iniparser_getint(ini, "Game:language", LANGUAGE_EN);309#endif310311engine.devMenu = true;312if (LoadDataPack(iniparser_getstring(ini, "Game:dataFile", "Data.rsdk"), 0, useBuffer))313engine.devMenu = iniparser_getboolean(ini, "Game:devMenu", false);314315#if !RETRO_USE_ORIGINAL_CODE316customSettings.region = iniparser_getint(ini, "Game:region", -1);317// customSettings.confirmButtonFlip = iniparser_getboolean(ini, "Game:confirmButtonFlip", false);318// customSettings.xyButtonFlip = iniparser_getboolean(ini, "Game:xyButtonFlip", false);319customSettings.confirmButtonFlip = iniparser_getboolean(ini, "Game:faceButtonFlip", false);320customSettings.xyButtonFlip = customSettings.confirmButtonFlip;321customSettings.enableControllerDebugging = iniparser_getboolean(ini, "Game:enableControllerDebugging", false);322customSettings.disableFocusPause = iniparser_getboolean(ini, "Game:disableFocusPause", false);323engine.fastForwardSpeed = iniparser_getint(ini, "Game:fastForwardSpeed", 8);324325#if RETRO_REV0U326customSettings.forceScripts = iniparser_getboolean(ini, "Game:txtScripts", false);327engine.gameReleaseID = iniparser_getint(ini, "Game:gameType", 1);328#endif329330sprintf_s(gameLogicName, sizeof(gameLogicName), "%s", iniparser_getstring(ini, "Game:gameLogic", "Game"));331sprintf_s(customSettings.username, sizeof(customSettings.username), "%s", iniparser_getstring(ini, "Game:username", ""));332333if (customSettings.region >= 0) {334#if RETRO_REV02335SKU::curSKU.region = customSettings.region;336#else337gameVerInfo.region = customSettings.region;338#endif339}340341engine.confirmFlip = customSettings.confirmButtonFlip;342engine.XYFlip = customSettings.xyButtonFlip;343#else344sprintf_s(gameLogicName, sizeof(gameLogicName), "Game");345#endif346347videoSettings.windowed = iniparser_getboolean(ini, "Video:windowed", true);348videoSettings.bordered = iniparser_getboolean(ini, "Video:border", true);349videoSettings.exclusiveFS = iniparser_getboolean(ini, "Video:exclusiveFS", false);350videoSettings.vsync = iniparser_getboolean(ini, "Video:vsync", false);351videoSettings.tripleBuffered = iniparser_getboolean(ini, "Video:tripleBuffering", false);352353videoSettings.pixWidth = iniparser_getint(ini, "Video:pixWidth", DEFAULT_PIXWIDTH);354355videoSettings.windowWidth = iniparser_getint(ini, "Video:winWidth", DEFAULT_PIXWIDTH);356videoSettings.windowHeight = iniparser_getint(ini, "Video:winHeight", SCREEN_YSIZE);357videoSettings.fsWidth = iniparser_getint(ini, "Video:fsWidth", 0);358videoSettings.fsHeight = iniparser_getint(ini, "Video:fsHeight", 0);359videoSettings.refreshRate = iniparser_getint(ini, "Video:refreshRate", 60);360videoSettings.shaderSupport = iniparser_getboolean(ini, "Video:shaderSupport", true);361videoSettings.shaderID = iniparser_getint(ini, "Video:screenShader", SHADER_NONE);362363#if !RETRO_USE_ORIGINAL_CODE364customSettings.maxPixWidth = iniparser_getint(ini, "Video:maxPixWidth", DEFAULT_PIXWIDTH);365#endif366367engine.streamsEnabled = iniparser_getboolean(ini, "Audio:streamsEnabled", true);368engine.streamVolume = (float)iniparser_getdouble(ini, "Audio:streamVolume", 0.8);369engine.soundFXVolume = (float)iniparser_getdouble(ini, "Audio:sfxVolume", 1.0);370371for (int32 i = CONT_P1; i <= PLAYER_COUNT; ++i) {372char buffer[0x30];373374sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:up", i);375controller[i].keyUp.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_UP]);376377sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:down", i);378controller[i].keyDown.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_DOWN]);379380sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:left", i);381controller[i].keyLeft.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_LEFT]);382383sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:right", i);384controller[i].keyRight.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_RIGHT]);385386sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonA", i);387controller[i].keyA.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_A]);388389sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonB", i);390controller[i].keyB.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_B]);391392sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonC", i);393controller[i].keyC.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_C]);394395sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonX", i);396controller[i].keyX.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_X]);397398sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonY", i);399controller[i].keyY.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_Y]);400401sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:buttonZ", i);402controller[i].keyZ.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_Z]);403404sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:start", i);405controller[i].keyStart.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_START]);406407sprintf_s(buffer, sizeof(buffer), "Keyboard Map %d:select", i);408controller[i].keySelect.keyMap = iniparser_getint(ini, buffer, defaultKeyMaps[i][KEY_SELECT]);409}410411gamePadCount = 0;412while (true) {413char buffer[0x30];414sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:name", CONT_P1 + gamePadCount);415if (strcmp(iniparser_getstring(ini, buffer, ";unknown;"), ";unknown;") != 0) {416gamePadCount++;417}418else {419break;420}421}422423#if !RETRO_USE_ORIGINAL_CODE424if (gamePadCount) {425#endif426#if RETRO_USE_MOD_LOADER427// using standard allocation here due to mod loader trickery428gamePadMappings = new GamePadMappings[gamePadCount];429#else430AllocateStorage((void **)&gamePadMappings, sizeof(GamePadMappings) * gamePadCount, DATASET_STG, true);431#endif432#if !RETRO_USE_ORIGINAL_CODE433}434#endif435436for (int32 i = 0; i < gamePadCount; ++i) {437char buffer[0x30];438char mappings[0x100];439440sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:name", CONT_P1 + i);441sprintf_s(gamePadMappings[i].name, sizeof(gamePadMappings[i].name), "%s", iniparser_getstring(ini, buffer, 0));442443sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:type", CONT_P1 + i);444gamePadMappings[i].type = iniparser_getint(ini, buffer, 0);445446sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:vendorID", CONT_P1 + i);447gamePadMappings[i].vendorID = iniparser_getint(ini, buffer, 0);448449sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:productID", CONT_P1 + i);450gamePadMappings[i].productID = iniparser_getint(ini, buffer, 0);451452sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:mappingTypes", CONT_P1 + i);453sprintf_s(mappings, sizeof(mappings), "%s", iniparser_getstring(ini, buffer, 0));454455char *tok = strtok(mappings, ", ");456for (int32 b = 0; tok; ++b) {457gamePadMappings[i].buttons[b].mappingType = atoi(tok);458tok = strtok(0, " ,.-");459}460461sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:offsets", CONT_P1 + i);462sprintf_s(mappings, sizeof(mappings), "%s", iniparser_getstring(ini, buffer, 0));463464tok = strtok(mappings, ", ");465for (int32 b = 0; tok; ++b) {466gamePadMappings[i].buttons[b].offset = atoi(tok);467tok = strtok(0, " ,.-");468}469470sprintf_s(buffer, sizeof(buffer), "GamePad Map %d:maskVals", CONT_P1 + i);471sprintf_s(mappings, sizeof(mappings), "%s", iniparser_getstring(ini, buffer, 0));472tok = strtok(mappings, ", ");473for (int32 b = 0; tok; ++b) {474int32 mask = 1;475for (int32 m = 0; m < 18; ++m) {476if (strcmp(buttonNames[m], tok) == 0) {477gamePadMappings[i].buttons[b].maskVal = mask;478break;479}480mask <<= 1;481}482483tok = strtok(0, " ,.-");484}485}486487iniparser_freedict(ini);488}489else {490videoSettings.windowed = true;491videoSettings.bordered = false;492videoSettings.exclusiveFS = true;493videoSettings.vsync = true;494videoSettings.tripleBuffered = false;495videoSettings.shaderSupport = true;496videoSettings.pixWidth = DEFAULT_PIXWIDTH;497videoSettings.fsWidth = 0;498videoSettings.windowWidth = videoSettings.pixWidth * 1;499videoSettings.windowHeight = SCREEN_YSIZE * 1;500videoSettings.fsHeight = 0;501videoSettings.refreshRate = 60;502videoSettings.shaderID = SHADER_NONE;503504engine.streamsEnabled = true;505engine.streamVolume = 1.0f;506engine.soundFXVolume = 1.0f;507engine.devMenu = false;508509#if !RETRO_USE_ORIGINAL_CODE510customSettings.region = -1;511customSettings.confirmButtonFlip = false;512customSettings.xyButtonFlip = false;513customSettings.enableControllerDebugging = false;514customSettings.disableFocusPause = false;515516#if RETRO_REV0U517customSettings.forceScripts = false;518engine.gameReleaseID = 0;519#endif520521sprintf_s(gameLogicName, sizeof(gameLogicName), "Game");522customSettings.username[0] = 0;523524customSettings.maxPixWidth = DEFAULT_PIXWIDTH;525526if (customSettings.region >= 0) {527#if RETRO_REV02528SKU::curSKU.region = customSettings.region;529#else530gameVerInfo.region = customSettings.region;531#endif532}533534engine.confirmFlip = customSettings.confirmButtonFlip;535engine.XYFlip = customSettings.xyButtonFlip;536#else537sprintf_s(gameLogicName, sizeof(gameLogicName), "Game");538#endif539540for (int32 i = CONT_P1; i <= PLAYER_COUNT; ++i) {541controller[i].keyUp.keyMap = defaultKeyMaps[i][KEY_UP];542controller[i].keyDown.keyMap = defaultKeyMaps[i][KEY_DOWN];543controller[i].keyLeft.keyMap = defaultKeyMaps[i][KEY_LEFT];544controller[i].keyRight.keyMap = defaultKeyMaps[i][KEY_RIGHT];545controller[i].keyA.keyMap = defaultKeyMaps[i][KEY_A];546controller[i].keyB.keyMap = defaultKeyMaps[i][KEY_B];547controller[i].keyC.keyMap = defaultKeyMaps[i][KEY_C];548controller[i].keyX.keyMap = defaultKeyMaps[i][KEY_X];549controller[i].keyY.keyMap = defaultKeyMaps[i][KEY_Y];550controller[i].keyZ.keyMap = defaultKeyMaps[i][KEY_Z];551controller[i].keyStart.keyMap = defaultKeyMaps[i][KEY_START];552controller[i].keySelect.keyMap = defaultKeyMaps[i][KEY_SELECT];553}554555SaveSettingsINI(true);556engine.devMenu = LoadDataPack("Data.rsdk", 0, useBuffer);557}558}559560void RSDK::SaveSettingsINI(bool32 writeToFile)561{562// the original only saves this file on windows and "dev", consoles use "options.bin"563// for the decomp, however, we want to save it regardless of platform564#if RETRO_USE_ORIGINAL_CODE565#if RETRO_REV02566if (SKU::curSKU.platform != PLATFORM_PC && SKU::curSKU.platform != PLATFORM_DEV)567return;568#else569if (gameVerInfo.platform != PLATFORM_PC && gameVerInfo.platform != PLATFORM_DEV)570return;571#endif572#endif573574if (changedVideoSettings || writeToFile) {575char pathBuffer[0x100];576sprintf_s(pathBuffer, sizeof(pathBuffer), "%sSettings.ini", SKU::userFileDir);577578dictionary *ini = iniparser_load(pathBuffer);579FileIO *file = fOpen(pathBuffer, "wb");580581// ================582// SIGNATURE583// ================584WriteText(file, "; Retro Engine Config File\n\n");585586// ================587// GAME588// ================589WriteText(file, "[Game]\n");590if (ini) {591if (strcmp(iniparser_getstring(ini, "Game:dataFile", ";unknown;"), ";unknown;") != 0 || (!RETRO_USE_ORIGINAL_CODE && RETRO_REV0U)) {592WriteText(file, "dataFile=%s\n", iniparser_getstring(ini, "Game:dataFile", "Data.rsdk"));593}594595if (strcmp(iniparser_getstring(ini, "Game:devMenu", ";unknown;"), ";unknown;") != 0 || (!RETRO_USE_ORIGINAL_CODE && RETRO_REV0U))596WriteText(file, "devMenu=%s\n", (engine.devMenu ? "y" : "n"));597598#if !RETRO_USE_ORIGINAL_CODE599if (strcmp(iniparser_getstring(ini, "Game:gameLogic", ";unknown;"), ";unknown;") != 0)600WriteText(file, "gameLogic=%s\n", iniparser_getstring(ini, "Game:gameLogic", "Game"));601602WriteText(file, "faceButtonFlip=%s\n", (customSettings.confirmButtonFlip ? "y" : "n"));603// WriteText(file, "confirmButtonFlip=%s\n", (customSettings.confirmButtonFlip ? "y" : "n"));604// WriteText(file, "xyButtonFlip=%s\n", (customSettings.xyButtonFlip ? "y" : "n"));605606if (engine.devMenu)607WriteText(file, "enableControllerDebugging=%s\n", (customSettings.enableControllerDebugging ? "y" : "n"));608609WriteText(file, "; Determines if the engine should pause when window focus is lost or not\n");610WriteText(file, "disableFocusPause=%s\n", (customSettings.disableFocusPause ? "y" : "n"));611612WriteText(file, "; The speed to run the game at while holding backspace. Defaults to x8 speed\n");613WriteText(file, "fastForwardSpeed=%d\n", engine.fastForwardSpeed);614615if (strcmp(iniparser_getstring(ini, "Game:username", ";unknown;"), ";unknown;") != 0)616WriteText(file, "username=%s\n", iniparser_getstring(ini, "Game:username", ""));617618WriteText(file, "; if -1, the game will decide what region to use, if 0 or higher, forces a specific region\n");619WriteText(file, "region=%d\n", customSettings.region);620621#if RETRO_REV0U622WriteText(file, "; Determines if legacy modes are forced to load from the scripts folder instead of bytecode\n");623WriteText(file, "txtScripts=%s\n", (customSettings.forceScripts ? "y" : "n"));624625WriteText(file, "; Determines game type in scripts (0 = Standalone/Original releases, 1 = Origins release)\n");626WriteText(file, "gameType=%d\n", engine.gameReleaseID);627#endif628#endif629}630631#if RETRO_REV02632WriteText(file, "language=%d\n", SKU::curSKU.language);633#else634WriteText(file, "language=%d\n", gameVerInfo.language);635#endif636637// ================638// VIDEO639// ================640WriteText(file, "\n[Video]\n");641WriteText(file, "; NB: Fullscreen Resolution can be explicitly set with values fsWidth and fsHeight\n");642WriteText(file, "; If not listed, fullscreen will just use the desktop resolution\n");643WriteText(file, "windowed=%s\n", (videoSettings.windowed ? "y" : "n"));644WriteText(file, "border=%s\n", (videoSettings.bordered ? "y" : "n"));645WriteText(file, "exclusiveFS=%s\n", (videoSettings.exclusiveFS ? "y" : "n"));646WriteText(file, "vsync=%s\n", (videoSettings.vsync ? "y" : "n"));647WriteText(file, "tripleBuffering=%s\n", (videoSettings.tripleBuffered ? "y" : "n"));648if (ini) {649if (strcmp(iniparser_getstring(ini, "Video:pixWidth", ";unknown;"), ";unknown;") == 0)650WriteText(file, "pixWidth=%d\n", videoSettings.pixWidth);651}652WriteText(file, "winWidth=%d\n", videoSettings.windowWidth);653WriteText(file, "winHeight=%d\n", videoSettings.windowHeight);654if (videoSettings.fsWidth > 0)655WriteText(file, "fsWidth=%d\n", videoSettings.fsWidth);656if (videoSettings.fsHeight > 0)657WriteText(file, "fsHeight=%d\n", videoSettings.fsHeight);658if (videoSettings.refreshRate > 0)659WriteText(file, "refreshRate=%d\n", videoSettings.refreshRate);660661WriteText(file, "shaderSupport=%s\n", (videoSettings.shaderSupport ? "y" : "n"));662WriteText(file, "screenShader=%d\n", videoSettings.shaderID);663664#if !RETRO_USE_ORIGINAL_CODE665WriteText(file, "; Maximum width the screen will be allowed to be. A value of 0 will disable the maximum width\n");666WriteText(file, "maxPixWidth=%d\n", customSettings.maxPixWidth);667#endif668669// ================670// AUDIO671// ================672WriteText(file, "\n[Audio]\n");673WriteText(file, "streamsEnabled=%s\n", (engine.streamsEnabled ? "y" : "n"));674WriteText(file, "streamVolume=%f\n", engine.streamVolume);675WriteText(file, "sfxVolume=%f\n", engine.soundFXVolume);676677// ==========================678// OPTIONS (decomp only)679// ==========================680681// ================682// KEYBOARD MAP683// ================684for (int32 i = 1; i <= PLAYER_COUNT; ++i) {685WriteText(file, "\n[Keyboard Map %d]\n", i);686WriteText(file, "up=0x%x\n", controller[i].keyUp.keyMap);687WriteText(file, "down=0x%x\n", controller[i].keyDown.keyMap);688WriteText(file, "left=0x%x\n", controller[i].keyLeft.keyMap);689WriteText(file, "right=0x%x\n", controller[i].keyRight.keyMap);690WriteText(file, "buttonA=0x%x\n", controller[i].keyA.keyMap);691WriteText(file, "buttonB=0x%x\n", controller[i].keyB.keyMap);692WriteText(file, "buttonC=0x%x\n", controller[i].keyC.keyMap);693WriteText(file, "buttonX=0x%x\n", controller[i].keyX.keyMap);694WriteText(file, "buttonY=0x%x\n", controller[i].keyY.keyMap);695WriteText(file, "buttonZ=0x%x\n", controller[i].keyZ.keyMap);696WriteText(file, "start=0x%x\n", controller[i].keyStart.keyMap);697WriteText(file, "select=0x%x\n", controller[i].keySelect.keyMap);698}699700for (int32 i = 0; i < gamePadCount; ++i) {701WriteText(file, "\n[Keyboard Map %d]\n", i + 1);702WriteText(file, "name=%s\n", gamePadMappings[i].name);703WriteText(file, "type=0x%x\n", gamePadMappings[i].type);704WriteText(file, "vendorID=0x%x\n", gamePadMappings[i].vendorID);705WriteText(file, "productID=0x%x\n", gamePadMappings[i].productID);706707WriteText(file, "mappingTypes=");708for (int32 b = 0; b < 24; ++b) {709WriteText(file, "%d,", gamePadMappings[i].buttons[b].mappingType);710}711WriteText(file, "\n");712WriteText(file, "offsets=");713for (int32 b = 0; b < 24; ++b) {714WriteText(file, "%d,", gamePadMappings[i].buttons[b].offset);715}716WriteText(file, "\n");717WriteText(file, "maskVals=");718for (int32 b = 0; b < 24; ++b) {719if (gamePadMappings[i].buttons[b].maskVal) {720int32 m = 0;721while (true) {722if (1 << m == gamePadMappings[i].buttons[b].maskVal) {723WriteText(file, "%d,", gamePadMappings[i].buttons[b].maskVal);724break;725}726}727728if (m == 18)729WriteText(file, "?,");730}731else {732WriteText(file, "?,");733}734}735WriteText(file, "\n");736}737738iniparser_freedict(ini);739fClose(file);740}741742#if RETRO_USE_MOD_LOADER743if (gamePadCount && gamePadMappings)744delete[] gamePadMappings;745gamePadMappings = NULL;746gamePadCount = 0;747#endif748}749750751