From de69af2d66842e6e25cd4cb6ede5596d5c388735 Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Mon, 22 Apr 2024 01:28:04 +0200 Subject: [PATCH] ALL SONGS subcategory --- popnhax/custom_categs.cc | 71 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/popnhax/custom_categs.cc b/popnhax/custom_categs.cc index 8984bce..b2dba8e 100644 --- a/popnhax/custom_categs.cc +++ b/popnhax/custom_categs.cc @@ -58,6 +58,8 @@ typedef struct { subcategory_s* subcategories; uint32_t g_subcateg_count = 0; +//subcategories[0] is the "ALL SONGS" virtual subcategory, +//actual subcategories then go from subcategories[1] to subcategories[g_subcateg_count] struct property *load_prop_file(const char *filename); @@ -80,6 +82,10 @@ static void add_song_to_subcateg(uint32_t songid, subcategory_s* subcateg) subcateg->songlist = (uint32_t *) realloc(subcateg->songlist, sizeof(uint32_t)*(++subcateg->size)); subcateg->songlist[subcateg->size-1] = songid; subcateg->songlist[subcateg->size-1] |= 0x00060000; // game wants this otherwise only easy difficulty will appear + + // Also add it to the "ALL SONGS" subcategory + subcategories[0].songlist = (uint32_t *) realloc(subcategories[0].songlist, sizeof(uint32_t)*(++subcategories[0].size)); + subcategories[0].songlist[subcategories[0].size-1] = subcateg->songlist[subcateg->size-1]; } } @@ -87,8 +93,9 @@ static subcategory_s* get_subcateg(char *title) { for (uint32_t i = 0; i < g_subcateg_count; i++) { - if (strcmp(title, subcategories[i].name) == 0) - return &(subcategories[i]); + //iterating over actual subcategories, excluding "ALL SONGS" + if (strcmp(title, subcategories[i+1].name) == 0) + return &(subcategories[i+1]); } return NULL; } @@ -116,16 +123,16 @@ uint32_t tmp_str_addr; void (*real_event_categ_generation)(); void hook_event_categ_generation() { - //chaine dans [esp+0x1C], on check si l'adresse correspond à l'une de nos subcateg - //si c'est pas le cas on s'en va sans rien faire - //si c'est le cas alors on met les coord de début et fin dans la struct_songlist et on envoie l'adresse de struct sur eax + //[esp+0x1C] contains the subcategory name string pointer, I compare it with my subcategories string pointers.. + // no match found -> we're actually processing the EVENT category, leave + // match found -> I need to fix eax with a pointer to my songlist before the subcall to the subcategory generating function __asm("mov _new_song_list, eax"); //save original intended value __asm("push ecx"); __asm("push edx"); - __asm("mov ebx, [esp+0x2C]\n"); + __asm("mov ebx, [esp+0x30]\n"); // +0x30 due to a couple implicit "push" added by the compiler __asm("mov _tmp_str_addr, ebx\n"); - for (uint32_t i = 0; i < g_subcateg_count; i++) + for (uint32_t i = 0; i < g_subcateg_count+1; i++) { if ( (uint32_t)subcategories[i].name == tmp_str_addr ) { @@ -154,7 +161,7 @@ void get_subcateg_name_impl() } uint32_t reimpl_value_1; -uint32_t reimpl_value_2; //commun aux deux fonctions +uint32_t reimpl_value_2; void (*get_subcateg_size)() = &get_subcateg_size_impl; void (*get_subcateg_name)() = &get_subcateg_name_impl; void (*reimpl_func_1)(); @@ -268,7 +275,12 @@ void categ_inject_songlist_subcategs() __asm("inc ebx\n"); __asm("mov dword ptr ss:[esp+0x34], ebx\n"); - __asm("cmp ebx, [_g_subcateg_count]\n"); + //effectively __asm("cmp ebx, [_g_subcateg_count+1]\n"); (to take "ALL SONGS" into account) + __asm("push edx\n"); + __asm("mov edx, [_g_subcateg_count]\n"); + __asm("inc edx\n"); + __asm("cmp ebx, edx\n"); + __asm("pop edx\n"); __asm("jb subcateg_loop\n"); __asm("mov ecx, dword ptr ss:[esp+0x24]\n"); @@ -340,23 +352,6 @@ void hook_categ_build_songlist() real_categ_build_songlist(); } -uint32_t songid_mask = 0; -void apply_mask_to_all() -{ - __asm("push eax"); - __asm("mov eax, [ebx]"); - __asm("mov _songid_mask, eax"); - __asm("pop eax"); - songid_mask &= 0xFFFF0000; - for (uint32_t i = 0; i < g_subcateg_count; i++) - { - for (uint32_t j = 0; j < subcategories[i].size; j++) - { - subcategories[i].songlist[j] |= songid_mask; - } - } -} - void (*real_categ_printf_call)(); void (*real_categ_title_printf)(); void hook_categ_title_printf() @@ -551,8 +546,8 @@ static void parse_musicdb(const char *input_filename) { subcategory_s *subcateg = get_subcateg(title); if ( subcateg == NULL ) { - subcategories = (subcategory_s*)realloc(subcategories, sizeof(subcategory_s)*(++g_subcateg_count)); - subcateg = &(subcategories[g_subcateg_count-1]); + subcategories = (subcategory_s*)realloc(subcategories, sizeof(subcategory_s)*((++g_subcateg_count)+1)); + subcateg = &(subcategories[g_subcateg_count]); subcateg->name = strdup(title); subcateg->songlist = NULL; subcateg->size = 0; @@ -575,6 +570,11 @@ static void parse_musicdb(const char *input_filename) { static void load_databases() { SearchFile s; g_subcateg_count = 0; + subcategories = (subcategory_s*)realloc(subcategories, sizeof(subcategory_s)*(1)); + subcategories[0].name = strdup("ALL SONGS"); + subcategories[0].songlist = NULL; + subcategories[0].size = 0; + printf("musicdb search...\n"); s.search("data_mods", "xml", true); auto result = s.getResult(); @@ -586,6 +586,13 @@ static void load_databases() { printf("(musicdb) Loading %s...\n", result[i].c_str()); parse_musicdb(result[i].c_str()); } + + for (uint32_t i = 0; i < g_subcateg_count+1; i++) + { + if (subcategories[i].size != 0) + LOG(" %s (%d songs)", subcategories[i].name, subcategories[i].size); + } + LOG("\n"); } bool patch_custom_categs(const char *dllFilename, uint8_t mode, uint16_t min, uint16_t max) @@ -602,12 +609,4 @@ bool patch_custom_categs(const char *dllFilename, uint8_t mode, uint16_t min, ui } return patch_custom_categ(dllFilename); -/* - LOG("Subcateg list :\n"); - for (uint32_t i = 0; i < g_subcateg_count; i++) - { - if (subcategories[i].size != 0) - LOG(" %s (%d songs)", subcategories[i].name, subcategories[i].size); - } - */ } \ No newline at end of file