diff --git a/UnX/DLL_VERSION.H b/UnX/DLL_VERSION.H index 48da31d..a453758 100644 --- a/UnX/DLL_VERSION.H +++ b/UnX/DLL_VERSION.H @@ -3,8 +3,8 @@ #define UNX_MAJOR 0 #define UNX_MINOR 8 -#define UNX_BUILD 6 -#define UNX_REV 5 +#define UNX_BUILD 7 +#define UNX_REV 0 diff --git a/UnX/cheat.cpp b/UnX/cheat.cpp index 7b47c2e..2c06e71 100644 --- a/UnX/cheat.cpp +++ b/UnX/cheat.cpp @@ -306,6 +306,12 @@ struct unx_ffx_memory_s { } *ap = nullptr; } ffx; +struct { + DWORD sensor = 0; + DWORD party_ap = 0; + DWORD speed = 0; +} last_changed; + #include #include @@ -378,7 +384,8 @@ UNX_ResumeThreads (std::queue threads) #include "log.h" -float __UNX_speed_mod = 1.0f; +float __UNX_speed_mod = 1.0f; +bool __UNX_skip_cutscenes = false; extern LPVOID __UNX_base_img_addr; @@ -411,6 +418,8 @@ UNX_FFX_AudioSkip (bool bSkip) //SK_GetCommandProcessor ()->ProcessCommandFormatted ("mem t %p %s", pFMODSyncAddr, orig_inst); } + __UNX_skip_cutscenes = bSkip; + VirtualProtect ((LPVOID)pFMODSyncAddr, 3, dwProtect, &dwProtect); UNX_ResumeThreads (tids); @@ -422,6 +431,8 @@ FFX_GameTick_pfn UNX_FFX_GameTick_Original = nullptr; void UNX_SpeedStep (void) { + last_changed.speed = timeGetTime (); + if (__UNX_speed_mod < config.cheat.ffx.max_speed) __UNX_speed_mod *= config.cheat.ffx.speed_step; else @@ -557,6 +568,14 @@ unx::CheatManager::Shutdown (void) #include "log.h" +void +UNX_TogglePartyAP (void) +{ + last_changed.party_ap = timeGetTime (); + + config.cheat.ffx.entire_party_earns_ap = (! config.cheat.ffx.entire_party_earns_ap); +} + void UNX_ToggleFreeLook (void) { @@ -570,6 +589,9 @@ UNX_ToggleFreeLook (void) void UNX_SetSensor (bool state) { + if (config.cheat.ffx.permanent_sensor != state) + last_changed.sensor = timeGetTime (); + config.cheat.ffx.permanent_sensor = state; ffx.debug_flags->permanent_sensor = @@ -582,10 +604,7 @@ UNX_ToggleSensor (void) if (game_type != GAME_FFX) return; - config.cheat.ffx.permanent_sensor = - (! config.cheat.ffx.permanent_sensor); - - UNX_SetSensor (config.cheat.ffx.permanent_sensor); + UNX_SetSensor (! config.cheat.ffx.permanent_sensor); } void @@ -644,8 +663,8 @@ UNX_Quickie (void) (sub_7C8650_pfn)((intptr_t)__UNX_base_img_addr + 0x3C8650); Menu (0x6); - extern bool schedule_load; - schedule_load = true; + extern volatile ULONG schedule_load; + InterlockedExchange (&schedule_load, TRUE); #endif } @@ -687,6 +706,10 @@ UNX_KillMeNow (void) memcpy (live, inst, 2); } + for (int i = 0; i < 8; i++) { + ffx.party [i].vitals.current.HP = 0UL; + } + std::queue suspended_tids = UNX_SuspendAllOtherThreads (); { @@ -706,12 +729,8 @@ UNX_KillMeNow (void) return true; } - for (int i = 0; i < 8; i++) { - ffx.party [i].vitals.current.HP = 0UL; - } - - extern bool queue_death; - queue_death = true; + extern volatile ULONG queue_death; + InterlockedExchange (&queue_death, TRUE); Sleep (33); } break; @@ -801,4 +820,61 @@ UNX_FFX2_UnitTest (void) ffx2.party [i].vitals.current.MP, ffx2.party [i].vitals.max.MP ); } +} + + +std::string +UNX_SummarizeCheats (DWORD dwTime) +{ + std::string summary = ""; + + const DWORD status_duration = 2500UL; + + switch (game_type) + { + case GAME_FFX: + { + if (last_changed.party_ap > dwTime - status_duration) { + summary += "Full Party AP: "; + summary += config.cheat.ffx.entire_party_earns_ap ? + "ON\n" : "OFF\n"; + } + + if (last_changed.sensor > dwTime - status_duration) { + summary += "Permanent Sensor: "; + summary += config.cheat.ffx.permanent_sensor ? + "ON\n" : "OFF\n"; + } + + if (last_changed.speed > dwTime - (status_duration * 2)) { + char szGameSpeed [64] = { '\0' }; + + sprintf ( szGameSpeed, "Game Speed: %4.1fx\n", + __UNX_speed_mod ); + summary += szGameSpeed; + } + + uint8_t* skip = (uint8_t *)((intptr_t)__UNX_base_img_addr + 0x12FBB63 - 0x400000); + + if (ffx.debug_flags->control.camera || *skip || __UNX_skip_cutscenes) { + summary += "SPECIAL MODE: "; + + if (ffx.debug_flags->control.camera) + summary += "(Free Look) "; + + if (*skip) + summary += "(Timestop) "; + + if (__UNX_skip_cutscenes) + summary += "(Cutscene Skip) "; + + summary += "\n"; + } + } break; + + default: + break; + } + + return summary; } \ No newline at end of file diff --git a/UnX/input.cpp b/UnX/input.cpp index 0cb0deb..469b444 100644 --- a/UnX/input.cpp +++ b/UnX/input.cpp @@ -533,7 +533,8 @@ SK_UNX_PluginKeyPress ( BOOL Control, } else if (vkCode == 'A') { - config.cheat.ffx.entire_party_earns_ap = (! config.cheat.ffx.entire_party_earns_ap); + extern void UNX_TogglePartyAP (void); + UNX_TogglePartyAP (); } else if (vkCode == 'V') { diff --git a/UnX/window.cpp b/UnX/window.cpp index c131b7e..00bcd1d 100644 --- a/UnX/window.cpp +++ b/UnX/window.cpp @@ -223,8 +223,8 @@ typedef LRESULT (CALLBACK *DetourWindowProc_pfn)( _In_ HWND hWnd, DetourWindowProc_pfn DetourWindowProc_Original = nullptr; -bool schedule_load = false; -bool queue_death = false; +volatile ULONG schedule_load = FALSE; +volatile ULONG queue_death = FALSE; bool shutting_down = false; bool last_active = unx::window.active; @@ -515,6 +515,11 @@ DXGISwap_ResizeBuffers_Detour ( typedef void (WINAPI *SK_BeginBufferSwap_pfn)(void); SK_BeginBufferSwap_pfn SK_BeginBufferSwap_Original = nullptr; +typedef BOOL (WINAPI *SKX_DrawExternalOSD_pfn)(const char* szAppName, const char* szText); +SKX_DrawExternalOSD_pfn SKX_DrawExternalOSD = nullptr; + +extern std::string UNX_SummarizeCheats (DWORD dwTime); + void WINAPI SK_BeginBufferSwap_Detour (void) @@ -528,11 +533,31 @@ SK_BeginBufferSwap_Detour (void) dll_log->Log (L" !!! Unexpected Lack of SK_BufferSwap_Override in dxgi.dll !!! "); } - if (queue_death) { - queue_death = false; - + if (InterlockedCompareExchange (&queue_death, FALSE, TRUE)) { SK_GetCommandProcessor ()->ProcessCommandLine ("mem b D2A8E2 2"); } + + if (SKX_DrawExternalOSD != nullptr) { + static bool first_frame = true; + static bool draw_osd_toggle = true; + static DWORD first_frame_time = timeGetTime (); + + DWORD now = timeGetTime (); + + std::string osd_out = ""; + + if (draw_osd_toggle) { + if (now - first_frame_time < 5000) { + osd_out += "Press Ctrl + Shift + O to toggle OSD\n\n"; + } else { + draw_osd_toggle = false; + } + } + + osd_out += UNX_SummarizeCheats (now); + + SKX_DrawExternalOSD ("UnX Status", osd_out.c_str ()); + } } void @@ -554,6 +579,14 @@ UNX_InstallWindowHook (HWND hWnd) "DXGISwap_ResizeBuffers_Override", DXGISwap_ResizeBuffers_Detour, (LPVOID *)&DXGISwap_ResizeBuffers_Original ); + + HMODULE hModInject = GetModuleHandleW (config.system.injector.c_str ()); + + SKX_DrawExternalOSD = + (SKX_DrawExternalOSD_pfn)GetProcAddress ( + hModInject, + "SKX_DrawExternalOSD" + ); } diff --git a/version.ini b/version.ini index e3c07b4..2efba95 100644 --- a/version.ini +++ b/version.ini @@ -1,16 +1,16 @@ [Version.Latest] -Title="Untitled" Project X (v 0.8.6.5) +Title="Untitled" Project X (v 0.8.7) BranchDescription=Default branch; fewer updates but stable. -Description=Fix for FFX booster functions :: RTFM to turn OSD OFF - TL;DR: Ctrl + Shift + O -ReleaseNotes=https://github.com/Kaldaien/UnX/releases/tag/unx_086 -InstallPackage=UNX_0_8_6_5,23 +Description=Adds FFX Status Indicator (Sensor/Gamespeed/etc.) to OSD +ReleaseNotes=https://github.com/Kaldaien/UnX/releases/tag/unx_087 +InstallPackage=UNX_0_8_7,24 [Version.Testing] -Title="Untitled" Project X (v 0.8.4) +Title="Untitled" Project X (v 0.8.7) BranchDescription=Latest Test Release (0.8.x) -Description=Suspends background threads during initialization -ReleaseNotes=https://github.com/Kaldaien/UnX/releases/tag/unx_084 -InstallPackage=UNX_0_8_4,16 +Description=Adds FFX Status Indicator (Sensor/Gamespeed/etc.) to OSD +ReleaseNotes=https://github.com/Kaldaien/UnX/releases/tag/unx_087 +InstallPackage=UNX_0_8_7,24 [Version.Compatibility] Title="Untitled" Project X (v 0.7.3) @@ -19,6 +19,9 @@ Description=Adds Keyboard Soft Reset Support (Ctrl + Shift + Backspace) ReleaseNotes=https://github.com/Kaldaien/UnX/releases/tag/unx_073 InstallPackage=UNX_0_7_3,4 +[Archive.UNX_0_8_7] +URL=https://github.com/Kaldaien/UnX/releases/download/unx_087/UnX.7z + [Archive.UNX_0_8_6_5] URL=https://github.com/Kaldaien/UnX/releases/download/unx_086/UnX_0_8_6_5.7z