Skip to content

Commit

Permalink
Eliminated netcode from Hatsune Miku
Browse files Browse the repository at this point in the history
Added complete framerate unlock to Hatsune Miku
  • Loading branch information
Kaldaien committed May 31, 2022
1 parent 2c17e38 commit ce33f96
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 13 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.txt
@@ -1,4 +1,11 @@
22.5.31-NOCEGUI
22.6.1-NOCEGUI
==============
+ Separate High FPS mod for Hatsune Miku no longer required, just set SK's framerate limit
* Menus will be locked to 60 FPS or your limit (whichever is lowest) for proper gameplay
+ Installing Special K locally for Hatsune Miku disables its stutter inducing network code
* This code is unrelated to leaderboards.

22.5.31-NOCEGUI
===============
+ Enabled SK's dynamic spinlock feature in Hatsune Miku to minimize audio/render desync
+ Configured default settings for Hatsune Miku to minimize latency at 60 FPS w/o Latent Sync
Expand Down
4 changes: 2 additions & 2 deletions include/SpecialK/DLL_VERSION.H
@@ -1,8 +1,8 @@
#pragma once

#define SK_YEAR 22
#define SK_MONTH 5
#define SK_DATE 31
#define SK_MONTH 6
#define SK_DATE 1
#define SK_REV_N 0
#define SK_REV 0

Expand Down
3 changes: 3 additions & 0 deletions include/SpecialK/plugin/plugin_mgr.h
Expand Up @@ -150,6 +150,9 @@ void SK_YS8_InitPlugin (void);
void SK_ER_InitPlugin (void);
void SK_ELEX2_InitPlugin (void);

void __stdcall
SK_HatsuneMiku_BeginFrame (void);

#else
HRESULT __stdcall
SK_SOM_PresentFirstFrame (IDXGISwapChain *, UINT, UINT);
Expand Down
32 changes: 32 additions & 0 deletions src/config.cpp
Expand Up @@ -71,6 +71,26 @@ UINT SK_RecursiveMove ( const wchar_t* wszOrigDir,
const wchar_t* wszDestDir,
bool replace );


using InternetFreeProxyInfoList_pfn = void (WINAPI *)(void *);
InternetFreeProxyInfoList_pfn
InternetFreeProxyInfoList_Original = nullptr;

void
WINAPI
InternetFreeProxyInfoList_Detour (void* pDontCare)
{
if (SK_GetCurrentGameID () != SK_GAME_ID::HatsuneMikuDIVAMegaMix)
InternetFreeProxyInfoList_Original (pDontCare);

else
{
MessageBox (NULL, L"Bye Bye", L"Heh", MB_OK);

TerminateThread (GetCurrentThread (), 0x0);
}
}

SK_GAME_ID
__stdcall
SK_GetCurrentGameID (void)
Expand Down Expand Up @@ -2242,6 +2262,7 @@ auto DeclKeybind =
config.threads.enable_dynamic_spinlocks = true;
} break;

#ifdef _M_AMD64
case SK_GAME_ID::HatsuneMikuDIVAMegaMix:
{
config.render.dxgi.ignore_thread_flags = true;
Expand Down Expand Up @@ -2272,9 +2293,20 @@ auto DeclKeybind =
memcpy ( (LPVOID) win_ver_check_addr, "\x90\x90\x90\x90\x90", 5);
VirtualProtect( (LPVOID)(win_ver_check_addr-3), 8, dwOrigProt,
&dwOrigProt);

plugin_mgr->begin_frame_fns.emplace (
SK_HatsuneMiku_BeginFrame
);
}
}

extern void SK_WinSock_GoOffline (void);

SK_MinHook_Init ();
SK_WinSock_GoOffline ();
SK_ApplyQueuedHooks ();
} break;
#endif

case SK_GAME_ID::Launcher:
{
Expand Down
24 changes: 14 additions & 10 deletions src/plugins/sekiro.cpp
Expand Up @@ -752,6 +752,18 @@ SK_Sekiro_PlugInCfg (void)
}


void SK_WinSock_GoOffline (void)
{
SK_CreateDLLHook2 (L"Ws2_32.dll", "getnameinfo",
getnameinfo_Detour, (void **)&getnameinfo_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSAWaitForMultipleEvents",
WSAWaitForMultipleEvents_Detour, (void **)&WSAWaitForMultipleEvents_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSASocketW",
WSASocketW_Detour, (void **)&WSASocketW_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSAStartup",
WSAStartup_Detour, (void **)&WSAStartup_Original);
}

void
SK_Sekiro_InitPlugin (void)
{
Expand All @@ -775,14 +787,6 @@ SK_Sekiro_InitPlugin (void)
disable_netcode->store (true);
}

SK_CreateDLLHook2 (L"Ws2_32.dll", "getnameinfo",
getnameinfo_Detour, (void **)&getnameinfo_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSAWaitForMultipleEvents",
WSAWaitForMultipleEvents_Detour, (void **)&WSAWaitForMultipleEvents_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSASocketW",
WSASocketW_Detour, (void **)&WSASocketW_Original);
SK_CreateDLLHook2 (L"Ws2_32.dll", "WSAStartup",
WSAStartup_Detour, (void **)&WSAStartup_Original);

SK_ApplyQueuedHooks ();
SK_WinSock_GoOffline ();
SK_ApplyQueuedHooks ();
}
40 changes: 40 additions & 0 deletions src/plugins/unclassified.cpp
Expand Up @@ -1265,4 +1265,44 @@ SK_ACO_PlugInCfg (void)

return true;
}
#endif


#ifdef _M_AMD64
void __stdcall
SK_HatsuneMiku_BeginFrame (void)
{
// Skip a few frames before doing the pointer scan
//
if (SK_GetFramesDrawn () < 500)
return;

extern float __target_fps;

static uint32_t* puiGameLimit =
(uint32_t *)((uintptr_t)SK_Debug_GetImageBaseAddr () + 0x14B2A78);

static auto menu_flag_addr = // Pointer at DivaMegaMix.exe+114EFF8h, Offset=780h
*(uintptr_t *)((uintptr_t)SK_Debug_GetImageBaseAddr () + 0x114EFF8) + 0x780;

// Menu is Active, 60 FPS (or lower) framerate cap is required
if ((*(uint8_t *)menu_flag_addr) & 0x1)
{
__target_fps =
std::min ( 60.0f, config.render.framerate.target_fps <= 0.0f ?
60.0f : config.render.framerate.target_fps );

*puiGameLimit = 60;
}

// Gameplay: Game needs no cap
else
{
__target_fps =
config.render.framerate.target_fps;

if ( __target_fps > 0.0f)
*puiGameLimit = static_cast <uint32_t> (__target_fps);
}
}
#endif

0 comments on commit ce33f96

Please sign in to comment.