forked from Popn_Tools/popnhax
Compare commits
4 Commits
main
...
wip_pollin
Author | SHA1 | Date | |
---|---|---|---|
d4f47bf9b4 | |||
98ba8de780 | |||
5eacda584e | |||
2f9d25df05 |
15
dist/popnhax/popnhax.xml
vendored
15
dist/popnhax/popnhax.xml
vendored
@ -19,6 +19,8 @@
|
||||
<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>
|
||||
|
||||
<!-- Stage management -->
|
||||
<!-- Premium free (unlimited stages per credit) -->
|
||||
@ -41,27 +43,22 @@
|
||||
<!-- Display offset adjust value on score result screen (requires hidden_is_offset, won't be sent over network) -->
|
||||
<show_offset __type="bool">0</show_offset>
|
||||
|
||||
<!-- Option patches -->
|
||||
<!-- Hi-speed -->
|
||||
<!-- Auto set hi-speed to match previously set BPM (0: off, 1: target higher bpm on soflan, 2: target lower bpm on soflan, 3: target longest bpm on soflan) -->
|
||||
<hispeed_auto __type="u8">0</hispeed_auto>
|
||||
<!-- Default target BPM, 0 to disable (requires hispeed_auto) -->
|
||||
<!-- Note: target is still updated when manually changing hi-speed (except soflan and "?" charts) -->
|
||||
<hispeed_default_bpm __type="u16">0</hispeed_default_bpm>
|
||||
|
||||
<!-- Gauge options -->
|
||||
<!-- IIDX-like hard gauge (start with full gauge, instant fail if gauge drops to 0) -->
|
||||
<!-- Gauge details: increment: +0.1% for each cool/great/good (like spicy gauge), decrement: -9% for each bad, or -4.5% if gauge <=30% ) -->
|
||||
<iidx_hard_gauge __type="bool">0</iidx_hard_gauge>
|
||||
<!-- Force full options by default (useful when no numpad is available) -->
|
||||
<force_full_opt __type="bool">0</force_full_opt>
|
||||
<!-- Guide SE defaults to OFF (useful for Battle mode) -->
|
||||
<guidese_off __type="bool">0</guidese_off>
|
||||
<!-- All net Ojama default to OFF (useful for Local mode) -->
|
||||
<netvs_off __type="bool">0</netvs_off>
|
||||
|
||||
<!-- Result screen display patches -->
|
||||
<!-- Details on result screen by default (no need to press yellow button) -->
|
||||
<!-- Display details on result screen by default (no need to press yellow button) -->
|
||||
<show_details __type="bool">0</show_details>
|
||||
<!-- Fast/Slow counter on result screen even on judge+ off/lost/panic -->
|
||||
<!-- Display fast/slow counter on result screen even on judge+ off/lost/panic -->
|
||||
<show_fast_slow __type="bool">0</show_fast_slow>
|
||||
|
||||
<!-- Input polling -->
|
||||
|
@ -24,8 +24,6 @@ struct popnhax_config {
|
||||
bool freeze_timer;
|
||||
bool skip_tutorials;
|
||||
bool force_full_opt;
|
||||
bool netvs_off;
|
||||
bool guidese_off;
|
||||
|
||||
bool patch_db;
|
||||
bool disable_expansions;
|
||||
@ -46,6 +44,7 @@ struct popnhax_config {
|
||||
uint8_t debounce;
|
||||
bool enhanced_polling_stats;
|
||||
int8_t enhanced_polling_priority;
|
||||
uint32_t enhanced_polling_nb_iter;
|
||||
uint8_t hispeed_auto;
|
||||
uint16_t hispeed_default_bpm;
|
||||
uint8_t survival_gauge;
|
||||
|
@ -132,10 +132,6 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, skip_tutorials
|
||||
"/popnhax/skip_tutorials")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, force_full_opt,
|
||||
"/popnhax/force_full_opt")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, netvs_off,
|
||||
"/popnhax/netvs_off")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, guidese_off,
|
||||
"/popnhax/guidese_off")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, patch_db,
|
||||
"/popnhax/patch_db")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, disable_expansions,
|
||||
@ -170,6 +166,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, translation_de
|
||||
"/popnhax/translation_debug")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, enhanced_polling,
|
||||
"/popnhax/enhanced_polling")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_U32, struct popnhax_config, enhanced_polling_nb_iter,
|
||||
"/popnhax/enhanced_polling_nb_iter")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_U8, struct popnhax_config, debounce,
|
||||
"/popnhax/debounce")
|
||||
PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, enhanced_polling_stats,
|
||||
@ -283,12 +281,6 @@ void omnimix_patch_jbx() {
|
||||
real_omnimix_patch_jbx();
|
||||
}
|
||||
|
||||
/* dummy function to replace real one when not found */
|
||||
bool is_normal_mode_best_effort(){
|
||||
return true;
|
||||
}
|
||||
bool (*popn22_is_normal_mode)() = is_normal_mode_best_effort;
|
||||
|
||||
uint32_t g_startsong_addr = 0;
|
||||
uint32_t g_transition_addr = 0;
|
||||
uint32_t g_stage_addr = 0;
|
||||
@ -309,21 +301,10 @@ void quickexit_screen_transition()
|
||||
else if (g_return_to_song_select)
|
||||
{
|
||||
__asm("mov dword ptr [edi+0x30], 0x17\n");
|
||||
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_change_flag");
|
||||
|
||||
if ( g_pfree_mode )
|
||||
{
|
||||
if (g_pfree_mode)
|
||||
g_return_to_song_select = false;
|
||||
}
|
||||
//flag is set back to false in hook_stage_increment otherwise
|
||||
}
|
||||
|
||||
__asm("skip_change_flag:");
|
||||
g_end_session = false;
|
||||
real_screen_transition();
|
||||
}
|
||||
@ -528,18 +509,8 @@ void quickexit_game_loop()
|
||||
/* numpad 8 is pressed: quick retry if pfree is active */
|
||||
use_sp_flg = 0;
|
||||
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_pfree_check");
|
||||
|
||||
if ( !g_pfree_mode )
|
||||
{
|
||||
__asm("skip_pfree_check:");
|
||||
if (!g_pfree_mode)
|
||||
__asm("jmp call_real\n");
|
||||
}
|
||||
|
||||
g_return_to_options = true;
|
||||
/* numpad 7 or 9 is pressed */
|
||||
__asm("leave_song:\n");
|
||||
@ -586,17 +557,8 @@ void quickexit_result_loop()
|
||||
__asm("cmp bl, 8\n");
|
||||
__asm("jne call_real_result\n");
|
||||
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_quickexit_pfree_check");
|
||||
|
||||
if ( !g_pfree_mode )
|
||||
{
|
||||
__asm("skip_quickexit_pfree_check:");
|
||||
if (!g_pfree_mode)
|
||||
__asm("jmp call_real_result\n");
|
||||
}
|
||||
|
||||
g_return_to_options = true; //transition screen hook will catch it
|
||||
__asm("jmp call_real_result\n");
|
||||
@ -679,17 +641,8 @@ void hook_stage_update()
|
||||
__asm("lea ebx, [ebx+0xC]\n");
|
||||
__asm("mov %0, ebx\n":"=b"(g_transition_addr): :);
|
||||
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_stage_update_pfree_check");
|
||||
|
||||
if ( !g_pfree_mode )
|
||||
{
|
||||
__asm("skip_stage_update_pfree_check:");
|
||||
if (!g_pfree_mode)
|
||||
real_stage_update();
|
||||
}
|
||||
}
|
||||
|
||||
/* this hook is installed only when back_to_song_select is enabled and pfree is not */
|
||||
@ -1817,13 +1770,14 @@ static bool force_show_fast_slow() {
|
||||
|
||||
|
||||
void (*real_show_detail_result)();
|
||||
void hook_show_detail_result(){
|
||||
void hook_show_detail_result()
|
||||
{
|
||||
static uint32_t last_call = 0;
|
||||
|
||||
__asm("push eax\n");
|
||||
__asm("push edx\n");
|
||||
|
||||
uint32_t curr_time = timeGetTime(); //will clobber eax
|
||||
uint32_t curr_time = timeGetTime(); //will clobber eax
|
||||
if ( curr_time - last_call > 10000 ) //will clobber edx
|
||||
{
|
||||
last_call = curr_time;
|
||||
@ -1851,7 +1805,7 @@ static bool force_show_details_result() {
|
||||
LOG("popnhax: show details: cannot find result screen button check (1)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//+0x26
|
||||
{
|
||||
int64_t pattern_offset = search(data, 0x50, "\x84\xC0", 2, first_loc);
|
||||
if (pattern_offset == -1) {
|
||||
@ -1870,219 +1824,9 @@ static bool force_show_details_result() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t g_pfree_song_offset = 0x54;
|
||||
uint16_t g_pfree_song_offset_2 = 0x558;
|
||||
void (*popn22_get_powerpoints)();
|
||||
void (*popn22_get_chart_level)();
|
||||
|
||||
/* POWER POINTS LIST FIX */
|
||||
uint8_t g_pplist_idx = 0; // also serves as elem count
|
||||
int32_t g_pplist[20] = {0}; // 20 elements for power_point_list (always ordered)
|
||||
int32_t g_power_point_value = -1; // latest value (hook uses update_pplist() to add to g_pplist array)
|
||||
int32_t *g_real_pplist; // list that the game retrieves from server
|
||||
uint32_t *allocated_pplist_copy; // pointer to the location where the game's pp_list modified copy resides
|
||||
|
||||
void pplist_reset()
|
||||
{
|
||||
for (int i=0; i<20; i++)
|
||||
g_pplist[i] = -1;
|
||||
g_pplist_idx = 0;
|
||||
}
|
||||
|
||||
/* add new value (stored in g_power_point_value) to g_pp_list */
|
||||
void pplist_update(){
|
||||
if ( g_power_point_value == -1 )
|
||||
return;
|
||||
|
||||
if ( g_pplist_idx == 20 )
|
||||
{
|
||||
for (int i = 0; i < 19; i++)
|
||||
{
|
||||
g_pplist[i] = g_pplist[i+1];
|
||||
}
|
||||
g_pplist_idx = 19;
|
||||
}
|
||||
|
||||
g_pplist[g_pplist_idx++] = g_power_point_value;
|
||||
g_power_point_value = -1;
|
||||
}
|
||||
|
||||
/* copy real pp_list to our local copy and check length */
|
||||
void pplist_retrieve(){
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
g_pplist[i] = g_real_pplist[i];
|
||||
}
|
||||
|
||||
/* in the general case your pplist will be full from the start so this is optimal */
|
||||
g_pplist_idx = 19;
|
||||
while ( g_pplist[g_pplist_idx] == -1 )
|
||||
{
|
||||
if ( g_pplist_idx == 0 )
|
||||
return;
|
||||
g_pplist_idx--;
|
||||
}
|
||||
g_pplist_idx++;
|
||||
}
|
||||
|
||||
void (*real_pfree_pplist_init)();
|
||||
void hook_pfree_pplist_init(){
|
||||
__asm("push eax");
|
||||
__asm("push ebx");
|
||||
__asm("lea ebx, [eax+0x1C4]\n");
|
||||
__asm("mov %0, ebx\n":"=m"(g_real_pplist));
|
||||
__asm("call %0\n"::"a"(pplist_retrieve));
|
||||
__asm("pop ebx");
|
||||
__asm("pop eax");
|
||||
real_pfree_pplist_init();
|
||||
}
|
||||
|
||||
void (*real_pfree_pplist_inject)();
|
||||
void hook_pfree_pplist_inject(){
|
||||
__asm("lea esi, %0\n"::"m"(g_pplist[g_pplist_idx]));
|
||||
__asm("mov dword ptr [esp+0x40], esi\n");
|
||||
|
||||
__asm("lea esi, %0\n"::"m"(g_pplist));
|
||||
__asm("mov eax, dword ptr [esp+0x3C]\n");
|
||||
__asm("mov %0, eax\n":"=m"(allocated_pplist_copy));
|
||||
__asm("mov dword ptr [esp+0x3C], esi\n");
|
||||
__asm("movzx eax, %0\n"::"m"(g_pplist_idx));
|
||||
|
||||
real_pfree_pplist_inject();
|
||||
}
|
||||
|
||||
/* restore original pointer so that it can be freed */
|
||||
void (*real_pfree_pplist_inject_cleanup)();
|
||||
void hook_pfree_pplist_inject_cleanup()
|
||||
{
|
||||
__asm("mov esi, %0\n"::"m"(allocated_pplist_copy));
|
||||
__asm("call %0\n"::"a"(pplist_reset));
|
||||
|
||||
real_pfree_pplist_inject_cleanup();
|
||||
}
|
||||
|
||||
/* hook is installed in stage increment function */
|
||||
void (*real_pfree_cleanup)();
|
||||
void hook_pfree_cleanup()
|
||||
{
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_pfree_cleanup");
|
||||
|
||||
__asm("push esi\n");
|
||||
__asm("push edi\n");
|
||||
__asm("push eax\n");
|
||||
__asm("push edx\n");
|
||||
__asm("movzx eax, byte ptr [%0]\n"::"m"(g_pfree_song_offset));
|
||||
__asm("movzx ebx, word ptr [%0]\n"::"m"(g_pfree_song_offset_2));
|
||||
__asm("lea edi, dword ptr [esi+eax]\n");
|
||||
__asm("lea esi, dword ptr [esi+ebx]\n");
|
||||
__asm("push esi\n");
|
||||
__asm("push edi\n");
|
||||
|
||||
/* compute powerpoints before cleanup */
|
||||
__asm("sub eax, 0x20\n"); // eax still contains g_pfree_song_offset
|
||||
__asm("neg eax\n");
|
||||
__asm("lea eax, dword ptr [edi+eax]\n");
|
||||
__asm("mov eax, dword ptr [eax]\n"); // music id (edi-0x38 or edi-0x34 depending on game)
|
||||
|
||||
__asm("cmp ax, 0xBB8\n"); // skip if music id is >= 3000 (cs_omni and user customs)
|
||||
__asm("jae cleanup_score\n");
|
||||
|
||||
__asm("push 0\n");
|
||||
__asm("push eax\n");
|
||||
__asm("shr eax, 0x10\n"); //sheet id in al
|
||||
__asm("call %0\n"::"b"(popn22_get_chart_level));
|
||||
__asm("add esp, 8\n");
|
||||
__asm("mov bl, byte ptr [edi+0x24]\n"); // medal
|
||||
|
||||
/* push "is full combo" param */
|
||||
__asm("cmp bl, 8\n");
|
||||
__asm("setae dl\n");
|
||||
__asm("movzx ecx, dl\n");
|
||||
__asm("push ecx\n");
|
||||
|
||||
/* push "is clear" param */
|
||||
__asm("cmp bl, 4\n");
|
||||
__asm("setae dl\n");
|
||||
__asm("movzx ecx, dl\n");
|
||||
__asm("push ecx\n");
|
||||
|
||||
__asm("mov ecx, eax\n"); // diff level
|
||||
__asm("mov eax, dword ptr [edi]\n"); // score
|
||||
__asm("call %0\n"::"b"(popn22_get_powerpoints));
|
||||
__asm("mov %0, eax\n":"=a"(g_power_point_value):);
|
||||
__asm("call %0\n"::"a"(pplist_update));
|
||||
|
||||
__asm("cleanup_score:\n");
|
||||
/* can finally cleanup score */
|
||||
__asm("pop edi\n");
|
||||
__asm("pop esi\n");
|
||||
__asm("mov ecx, 0x98");
|
||||
__asm("rep movsd");
|
||||
__asm("pop edx");
|
||||
__asm("pop eax");
|
||||
__asm("pop edi");
|
||||
__asm("pop esi");
|
||||
__asm("jmp cleanup_end");
|
||||
|
||||
__asm("skip_pfree_cleanup:\n");
|
||||
real_pfree_cleanup();
|
||||
|
||||
__asm("cleanup_end:\n");
|
||||
}
|
||||
|
||||
/* hook without the power point fixes (eclale best effort) */
|
||||
void hook_pfree_cleanup_simple()
|
||||
{
|
||||
__asm("push eax");
|
||||
__asm("call %0"::"a"(popn22_is_normal_mode));
|
||||
__asm("test al,al");
|
||||
__asm("pop eax");
|
||||
__asm("je skip_pfree_cleanup_simple");
|
||||
|
||||
__asm("push esi\n");
|
||||
__asm("push edi\n");
|
||||
__asm("push eax\n");
|
||||
__asm("push ebx\n");
|
||||
__asm("push edx\n");
|
||||
__asm("movsx eax, byte ptr [%0]\n"::"m"(g_pfree_song_offset));
|
||||
__asm("movsx ebx, word ptr [%0]\n"::"m"(g_pfree_song_offset_2));
|
||||
__asm("lea edi, dword ptr [esi+eax]\n");
|
||||
__asm("lea esi, dword ptr [esi+ebx]\n");
|
||||
__asm("mov ecx, 0x98");
|
||||
__asm("rep movsd");
|
||||
__asm("pop edx");
|
||||
__asm("pop ebx");
|
||||
__asm("pop eax");
|
||||
__asm("pop edi");
|
||||
__asm("pop esi");
|
||||
__asm("ret");
|
||||
|
||||
__asm("skip_pfree_cleanup_simple:\n");
|
||||
real_pfree_cleanup();
|
||||
}
|
||||
|
||||
static bool patch_pfree() {
|
||||
DWORD dllSize = 0;
|
||||
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||
bool simple = false;
|
||||
pplist_reset();
|
||||
|
||||
/* retrieve is_normal_mode function */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x0C\x33\xC0\xC3\xCC\xCC\xCC\xCC\xE8", 11, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find is_normal_mode function, fallback to best effort (active in all modes)\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
popn22_is_normal_mode = (bool(*)()) (data + pattern_offset + 0x0A);
|
||||
}
|
||||
}
|
||||
|
||||
/* stop stage counter (2 matches, 1st one is the good one) */
|
||||
{
|
||||
@ -2115,7 +1859,6 @@ static bool patch_pfree() {
|
||||
offset_from_base = 0x54;
|
||||
offset_from_stage1[0] = 0x04;
|
||||
offset_from_stage1[1] = 0x05;
|
||||
simple = true;
|
||||
goto pfree_apply;
|
||||
}
|
||||
uint32_t child_fun_rel = *(uint32_t *) ((int64_t)data + offset - 0x04);
|
||||
@ -2150,104 +1893,38 @@ static bool patch_pfree() {
|
||||
}
|
||||
|
||||
pfree_apply:
|
||||
g_pfree_song_offset = offset_from_base;
|
||||
g_pfree_song_offset_2 = *((uint16_t*)offset_from_stage1);
|
||||
g_pfree_song_offset_2 += offset_from_base;
|
||||
|
||||
/* cleanup score and stats */
|
||||
int64_t first_loc = 0;
|
||||
/* cleanup score and stats part1 */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\xFE\x46\x0E\x80", 4, 0);
|
||||
first_loc = search(data, dllSize, "\xFE\x46\x0E\x80", 4, 0);
|
||||
if (first_loc == -1) {
|
||||
LOG("popnhax: pfree: cannot find stage update function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + first_loc;
|
||||
patch_memory(patch_addr, (char *)"\x90\x90\x90", 3);
|
||||
}
|
||||
|
||||
/* cleanup score and stats part2 */
|
||||
{
|
||||
int64_t pattern_offset = search(data, 0x40, "\x83\xC4\x08\x8A", 4, first_loc);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find stage update function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset;
|
||||
char patch_str[24] = "\x56\x57\x8D\x7E\x54\x8D\xB6\x58\x05\x00\x00\xB9\x98\x00\x00\x00\xF3\xA5\x5F\x5E\xC3\xCC\xCC";
|
||||
patch_str[4] = offset_from_base;
|
||||
patch_str[7] = offset_from_stage1[0] + offset_from_base;
|
||||
patch_str[8] = offset_from_stage1[1];
|
||||
|
||||
/* replace stage number increment with a score cleanup function */
|
||||
if ( simple )
|
||||
{
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_pfree_cleanup_simple,
|
||||
(void **)&real_pfree_cleanup);
|
||||
LOG("popnhax: premium free enabled (WARN: no power points fix)\n");
|
||||
return true;
|
||||
}
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x03;
|
||||
|
||||
/* compute and save power points to g_pplist before cleaning up memory zone */
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_pfree_cleanup,
|
||||
(void **)&real_pfree_cleanup);
|
||||
}
|
||||
add_stage_addr = (int64_t)data + pattern_offset + 0x03;
|
||||
|
||||
/* fix power points */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x8A\xD8\x8B\x44\x24\x0C\xE8", 7, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find get_power_points function\n");
|
||||
return false;
|
||||
}
|
||||
patch_memory(patch_addr, patch_str, 23);
|
||||
|
||||
popn22_get_chart_level = (void(*)()) (data + pattern_offset - 0x07);
|
||||
}
|
||||
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x3D\x50\xC3\x00\x00\x7D\x05", 7, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find get_power_points function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
popn22_get_powerpoints = (void(*)()) (data + pattern_offset);
|
||||
}
|
||||
/* init pp_list */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x6B\xD2\x64\x2B\xCA\x51\x50\x68", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find power point load function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset - 0x1A;
|
||||
|
||||
/* copy power point list to g_pplist on profile load and init g_pplist_idx */
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_pfree_pplist_init,
|
||||
(void **)&real_pfree_pplist_init);
|
||||
}
|
||||
|
||||
/* inject pp_list at end of credit */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x8B\x74\x24\x3C\x66\x8B\x04\x9E", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find end of credit power point handling function (1)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset - 0x07;
|
||||
|
||||
/* make power point list pointers point to g_pplist at the end of processing */
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_pfree_pplist_inject,
|
||||
(void **)&real_pfree_pplist_inject);
|
||||
}
|
||||
/* prevent crash when playing only customs in a credit */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\x0F\x8E\x5C\xFF\xFF\xFF\xEB\x04", 8, 6, "\x90\x90", 2))
|
||||
{
|
||||
LOG("popnhax: pfree: cannot patch end list pointer\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* restore pp_list pointer so that it is freed at end of credit */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x7E\x04\x2B\xC1\x8B\xF8\x3B\xF5", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: pfree: cannot find end of credit power point handling function (2)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x06;
|
||||
|
||||
/* make power point list pointers point to g_pplist at the end of processing */
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_pfree_pplist_inject_cleanup,
|
||||
(void **)&real_pfree_pplist_inject_cleanup);
|
||||
}
|
||||
|
||||
LOG("popnhax: premium free enabled\n");
|
||||
@ -2346,7 +2023,7 @@ static bool patch_quick_retire(bool pfree)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x1A;
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x1D;
|
||||
MH_CreateHook((LPVOID)patch_addr, (LPVOID)quickexit_result_button_loop,
|
||||
(void **)&real_result_button_loop);
|
||||
|
||||
@ -2527,6 +2204,20 @@ static bool patch_add_to_base_offset(int8_t delta) {
|
||||
bool g_enhanced_poll_ready = false;
|
||||
int (*usbPadRead)(uint32_t*);
|
||||
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
static uint32_t __inline wait_a_little(uint32_t nb_iter)
|
||||
{
|
||||
uint32_t j=0;
|
||||
for (uint32_t i=0; i<nb_iter; i++)
|
||||
{
|
||||
j++;
|
||||
}
|
||||
return timeGetTime();
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
uint32_t g_poll_rate_avg = 0;
|
||||
uint32_t g_last_button_state = 0;
|
||||
uint8_t g_debounce = 0;
|
||||
@ -2564,13 +2255,15 @@ static unsigned int __stdcall enhanced_polling_stats_proc(void *ctx)
|
||||
/* 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;
|
||||
{
|
||||
do {
|
||||
curr_poll_time = wait_a_little(config.enhanced_polling_nb_iter);
|
||||
while (curr_poll_time == prev_poll_time);
|
||||
}
|
||||
prev_poll_time = curr_poll_time;
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
@ -3532,6 +3225,45 @@ void patch_numpad0_options() {
|
||||
real_numpad0_options();
|
||||
}
|
||||
|
||||
static bool patch_options()
|
||||
{
|
||||
DWORD dllSize = 0;
|
||||
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||
/* starting value */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\xFF\xD0\xB8\x01\x00\x00\x00\x01\x46\x34\x01\x46\x38\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x8B\x4C\x24\x04\x8B\x54\x24\x08\x89\x48\x20\x89\x50\x24\xC7\x40\x2C\x00\x00\x00\x00\xC6\x40\x30\x01\xC2\x08\x00\xCC\xCC\xCC\xCC\x83\xEC\x18\x33\xC0", 60, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: always full options: cannot find function call\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset;
|
||||
|
||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)patch_song_options,
|
||||
(void **)&real_song_options);
|
||||
|
||||
}
|
||||
/* prevent switching with numpad 0 */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\xC6\x85\x1F\x0A\x00\x00\x00\xC6\x85\x20\x0A\x00\x00\x00\xE9\x3E\x01\x00\x00\x33\xC9", 21, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: always full options: cannot find numpad0 check\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x22;
|
||||
|
||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)patch_numpad0_options,
|
||||
(void **)&real_numpad0_options);
|
||||
|
||||
}
|
||||
|
||||
LOG("popnhax: always display full options\n");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* r2nk226 */
|
||||
|
||||
|
||||
@ -3934,9 +3666,9 @@ const char menu_1[] = "--- Practice Mode ---";
|
||||
const char menu_2[] = "Scores are not recorded."; //NO CONTEST 表現がわからん
|
||||
const char menu_3[] = "REGUL SPEED (numpad4) >> %s";
|
||||
const char menu_4[] = "R-RANDOM (numpad6) >> %s";
|
||||
const char menu_5[] = "SPEED (numpad5) >> %s";
|
||||
const char menu_5[] = "SPEED (numpad8) >> %s";
|
||||
//const char menu_6[] = "menu display on/off (numpad9)";
|
||||
const char menu_7[] = "quick retry (numpad8)";
|
||||
const char menu_7[] = "quick retry (numpad7)";
|
||||
const char menu_8[] = "quick retire (numpad9)";
|
||||
const char menu_6[] = "quit pfree mode (numpad9)";
|
||||
const char menu_on[] = "ON";
|
||||
@ -3972,12 +3704,12 @@ void new_menu()
|
||||
flg_3 = menu_on;
|
||||
}
|
||||
|
||||
__asm("mov ecx, 5\n");
|
||||
__asm("mov ecx, 8\n");
|
||||
__asm("call %0\n"::"a"(input_func));
|
||||
__asm("test al, al\n");
|
||||
__asm("je SW_5\n");
|
||||
__asm("je SW_8\n");
|
||||
speed++;
|
||||
__asm("SW_5:\n");
|
||||
__asm("SW_8:\n");
|
||||
|
||||
__asm("mov eax, [%0]\n"::"a"(*g_rend_addr));
|
||||
__asm("cmp eax, 0\n");
|
||||
@ -4438,8 +4170,8 @@ void hook_read_hispeed()
|
||||
|
||||
g_hispeed_double = (double)g_target_bpm / (double)(*g_base_bpm_ptr/10.0);
|
||||
g_hispeed = (uint32_t)(g_hispeed_double+0.5); //rounding to nearest
|
||||
if (g_hispeed > 0x64) g_hispeed = 0x64;
|
||||
if (g_hispeed < 0x0A) g_hispeed = 0x0A;
|
||||
if (g_hispeed > 0x64) g_hispeed = 0x0A;
|
||||
if (g_hispeed < 0x0A) g_hispeed = 0x64;
|
||||
|
||||
__asm("and edi, 0xFFFF0000\n"); //keep existing popkun and hidden status values
|
||||
__asm("or edi, dword ptr[%0]\n"::"m"(g_hispeed)); //fix hispeed initial display on option screen
|
||||
@ -4468,7 +4200,7 @@ void hook_increase_hispeed()
|
||||
}
|
||||
|
||||
//increase hispeed
|
||||
__asm("movzx ecx, word ptr[edi]\n");
|
||||
__asm("mov ecx, dword ptr[edi]\n");
|
||||
__asm("inc ecx\n");
|
||||
__asm("cmp ecx, 0x65\n");
|
||||
__asm("jb skip_hispeed_rollover_high\n");
|
||||
@ -4509,7 +4241,7 @@ void hook_decrease_hispeed()
|
||||
}
|
||||
|
||||
//decrease hispeed
|
||||
__asm("movzx ecx, word ptr[edi]\n");
|
||||
__asm("mov ecx, dword ptr[edi]\n");
|
||||
__asm("dec ecx\n");
|
||||
__asm("cmp ecx, 0x0A\n");
|
||||
__asm("jge skip_hispeed_rollover_low\n");
|
||||
@ -4694,90 +4426,17 @@ void hook_survival_gauge_medal()
|
||||
{
|
||||
__asm("cmp eax, 0\n"); //empty gauge should still fail
|
||||
__asm("jz skip_force_clear\n");
|
||||
|
||||
/* fix gauge ( [0;1023] -> [725;1023] ) */
|
||||
__asm("push eax");
|
||||
__asm("push ebx");
|
||||
__asm("push edx");
|
||||
__asm("xor edx,edx");
|
||||
__asm("mov eax, dword ptr [edi+4]");
|
||||
|
||||
/* bigger interval for first bar */
|
||||
__asm("cmp eax, 42");
|
||||
__asm("jge skip_lower");
|
||||
__asm("mov eax, 42");
|
||||
__asm("skip_lower:");
|
||||
|
||||
/* tweak off by one/two values */
|
||||
__asm("cmp eax, 297");
|
||||
__asm("je decrease_once");
|
||||
__asm("cmp eax, 298");
|
||||
__asm("je decrease_twice");
|
||||
__asm("cmp eax, 426");
|
||||
__asm("je decrease_once");
|
||||
__asm("cmp eax, 681");
|
||||
__asm("je decrease_once");
|
||||
__asm("cmp eax, 936");
|
||||
__asm("je decrease_once");
|
||||
__asm("cmp eax, 937");
|
||||
__asm("je decrease_twice");
|
||||
|
||||
__asm("jmp no_decrease");
|
||||
|
||||
__asm("decrease_twice:");
|
||||
__asm("dec eax");
|
||||
__asm("decrease_once:");
|
||||
__asm("dec eax");
|
||||
|
||||
__asm("no_decrease:");
|
||||
|
||||
/* perform ((gauge+99)/3) + 678 */
|
||||
__asm("add eax, 99");
|
||||
__asm("mov bx, 3");
|
||||
__asm("idiv bx");
|
||||
__asm("add eax, 678");
|
||||
|
||||
/* higher cap value */
|
||||
__asm("cmp eax, 1023");
|
||||
__asm("jle skip_trim");
|
||||
__asm("mov eax, 1023");
|
||||
__asm("skip_trim:");
|
||||
|
||||
__asm("mov dword ptr [edi+4], eax");
|
||||
__asm("pop edx");
|
||||
__asm("pop ebx");
|
||||
__asm("pop eax");
|
||||
|
||||
__asm("jmp %0\n"::"m"(real_survival_gauge_medal_clear));
|
||||
}
|
||||
__asm("skip_force_clear:\n");
|
||||
real_survival_gauge_medal();
|
||||
}
|
||||
|
||||
void (*real_get_retire_timer)();
|
||||
void hook_get_retire_timer()
|
||||
{
|
||||
if ( g_hard_gauge_selected )
|
||||
{
|
||||
__asm("mov eax, 0xFFFF\n");
|
||||
__asm("ret\n");
|
||||
}
|
||||
real_get_retire_timer();
|
||||
}
|
||||
|
||||
bool patch_hard_gauge_survival(uint8_t severity)
|
||||
{
|
||||
DWORD dllSize = 0;
|
||||
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||
|
||||
/* refill gauge at each stage */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\x84\xC0\x75\x0B\xB8\x00\x04\x00\x00", 9, 0, "\x90\x90\x90\x90", 4))
|
||||
{
|
||||
LOG("popnhax: survival gauge: cannot patch gauge refill\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* change is_survival_gauge function behavior */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x33\xC9\x83\xF8\x04\x0F\x94\xC1\x8A\xC1", 10, 0);
|
||||
@ -4792,21 +4451,6 @@ bool patch_hard_gauge_survival(uint8_t severity)
|
||||
(void **)&real_check_survival_gauge);
|
||||
}
|
||||
|
||||
/* change get_retire_timer function behavior (fix bug with song not exiting on empty gauge when paseli is on) */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x3D\xB0\x04\x00\x00\x7C", 6, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: survival gauge: cannot find get retire timer function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t fun_rel = *(int32_t *)(data + pattern_offset - 0x04 ); // function call is just before our pattern
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + fun_rel;
|
||||
|
||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)hook_get_retire_timer,
|
||||
(void **)&real_get_retire_timer);
|
||||
}
|
||||
|
||||
/* hook commit option to flag hard gauge being selected */
|
||||
{
|
||||
/* find option commit function (unilab) */
|
||||
@ -4968,164 +4612,6 @@ bool patch_survival_spicy()
|
||||
return true;
|
||||
}
|
||||
|
||||
void (*skip_convergence_value_get_score)();
|
||||
void (*real_convergence_value_compute)();
|
||||
void hook_convergence_value_compute()
|
||||
{
|
||||
__asm("push eax\n");
|
||||
__asm("mov eax, dword ptr [eax]\n"); // music id (edi-0x38 or edi-0x34 depending on game)
|
||||
__asm("cmp ax, 0xBB8\n"); // skip if music id is >= 3000 (cs_omni and user customs)
|
||||
__asm("jae force_convergence_value\n");
|
||||
__asm("pop eax\n");
|
||||
__asm("jmp %0\n"::"m"(real_convergence_value_compute));
|
||||
__asm("force_convergence_value:\n");
|
||||
__asm("pop eax\n");
|
||||
__asm("xor eax, eax\n");
|
||||
__asm("jmp %0\n"::"m"(skip_convergence_value_get_score));
|
||||
}
|
||||
|
||||
void (*skip_pp_list_elem)();
|
||||
void (*real_pp_increment_compute)();
|
||||
void hook_pp_increment_compute()
|
||||
{
|
||||
__asm("cmp ecx, 0xBB8\n"); // skip if music id is >= 3000 (cs_omni and user customs)
|
||||
__asm("jb process_pp_elem\n");
|
||||
__asm("jmp %0\n"::"m"(skip_pp_list_elem));
|
||||
__asm("process_pp_elem:\n");
|
||||
__asm("jmp %0\n"::"m"(real_pp_increment_compute));
|
||||
}
|
||||
|
||||
static bool patch_db_fix_cursor(){
|
||||
/* bypass song id sanitizer */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\x0F\xB7\x06\x66\x85\xC0\x7C\x1C", 8, -5, "\x90\x90\x90\x90\x90", 5))
|
||||
{
|
||||
LOG("popnhax: patch_db: cannot fix cursor\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* skip 2nd check */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\x0F\xB7\x06\x66\x85\xC0\x7C\x1C", 8, 0x1A, "\xEB", 1))
|
||||
{
|
||||
LOG("popnhax: patch_db: cannot fix cursor (2)\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool patch_db_power_points()
|
||||
{
|
||||
DWORD dllSize = 0;
|
||||
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||
|
||||
int64_t child_fun_loc = 0;
|
||||
{
|
||||
int64_t offset = search(data, dllSize, "\x8D\x46\xFF\x83\xF8\x0A\x0F", 7, 0);
|
||||
if (offset == -1) {
|
||||
#if DEBUG == 1
|
||||
LOG("popnhax: patch_db: failed to retrieve struct size and offset\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
uint32_t child_fun_rel = *(uint32_t *) ((int64_t)data + offset - 0x04);
|
||||
child_fun_loc = offset + child_fun_rel;
|
||||
}
|
||||
|
||||
{
|
||||
int64_t pattern_offset = search(data, 0x40, "\x8d\x74\x01", 3, child_fun_loc);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: patch_db: failed to retrieve offset from base\n");
|
||||
g_pfree_song_offset = 0x54; // best effort
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pfree_song_offset = *(uint8_t *) ((int64_t)data + pattern_offset + 0x03);
|
||||
}
|
||||
|
||||
/* Adapt convergence value computation (skip cs_omni and customs) */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x84\xC0\x75\x11\x8D\x44\x24\x38", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: patch_db: cannot find convergence value computation\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x08;
|
||||
|
||||
skip_convergence_value_get_score = (void(*)()) (patch_addr + 0x05);
|
||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)hook_convergence_value_compute,
|
||||
(void **)&real_convergence_value_compute);
|
||||
}
|
||||
|
||||
/* skip cs_omni and customs in new stages pplist */
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x8A\x1E\x6A\x00\x51\xE8", 6, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: patch_db: cannot find pp increment computation\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x02;
|
||||
|
||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)hook_pp_increment_compute,
|
||||
(void **)&real_pp_increment_compute);
|
||||
|
||||
int64_t jump_addr_offset = search(data, dllSize, "\x8B\x54\x24\x5C\x0F\xB6\x42\x0E\x45", 9, 0);
|
||||
if (jump_addr_offset == -1) {
|
||||
LOG("popnhax: patch_db: cannot find pp increment computation next iter\n");
|
||||
return false;
|
||||
}
|
||||
skip_pp_list_elem = (void(*)()) ((int64_t)data + jump_addr_offset);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool option_full()
|
||||
{
|
||||
/* patch default values in memory init function */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\x88\x48\x1A\x88\x48\x1B\x88\x48\x1C", 9, 0, "\xC7\x40\x1A\x00\x00\x01\x00\x90\x90", 9))
|
||||
{
|
||||
LOG("popnhax: cannot set full options by default\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LOG("popnhax: always display full options\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool option_guide_se_off(){
|
||||
/* set guide SE OFF by default in all modes */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\xC6\x40\x24\x01\x88\x48\x25", 7, 3, "\x00", 1) /* unilab */
|
||||
&& !find_and_patch_hex(g_game_dll_fn, "\x89\x48\x20\x88\x48\x24\xC3\xCC", 8, 3, "\xC6\x40\x24\x01\xC3", 5) ) /* usaneko-kaimei */
|
||||
{
|
||||
LOG("popnhax: guidese_off: cannot set guide SE off by default\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LOG("popnhax: guidese_off: Guide SE OFF by default\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool option_net_ojama_off(){
|
||||
/* set netvs ojama OFF by default */
|
||||
{
|
||||
if (!find_and_patch_hex(g_game_dll_fn, "\xC6\x40\xFD\x00\xC6\x00\x01", 7, 6, "\x00", 1))
|
||||
{
|
||||
LOG("popnhax: netvs_off: cannot set net ojama off by default\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LOG("popnhax: netvs_off: net ojama OFF by default\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
@ -5230,11 +4716,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
LOG("popnhax: multiboot: auto disable omnimix patch (not compatible)\n");
|
||||
config.patch_db = false;
|
||||
}
|
||||
if (config.guidese_off && ( strcmp(config.force_datecode,"2016121400") < 0 ) )
|
||||
{
|
||||
LOG("popnhax: multiboot: auto disable Guide SE patch (not compatible)\n");
|
||||
config.guidese_off = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5414,8 +4895,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
if (config.patch_db) {
|
||||
LOG("popnhax: patching songdb\n");
|
||||
/* must be called after force_datecode */
|
||||
patch_db_power_points();
|
||||
patch_db_fix_cursor();
|
||||
patch_database(config.force_unlocks);
|
||||
}
|
||||
|
||||
@ -5430,13 +4909,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
}
|
||||
|
||||
if (config.force_full_opt)
|
||||
option_full();
|
||||
|
||||
if (config.netvs_off)
|
||||
option_net_ojama_off();
|
||||
|
||||
if (config.guidese_off)
|
||||
option_guide_se_off();
|
||||
patch_options();
|
||||
|
||||
if (config.fps_uncap)
|
||||
patch_fps_uncap();
|
||||
|
Loading…
Reference in New Issue
Block a user