diff --git a/dist/jb/gamestart-03.bat b/dist/jb/gamestart-03.bat index 8a9ab32..76acc78 100644 --- a/dist/jb/gamestart-03.bat +++ b/dist/jb/gamestart-03.bat @@ -3,6 +3,7 @@ cd /d %~dp0 if not exist dev\nvram mkdir dev\nvram +if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml if not exist dev\raw mkdir dev\raw diff --git a/dist/jb/gamestart-04.bat b/dist/jb/gamestart-04.bat index 33e786b..245e314 100644 --- a/dist/jb/gamestart-04.bat +++ b/dist/jb/gamestart-04.bat @@ -3,6 +3,7 @@ cd /d %~dp0 if not exist dev\nvram mkdir dev\nvram +if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml if not exist dev\raw mkdir dev\raw diff --git a/src/main/jbhook1/avs-boot.c b/src/main/jbhook1/avs-boot.c index 969fbd8..dccba69 100644 --- a/src/main/jbhook1/avs-boot.c +++ b/src/main/jbhook1/avs-boot.c @@ -52,18 +52,18 @@ static const struct hook_symbol jbhook1_log_gftools_hook_syms2[] = { .link = (void **) &real_ea3_boot}, }; -static void avs_boot_replace_property_uint32( - struct property_node *node, const char *name, uint32_t val) +static void avs_boot_create_property_str( + struct property *config, const char *name, const char *val) { struct property_node *tmp; - tmp = property_search(NULL, node, name); + tmp = property_node_create(config, NULL, PROPERTY_TYPE_STR, name, val); if (tmp) { - property_node_remove(tmp); + property_node_datasize(tmp); + } else { + log_fatal("Could not avs_boot_create_prop_str(%s, %s)", name, val); } - - property_node_create(NULL, node, PSMAP_TYPE_U32, name, val); } static void avs_boot_replace_property_str( @@ -81,11 +81,13 @@ static void avs_boot_replace_property_str( if (tmp) { property_node_datasize(tmp); + } else { + log_fatal("Could not avs_boot_replace_property_str(%s, %s)", name, val); } } static void my_avs_boot( - struct property_node *config, + struct property_node *_config, void *std_heap, size_t sz_std_heap, void *avs_heap, @@ -95,14 +97,44 @@ static void my_avs_boot( { log_info("Called my_avs_boot"); - avs_boot_replace_property_uint32(config, "log/level", 4); - avs_boot_replace_property_str( + // avshelper gates this behind a check that might not always be true + CreateDirectoryA("./CONF", 0); + CreateDirectoryA("./CONF/NVRAM", 0); + CreateDirectoryA("./CONF/RAW", 0); + + // The default config isn't very exciting, and we need to replace the NVRAM + // settings with our own anyway. Trying to edit the config almost always + // fails because of some weird fragmentation issues causing node insert to + // fail, so just recreate the entire thing from scratch. + uint8_t cfg_buf[2048]; + struct property *config = property_create( + PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE, + cfg_buf, + sizeof(cfg_buf)); + + log_assert(config); + + property_node_create( + config, NULL, PROPERTY_TYPE_U32, "/config/log/level", 4); + avs_boot_create_property_str(config, "/config/fs/root/device", "."); + avs_boot_create_property_str(config, "/config/fs/raw/device", "./CONF/RAW"); + avs_boot_create_property_str( config, "/config/fs/nvram/device", "./CONF/NVRAM"); - avs_boot_replace_property_str( - config, "/config/fs/raw/device", "./CONF/RAW"); + avs_boot_create_property_str(config, "/config/fs/nvram/fstype", "fs"); + avs_boot_create_property_str(config, "/config/fs/nvram/option", ""); + property_node_create( + config, NULL, PROPERTY_TYPE_U16, "/config/net/nr_protocol", 8); + property_node_create( + config, NULL, PROPERTY_TYPE_U16, "/config/net/nr_socket", 8); + property_node_create( + config, NULL, PROPERTY_TYPE_U8, "/config/net/enable_raw", 1); + + struct property_node *config_node = + property_search(config, NULL, "/config"); + log_assert(config_node); real_avs_boot( - config, + config_node, std_heap, sz_std_heap, avs_heap, @@ -168,4 +200,4 @@ void jbhook1_avs_boot_set_eamuse_addr(const struct net_addr *server_addr) &jbhook1_avs_boot_eamuse_server_addr, server_addr, sizeof(struct net_addr)); -} \ No newline at end of file +} diff --git a/src/main/jbhook1/dllmain.c b/src/main/jbhook1/dllmain.c index 57d62f7..42f8dc9 100644 --- a/src/main/jbhook1/dllmain.c +++ b/src/main/jbhook1/dllmain.c @@ -47,6 +47,29 @@ my_mwindow_create(HINSTANCE, void *, const char *, DWORD, DWORD, BOOL); static HWND(CDECL *real_mwindow_create)( HINSTANCE, void *, const char *, DWORD, DWORD, BOOL); +static BOOL STDCALL my_CreateProcessA( + LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation); +static BOOL(STDCALL *real_CreateProcessA)( + LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation); + static const struct hook_symbol init_hook_syms[] = { { .name = "mwindow_create", @@ -55,6 +78,17 @@ static const struct hook_symbol init_hook_syms[] = { }, }; +static const struct hook_symbol kernel32_hook_syms[] = { + { + .name = "CreateProcessA", + .patch = my_CreateProcessA, + .link = (void **) &real_CreateProcessA, + }, +}; + +// so our CreateProcessA hook can check +static bool vertical; + /** * This seems to be a good entry point to intercept before the game calls * anything important (very close to the start of WinMain). @@ -107,6 +141,7 @@ static HWND CDECL my_mwindow_create( jbhook1_log_gftools_init(); fullscreen = !config_gfx.windowed; + vertical = config_gfx.vertical; if (config_gfx.vertical) { DWORD tmp = window_width; @@ -175,9 +210,53 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx) /* Actual hooks for game specific stuff */ + hook_table_apply( + NULL, + "kernel32.dll", + kernel32_hook_syms, + lengthof(kernel32_hook_syms)); + acp_hook_init(); adapter_hook_init(); } return TRUE; } + +static BOOL STDCALL my_CreateProcessA( + LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) +{ + LPSTR rot_arg; + + // de-rotate the error window if needed. In theory this should parse the + // commandline properly, in practice this works on all the .exe jubeats. + if (vertical && lpCommandLine) { + if ((rot_arg = strstr(lpCommandLine, " -R90 "))) { // jubeat 01 + memcpy(rot_arg, " -R0 ", strlen(" -R0 ")); + } else if ((rot_arg = + strstr(lpCommandLine, " -rot:90 "))) { // jubeat 02 + memcpy(rot_arg, " -rot:0 ", strlen(" -rot:0 ")); + } + } + + return real_CreateProcessA( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation); +}