From 69f0d5254d2253c6c83bce7188ce15f8be3b145d Mon Sep 17 00:00:00 2001 From: MainMemory Date: Tue, 8 Aug 2017 00:46:41 -0500 Subject: [PATCH] Updating to VS2017, adding support for parsing level and character ids by name. --- sadx-mod-loader | 2 +- sadx-test-spawn.sln | 8 +-- sadx-test-spawn/mod.cpp | 91 +++++++++++++++++++++++-- sadx-test-spawn/sadx-test-spawn.vcxproj | 6 +- 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/sadx-mod-loader b/sadx-mod-loader index 3daac0f..9b0ae88 160000 --- a/sadx-mod-loader +++ b/sadx-mod-loader @@ -1 +1 @@ -Subproject commit 3daac0f1319fef788aafb7b7397defa65cabfde0 +Subproject commit 9b0ae880efbc97849208c107b943fff31c921177 diff --git a/sadx-test-spawn.sln b/sadx-test-spawn.sln index 2a86a40..8b89f0f 100644 --- a/sadx-test-spawn.sln +++ b/sadx-test-spawn.sln @@ -1,22 +1,18 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sadx-test-spawn", "sadx-test-spawn\sadx-test-spawn.vcxproj", "{C2E5E466-38DD-41FC-B13D-64680D2C86FE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Debug|x64.ActiveCfg = Debug|Win32 {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Debug|x86.ActiveCfg = Debug|Win32 {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Debug|x86.Build.0 = Debug|Win32 - {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Release|x64.ActiveCfg = Release|Win32 {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Release|x86.ActiveCfg = Release|Win32 {C2E5E466-38DD-41FC-B13D-64680D2C86FE}.Release|x86.Build.0 = Release|Win32 EndGlobalSection diff --git a/sadx-test-spawn/mod.cpp b/sadx-test-spawn/mod.cpp index ad060be..7d4d3c1 100644 --- a/sadx-test-spawn/mod.cpp +++ b/sadx-test-spawn/mod.cpp @@ -3,8 +3,12 @@ #include #include // for CommandLineToArgvW #include +#include +#include +using std::wstring; +using std::unordered_map; -constexpr auto loc_40C318 = (const void*)0x0040C318; +auto loc_40C318 = (const void*)0x0040C318; __declspec(naked) void ForceTrialMode() { @@ -15,6 +19,79 @@ __declspec(naked) void ForceTrialMode() } } +static const unordered_map levelidsnamemap = { + { L"hedgehoghammer", LevelIDs_HedgehogHammer }, + { L"emeraldcoast", LevelIDs_EmeraldCoast }, + { L"windyvalley", LevelIDs_WindyValley }, + { L"twinklepark", LevelIDs_TwinklePark }, + { L"speedhighway", LevelIDs_SpeedHighway }, + { L"redmountain", LevelIDs_RedMountain }, + { L"skydeck", LevelIDs_SkyDeck }, + { L"lostworld", LevelIDs_LostWorld }, + { L"icecap", LevelIDs_IceCap }, + { L"casinopolis", LevelIDs_Casinopolis }, + { L"finalegg", LevelIDs_FinalEgg }, + { L"hotshelter", LevelIDs_HotShelter }, + { L"chaos0", LevelIDs_Chaos0 }, + { L"chaos2", LevelIDs_Chaos2 }, + { L"chaos4", LevelIDs_Chaos4 }, + { L"chaos6", LevelIDs_Chaos6 }, + { L"perfectchaos", LevelIDs_PerfectChaos }, + { L"egghornet", LevelIDs_EggHornet }, + { L"eggwalker", LevelIDs_EggWalker }, + { L"eggviper", LevelIDs_EggViper }, + { L"zero", LevelIDs_Zero }, + { L"e101", LevelIDs_E101 }, + { L"e101r", LevelIDs_E101R }, + { L"stationsquare", LevelIDs_StationSquare }, + { L"eggcarrieroutside", LevelIDs_EggCarrierOutside }, + { L"eggcarrierinside", LevelIDs_EggCarrierInside }, + { L"mysticruins", LevelIDs_MysticRuins }, + { L"past", LevelIDs_Past }, + { L"twinklecircuit", LevelIDs_TwinkleCircuit }, + { L"skychase1", LevelIDs_SkyChase1 }, + { L"skychase2", LevelIDs_SkyChase2 }, + { L"sandhill", LevelIDs_SandHill }, + { L"ssgarden", LevelIDs_SSGarden }, + { L"ecgarden", LevelIDs_ECGarden }, + { L"mrgarden", LevelIDs_MRGarden }, + { L"chaorace", LevelIDs_ChaoRace } +}; + +static uint8_t ParseLevelID(const wstring &str) +{ + wstring str2 = str; + std::transform(str2.begin(), str2.end(), str2.begin(), ::towlower); + auto lv = levelidsnamemap.find(str2); + if (lv != levelidsnamemap.end()) + return lv->second; + else + return (uint8_t)wcstol(str.c_str(), nullptr, 10); +} + +static const unordered_map charnamemap = { + { L"sonic", Characters_Sonic }, + { L"eggman", Characters_Eggman }, + { L"tails", Characters_Tails }, + { L"knuckles", Characters_Knuckles }, + { L"tikal", Characters_Tikal }, + { L"amy", Characters_Amy }, + { L"gamma", Characters_Gamma }, + { L"big", Characters_Big }, + { L"metalsonic", Characters_MetalSonic } +}; + +static uint8_t ParseCharacterID(const wstring &str) +{ + wstring s = str; + transform(s.begin(), s.end(), s.begin(), ::towlower); + auto ch = charnamemap.find(s); + if (ch != charnamemap.end()) + return ch->second; + else + return (uint8_t)wcstol(str.c_str(), nullptr, 10); +} + extern "C" { __declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer }; @@ -29,13 +106,13 @@ extern "C" // Prevents CurrentCharacter from being overwritten. There could be other side effects, // but there are none that I've noticed thus far. - WriteData((void*)0x00415007, 0x90i8, 5); + WriteData<5>((void*)0x00415007, 0x90i8); for (int i = 1; i < argc; i++) { if (!wcscmp(argv[i], L"--level") || !wcscmp(argv[i], L"-l")) { - CurrentLevel = _wtoi(argv[++i]); + CurrentLevel = ParseLevelID(argv[++i]); PrintDebug("Loading level: %d\n", CurrentLevel); level_set = true; } @@ -47,7 +124,13 @@ extern "C" } else if (!wcscmp(argv[i], L"--character") || !wcscmp(argv[i], L"-c")) { - CurrentCharacter = _wtoi(argv[++i]); + auto ch = ParseCharacterID(argv[++i]); + if (ch == Characters_MetalSonic) + { + MetalSonicFlag = 1; + ch = 0; + } + CurrentCharacter = ch; PrintDebug("Loading character: %d\n", CurrentCharacter); } else if (!wcscmp(argv[i], L"--position") || !wcscmp(argv[i], L"-p")) diff --git a/sadx-test-spawn/sadx-test-spawn.vcxproj b/sadx-test-spawn/sadx-test-spawn.vcxproj index 07a481b..13329d2 100644 --- a/sadx-test-spawn/sadx-test-spawn.vcxproj +++ b/sadx-test-spawn/sadx-test-spawn.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -20,13 +20,13 @@ DynamicLibrary true - v140_xp + v141_xp Unicode DynamicLibrary false - v140_xp + v141_xp true Unicode