diff --git a/Module.mk b/Module.mk index 3359a25..09d2cf2 100644 --- a/Module.mk +++ b/Module.mk @@ -123,6 +123,7 @@ include src/main/iidxhook5/Module.mk include src/main/iidxhook6/Module.mk include src/main/iidxhook7/Module.mk include src/main/iidxhook8/Module.mk +include src/main/iidxhook9/Module.mk include src/main/iidxio/Module.mk include src/main/iidxio-ezusb/Module.mk include src/main/iidxio-ezusb2/Module.mk @@ -352,6 +353,22 @@ $(zipdir)/iidx-25-to-26.zip: \ $(V)echo ... $@ $(V)zip -j $@ $^ +$(zipdir)/iidx-27.zip: \ + build/bin/avs2_1700-64/iidxhook9.dll \ + build/bin/avs2_1700-64/launcher.exe \ + build/bin/indep-64/config.exe \ + build/bin/indep-64/eamio.dll \ + build/bin/indep-64/geninput.dll \ + build/bin/indep-64/iidxio.dll \ + build/bin/indep-64/vefxio.dll \ + dist/iidx/config.bat \ + dist/iidx/gamestart-27.bat \ + dist/iidx/iidxhook-27.conf \ + dist/iidx/vefx.txt \ + | $(zipdir)/ + $(V)echo ... $@ + $(V)zip -j $@ $^ + $(zipdir)/iidx-hwio-x86.zip: \ build/bin/indep-32/eamio-icca.dll \ build/bin/indep-32/iidxio-ezusb.dll \ @@ -563,6 +580,7 @@ $(BUILDDIR)/bemanitools.zip: \ $(zipdir)/iidx-20.zip \ $(zipdir)/iidx-21-to-24.zip \ $(zipdir)/iidx-25-to-26.zip \ + $(zipdir)/iidx-27.zip \ $(zipdir)/iidx-hwio-x86.zip \ $(zipdir)/iidx-hwio-x64.zip \ $(zipdir)/jb-01.zip \ diff --git a/dist/iidx/gamestart-27.bat b/dist/iidx/gamestart-27.bat new file mode 100644 index 0000000..04a3909 --- /dev/null +++ b/dist/iidx/gamestart-27.bat @@ -0,0 +1,16 @@ +@echo off +cd /d %~dp0 + +if not exist dev mkdir dev +if not exist dev\e mkdir dev\e +if not exist dev\g mkdir dev\g +if not exist dev\nvram mkdir dev\nvram +if not exist dev\raw mkdir dev\raw +if not exist dev\raw\log mkdir dev\raw\log +if not exist dev\raw\fscache mkdir dev\raw\fscache + +for /R prop\defaults %%D in (*.*) do ( + if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram +) + +launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-27.conf %* diff --git a/dist/iidx/iidxhook-27.conf b/dist/iidx/iidxhook-27.conf new file mode 100644 index 0000000..7627a20 --- /dev/null +++ b/dist/iidx/iidxhook-27.conf @@ -0,0 +1,63 @@ +# Disable card reader emulation and enable usage of real card reader hardware on COM0 (for games supporting slotted readers) +io.disable_card_reader_emu=false + +# Disable BIO2 emulation and enable usage of real BIO2 hardware +io.disable_bio2_emu=false + +# Disables the poll limiter, warning very high CPU usage may arise +io.disable_poll_limiter=false + +# Lightning cab mode (requires additional IO emulation) +io.lightning_mode=false + +# Disable camera connection +io.disable_cams=false + +# Disables the built in file hooks, requiring manual file creation +io.disable_file_hooks=false + +# Disables the camera emulation +cam.disable_emu=false + +# Override camera device ID detection (copy from device manager, do not escape) +cam.device_id1= + +# Override camera device ID detection (copy from device manager, do not escape) +cam.device_id2= + +# Run the game in a framed window (requires windowed option) +gfx.framed=true + +# Run the game windowed +gfx.windowed=false + +# Confine mouse coursor to window +gfx.confined=false + +# Windowed width, -1 for default size +gfx.window_width=-1 + +# Windowed height, -1 for default size +gfx.window_height=-1 + +# Forced refresh rate, -1 to not force any (try 59 or 60 if monitor check fails to lock on high refresh rate monitors) +gfx.forced_refresh_rate=-1 + +# D3D9ex device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter +gfx.device_adapter=-1 + +# Orientation to force monitor into, -1 to use default, 0, 1, 2, 3 to do 0, 90, 180, 270 degrees +gfx.force_orientation=-1 + +# IP of adapter to force override with +adapter.override_ip= + +# Force ASIO audio mode/device (if applicable / TDJ default) +asio.force_asio=false + +# Force WASAPI audio mode (if applicable / LDJ default) +asio.force_wasapi=true + +# The ASIO device name to use +asio.device_name=XONAR SOUND CARD(64) + diff --git a/doc/iidxhook/README.md b/doc/iidxhook/README.md index a65dc70..e248c55 100644 --- a/doc/iidxhook/README.md +++ b/doc/iidxhook/README.md @@ -23,6 +23,7 @@ games: * [iidxhook6](iidxhook6.md): Tricoro * [iidxhook7](iidxhook7.md): SPADA, PENDUAL, copula, SINOBUZ * [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage +* [iidxhook8](iidxhook9.md): Heroic Verse When building kactools, independent packages are created for each set of games which are ready to be dropped on top of vanilla AC data dumps. We recommend diff --git a/doc/iidxhook/iidxhook9.md b/doc/iidxhook/iidxhook9.md new file mode 100644 index 0000000..b06be26 --- /dev/null +++ b/doc/iidxhook/iidxhook9.md @@ -0,0 +1,179 @@ +# Game list + +The following games are compatible with this version of iidxhook: +* Heroic Verse + +The games must be bootstrapped using [launcher](../launcher.md). + +# Data setup and running the game + +## Supported versions of Windows + +This version requires at least Win 7 x64 and will not run, like the +former versions, on Win XP x86! + +## Dependencies + +Make sure to have the following dependencies installed: +* DirectX 9 +* Visual C++ 2010 Redistributable Package (x64) + +## Data setup + +We assume that you are using a clean/vanilla data dump. Ensure your ("concents") +folder with your unpacked data looks like this: +- data +- modules +- prop + +* Copy/Move all files from the *modules* directory to the root folder, so they +are located next to the *data* and *prop* folders. +* Copy all files from *prop/defaults* to the *prop* folder. +* Setup proper paths for *dev/nvram* and *dev/raw* in *prop/avs-config.xml* by +replacing the **-block in that file with the following block: +``` + + + . + + + + + + 256 + 256 + +``` +* Unpack the package containing iidxhook9 into the root folder so iidxhook9.dll +and all other files are located in the same folder as *data*, *prop*, +*bm2dx.dll*, etc. +* Run the gamestart-XX.bat file as admin. Where XX matches the version you +want to run. + +* Note: if you know what you're doing and would like to keep all the dlls in the +*modules* folder then you extract iidxhook9 into that directory, move +gamestart-XX.bat up, and edit the paths. + +# Configuring iidxhook + +The hook library can be configured via cmd arguments or a configuration file. +The latter is generated (*iidxhook-XX.conf* in the same directory) on the first +start of the game using the gamestart-XX.bat file (again, XX matches your target +game version). It contains default values for all available parameters and +comments explaining each parameter. Please follow the comments when configuring +your setup. + +Add the argument *-h* when running gamestart-XX.bat +(e.g. *gamestart-XX.bat -h*) to print help/usage information with a list of +all available parameters. Every parameter can be either set as command line +argument or using a configuration file. + +To set a parameter from the command line, just add it as an argument after +the bat file like this +``` +gamestart-09.bat -p gfx.windowed=true -p gfx.framed=true +``` + +The syntax for the "key=value" is the same as in the config file. Make sure +to have a pre-ceeding "-p" for every parameter added. + +However, if a parameter is specifed in the configuration file and as a command +line argument, the command line argument overrides the config file's value. + +# Eamuse network setup + +If you want to run the games online, you need a valid PCBID and the service URL. +Open *prop/ea3-config.xml* and set the values of the *ea3/id/pcbid* and +*ea3/network/services* nodes accordingly. + +Run the game with the gamestart-XX.bat file and enable network on the operator +menu. When enabled, the game seems to hang and expects you to power +cycle the machine (i.e. quit the game and restart it). + +# Real hardware support + +### BIO2 hardware + +Set the *io.disable_bio2_emu* configuration value to *1* to disable BIO2 +emulation to run the game using real BIO2 hardware. + +### Ezusb and other + +Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use +the IO2 EZUSB board, to run the game on real hardware. Thanks to a common +abstraction layer, you can also use custom IO boards or whatever Konami hardware +is going to be available in the future. Obviously, someone has to write a +driver, first. + +## Slotted/Wave pass card readers + +Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your +slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers +conencted and and assigned to *COM1*. + +### ICCA device settings (device manager) +* Port: COM1 +* BAUD rate: 57600 +* Data bits: 8 +* Parity: None +* Stop bits: 1 +* Flow control: None + +If you encounter issues after the game opened the device, e.g. application +stuck, try a USB <-> COM dongle instead of using one of the COM ports of the +mainboard. + +# Troubleshooting and FAQ + +## The game does not run "well" (frame drops, drifting offsync etc) +This can be related to various issues: +* Make sure to run the game as (true) Administrator especially on Windows 7 and +newer. This will also get rid of various other errors (see below) that are +related to permission issues. +* Run the game's process with a higher priority: +``` +start "" /relatime "gamestart.bat" +``` +* Enforce v-sync enabled in your GPU settings. +* Ensure that you have a constant refresh rate around the 60 hz (59.9xx or 60.0xx) +that is not jumping around. Use the timebase feature of one of the newer games to +check that or enable iidxhook's timebase and check the log output for the +determined value. Run this a few times and check if the results differ. + +## "NETWORK WARNING" instead of "NETWORK OK" +This can be caused by: +* Invalid PCBID +* Firewall blocking connections +* Invalid eamuse url or port specified +* Game is not run using the Administrator account +Make sure to check these things first + +## My songs are offsync +From IIDX 20 (or Lincle very final revision) onwards, the game comes with +a built-in auto timebase option ("monitor check" on startup) which +dynamically, detects the refresh rate of your current setup. Thus, BT5's +timebase option is not included from this hook version onwards, anymore. +Ensure that refresh rate displayed is very stable, e.g. 60.00x hz, and the +game should be able to provide you with a smooth and sync game experience. + +## My game runs too fast +iidxhook can limit the frame rate for you (refer to help/config file) + +## My game crashes when I try fullscreen +Use dxwnd and set settings like "Acquire admin caps" and "Fullscreen only" + +## Background videos aren't working. When starting a song, windows is playing the error sound and a message box appears +You are missing a codec to decode and play the videos. There are different +methods available to get background videos working. Probably, the easiest +solution: grab the CLVSD.ax file and go to Start -> Run -> regsvr32 clvsd.ax +Make sure to run cmd.exe as Administrator, otherwise you will get errors caused +by invalid permissions. + +## I installed the CLVSD.ax codec but the game crashes or displays a message box that tells me to disable my debugger +If songs keep crashing upon start and you get an error message that says +``` +DirectShow Texture3D Sample +Could not create source filter to graph! hr=0x80040266 +``` +despite having the codec (CLVSD.ax) installed, remove the debug flag (*-D*) +from gamestart or use a CLVSD.ax codec which has the debugger checks removed. diff --git a/src/main/asio/config-asio.c b/src/main/asio/config-asio.c index 542d70d..b69882f 100644 --- a/src/main/asio/config-asio.c +++ b/src/main/asio/config-asio.c @@ -5,9 +5,11 @@ #include "util/log.h" #define ASIOHOOK_CONFIG_IO_FORCE_ASIO_KEY "asio.force_asio" +#define ASIOHOOK_CONFIG_IO_FORCE_WASAPI_KEY "asio.force_wasapi" #define ASIOHOOK_CONFIG_IO_ASIO_DEVICE_NAME_KEY "asio.device_name" #define ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_ASIO_VALUE false +#define ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_WASAPI_VALUE false #define ASIOHOOK_CONFIG_IO_DEFAULT_ASIO_DEVICE_NAME_VALUE \ "XONAR SOUND CARD(64)" @@ -17,7 +19,13 @@ void asiohook_config_init(struct cconfig *config) config, ASIOHOOK_CONFIG_IO_FORCE_ASIO_KEY, ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_ASIO_VALUE, - "Force ASIO audio mode/device"); + "Force ASIO audio mode/device (if applicable)"); + + cconfig_util_set_bool( + config, + ASIOHOOK_CONFIG_IO_FORCE_WASAPI_KEY, + ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_WASAPI_VALUE, + "Force WASAPI audio mode (if applicable)"); cconfig_util_set_str( config, @@ -40,6 +48,17 @@ void asiohook_config_asio_get( ASIOHOOK_CONFIG_IO_FORCE_ASIO_KEY, ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_ASIO_VALUE); } + if (!cconfig_util_get_bool( + config, + ASIOHOOK_CONFIG_IO_FORCE_WASAPI_KEY, + &config_asio->force_wasapi, + ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_WASAPI_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + ASIOHOOK_CONFIG_IO_FORCE_WASAPI_KEY, + ASIOHOOK_CONFIG_IO_DEFAULT_FORCE_WASAPI_VALUE); + } if (!cconfig_util_get_str( config, diff --git a/src/main/asio/config-asio.h b/src/main/asio/config-asio.h index 751fb13..3df72f5 100644 --- a/src/main/asio/config-asio.h +++ b/src/main/asio/config-asio.h @@ -7,6 +7,7 @@ struct asiohook_config_asio { bool force_asio; + bool force_wasapi; char replacement_name[128]; }; diff --git a/src/main/iidxhook9/Module.mk b/src/main/iidxhook9/Module.mk new file mode 100644 index 0000000..30384f1 --- /dev/null +++ b/src/main/iidxhook9/Module.mk @@ -0,0 +1,32 @@ +avsdlls += iidxhook9 + +ldflags_iidxhook9 := \ + -liphlpapi \ + -lsetupapi \ + -lcfgmgr32 \ + -lmf \ + -lmfplat \ + -lole32 \ + +deplibs_iidxhook9 := \ + avs \ + +libs_iidxhook9 := \ + iidxhook-util \ + acioemu \ + asio \ + bio2emu \ + bio2emu-iidx \ + camhook \ + d3d9exhook \ + dinput \ + iidxio \ + hook \ + hooklib \ + cconfig \ + util \ + eamio \ + +src_iidxhook9 := \ + config-io.c \ + dllmain.c \ diff --git a/src/main/iidxhook9/config-io.c b/src/main/iidxhook9/config-io.c new file mode 100644 index 0000000..2d5eb0e --- /dev/null +++ b/src/main/iidxhook9/config-io.c @@ -0,0 +1,136 @@ +#include "cconfig/cconfig-util.h" + +#include "iidxhook9/config-io.h" + +#include "util/log.h" + +#define IIDXHOOK9_CONFIG_IO_DISABLE_CARD_READER_EMU_KEY \ + "io.disable_card_reader_emu" +#define IIDXHOOK9_CONFIG_IO_DISABLE_BIO2_EMU_KEY "io.disable_bio2_emu" +#define IIDXHOOK9_CONFIG_IO_DISABLE_POLL_LIMITER_KEY "io.disable_poll_limiter" +#define IIDXHOOK9_CONFIG_IO_LIGHTNING_MODE_KEY "io.lightning_mode" +#define IIDXHOOK9_CONFIG_IO_DISABLE_CAMS_KEY "io.disable_cams" +#define IIDXHOOK9_CONFIG_IO_DISABLE_FILE_HOOKS_KEY "io.disable_file_hooks" + +#define IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE false +#define IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE false +#define IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE false +#define IIDXHOOK9_CONFIG_IO_DEFAULT_LIGHTNING_MODE_VALUE false +#define IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CAMS_VALUE false +#define IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE false + +void iidxhook9_config_io_init(struct cconfig *config) +{ + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_CARD_READER_EMU_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE, + "Disable card reader emulation and enable usage of real card reader " + "hardware on COM0 (for games supporting slotted readers)"); + + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_BIO2_EMU_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE, + "Disable BIO2 emulation and enable usage of real BIO2 hardware"); + + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_POLL_LIMITER_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE, + "Disables the poll limiter, warning very high CPU usage may arise"); + + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_LIGHTNING_MODE_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_LIGHTNING_MODE_VALUE, + "Lightning cab mode (requires additional IO emulation)"); + + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_CAMS_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CAMS_VALUE, + "Disable camera connection"); + + cconfig_util_set_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_FILE_HOOKS_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE, + "Disables the built in file hooks, requiring manual file creation"); +} + +void iidxhook9_config_io_get( + struct iidxhook9_config_io *config_io, struct cconfig *config) +{ + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_CARD_READER_EMU_KEY, + &config_io->disable_card_reader_emu, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_DISABLE_CARD_READER_EMU_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE); + } + + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_BIO2_EMU_KEY, + &config_io->disable_bio2_emu, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_DISABLE_BIO2_EMU_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE); + } + + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_POLL_LIMITER_KEY, + &config_io->disable_poll_limiter, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_DISABLE_POLL_LIMITER_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE); + } + + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_LIGHTNING_MODE_KEY, + &config_io->lightning_mode, + IIDXHOOK9_CONFIG_IO_DEFAULT_LIGHTNING_MODE_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_LIGHTNING_MODE_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_LIGHTNING_MODE_VALUE); + } + + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_CAMS_KEY, + &config_io->disable_cams, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CAMS_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_DISABLE_CAMS_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_CAMS_VALUE); + } + + if (!cconfig_util_get_bool( + config, + IIDXHOOK9_CONFIG_IO_DISABLE_FILE_HOOKS_KEY, + &config_io->disable_file_hooks, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + IIDXHOOK9_CONFIG_IO_DISABLE_FILE_HOOKS_KEY, + IIDXHOOK9_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE); + } +} diff --git a/src/main/iidxhook9/config-io.h b/src/main/iidxhook9/config-io.h new file mode 100644 index 0000000..564b360 --- /dev/null +++ b/src/main/iidxhook9/config-io.h @@ -0,0 +1,22 @@ +#ifndef IIDXHOOK9_CONFIG_IO_H +#define IIDXHOOK9_CONFIG_IO_H + +#include + +#include "cconfig/cconfig.h" + +struct iidxhook9_config_io { + bool disable_card_reader_emu; + bool disable_bio2_emu; + bool disable_poll_limiter; + bool lightning_mode; + bool disable_cams; + bool disable_file_hooks; +}; + +void iidxhook9_config_io_init(struct cconfig *config); + +void iidxhook9_config_io_get( + struct iidxhook9_config_io *config_io, struct cconfig *config); + +#endif \ No newline at end of file diff --git a/src/main/iidxhook9/dllmain.c b/src/main/iidxhook9/dllmain.c new file mode 100644 index 0000000..cf3c0c9 --- /dev/null +++ b/src/main/iidxhook9/dllmain.c @@ -0,0 +1,290 @@ +#include + +#include +#include +#include +#include + +#include "bemanitools/eamio.h" +#include "bemanitools/iidxio.h" + +#include "cconfig/cconfig-hook.h" + +#include "hooklib/acp.h" +#include "hooklib/adapter.h" +#include "hooklib/app.h" +#include "hooklib/config-adapter.h" +#include "hooklib/memfile.h" +#include "hooklib/rs232.h" +#include "hooklib/setupapi.h" + +#include "iidxhook-util/acio.h" +#include "iidxhook-util/log-server.h" + +#include "bio2emu/emu.h" + +#include "bio2emu-iidx/bi2a.h" + +#include "iidxhook9/config-io.h" + +#include "camhook/cam.h" +#include "camhook/config-cam.h" + +#include "asio/asio-reghook.h" +#include "asio/config-asio.h" +#include "d3d9exhook/d3d9ex.h" +#include "dinput/dinput.h" + +#include "imports/avs.h" + +#include "util/cmdline.h" +#include "util/log.h" +#include "util/str.h" +#include "util/thread.h" + +#define IIDXHOOK9_INFO_HEADER \ + "iidxhook for Heroic Verse" \ + ", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) "\n" +#define IIDXHOOK9_CMD_USAGE \ + "Usage: launcher.exe -B iidxhook9-prehook.dll -K iidxhook9.dll " \ + " [options...]" + +static struct iidxhook9_config_io iidxhook9_config_io; +static struct camhook_config_cam config_cam; +static struct asiohook_config_asio config_asio; +static struct hooklib_config_adapter config_adapter; +static struct d3d9exhook_config_gfx config_gfx; + +static struct bio2emu_port bio2_emu = { + .port = "COM4", + .wport = L"COM4", + .dispatcher = bio2_emu_bi2a_dispatch_request, +}; + +static bool load_configs() { + struct cconfig *config; + config = cconfig_init(); + + iidxhook9_config_io_init(config); + camhook_config_cam_init(config, 2); + + d3d9exhook_config_gfx_init(config); + + hooklib_config_adapter_init(config); + asiohook_config_init(config); + + if (!cconfig_hook_config_init( + config, + IIDXHOOK9_INFO_HEADER "\n" IIDXHOOK9_CMD_USAGE, + CCONFIG_CMD_USAGE_OUT_DBG)) { + cconfig_finit(config); + return false; + } + + iidxhook9_config_io_get(&iidxhook9_config_io, config); + camhook_config_cam_get(&config_cam, config, 2); + + d3d9exhook_config_gfx_get(&config_gfx, config); + + hooklib_config_adapter_get(&config_adapter, config); + asiohook_config_asio_get(&config_asio, config); + + cconfig_finit(config); + + return true; +} + +static bool my_dll_entry_init(char *sidcode, struct property_node *param) +{ + // log_server_init is required due to IO occuring in a non avs_thread + log_server_init(); + + log_info("-------------------------------------------------------------"); + log_info("--------------- Begin iidxhook dll_entry_init ---------------"); + log_info("-------------------------------------------------------------"); + + log_info(IIDXHOOK9_INFO_HEADER); + log_info("Initializing iidxhook..."); + + // reload configs again so they get logged through avs as well + // (so we get a copy of them in the -Y logfile) + if (!load_configs()) { + log_server_fini(); + exit(EXIT_FAILURE); + } + + d3d9ex_configure(&config_gfx); + d3d9ex_hook_init(); + + acp_hook_init(); + adapter_hook_init(); + dinput_init(); + + /* Start up IIDXIO.DLL */ + if (!iidxhook9_config_io.disable_bio2_emu) { + log_info("Starting IIDX IO backend"); + iidx_io_set_loggers( + log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal); + + if (!iidx_io_init( + avs_thread_create, avs_thread_join, avs_thread_destroy)) { + log_fatal("Initializing IIDX IO backend failed"); + } + } + + /* Start up EAMIO.DLL */ + if (!iidxhook9_config_io.disable_card_reader_emu) { + log_misc("Initializing card reader backend"); + eam_io_set_loggers( + log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal); + + if (!eam_io_init( + avs_thread_create, avs_thread_join, avs_thread_destroy)) { + log_fatal("Initializing card reader backend failed"); + } + } + + iohook_push_handler(iidxhook_util_acio_dispatch_irp); + iohook_push_handler(bio2emu_port_dispatch_irp); + + if (!iidxhook9_config_io.disable_file_hooks) { + memfile_hook_init(); + iohook_push_handler(memfile_hook_dispatch_irp); + + // game uses this file to determine what mode to put the cab in + // the default depends on a value embedded in the dll + if (iidxhook9_config_io.lightning_mode) { + memfile_hook_add_fd("d:\\\\001rom.txt", ABSOLUTE_MATCH, "TDJ", 3); + } else { + memfile_hook_add_fd("d:\\\\001rom.txt", ABSOLUTE_MATCH, "LDJ", 3); + } + } + + rs232_hook_init(); + rs232_hook_limit_hooks(); + + if (!iidxhook9_config_io.disable_bio2_emu) { + if (!iidxhook9_config_io.lightning_mode) { + bio2emu_init(); + bio2_emu_bi2a_init(&bio2_emu, iidxhook9_config_io.disable_poll_limiter); + } + } + + if (!iidxhook9_config_io.disable_card_reader_emu) { + if (iidxhook9_config_io.lightning_mode) { + // TDJ mode expects 1.7.0 readers + iidxhook_util_acio_override_version(v170); + } + + iidxhook_util_acio_init(false); + } + + // camera hooks + if (!config_cam.disable_emu) { + camhook_init(&config_cam); + } + + adapter_hook_override(config_adapter.override_ip); + + // asio hooks + if (config_asio.force_asio) { + asio_reghook_init("XONAR SOUND CARD(64)", config_asio.replacement_name); + } + + log_info("-------------------------------------------------------------"); + log_info("---------------- End iidxhook dll_entry_init ----------------"); + log_info("-------------------------------------------------------------"); + + return app_hook_invoke_init(sidcode, param); +} + +static bool my_dll_entry_main(void) +{ + bool result; + + result = app_hook_invoke_main(); + + if (!config_cam.disable_emu) { + camhook_fini(); + } + + if (!iidxhook9_config_io.disable_card_reader_emu) { + log_misc("Shutting down card reader backend"); + eam_io_fini(); + } + + if (!iidxhook9_config_io.disable_bio2_emu) { + log_misc("Shutting down IIDX IO backend"); + iidx_io_fini(); + } + + if (!iidxhook9_config_io.disable_file_hooks) { + memfile_hook_fini(); + } + + log_server_fini(); + + return result; +} + +static void pre_hook() +{ + log_info("-------------------------------------------------------------"); + log_info("------------------ Begin iidxhook pre_hook ------------------"); + log_info("-------------------------------------------------------------"); + + if (!load_configs()) { + exit(EXIT_FAILURE); + } + + // asio hooks + if (config_asio.force_asio) { + SetEnvironmentVariable("SOUND_OUTPUT_DEVICE", "asio"); + } else if (config_asio.force_wasapi) { + SetEnvironmentVariable("SOUND_OUTPUT_DEVICE", "wasapi"); + } + + if (iidxhook9_config_io.disable_cams) { + // this disables the entire camera subsystem + // useful for skipping the camera error entierly + SetEnvironmentVariable("CONNECT_CAMERA", "0"); + } + + log_info("-------------------------------------------------------------"); + log_info("------------------- End iidxhook pre_hook -------------------"); + log_info("-------------------------------------------------------------"); +} + +/** + * Hook library HV+ + */ +BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx) +{ + if (reason != DLL_PROCESS_ATTACH) { + goto end; + } + + + if (avs_is_active()){ + // if AVS is loaded, we're likely too late to be a prehook + // so we warn the user + // and switch the current logging context to AVS so it shows up in logs + log_to_external( + log_body_misc, log_body_info, log_body_warning, log_body_fatal); + log_warning("iidxhook9 is designed to be used as a prehook"); + log_warning("please ensure that it is being loaded with -B"); + log_fatal("cya l8r in the prehook :3"); + } else { + // we can't log to external in DllMain (AVS) as we're a prehook + // later during my_dll_entry_init, log_server_init is called + // which sets swaps the main log write to that instead + log_to_writer(log_writer_file, stdout); + } + + pre_hook(); + + app_hook_init(my_dll_entry_init, my_dll_entry_main); + +end: + return TRUE; +} diff --git a/src/main/iidxhook9/iidxhook9.def b/src/main/iidxhook9/iidxhook9.def new file mode 100644 index 0000000..32f7f78 --- /dev/null +++ b/src/main/iidxhook9/iidxhook9.def @@ -0,0 +1,4 @@ +LIBRARY iidxhook9 + +EXPORTS + DllMain@12 @1 NONAME