Bemanitools v5.26 release

This commit is contained in:
icex2
2019-09-27 22:36:50 +02:00
commit cbd7720349
718 changed files with 62731 additions and 0 deletions
+276
View File
@@ -0,0 +1,276 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "imports/avs.h"
#include "imports/avs-ea3.h"
#include "launcher/avs-context.h"
#include "launcher/ea3-config.h"
#include "launcher/module.h"
#include "launcher/options.h"
#include "launcher/property.h"
#include "launcher/stubs.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/mem.h"
#include "util/str.h"
#include "util/codepage.h"
/* Gratuitous API changes orz */
static AVS_LOG_WRITER(log_callback, chars, nchars, ctx)
{
wchar_t *utf16;
char *utf8;
int utf16_len;
int utf8_len;
int result;
DWORD nwritten;
HANDLE console;
HANDLE file;
/* Ignore existing NUL terminator */
nchars--;
/* Transcode shit_jis to UTF-8 */
utf16_len = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, NULL, 0);
if (utf16_len == 0) {
abort();
}
utf16 = xmalloc(sizeof(*utf16) * utf16_len);
result = MultiByteToWideChar(CP_SHIFT_JIS, 0, chars, nchars, utf16,
utf16_len);
if (result == 0) {
abort();
}
utf8_len = WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, NULL, 0,
NULL, NULL);
if (utf8_len == 0) {
abort();
}
utf8 = xmalloc(utf8_len + 2);
result = WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8, utf8_len,
NULL, NULL);
if (result == 0) {
abort();
}
#if AVS_VERSION >= 1500
utf8[utf8_len + 0] = '\r';
utf8[utf8_len + 1] = '\n';
utf8_len += 2;
#endif
/* Write to console and log file */
file = (HANDLE) ctx;
console = GetStdHandle(STD_OUTPUT_HANDLE);
if (ctx != INVALID_HANDLE_VALUE) {
WriteFile(file, utf8, utf8_len, &nwritten, NULL);
}
WriteFile(console, utf8, utf8_len, &nwritten, NULL);
/* Clean up */
free(utf8);
free(utf16);
}
int main(int argc, const char **argv)
{
int i;
const char *hook_dll;
bool ok;
HANDLE logfile;
struct ea3_ident ea3;
struct module_context module;
struct options options;
struct property *app_config;
struct property *avs_config;
struct property *ea3_config;
struct property_node *app_config_root;
struct property_node *avs_config_root;
struct property_node *ea3_config_root;
log_to_writer(log_writer_file, stdout);
/* Read command line */
options_init(&options);
if (!options_read_cmdline(&options, argc, argv)) {
options_print_usage();
return EXIT_FAILURE;
}
/* If enabled, wait for a remote debugger to attach. Spawning launcher
with a debugger crashes it for some reason (e.g. on jubeat08). However,
starting the launcher separately and attaching a remote debugger works */
if (options.remote_debugger) {
log_info("Waiting until debugger attaches to remote process...");
while (true) {
BOOL res = FALSE;
if (!CheckRemoteDebuggerPresent(GetCurrentProcess(), &res)) {
log_fatal("CheckRemoteDebuggerPresent failed: %08x",
(unsigned int) GetLastError());
}
if (res) {
log_info("Debugger attached, resuming");
break;
}
Sleep(1000);
}
}
/* Start up AVS */
if (options.logfile != NULL) {
logfile = CreateFileA(options.logfile, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, 0, NULL);
} else {
logfile = INVALID_HANDLE_VALUE;
}
avs_config = boot_property_load(options.avs_config_path);
avs_config_root = property_search(avs_config, 0, "/config");
if (avs_config_root == NULL) {
log_fatal("%s: /config missing", options.avs_config_path);
}
avs_context_init(avs_config_root,
options.avs_heap_size, options.std_heap_size,
log_callback, logfile);
boot_property_free(avs_config);
log_to_external(log_body_misc, log_body_info, log_body_warning,
log_body_fatal);
/* Load game DLL */
module_context_init(&module, options.module);
/* Load hook DLLs */
for (i = 0 ; i < options.hook_dlls.nitems ; i++) {
hook_dll = *array_item(char *, &options.hook_dlls, i);
if (LoadLibraryA(hook_dll) == NULL) {
LPSTR buffer;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &buffer, 0, NULL);
log_fatal("%s: Failed to load hook DLL: %s", hook_dll, buffer);
LocalFree(buffer);
}
}
/* Inject GetModuleHandle hooks */
stubs_init();
/* Prepare ea3 config */
ea3_config = boot_property_load(options.ea3_config_path);
ea3_config_root = property_search(ea3_config, 0, "/ea3");
if (ea3_config_root == NULL) {
log_fatal("%s: /ea3 missing", options.ea3_config_path);
}
ea3_ident_init(&ea3);
if (!ea3_ident_from_property(&ea3, ea3_config)) {
log_fatal("%s: Error reading IDs from config file",
options.ea3_config_path);
}
if (options.softid != NULL) {
str_cpy(ea3.softid, lengthof(ea3.softid), options.softid);
}
if (options.pcbid != NULL) {
str_cpy(ea3.pcbid, lengthof(ea3.pcbid), options.pcbid);
}
if (!ea3.hardid[0]) {
ea3_ident_hardid_from_ethernet(&ea3);
}
/* Invoke dll_entry_init */
app_config = boot_property_load(options.app_config_path);
app_config_root = property_search(app_config, 0, "/param");
if (app_config_root == NULL) {
log_fatal("%s: /param missing", options.app_config_path);
}
if (IsDebuggerPresent()) {
/* Opportunity for breakpoint setup etc */
DebugBreak();
}
ok = ea3_ident_invoke_module_init(&ea3, &module, app_config_root);
if (!ok) {
log_fatal("%s: dll_module_init() returned failure", options.module);
}
boot_property_free(app_config);
ea3_ident_to_property(&ea3, ea3_config);
/* Start up e-Amusement client */
ea3_boot(ea3_config_root);
boot_property_free(ea3_config);
/* Run application */
module_context_invoke_main(&module);
/* Shut down */
ea3_shutdown();
log_to_writer(log_writer_file, stdout);
avs_context_fini();
if (logfile != INVALID_HANDLE_VALUE) {
CloseHandle(logfile);
}
module_context_fini(&module);
options_fini(&options);
return EXIT_SUCCESS;
}