forked from Popn_Tools/popnhax
enhanced_polling_stats and audio_offset
This commit is contained in:
parent
c45d6c8d75
commit
8b105d1e50
153
dist/popnhax/popnhax.xml
vendored
153
dist/popnhax/popnhax.xml
vendored
@ -1,93 +1,108 @@
|
|||||||
<?xml version='1.0' encoding='shift-jis'?>
|
<?xml version='1.0' encoding='shift-jis'?>
|
||||||
<popnhax>
|
<popnhax>
|
||||||
<!-- Hidden+ setting (press 0 for advanced options) is now an offset adjust (negative means you have to hit earlier) -->
|
<!-- Classic patches -->
|
||||||
<hidden_is_offset __type="bool">0</hidden_is_offset>
|
<!-- Prevent crash on boot when using a different default audio source (aka HDMI audio patch) -->
|
||||||
<!-- Display offset adjust on score result screen (requires hidden_is_offset, won't be sent over network) -->
|
<audio_source_fix __type="bool">0</audio_source_fix>
|
||||||
<show_offset __type="bool">0</show_offset>
|
<!-- Prevent Windows volume from being reset on boot -->
|
||||||
<!-- Display fast/slow counter on result screen even on judge+ off/lost/panic -->
|
<unset_volume __type="bool">0</unset_volume>
|
||||||
<show_fast_slow __type="bool">0</show_fast_slow>
|
<!-- Force booting directly into event mode -->
|
||||||
|
<event_mode __type="bool">0</event_mode>
|
||||||
|
<!-- Remove the timer completely without event mode -->
|
||||||
|
<remove_timer __type="bool">0</remove_timer>
|
||||||
|
<!-- or Freeze the timer at 10 seconds after counting down -->
|
||||||
|
<freeze_timer __type="bool">0</freeze_timer>
|
||||||
|
<!-- Force skip menu and long note tutorials without a card -->
|
||||||
|
<skip_tutorials __type="bool">0</skip_tutorials>
|
||||||
|
<!-- Force full options to display (useful when no numpad is available) -->
|
||||||
|
<force_full_opt __type="bool">0</force_full_opt>
|
||||||
|
|
||||||
<!-- Premium free (unlimited stages per credit) -->
|
<!-- Stage management -->
|
||||||
<pfree __type="bool">0</pfree>
|
<!-- Premium free (unlimited stages per credit) -->
|
||||||
|
<pfree __type="bool">0</pfree>
|
||||||
|
|
||||||
<!-- Press numpad 9 in song to retire instantly, or on result screen to leave game session (thank you for playing) -->
|
<!-- Press numpad 9 in song to retire instantly, or on result screen to leave game session (thank you for playing) -->
|
||||||
<!-- quick_retire with pfree also enables quick retry: hold numpad 7 to retry -->
|
<!-- quick_retire with pfree also enables quick retry: hold numpad 7 to retry -->
|
||||||
<quick_retire __type="bool">0</quick_retire>
|
<quick_retire __type="bool">0</quick_retire>
|
||||||
|
|
||||||
<!-- Bring back score challenge in the game for servers supporting it (only for kaimei onwards) -->
|
<!-- Network features -->
|
||||||
<score_challenge __type="bool">0</score_challenge>
|
<!-- Bring back score challenge in the game for servers supporting it (only for kaimei onwards) -->
|
||||||
|
<score_challenge __type="bool">0</score_challenge>
|
||||||
|
|
||||||
<!-- HD timing for pcb_type=0 -->
|
<!-- Visual offset -->
|
||||||
<force_hd_timing __type="bool">0</force_hd_timing>
|
<!-- Hidden+ setting (press 0 for advanced options) is now a visual offset adjust (negative means you have to hit earlier) -->
|
||||||
<!-- HD resolution for pcb_type=0 (0: no, 1: keep texts as on HD cab (smaller LCD mod), 2: center texts (32" LCD mod) ) -->
|
<hidden_is_offset __type="bool">0</hidden_is_offset>
|
||||||
<force_hd_resolution __type="u8">0</force_hd_resolution>
|
<!-- Display offset adjust on score result screen (requires hidden_is_offset, won't be sent over network) -->
|
||||||
|
<show_offset __type="bool">0</show_offset>
|
||||||
|
<!-- Display fast/slow counter on result screen even on judge+ off/lost/panic -->
|
||||||
|
<show_fast_slow __type="bool">0</show_fast_slow>
|
||||||
|
|
||||||
<!-- Force unlock music, charts, and characters -->
|
<!-- Audio offset -->
|
||||||
<force_unlocks __type="bool">0</force_unlocks>
|
<!-- Offset the audio by x ms (negative plays audio earlier). This will disable keysounds -->
|
||||||
<!-- Force unlock deco parts (avoid using this on later games without deco) -->
|
<audio_offset __type="s8">0</audio_offset>
|
||||||
<force_unlock_deco __type="bool">0</force_unlock_deco>
|
|
||||||
|
|
||||||
<!-- Prevent crash on boot when using a different default audio source (aka HDMI audio patch) -->
|
<!-- Input polling -->
|
||||||
<audio_source_fix __type="bool">0</audio_source_fix>
|
<!-- 1000Hz polling rate (no more shifting timing windows/magic bpm, consistent scoring independently of framerate) -->
|
||||||
<!-- Prevent Windows volume from being reset on boot -->
|
<enhanced_polling __type="bool">0</enhanced_polling>
|
||||||
<unset_volume __type="bool">0</unset_volume>
|
<!-- button release debounce time in ms (for enhanced_polling only) -->
|
||||||
<!-- Force booting directly into event mode -->
|
<debounce __type="u8">5</debounce>
|
||||||
<event_mode __type="bool">0</event_mode>
|
<!-- 1000Hz polling stats (display onscreen info to check performance on your system) -->
|
||||||
<!-- Remove the timer completely without event mode -->
|
<enhanced_polling_stats __type="bool">0</enhanced_polling_stats>
|
||||||
<remove_timer __type="bool">0</remove_timer>
|
|
||||||
<!-- or Freeze the timer at 10 seconds after counting down -->
|
<!-- Databases -->
|
||||||
<freeze_timer __type="bool">0</freeze_timer>
|
<!-- Force unlock music, charts, and characters -->
|
||||||
<!-- Force skip menu and long note tutorials without a card -->
|
<force_unlocks __type="bool">0</force_unlocks>
|
||||||
<skip_tutorials __type="bool">0</skip_tutorials>
|
<!-- Force unlock deco parts (avoid using this on later games without deco) -->
|
||||||
<!-- Force full options to display (useful when no numpad is available) -->
|
<force_unlock_deco __type="bool">0</force_unlock_deco>
|
||||||
<force_full_opt __type="bool">0</force_full_opt>
|
|
||||||
|
<!-- Enable database modifications (omnimix, custom tracks) -->
|
||||||
|
<patch_db __type="bool">0</patch_db>
|
||||||
|
<!-- Auto select patch file from data_mods folder (will detect datecode from ea3-config or force_datecode option) -->
|
||||||
|
<patch_xml_auto __type="bool">1</patch_xml_auto>
|
||||||
|
<!-- Manually set XML file containing patches (requires patch_xml_auto to be disabled) -->
|
||||||
|
<patch_xml_filename __type="str"></patch_xml_filename>
|
||||||
|
|
||||||
|
<!-- LCD mod on CRT cabs -->
|
||||||
|
<!-- HD timing for pcb_type=0 -->
|
||||||
|
<force_hd_timing __type="bool">0</force_hd_timing>
|
||||||
|
<!-- HD resolution for pcb_type=0 (0: no, 1: keep texts as on HD cab (smaller LCD mod), 2: center texts (32" LCD mod) ) -->
|
||||||
|
<force_hd_resolution __type="u8">0</force_hd_resolution>
|
||||||
|
|
||||||
<!-- Enable database modifications (omnimix, custom tracks) -->
|
|
||||||
<patch_db __type="bool">0</patch_db>
|
|
||||||
<!-- Auto select patch file from data_mods folder (will detect datecode from ea3-config or force_datecode option) -->
|
|
||||||
<patch_xml_auto __type="bool">1</patch_xml_auto>
|
|
||||||
<!-- Manually set XML file containing patches (requires patch_xml_auto to be disabled) -->
|
|
||||||
<patch_xml_filename __type="str"></patch_xml_filename>
|
|
||||||
<!-- END OF USER SETTINGS -->
|
<!-- END OF USER SETTINGS -->
|
||||||
|
|
||||||
<!-- EXPERIMENTAL PATCHES (USE AT OWN RISK, PREFERABLY OFFLINE, MIGHT INTERFERE WITH OTHER OPTIONS) -->
|
<!-- EXPERIMENTAL PATCHES (USE AT OWN RISK, PREFERABLY OFFLINE, MIGHT INTERFERE WITH OTHER OPTIONS) -->
|
||||||
<!-- Enable practice mode menu (r-ran, constant chart speed, slow motion, etc...) -->
|
<!-- Enable practice mode menu (r-ran, constant chart speed, slow motion, etc...) -->
|
||||||
<practice_mode __type="bool">0</practice_mode>
|
<practice_mode __type="bool">0</practice_mode>
|
||||||
|
|
||||||
<!-- DEBUG OPTIONS FOLLOW (GENERALLY SHOULD NOT BE CHANGED UNLESS YOU KNOW WHAT YOU'RE DOING) -->
|
<!-- DEBUG OPTIONS FOLLOW (GENERALLY SHOULD NOT BE CHANGED UNLESS YOU KNOW WHAT YOU'RE DOING) -->
|
||||||
|
|
||||||
<!-- Datecode and Multiboot -->
|
<!-- Datecode and Multiboot -->
|
||||||
<!-- Force a different datecode than the one found in ea3-config (yyyymmdd00) -->
|
<!-- Force a different datecode than the one found in ea3-config (yyyymmdd00) -->
|
||||||
<force_datecode __type="str"></force_datecode>
|
<force_datecode __type="str"></force_datecode>
|
||||||
<!-- Also apply force_datecode to network packets -->
|
<!-- Also apply force_datecode to network packets -->
|
||||||
<network_datecode __type="bool">1</network_datecode>
|
<network_datecode __type="bool">1</network_datecode>
|
||||||
<!-- Disable multiboot auto conf tuning (which takes place when using popn22_yyyymmddrr.dll format and an xml without force_datecode option) -->
|
<!-- Disable multiboot auto conf tuning (which takes place when using popn22_yyyymmddrr.dll format and an xml without force_datecode option) -->
|
||||||
<disable_multiboot __type="bool">0</disable_multiboot>
|
<disable_multiboot __type="bool">0</disable_multiboot>
|
||||||
|
|
||||||
<!-- Timing and lanes -->
|
<!-- Timing and lanes -->
|
||||||
<!-- Disable keysounds -->
|
<!-- Automatically play keysounds during songs -->
|
||||||
<disable_keysounds __type="bool">0</disable_keysounds>
|
<disable_keysounds __type="bool">0</disable_keysounds>
|
||||||
<!-- Offset the keysounds by x ms (negative is earlier). With disable_keysounds, becomes an audio offset -->
|
<!-- Offset the keysounds by x ms (negative is earlier). With disable_keysounds, becomes an audio offset -->
|
||||||
<keysound_offset __type="s8">0</keysound_offset>
|
<keysound_offset __type="s8">0</keysound_offset>
|
||||||
<!-- Adjust pop-kun and beam brightness (won't affect long popkuns) -->
|
<!-- Adjust pop-kun and beam brightness (won't affect long popkuns) -->
|
||||||
<beam_brightness __type="s8">0</beam_brightness>
|
<beam_brightness __type="s8">0</beam_brightness>
|
||||||
<!-- Disable the builtin frame limiter (faster/smoother animations at 120fps+) -->
|
<!-- Disable the builtin frame limiter (faster/smoother animations at 120fps+) -->
|
||||||
<fps_uncap __type="bool">0</fps_uncap>
|
<fps_uncap __type="bool">0</fps_uncap>
|
||||||
<!-- 1000Hz polling rate (no more shifting timing windows/magic bpm, consistent scoring independently of framerate) -->
|
|
||||||
<enhanced_polling __type="bool">0</enhanced_polling>
|
|
||||||
<!-- button release debounce time in ms (for enhanced_polling only) -->
|
|
||||||
<debounce __type="u8">5</debounce>
|
|
||||||
|
|
||||||
<!-- Song db patches -->
|
<!-- Song db patches -->
|
||||||
<!-- Force the newly created buffers to be the same size as the original buffers -->
|
<!-- Force the newly created buffers to be the same size as the original buffers -->
|
||||||
<disable_expansions __type="bool">0</disable_expansions>
|
<disable_expansions __type="bool">0</disable_expansions>
|
||||||
<!-- Copy the new table information over top the old tables (automatically enables disable_expansions) -->
|
<!-- Copy the new table information over top the old tables (automatically enables disable_expansions) -->
|
||||||
<disable_redirection __type="bool">0</disable_redirection>
|
<disable_redirection __type="bool">0</disable_redirection>
|
||||||
|
|
||||||
<!-- Translation -->
|
<!-- Translation -->
|
||||||
<!-- Disable .dict string replacements and .ips patches -->
|
<!-- Disable .dict string replacements and .ips patches -->
|
||||||
<disable_translation __type="bool">0</disable_translation>
|
<disable_translation __type="bool">0</disable_translation>
|
||||||
<!-- Dump applied translations and dll runtime data to help debug translation -->
|
<!-- Dump applied translations and dll runtime data to help debug translation -->
|
||||||
<translation_debug __type="bool">0</translation_debug>
|
<translation_debug __type="bool">0</translation_debug>
|
||||||
|
|
||||||
</popnhax>
|
</popnhax>
|
||||||
|
@ -31,6 +31,7 @@ struct popnhax_config {
|
|||||||
char patch_xml_filename[MAX_PATH];
|
char patch_xml_filename[MAX_PATH];
|
||||||
char force_datecode[11];
|
char force_datecode[11];
|
||||||
bool network_datecode;
|
bool network_datecode;
|
||||||
|
int8_t audio_offset;
|
||||||
bool disable_keysounds;
|
bool disable_keysounds;
|
||||||
int8_t keysound_offset;
|
int8_t keysound_offset;
|
||||||
int8_t beam_brightness;
|
int8_t beam_brightness;
|
||||||
@ -39,6 +40,7 @@ struct popnhax_config {
|
|||||||
bool translation_debug;
|
bool translation_debug;
|
||||||
bool enhanced_polling;
|
bool enhanced_polling;
|
||||||
uint8_t debounce;
|
uint8_t debounce;
|
||||||
|
bool enhanced_polling_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,7 +37,6 @@ FILE *g_log_fp = NULL;
|
|||||||
|
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#define POLLING_DEBUG 1
|
|
||||||
|
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
double g_multiplier = 1.;
|
double g_multiplier = 1.;
|
||||||
@ -145,6 +144,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, disable_keysou
|
|||||||
"/popnhax/disable_keysounds")
|
"/popnhax/disable_keysounds")
|
||||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, keysound_offset,
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, keysound_offset,
|
||||||
"/popnhax/keysound_offset")
|
"/popnhax/keysound_offset")
|
||||||
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, audio_offset,
|
||||||
|
"/popnhax/audio_offset")
|
||||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, beam_brightness,
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_S8, struct popnhax_config, beam_brightness,
|
||||||
"/popnhax/beam_brightness")
|
"/popnhax/beam_brightness")
|
||||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, fps_uncap,
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, fps_uncap,
|
||||||
@ -157,6 +158,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, enhanced_polli
|
|||||||
"/popnhax/enhanced_polling")
|
"/popnhax/enhanced_polling")
|
||||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_U8, struct popnhax_config, debounce,
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_U8, struct popnhax_config, debounce,
|
||||||
"/popnhax/debounce")
|
"/popnhax/debounce")
|
||||||
|
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, enhanced_polling_stats,
|
||||||
|
"/popnhax/enhanced_polling_stats")
|
||||||
PSMAP_END
|
PSMAP_END
|
||||||
|
|
||||||
enum BufferIndexes {
|
enum BufferIndexes {
|
||||||
@ -1915,18 +1918,12 @@ static bool patch_add_to_base_offset(int8_t delta) {
|
|||||||
bool g_enhanced_poll_ready = false;
|
bool g_enhanced_poll_ready = false;
|
||||||
int (*usbPadRead)(uint32_t*);
|
int (*usbPadRead)(uint32_t*);
|
||||||
|
|
||||||
#if POLLING_DEBUG >=1
|
uint32_t g_poll_rate_avg = 0;
|
||||||
FILE *debug_fp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t g_last_button_state = 0;
|
uint32_t g_last_button_state = 0;
|
||||||
uint8_t g_debounce = 0;
|
uint8_t g_debounce = 0;
|
||||||
int32_t g_button_state[9] = {0};
|
int32_t g_button_state[9] = {0};
|
||||||
static unsigned int __stdcall enhanced_polling_proc(void *ctx)
|
static unsigned int __stdcall enhanced_polling_stats_proc(void *ctx)
|
||||||
{
|
{
|
||||||
#if POLLING_DEBUG >=1
|
|
||||||
debug_fp = fopen("polling.log", "w");
|
|
||||||
#endif
|
|
||||||
HMODULE hinstLib = GetModuleHandleA("ezusb.dll");
|
HMODULE hinstLib = GetModuleHandleA("ezusb.dll");
|
||||||
usbPadRead = (int(*)(uint32_t*))GetProcAddress(hinstLib, "?usbPadRead@@YAHPAK@Z");
|
usbPadRead = (int(*)(uint32_t*))GetProcAddress(hinstLib, "?usbPadRead@@YAHPAK@Z");
|
||||||
static uint8_t button_debounce[9] = {0};
|
static uint8_t button_debounce[9] = {0};
|
||||||
@ -1943,22 +1940,95 @@ static unsigned int __stdcall enhanced_polling_proc(void *ctx)
|
|||||||
|
|
||||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
|
|
||||||
#if POLLING_DEBUG >= 1
|
|
||||||
fprintf(debug_fp, "Thread priority is 0x%x\n", GetThreadPriority(GetCurrentThread()));
|
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint32_t count_time = 0;
|
uint32_t count_time = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t curr_poll_time = 0;
|
uint32_t curr_poll_time = 0;
|
||||||
uint32_t prev_poll_time = 0;
|
uint32_t prev_poll_time = 0;
|
||||||
while (g_enhanced_poll_ready)
|
while (g_enhanced_poll_ready)
|
||||||
{
|
{
|
||||||
#if POLLING_DEBUG >= 1
|
uint32_t pad_bits;
|
||||||
|
/* ensure at least 1ms has elapsed between polls
|
||||||
|
* (beware of SD cab hardware compatibility)
|
||||||
|
*/
|
||||||
|
curr_poll_time = timeGetTime();
|
||||||
|
if (curr_poll_time == prev_poll_time)
|
||||||
|
{
|
||||||
|
curr_poll_time++;
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
prev_poll_time = curr_poll_time;
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
count_time = timeGetTime();
|
count_time = curr_poll_time;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
usbPadRead(&pad_bits);
|
||||||
|
g_last_button_state = pad_bits;
|
||||||
|
|
||||||
|
unsigned int buttonState = (g_last_button_state >> 8) & 0x1FF;
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
if ( ((buttonState >> i)&1) )
|
||||||
|
{
|
||||||
|
if (g_button_state[i] == -1)
|
||||||
|
{
|
||||||
|
g_button_state[i] = curr_poll_time;
|
||||||
|
}
|
||||||
|
//debounce on release (since we're forced to stub usbPadReadLast)
|
||||||
|
button_debounce[i] = g_debounce;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (button_debounce[i]>0)
|
||||||
|
{
|
||||||
|
button_debounce[i]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button_debounce[i] == 0)
|
||||||
|
{
|
||||||
|
g_button_state[i] = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//debounce ongoing: flag button as still pressed
|
||||||
|
g_last_button_state |= 1<<(8+i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
if (count == 100)
|
||||||
|
{
|
||||||
|
g_poll_rate_avg = timeGetTime() - count_time;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int __stdcall enhanced_polling_proc(void *ctx)
|
||||||
|
{
|
||||||
|
HMODULE hinstLib = GetModuleHandleA("ezusb.dll");
|
||||||
|
usbPadRead = (int(*)(uint32_t*))GetProcAddress(hinstLib, "?usbPadRead@@YAHPAK@Z");
|
||||||
|
static uint8_t button_debounce[9] = {0};
|
||||||
|
|
||||||
|
for (int i=0; i<9; i++)
|
||||||
|
{
|
||||||
|
g_button_state[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!g_enhanced_poll_ready)
|
||||||
|
{
|
||||||
|
Sleep(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||||
|
|
||||||
|
uint32_t curr_poll_time = 0;
|
||||||
|
uint32_t prev_poll_time = 0;
|
||||||
|
while (g_enhanced_poll_ready)
|
||||||
|
{
|
||||||
uint32_t pad_bits;
|
uint32_t pad_bits;
|
||||||
/* ensure at least 1ms has elapsed between polls
|
/* ensure at least 1ms has elapsed between polls
|
||||||
* (beware of SD cab hardware compatibility)
|
* (beware of SD cab hardware compatibility)
|
||||||
@ -2004,15 +2074,6 @@ static unsigned int __stdcall enhanced_polling_proc(void *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if POLLING_DEBUG >= 1
|
|
||||||
count++;
|
|
||||||
if (count == 100000)
|
|
||||||
{
|
|
||||||
fprintf(debug_fp, "did 100000 iterations in %ld milliseconds\n", timeGetTime() - count_time);
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
fflush(debug_fp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2027,11 +2088,6 @@ uint32_t buttonGetMillis(uint8_t button)
|
|||||||
if (but <= curr)
|
if (but <= curr)
|
||||||
{
|
{
|
||||||
uint32_t res = curr - but;
|
uint32_t res = curr - but;
|
||||||
#if POLLING_DEBUG >= 2
|
|
||||||
/* these fprintf will mess up timing eval */
|
|
||||||
fprintf(debug_fp, "%ld: buttonGetMillis: button %d : %d millis\n", timeGetTime(), button, res);
|
|
||||||
fflush(debug_fp);
|
|
||||||
#endif
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2046,13 +2102,10 @@ int usbPadReadHook(uint32_t *pad_bits)
|
|||||||
|
|
||||||
// return last known input
|
// return last known input
|
||||||
*pad_bits = g_last_button_state;
|
*pad_bits = g_last_button_state;
|
||||||
#if POLLING_DEBUG >= 2
|
|
||||||
fprintf(debug_fp, "%ld: usbPadReadHook: %x\n", timeGetTime(), *pad_bits);
|
|
||||||
fflush(debug_fp);
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t g_offset_fix[9] = {0};
|
||||||
uint8_t g_poll_index = 0;
|
uint8_t g_poll_index = 0;
|
||||||
uint32_t g_poll_offset = 0;
|
uint32_t g_poll_offset = 0;
|
||||||
void (*real_enhanced_poll)();
|
void (*real_enhanced_poll)();
|
||||||
@ -2065,24 +2118,38 @@ void patch_enhanced_poll() {
|
|||||||
__asm("mov %0, al\n":"=m"(g_poll_index): :);
|
__asm("mov %0, al\n":"=m"(g_poll_index): :);
|
||||||
g_poll_offset = buttonGetMillis(g_poll_index);
|
g_poll_offset = buttonGetMillis(g_poll_index);
|
||||||
__asm("sub esi, %0\n": :"b"(g_poll_offset));
|
__asm("sub esi, %0\n": :"b"(g_poll_offset));
|
||||||
|
g_offset_fix[g_poll_index] = g_poll_offset;
|
||||||
real_enhanced_poll();
|
real_enhanced_poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE enhanced_polling_thread;
|
static HANDLE enhanced_polling_thread;
|
||||||
|
|
||||||
static bool patch_enhanced_polling(uint8_t debounce)
|
static bool patch_enhanced_polling(uint8_t debounce, bool stats)
|
||||||
{
|
{
|
||||||
g_debounce = debounce;
|
g_debounce = debounce;
|
||||||
|
|
||||||
if (enhanced_polling_thread == NULL) {
|
if (enhanced_polling_thread == NULL) {
|
||||||
enhanced_polling_thread = (HANDLE) _beginthreadex(
|
if (stats)
|
||||||
NULL,
|
{
|
||||||
0,
|
enhanced_polling_thread = (HANDLE) _beginthreadex(
|
||||||
enhanced_polling_proc,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
enhanced_polling_stats_proc,
|
||||||
NULL);
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enhanced_polling_thread = (HANDLE) _beginthreadex(
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
enhanced_polling_proc,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
} // thread will remain dormant while g_enhanced_poll_ready == false
|
} // thread will remain dormant while g_enhanced_poll_ready == false
|
||||||
|
|
||||||
/* patch eval timing function to fix offset depending on how long ago the button was pressed */
|
/* patch eval timing function to fix offset depending on how long ago the button was pressed */
|
||||||
@ -2526,7 +2593,10 @@ static bool patch_keysound_offset(int8_t value)
|
|||||||
MH_CreateHook((LPVOID)(patch_addr-0x03), (LPVOID)patch_eval_timing,
|
MH_CreateHook((LPVOID)(patch_addr-0x03), (LPVOID)patch_eval_timing,
|
||||||
(void **)&real_eval_timing); // preload esi with g_keysound_offset
|
(void **)&real_eval_timing); // preload esi with g_keysound_offset
|
||||||
|
|
||||||
LOG("popnhax: keysound offset: timing offset by %d ms\n", value);
|
if (!config.audio_offset)
|
||||||
|
LOG("popnhax: keysound offset: timing offset by %d ms\n", value);
|
||||||
|
else
|
||||||
|
LOG("popnhax: audio offset: audio offset by %d ms\n", -1*value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -3496,6 +3566,116 @@ static bool patch_practice_mode()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* enhanced_polling_stats */
|
||||||
|
const char stats_disp_header[] = "--- 1000Hz Polling ---";
|
||||||
|
const char stats_disp_lastpoll[] = "last input: 0x%06x";
|
||||||
|
const char stats_disp_avgpoll[] = "100 polls in %dms";
|
||||||
|
const char stats_disp_offset_header[] = "--Latest correction--";
|
||||||
|
const char stats_disp_offset_top[] = "%s";
|
||||||
|
char stats_disp_offset_top_str[15] = "";
|
||||||
|
const char stats_disp_offset_bottom[] = "%s";
|
||||||
|
char stats_disp_offset_bottom_str[19] = "";
|
||||||
|
void (*real_render_loop)();
|
||||||
|
void enhanced_polling_stats_disp()
|
||||||
|
{
|
||||||
|
__asm("mov eax, [%0]\n"::"a"(*g_rend_addr));
|
||||||
|
__asm("cmp eax, 0\n");
|
||||||
|
__asm("je call_stat_menu\n");
|
||||||
|
__asm("mov dword ptr [eax], 2\n");
|
||||||
|
__asm("mov dword ptr [eax+4], 1\n");
|
||||||
|
__asm("mov dword ptr [eax+8], 0\n");
|
||||||
|
__asm("mov dword ptr [eax+0x34], 1\n");
|
||||||
|
|
||||||
|
__asm("call_stat_menu:\n");
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_header));
|
||||||
|
__asm("push 0x2A\n");
|
||||||
|
__asm("push 0x160\n");
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+0x60)); //0x50 Blue 0x30 yellow 0x40 red 0x10 green 0x20 grey
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x0C\n");
|
||||||
|
|
||||||
|
uint8_t color = 0x10;
|
||||||
|
if (g_poll_rate_avg > 100)
|
||||||
|
color = 0x40;
|
||||||
|
__asm("push %0\n"::"D"(g_poll_rate_avg));
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_avgpoll));
|
||||||
|
__asm("push 0x5C\n");
|
||||||
|
__asm("push 0x160\n");
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+color)); //0x50 Blue 0x30 yellow 0x40 red 0x10 green
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x10\n");
|
||||||
|
|
||||||
|
__asm("push %0\n"::"D"(g_last_button_state));
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_lastpoll));
|
||||||
|
__asm("push 0x48\n");
|
||||||
|
__asm("push 0x160\n");
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+0x60)); //0x50 Blue 0x30 yellow 0x40 red 0x10 green
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x10\n");
|
||||||
|
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_offset_header));
|
||||||
|
__asm("push 0x2A\n");
|
||||||
|
__asm("push 0x200\n");
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+0x60)); //0x50 Blue 0x30 yellow 0x40 red 0x10 green
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x0C\n");
|
||||||
|
|
||||||
|
sprintf(stats_disp_offset_top_str, "%02u %02u %02u %02u", g_offset_fix[1], g_offset_fix[3], g_offset_fix[5], g_offset_fix[7]);
|
||||||
|
__asm("push %0\n"::"D"(stats_disp_offset_top_str));
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_offset_top));
|
||||||
|
__asm("push 0x48\n"); //y coord
|
||||||
|
__asm("push 0x200\n"); //x coord
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+0x40)); //Red
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x10\n");
|
||||||
|
|
||||||
|
sprintf(stats_disp_offset_bottom_str, "%02u %02u %02u %02u %02u", g_offset_fix[0], g_offset_fix[2], g_offset_fix[4], g_offset_fix[6], g_offset_fix[8]);
|
||||||
|
__asm("push %0\n"::"D"(stats_disp_offset_bottom_str));
|
||||||
|
__asm("push %0\n"::"a"(stats_disp_offset_top));
|
||||||
|
__asm("push 0x5C\n"); //y coord
|
||||||
|
__asm("push 0x1FD\n"); //x coord
|
||||||
|
__asm("mov esi, %0\n"::"a"(*font_color+0x40)); //Red
|
||||||
|
__asm("call %0\n"::"a"(font_rend_func));
|
||||||
|
__asm("add esp, 0x10\n");
|
||||||
|
|
||||||
|
real_render_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool patch_enhanced_polling_stats()
|
||||||
|
{
|
||||||
|
if (config.practice_mode)
|
||||||
|
{
|
||||||
|
LOG("popnhax: enhanced_polling_stats: cannot display stats when practice mode is enabled.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DWORD dllSize = 0;
|
||||||
|
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||||
|
|
||||||
|
{
|
||||||
|
int64_t pattern_offset = search(data, dllSize, "\x83\xEC\x40\x53\x56\x57", 6, 0);
|
||||||
|
|
||||||
|
if (pattern_offset == -1) {
|
||||||
|
LOG("popnhax: enhanced_polling_stats: cannot retrieve aging loop\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t patch_addr = (int64_t)data + pattern_offset + 6;
|
||||||
|
if (!get_rendaddr())
|
||||||
|
{
|
||||||
|
LOG("popnhax: enhanced_polling_stats: cannot find address for drawing\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MH_CreateHook((LPVOID)patch_addr, (LPVOID)enhanced_polling_stats_disp,
|
||||||
|
(void **)&real_render_loop);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("popnhax: enhanced polling stats displayed\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||||
switch (ul_reason_for_call) {
|
switch (ul_reason_for_call) {
|
||||||
case DLL_PROCESS_ATTACH: {
|
case DLL_PROCESS_ATTACH: {
|
||||||
@ -3700,6 +3880,19 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
force_show_fast_slow();
|
force_show_fast_slow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.audio_offset){
|
||||||
|
if (config.keysound_offset)
|
||||||
|
{
|
||||||
|
LOG("popnhax: audio_offset cannot be used when keysound_offset is already set\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config.disable_keysounds = true;
|
||||||
|
config.keysound_offset = -1*config.audio_offset;
|
||||||
|
LOG("popnhax: audio_offset: disable keysounds then offset timing by %d ms\n", config.keysound_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config.disable_keysounds){
|
if (config.disable_keysounds){
|
||||||
patch_disable_keysound();
|
patch_disable_keysound();
|
||||||
}
|
}
|
||||||
@ -3756,8 +3949,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
patch_fps_uncap();
|
patch_fps_uncap();
|
||||||
|
|
||||||
if (config.enhanced_polling)
|
if (config.enhanced_polling)
|
||||||
patch_enhanced_polling(config.debounce);
|
{
|
||||||
|
patch_enhanced_polling(config.debounce, config.enhanced_polling_stats);
|
||||||
|
if (config.enhanced_polling_stats)
|
||||||
|
{
|
||||||
|
patch_enhanced_polling_stats();
|
||||||
|
}
|
||||||
|
}
|
||||||
#if DEBUG == 1
|
#if DEBUG == 1
|
||||||
patch_get_time();
|
patch_get_time();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user