forked from Popn_Tools/popnhax
Compare commits
No commits in common. "c099d5da17c7bbf53e798fe90d90845ae6b4cc79" and "bec2d2a39f43a6bcc6a304808a848f2aab2fcc58" have entirely different histories.
c099d5da17
...
bec2d2a39f
@ -3985,54 +3985,9 @@ bool g_mystery_bpm = 0;
|
|||||||
uint16_t *g_base_bpm_ptr = 0; //will point to g_low_bpm or g_hi_bpm according to mode
|
uint16_t *g_base_bpm_ptr = 0; //will point to g_low_bpm or g_hi_bpm according to mode
|
||||||
uint16_t g_low_bpm = 0;
|
uint16_t g_low_bpm = 0;
|
||||||
uint16_t g_hi_bpm = 0;
|
uint16_t g_hi_bpm = 0;
|
||||||
uint16_t g_longest_bpm = 0;
|
|
||||||
uint32_t g_hispeed = 0;
|
uint32_t g_hispeed = 0;
|
||||||
unsigned char *g_chart_addr = 0;
|
|
||||||
bool g_longest_bpm_old_chart = false;
|
|
||||||
|
|
||||||
typedef struct chart_chunk_s {
|
|
||||||
uint32_t timestamp;
|
|
||||||
uint16_t operation;
|
|
||||||
uint16_t data;
|
|
||||||
uint32_t duration;
|
|
||||||
} chart_chunk_t;
|
|
||||||
#define CHART_OP_BPM 0x0445
|
|
||||||
#define CHART_OP_END 0x0645
|
|
||||||
|
|
||||||
void compute_longest_bpm(){
|
|
||||||
chart_chunk_t* chunk = NULL;
|
|
||||||
unsigned char *chart_ptr = g_chart_addr;
|
|
||||||
int chunk_size = g_longest_bpm_old_chart? 8 : 12;
|
|
||||||
uint32_t prev_timestamp = 0x64;
|
|
||||||
uint16_t prev_bpm = 0;
|
|
||||||
|
|
||||||
uint32_t max_duration = 0;
|
|
||||||
uint16_t longest_bpm = 0;
|
|
||||||
do {
|
|
||||||
chunk = (chart_chunk_t*) chart_ptr;
|
|
||||||
|
|
||||||
if ( chunk->operation == CHART_OP_BPM || chunk->operation == CHART_OP_END )
|
|
||||||
{
|
|
||||||
if (prev_bpm)
|
|
||||||
{
|
|
||||||
uint32_t duration = chunk->timestamp - prev_timestamp;
|
|
||||||
//if prev_bpm doesn't have an entry, make one
|
|
||||||
|
|
||||||
//add duration to prev_bpm entry
|
|
||||||
|
|
||||||
//check if prev_bpm entry is > max_duration : max_duration=entry[prev_bpm] and longest_bpm=prev_bpm if required
|
|
||||||
|
|
||||||
}
|
|
||||||
prev_bpm = chunk->data;
|
|
||||||
prev_timestamp = chunk->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
chart_ptr += chunk_size;
|
|
||||||
} while ( chunk->operation != CHART_OP_END );
|
|
||||||
|
|
||||||
g_longest_bpm = longest_bpm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool g_set_hispeed_addr = false;
|
||||||
void (*real_set_hispeed)();
|
void (*real_set_hispeed)();
|
||||||
void hook_set_hispeed()
|
void hook_set_hispeed()
|
||||||
{
|
{
|
||||||
@ -4041,33 +3996,6 @@ void hook_set_hispeed()
|
|||||||
real_set_hispeed();
|
real_set_hispeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*real_retrieve_chart_addr)();
|
|
||||||
void hook_retrieve_chart_addr()
|
|
||||||
{
|
|
||||||
__asm("push eax\n");
|
|
||||||
__asm("push ecx\n");
|
|
||||||
__asm("push edx\n");
|
|
||||||
__asm("mov %0, esi\n":"=a"(g_chart_addr): :);
|
|
||||||
__asm("call %0\n"::"r"(compute_longest_bpm));
|
|
||||||
__asm("pop edx\n");
|
|
||||||
__asm("pop ecx\n");
|
|
||||||
__asm("pop eax\n");
|
|
||||||
real_retrieve_chart_addr();
|
|
||||||
}
|
|
||||||
void (*real_retrieve_chart_addr_old)();
|
|
||||||
void hook_retrieve_chart_addr_old()
|
|
||||||
{
|
|
||||||
__asm("push eax\n");
|
|
||||||
__asm("push ecx\n");
|
|
||||||
__asm("push edx\n");
|
|
||||||
__asm("mov %0, edi\n":"=a"(g_chart_addr): :);
|
|
||||||
__asm("call %0\n"::"r"(compute_longest_bpm));
|
|
||||||
__asm("pop edx\n");
|
|
||||||
__asm("pop ecx\n");
|
|
||||||
__asm("pop eax\n");
|
|
||||||
real_retrieve_chart_addr_old();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called a lot of times: when arriving on option select, and when changing/navigating *any* option
|
* This is called a lot of times: when arriving on option select, and when changing/navigating *any* option
|
||||||
* I'm hooking here to set hi-speed to the target BPM
|
* I'm hooking here to set hi-speed to the target BPM
|
||||||
@ -4079,19 +4007,13 @@ void hook_read_hispeed()
|
|||||||
__asm("push eax\n");
|
__asm("push eax\n");
|
||||||
__asm("push ecx\n");
|
__asm("push ecx\n");
|
||||||
__asm("push edx\n");
|
__asm("push edx\n");
|
||||||
|
if ( g_bypass_hispeed ) //bypass for mystery BPM and soflan songs (to avoid hi-speed being locked since target won't change)
|
||||||
|
__asm("jmp leave_read_hispeed\n");
|
||||||
|
|
||||||
__asm("mov %0, word ptr [ebp+0xA1A]\n":"=a"(g_low_bpm): :);
|
__asm("mov %0, word ptr [ebp+0xA1A]\n":"=a"(g_low_bpm): :);
|
||||||
__asm("mov %0, word ptr [ebp+0xA1C]\n":"=a"(g_hi_bpm): :);
|
__asm("mov %0, word ptr [ebp+0xA1C]\n":"=a"(g_hi_bpm): :);
|
||||||
__asm("mov %0, byte ptr [ebp+0xA1E]\n":"=a"(g_mystery_bpm): :);
|
__asm("mov %0, byte ptr [ebp+0xA1E]\n":"=a"(g_mystery_bpm): :);
|
||||||
|
|
||||||
if ( g_bypass_hispeed || g_target_bpm == 0 ) //bypass for mystery BPM and soflan songs (to avoid hi-speed being locked since target won't change)
|
|
||||||
{
|
|
||||||
__asm("jmp leave_read_hispeed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( g_low_bpm == g_hi_bpm )
|
|
||||||
g_longest_bpm = g_hi_bpm;
|
|
||||||
|
|
||||||
g_hispeed_double = (double)g_target_bpm / (double)(*g_base_bpm_ptr/10.0);
|
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
|
g_hispeed = (uint32_t)(g_hispeed_double+0.5); //rounding to nearest
|
||||||
if (g_hispeed > 0x64) g_hispeed = 0x0A;
|
if (g_hispeed > 0x64) g_hispeed = 0x0A;
|
||||||
@ -4200,9 +4122,7 @@ bool patch_hispeed_auto(uint8_t mode, uint16_t default_bpm)
|
|||||||
g_base_bpm_ptr = &g_hi_bpm;
|
g_base_bpm_ptr = &g_hi_bpm;
|
||||||
if (mode == 2)
|
if (mode == 2)
|
||||||
g_base_bpm_ptr = &g_low_bpm;
|
g_base_bpm_ptr = &g_low_bpm;
|
||||||
else if (mode == 3)
|
|
||||||
g_base_bpm_ptr = &g_longest_bpm;
|
|
||||||
|
|
||||||
g_target_bpm = default_bpm;
|
g_target_bpm = default_bpm;
|
||||||
/* retrieve hi-speed address */
|
/* retrieve hi-speed address */
|
||||||
{
|
{
|
||||||
@ -4257,44 +4177,13 @@ bool patch_hispeed_auto(uint8_t mode, uint16_t default_bpm)
|
|||||||
(void **)&real_decrease_hispeed);
|
(void **)&real_decrease_hispeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute longest bpm for mode 3 */
|
|
||||||
if (mode == 3)
|
|
||||||
{
|
|
||||||
int64_t pattern_offset = search(data, dllSize, "\x00\x00\x72\x05\xB9\xFF", 6, 0);
|
|
||||||
if (pattern_offset == -1) {
|
|
||||||
LOG("popnhax: auto hi-speed: cannot find chart address\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* detect if usaneko+ */
|
|
||||||
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x0F;
|
|
||||||
uint8_t check_byte = *((uint8_t *)(patch_addr + 1));
|
|
||||||
|
|
||||||
if (check_byte == 0x04)
|
|
||||||
{
|
|
||||||
patch_addr += 9;
|
|
||||||
g_longest_bpm_old_chart = true;
|
|
||||||
LOG("popnhax: auto hi-speed: old game version\n");
|
|
||||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)hook_retrieve_chart_addr_old,
|
|
||||||
(void **)&real_retrieve_chart_addr_old);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
patch_addr += 11;
|
|
||||||
MH_CreateHook((LPVOID)(patch_addr), (LPVOID)hook_retrieve_chart_addr,
|
|
||||||
(void **)&real_retrieve_chart_addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG("popnhax: auto hi-speed enabled");
|
LOG("popnhax: auto hi-speed enabled");
|
||||||
if (g_target_bpm != 0)
|
if (g_target_bpm != 0)
|
||||||
LOG(" with default %hubpm", g_target_bpm);
|
LOG(" with default %hubpm", g_target_bpm);
|
||||||
if (mode == 2)
|
if (mode == 1)
|
||||||
LOG(" (lower bpm target)");
|
|
||||||
else if (mode == 3)
|
|
||||||
LOG(" (longest bpm target)");
|
|
||||||
else
|
|
||||||
LOG(" (higher bpm target)");
|
LOG(" (higher bpm target)");
|
||||||
|
else if (mode == 2)
|
||||||
|
LOG(" (lower bpm target)");
|
||||||
|
|
||||||
LOG("\n");
|
LOG("\n");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user