Compare commits

...

22 Commits
v5.28 ... v5.29

Author SHA1 Message Date
icex2
596b962cfe Update changelog for 5.29 release 2020-02-01 11:07:18 +01:00
Will Xyen
5969573dc9 d3d9exhook: actually rotate the right monitor 2020-01-29 00:29:46 -05:00
Will Xyen
5da6997805 address MR comments. 2020-01-29 00:09:26 -05:00
Will Xyen
dc98103419 formatting update 2020-01-28 04:25:25 -05:00
Will Xyen
2d07bd6f5a d3d9exhook/sdvxhook2: add option to force monitor orientation
also adds adapter hook into sdvxhook2
2020-01-28 04:23:19 -05:00
Will Xyen
a21e37c894 hooklib: add adapter_hook_override to allow specifying network adapter id 2020-01-28 04:15:47 -05:00
Will Xyen
fbb7731681 dist: Update sdvxhook2.conf provided to have new d3d9exhook options 2020-01-21 06:13:36 -05:00
Will Xyen
3659494c18 misc: touchup some comments 2020-01-13 21:21:43 -05:00
Will Xyen
6d638ff1ae sdvxhook2-cn: sdvx5 cn support 2020-01-13 16:16:12 -05:00
Will Xyen
214a31b24d iidxhook/d3d9exhook: Use -1 to specify default adapter instead of 0 because the indexing starts at 0
Originally thought the default monitor showed up again later, it does not
2020-01-10 17:36:34 -05:00
Will Xyen
66d1131664 clang-format pass 2020-01-10 17:24:47 -05:00
Will Xyen
3450686cf5 iidxhook: allow forcing adapter and refresh rate in d3d9 based IIDX games 2020-01-10 10:44:21 -05:00
Will Xyen
3b8f6ac1d9 launcher: make app_config.xml optional 2019-12-23 20:40:51 -05:00
Will Xyen
8ae06f6f4b d3d9exhook: Add option to specify the display adapter to open 2019-12-23 20:14:26 -05:00
Will Xyen
b1fd175318 dist/docs: --config not --options 2019-12-18 21:48:47 -05:00
Will Xyen
b1329d10bf camhook: Fix cameras not being auto-detected sometimes on older machines
MFStartup needs to be called before any MF functions are used (such as for auto detect)
2019-12-10 15:24:46 -05:00
icex2
bf3d543893 Add some general notes about data setup for OS to README 2019-12-09 15:17:09 +01:00
icex2
f1f26dece3 Update development doc with some useful dev tools 2019-12-09 15:08:14 +01:00
icex2
fe0996ec3b Update MR templates, add checklist for guidance 2019-12-09 15:01:16 +01:00
icex2
d551930ea0 Version bump to 5.29 2019-12-06 23:25:21 +01:00
icex2
daad6a09c5 Fix versioning for sdvx distribution packages
sdvx.zip -> sdvx-01-to-04.zip
sdvx5.zip -> sdvx-05.zip
2019-12-06 23:23:12 +01:00
icex2
27fdabe17a Add instructions how to create releases 2019-12-06 23:19:27 +01:00
71 changed files with 1408 additions and 45 deletions

View File

@@ -13,4 +13,15 @@
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
<!--- see how your change affects other areas of the code, etc. -->
## Checklist
<!-- Make sure you covered all items, which apply, of the checklist below. -->
<!-- Strikethrough items that do not apply and provide a brief description why. -->
* [ ] Implemented (unit) test(s) which prove that the introduced changes are working as expected.
* Tested with the following games:
* [ ] ... <!-- insert game name 1-->
* [ ] ... <!-- insert game name 2--->
* [ ] Followed the developer (style) guidelines.
* [ ] Updated existing doc of or add new doc to README file(s).
* [ ] Updated development documentation.

View File

@@ -13,4 +13,15 @@
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
<!--- see how your change affects other areas of the code, etc. -->
## Checklist
<!-- Make sure you covered all items, which apply, of the checklist below. -->
<!-- Strikethrough items that do not apply and provide a brief description why. -->
* [ ] Implemented (unit) test(s) which prove that the introduced changes are working as expected.
* Tested with the following games:
* [ ] ... <!-- insert game name 1-->
* [ ] ... <!-- insert game name 2--->
* [ ] Followed the developer (style) guidelines.
* [ ] Updated existing doc of or add new doc to README file(s).
* [ ] Updated development documentation.

View File

@@ -1,4 +1,11 @@
# Release history
## 5.29
* SDVX: Add option for monitor rotation
* SDVX: Add option to allow overriding network adapter IP
* IIDX: Add force display adapter and refresh rate configuration
* SDVX: Allow specifying display adapter to open for d3d9ex hook
* IIDX/SDVX camerahooks bugfix: Camera sometimes not detected on some older machines
## 5.28
* Improve documentation in various places
* Automatic code formatting in build pipeline

View File

@@ -136,6 +136,7 @@ include src/main/p4ioemu/Module.mk
include src/main/pcbidgen/Module.mk
include src/main/sdvxhook/Module.mk
include src/main/sdvxhook2/Module.mk
include src/main/sdvxhook2-cn/Module.mk
include src/main/sdvxio/Module.mk
include src/main/sdvxio-kfca/Module.mk
include src/main/security/Module.mk
@@ -407,7 +408,7 @@ $(zipdir)/jb-08.zip: \
$(V)echo ... $@
$(V)zip -j $@ $^
$(zipdir)/sdvx.zip: \
$(zipdir)/sdvx-01-to-04.zip: \
build/bin/avs2_1508-32/launcher.exe \
build/bin/avs2_1508-32/sdvxhook.dll \
build/bin/indep-32/config.exe \
@@ -421,7 +422,7 @@ $(zipdir)/sdvx.zip: \
$(V)echo ... $@
$(V)zip -j $@ $^
$(zipdir)/sdvx5.zip: \
$(zipdir)/sdvx-05.zip: \
build/bin/avs2_1700-64/launcher.exe \
build/bin/avs2_1700-64/sdvxhook2.dll \
build/bin/indep-64/config.exe \
@@ -436,6 +437,20 @@ $(zipdir)/sdvx5.zip: \
$(V)echo ... $@
$(V)zip -j $@ $^
$(zipdir)/sdvx-05-cn.zip: \
build/bin/avs2_1700-64/launcher.exe \
build/bin/avs2_1700-64/sdvxhook2-cn.dll \
build/bin/indep-64/config.exe \
build/bin/indep-64/eamio.dll \
build/bin/indep-64/geninput.dll \
build/bin/indep-64/sdvxio.dll \
dist/sdvx5/config.bat \
dist/sdvx5/gamestart-cn.bat \
dist/sdvx5/sdvxhook2-cn.conf \
| $(zipdir)/
$(V)echo ... $@
$(V)zip -j $@ $^
$(zipdir)/ddr-12-to-16.zip: \
build/bin/avs2_1508-32/launcher.exe \
build/bin/avs2_1508-32/ddrhook.dll \
@@ -521,8 +536,9 @@ $(BUILDDIR)/bemanitools.zip: \
$(zipdir)/jb-05-to-07.zip \
$(zipdir)/jb-08.zip \
$(zipdir)/src.zip \
$(zipdir)/sdvx.zip \
$(zipdir)/sdvx5.zip \
$(zipdir)/sdvx-01-to-04.zip \
$(zipdir)/sdvx-05.zip \
$(zipdir)/sdvx-05-cn.zip \
$(zipdir)/tools.zip \
$(zipdir)/tools-x64.zip \
CHANGELOG.md \

View File

@@ -1,7 +1,7 @@
# Bemanitools 5
[![pipeline status](https://dev.s-ul.eu/djhackers/bemanitools/badges/master/pipeline.svg)](https://dev.s-ul.eu/djhackers/bemanitools/commits/master)
Version: 5.28</br>
Version: 5.29</br>
[Release history](CHANGELOG.md)
A collection of tools to run [various Bemani arcade games](#list-of-supported-games).
@@ -47,11 +47,11 @@ authentic gameplay experience, and easier support for a broader range of release
* jubeat Qubell (jb-05-to-07.zip) using jbhook
* jubeat clan (jb-08.zip) using jbhook
* SOUND VOLTEX
* SOUND VOLTEX BOOTH (sdvx.zip) using sdvxhook
* SOUND VOLTEX II -infinite infection- (sdvx.zip) using sdvxhook
* SOUND VOLTEX III GRAVITY WARS (sdvx.zip) using sdvxhook
* SOUND VOLTEX IV HEAVENLY HAVEN (sdvx.zip) using sdvxhook
* SOUND VOLTEX Vivid Wave (sdvx2.zip) using sdvxhook2
* SOUND VOLTEX BOOTH (sdvx-01-to-04.zip) using sdvxhook
* SOUND VOLTEX II -infinite infection- (sdvx-01-to-04.zip) using sdvxhook
* SOUND VOLTEX III GRAVITY WARS (sdvx-01-to-04.zip) using sdvxhook
* SOUND VOLTEX IV HEAVENLY HAVEN (sdvx-01-to-04.zip) using sdvxhook
* SOUND VOLTEX Vivid Wave (sdvx-05.zip) using sdvxhook2
# Supported platforms
Our main platforms are currently Windows XP and Windows 7 which are also the target platforms on the original hardware
@@ -67,6 +67,16 @@ You will find *.md files in various sub-packages that give you further instructi
or FAQ. We advice you to read them as your questions and concerns might already be answered by them. If not, let us
know if there is any information that you consider helpful or important to know and should be added.
# Setup and dependencies
Most (older generation) games were developed for Windows XP Embedded but should run fine on any
consumer version of Windows XP. Newer versions of Windows, e.g. Windows 7, 8 and 10, should be fine
as well. Some hooks also include fixes required to run the games on a more recent version.
Depending on the game, you also need the following dependencies installed:
* DirectX 9 runtime
* Microsoft Visual C++ Redistributables 2010 **and** 2013: Depends on the game and age but both
should cover most if not all of the games so far
# Contributions
Please refer to the [dedicated documentation](CONTRIBUTING.md).

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix broken 3D background on Happy Sky's music select (if appearing completely white)
misc.happy_sky_ms_bg_fix=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Fix broken 3D background on DistorteD's music select (if appearing completely black)
misc.distorted_ms_bg_fix=false

View File

@@ -37,6 +37,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -37,6 +37,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -40,6 +40,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false

View File

@@ -30,3 +30,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -27,3 +27,9 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1

View File

@@ -28,6 +28,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disables the camera emulation
cam.disable_emu=false

View File

@@ -28,6 +28,12 @@ gfx.scale_back_buffer_height=0
# Filter type to use for up-/downscaling the back buffer. Only used if scaling feature was enabled by setting the scaling width and height parameters. Available types: none, linear, point (refer to D3DTEXTUREFILTERTYPE for explanation).
gfx.scale_back_buffer_filter=none
# 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
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
gfx.device_adapter=-1
# Disables the camera emulation
cam.disable_emu=false

17
dist/sdvx5/gamestart-cn.bat vendored Normal file
View File

@@ -0,0 +1,17 @@
@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\c.dest echo $null >> dev\raw\c.dest
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 268435456 -K sdvxhook2-cn.dll soundvoltex.dll --config sdvxhook2-cn.conf %*

View File

@@ -13,4 +13,4 @@ for /R prop\defaults %%D in (*.*) do (
if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram
)
launcher -H 268435456 -K sdvxhook2.dll soundvoltex.dll --options sdvxhook2.conf %*
launcher -H 268435456 -K sdvxhook2.dll soundvoltex.dll --config sdvxhook2.conf %*

24
dist/sdvx5/sdvxhook2-cn.conf vendored Normal file
View File

@@ -0,0 +1,24 @@
# Disable IO emulation and enable usage of real KFCA hardware
io.disable_io_emu=false
# Path to unis version file under the prop.s folder
cn.unis_path=prop/unis.xml
# Run the game in a framed window (requires windowed option)
gfx.framed=true
# Run the game windowed
gfx.windowed=false
# Windowed width, -1 for default size
gfx.window_width=720
# Windowed height, -1 for default size
gfx.window_height=1280
# Disables the camera emulation
cam.disable_emu=false
# Override camera device ID detection (copy from device manager, do not escape)
cam.device_id1=

View File

@@ -14,10 +14,19 @@ gfx.framed=true
gfx.windowed=false
# Windowed width, -1 for default size
gfx.window_width=720
gfx.window_width=1080
# Windowed height, -1 for default size
gfx.window_height=1280
gfx.window_height=1920
# 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
# Disables the camera emulation
cam.disable_emu=false
@@ -25,3 +34,6 @@ cam.disable_emu=false
# Override camera device ID detection (copy from device manager, do not escape)
cam.device_id1=
# IP of adapter to force override with
adapter.override_ip=

View File

@@ -36,6 +36,13 @@ development environment which we run on a Linux distribution of our choice:
* C++ Intellisense
* Clang-Format
### Further tools for testing and debugging
* Debugger: Can be part of your reverse engineering IDE of your choice or stand-along like
[OllyDbg](http://www.ollydbg.de/).
* [apitrace](https://apitrace.github.io/): Trace render calls to graphics APIs like D3D and OpenGL.
This tool allows you to record and re-play render calls of an application with frame-by-frame
debugging. Very useful to analyze the render pipeline or debug graphicial glitches.
## Building
Simply run make in the root folder:
```
@@ -51,6 +58,39 @@ command:
make release
```
## Creating releases
For developers to create official releases with major and minor versioning:
1. Ensure that all everything you want to have for this release is merged into master.
1. Create a [changelog](CHANGELOG.md) based on aggregating and summerizing commit messages of
whatever got added starting from the tag of the current version to the current head of master.
Commit that changelog and push to master.
1. Create a tag with the next version number, e.g. for 5.28:
```bash
git tag v5.28
```
1. Push the tag upstream:
```bash
git push origin v5.28
```
1. Wait for the CI pipeline to finish building the release and check if everything's ok.
1. On GitLab, go to "Tags" in the repository, click on the commit ID below the tag in the list you
just created.
1. Click on the "Pipelines" tab and click on the download button on the right and on "Download
release artifacts".
1. Rename the downloaded zip to "bemanitools-v5.28.zip" and the replace v5.28 with the version
you want to release.
1. Upload the release.
1. For publishing the release, create a post with the following contents:
```
v5.28
<insert link to uploaded zip here>
<additional comments or things to point out for this release>
Changelog copy-paste:
<insert copy-pasted changelog you created previously here>
```
## Code formatting
To apply our code style using clang-format, simply run the following command:
```

View File

@@ -14,12 +14,12 @@ it to the list of libraries to inject:
Example when using *inject.exe*:
```
inject iidxhook3.dll mempatch-hook.dll bm2dx.exe --options iidxhook-16.conf --mempatch myPatch.mph %*
inject iidxhook3.dll mempatch-hook.dll bm2dx.exe --config iidxhook-16.conf --mempatch myPatch.mph %*
```
When using *launcher.exe*:
```
launcher -K iidxhook4.dll -K mempatch-hook.dll bm2dx.dll --options iidxhook.conf --mempatch myPatch.mph %*
launcher -K iidxhook4.dll -K mempatch-hook.dll bm2dx.dll --config iidxhook.conf --mempatch myPatch.mph %*
```
To load a patch script, add the *--mempatch <path to patch script>* argument (as

View File

@@ -206,6 +206,7 @@ my_CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
char builtString[CAMERA_DATA_STRING_SIZE] = {0};
if (pdnDevInst) {
log_info("seeking: %s", pDeviceID);
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
if (camData[i].setup) {
snprintf(
@@ -213,6 +214,7 @@ my_CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
CAMERA_DATA_STRING_SIZE,
"USB\\VID_288C&PID_0002&MI_00\\%s",
camData[i].extra_upper);
log_info("built: %s", builtString);
if (strcmp(pDeviceID, builtString) == 0) {
if (!camData[i].fake_located) {
camData[i].fake_located_node = num_located_cams;
@@ -280,7 +282,9 @@ HRESULT my_GetAllocatedString(
// should probably check GUID, oh well
ret = real_GetAllocatedString(self, guidKey, ppwszValue, pcchLength);
log_info("Obtained: %ls", *ppwszValue);
char *pMBBuffer = (char *) malloc(0x100);
wcstombs(pMBBuffer, *ppwszValue, 0x100);
log_info("Obtained: %s", pMBBuffer);
wchar_t *pwc = NULL;
@@ -308,8 +312,11 @@ HRESULT my_GetAllocatedString(
pwc[29] = L'0';
pwc[30] = L'0';
log_info("Replaced: %ls", *ppwszValue);
wcstombs(pMBBuffer, *ppwszValue, 0x100);
log_info("Replaced: %s", pMBBuffer);
}
free(pMBBuffer);
return ret;
}
@@ -787,6 +794,8 @@ void fill_cam_struct(struct CameraData *data, const char *devid)
void camhook_init(struct camhook_config_cam *config_cam)
{
MFStartup(0x20070u, 0);
// fill before applying hooks
for (size_t i = 0; i < config_cam->num_devices; ++i) {
fill_cam_struct(&camData[i], config_cam->device_id[i]);
@@ -814,3 +823,8 @@ void camhook_init(struct camhook_config_cam *config_cam)
log_info("No cams detected, not hooking");
}
}
void camhook_fini(void)
{
MFShutdown();
}

View File

@@ -5,4 +5,6 @@
void camhook_init(struct camhook_config_cam *config_cam);
void camhook_fini(void);
#endif

View File

@@ -9,5 +9,6 @@ bool cconfig_hook_config_init(
const char *usage_header,
enum cconfig_cmd_usage_out cmd_usage_out)
{
return cconfig_main_config_init(config, "--config", NULL, "--help", "-h", usage_header, cmd_usage_out);
return cconfig_main_config_init(
config, "--config", NULL, "--help", "-h", usage_header, cmd_usage_out);
}

View File

@@ -6,7 +6,7 @@
/**
* Init function for cconfig for hooks
*
*
* calls cconfig_main_config_init with some defaults for hook dlls
* see: cconfig_main_config_init for more details
*/

View File

@@ -29,7 +29,8 @@ bool cconfig_main_config_init(
args_recover(&argc, &argv);
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], help_parameter_short_name) || !strcmp(argv[i], help_parameter_name)) {
if (!strcmp(argv[i], help_parameter_short_name) ||
!strcmp(argv[i], help_parameter_name)) {
goto failure_usage;
}
}

View File

@@ -6,7 +6,7 @@
/**
* Init function for cconfig after all cconfig_util_set's have been called
*
*
* will parse a config file first (if specified)
* then uses override config parameters from cmd
*/

View File

@@ -1,3 +1,5 @@
#include <d3d9.h>
#include <string.h>
#include "cconfig/cconfig-util.h"
@@ -10,13 +12,17 @@
#define D3D9EXHOOK_CONFIG_GFX_WINDOWED_KEY "gfx.windowed"
#define D3D9EXHOOK_CONFIG_GFX_WINDOW_WIDTH_KEY "gfx.window_width"
#define D3D9EXHOOK_CONFIG_GFX_WINDOW_HEIGHT_KEY "gfx.window_height"
#define D3D9EXHOOK_CONFIG_GFX_FORCED_RR_KEY "gfx.forced_refresh_rate"
#define D3D9EXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY "gfx.forced_refresh_rate"
#define D3D9EXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY "gfx.device_adapter"
#define D3D9EXHOOK_CONFIG_GFX_FORCE_ORIENTATION_KEY "gfx.force_orientation"
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_FRAMED_VALUE false
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOWED_VALUE false
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE -1
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE -1
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE -1
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE -1
#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCE_ORIENTATION_VALUE -1
void d3d9exhook_config_gfx_init(struct cconfig *config)
{
@@ -46,9 +52,24 @@ void d3d9exhook_config_gfx_init(struct cconfig *config)
cconfig_util_set_int(
config,
D3D9EXHOOK_CONFIG_GFX_FORCED_RR_KEY,
D3D9EXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE,
"Forced refresh rate, -1 to not force any (try 59 or 60 if monitor check fails to lock on high refresh rate monitors)");
"Forced refresh rate, -1 to not force any (try 59 or 60 if monitor "
"check fails to lock on high refresh rate monitors)");
cconfig_util_set_int(
config,
D3D9EXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE,
"D3D9ex device adapter (monitor), -1 to use default, "
"0, 1, 2 etc. to use specified adapter");
cconfig_util_set_int(
config,
D3D9EXHOOK_CONFIG_GFX_FORCE_ORIENTATION_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCE_ORIENTATION_VALUE,
"Orientation to force monitor into, -1 to use default, "
"0, 1, 2, 3 to do 0, 90, 180, 270 degrees");
}
void d3d9exhook_config_gfx_get(
@@ -104,13 +125,37 @@ void d3d9exhook_config_gfx_get(
if (!cconfig_util_get_int(
config,
D3D9EXHOOK_CONFIG_GFX_FORCED_RR_KEY,
D3D9EXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
&config_gfx->forced_refresh_rate,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
D3D9EXHOOK_CONFIG_GFX_FORCED_RR_KEY,
D3D9EXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE);
}
if (!cconfig_util_get_int(
config,
D3D9EXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
&config_gfx->device_adapter,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
D3D9EXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE);
}
if (!cconfig_util_get_int(
config,
D3D9EXHOOK_CONFIG_GFX_FORCE_ORIENTATION_KEY,
&config_gfx->force_orientation,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCE_ORIENTATION_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
D3D9EXHOOK_CONFIG_GFX_FORCE_ORIENTATION_KEY,
D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCE_ORIENTATION_VALUE);
}
}

View File

@@ -5,7 +5,7 @@
/**
* Config struct for d3d9exhook
*
*
* Note: forced_refresh_rate sets the monitor's refresh rate
* (it does not limit FPS or anything)
*/
@@ -15,6 +15,8 @@ struct d3d9exhook_config_gfx {
int32_t window_width;
int32_t window_height;
int32_t forced_refresh_rate;
int32_t device_adapter;
int32_t force_orientation;
};
/**

View File

@@ -86,6 +86,8 @@ static int32_t d3d9ex_force_refresh_rate = -1;
static int32_t d3d9ex_window_width = -1;
static int32_t d3d9ex_window_height = -1;
static bool d3d9ex_window_framed;
static int32_t d3d9ex_device_adapter = -1;
static int32_t d3d9ex_force_orientation = -1;
/* ------------------------------------------------------------------------- */
@@ -194,25 +196,78 @@ static HRESULT STDCALL my_CreateDeviceEx(
IDirect3D9Ex *real = COM_PROXY_UNWRAP(self);
HRESULT hr;
if (d3d9ex_device_adapter >= 0) {
log_info("Forcing adapter %d -> %d", adapter, d3d9ex_device_adapter);
adapter = d3d9ex_device_adapter;
}
if (d3d9ex_windowed) {
fdm = NULL;
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
} else {
if (d3d9ex_force_refresh_rate != -1) {
log_info("Forcing refresh rate %d -> %d", pp->FullScreen_RefreshRateInHz, d3d9ex_force_refresh_rate);
if (d3d9ex_force_refresh_rate > 0) {
log_info(
"Forcing refresh rate %d -> %d",
pp->FullScreen_RefreshRateInHz,
d3d9ex_force_refresh_rate);
pp->FullScreen_RefreshRateInHz = d3d9ex_force_refresh_rate;
if (fdm) {
fdm->RefreshRate = pp->FullScreen_RefreshRateInHz;
}
}
if (d3d9ex_force_orientation >= DMDO_DEFAULT &&
d3d9ex_force_orientation <= DMDO_270) {
D3DADAPTER_IDENTIFIER9 adapter_ident;
if (IDirect3D9Ex_GetAdapterIdentifier(
real, adapter, 0, &adapter_ident) == D3D_OK) {
// straight outta MSDN
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (EnumDisplaySettings(
adapter_ident.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
int32_t delta =
d3d9ex_force_orientation - dm.dmDisplayOrientation;
if (delta % 2 != 0) {
// swap height and width
DWORD dwTemp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = dwTemp;
}
dm.dmDisplayOrientation = d3d9ex_force_orientation;
long cd_ret = ChangeDisplaySettingsEx(
adapter_ident.DeviceName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL);
if (cd_ret == DISP_CHANGE_SUCCESSFUL) {
log_info(
"Overriding rotation suceeded: %s",
adapter_ident.DeviceName);
} else {
log_info(
"Overriding rotation failed %s %ld",
adapter_ident.DeviceName,
cd_ret);
}
}
}
}
}
hr = IDirect3D9Ex_CreateDeviceEx(
real, adapter, type, hwnd, flags, pp, fdm, pdev);
// TODO stuff
return hr;
}
@@ -261,7 +316,7 @@ void d3d9ex_hook_init(void)
log_info("Inserted graphics hooks");
}
void d3d9ex_configure(struct d3d9exhook_config_gfx* gfx_config)
void d3d9ex_configure(struct d3d9exhook_config_gfx *gfx_config)
{
d3d9ex_windowed = gfx_config->windowed;
d3d9ex_window_framed = gfx_config->framed;
@@ -269,6 +324,8 @@ void d3d9ex_configure(struct d3d9exhook_config_gfx* gfx_config)
d3d9ex_window_height = gfx_config->window_height;
d3d9ex_force_refresh_rate = gfx_config->forced_refresh_rate;
d3d9ex_device_adapter = gfx_config->device_adapter;
d3d9ex_force_orientation = gfx_config->force_orientation;
}
/* ------------------------------------------------------------------------- */

View File

@@ -16,6 +16,6 @@ void d3d9ex_hook_init(void);
*
* @param gfx_config Config to apply.
*/
void d3d9ex_configure(struct d3d9exhook_config_gfx* gfx_config);
void d3d9ex_configure(struct d3d9exhook_config_gfx *gfx_config);
#endif

View File

@@ -4,6 +4,7 @@ src_hooklib := \
acp.c \
app.c \
adapter.c \
config-adapter.c \
rs232.c \
setupapi.c \

View File

@@ -3,12 +3,16 @@
#include <windows.h>
#include <winsock2.h>
#include <stdbool.h>
#include <string.h>
#include "hook/table.h"
#include "hooklib/adapter.h"
#include "util/codepage.h"
#include "util/defs.h"
#include "util/log.h"
static DWORD WINAPI
my_GetAdaptersInfo(PIP_ADAPTER_INFO adapter_info, PULONG out_buf_len);
@@ -16,6 +20,9 @@ my_GetAdaptersInfo(PIP_ADAPTER_INFO adapter_info, PULONG out_buf_len);
static DWORD(WINAPI *real_GetAdaptersInfo)(
PIP_ADAPTER_INFO adapter_info, PULONG out_buf_len);
static IP_ADDRESS_STRING override_address;
static bool use_address_override;
static const struct hook_symbol adapter_hook_syms[] = {
{.name = "GetAdaptersInfo",
.patch = my_GetAdaptersInfo,
@@ -37,6 +44,34 @@ my_GetAdaptersInfo(PIP_ADAPTER_INFO adapter_info, PULONG out_buf_len)
return ret;
}
info = adapter_info;
if (use_address_override) {
while (info) {
// this is well defined to be at most sizeof(IP_ADDRESS_STRING)
// and NULL filled if shorter (hence the memset in
// adapter_hook_override)
if (!memcmp(
info->IpAddressList.IpAddress.String,
override_address.String,
sizeof(IP_ADDRESS_STRING))) {
log_info(
"%s: using [override] adapter: %s, %s, %s, %s",
__FUNCTION__,
info->AdapterName,
info->Description,
info->IpAddressList.IpAddress.String,
info->IpAddressList.IpMask.String);
// copy only this adapter over
memcpy(adapter_info, info, sizeof(*info));
adapter_info->Next = 0;
return ret;
}
info = info->Next;
}
}
ip_fwd_table = (MIB_IPFORWARDTABLE *) malloc(sizeof(MIB_IPFORWARDTABLE));
table_size = 0;
@@ -58,6 +93,15 @@ my_GetAdaptersInfo(PIP_ADAPTER_INFO adapter_info, PULONG out_buf_len)
while (info) {
if (info->Index == best_adapter) {
log_info(
"%s: using [best] adapter: %s, %s, %s, %s",
__FUNCTION__,
info->AdapterName,
info->Description,
info->IpAddressList.IpAddress.String,
info->IpAddressList.IpMask.String);
// copy only this adapter over
memcpy(adapter_info, info, sizeof(*info));
adapter_info->Next = 0;
return ret;
@@ -73,3 +117,26 @@ void adapter_hook_init(void)
hook_table_apply(
NULL, "iphlpapi.dll", adapter_hook_syms, lengthof(adapter_hook_syms));
}
void adapter_hook_override(const char *adapter_address)
{
// starts off false anyways due to static
// but in case it gets called multiple times, set it anyways
use_address_override = false;
if (adapter_address == NULL || *adapter_address == NULL) {
// empty, do nothing
return;
}
if (strlen(adapter_address) > sizeof(IP_ADDRESS_STRING)) {
log_warning(
"%s: %s is not an ipv4 address", __FUNCTION__, adapter_address);
return;
}
memset(override_address.String, 0, sizeof(IP_ADDRESS_STRING));
memcpy(override_address.String, adapter_address, sizeof(IP_ADDRESS_STRING));
use_address_override = true;
}

View File

@@ -1,6 +1,18 @@
#ifndef HOOKLIB_ADAPTER_H
#define HOOKLIB_ADAPTER_H
/**
* Hooks GetAdaptersInfo to attempt only returning 1 adapter.
*
*/
void adapter_hook_init(void);
/**
* Uses the provided address to try and match a network adapter.
* This adapter is then returned as the only adapter.
*
* @param network ip to match
*/
void adapter_hook_override(const char *adapter_address);
#endif

View File

@@ -0,0 +1,35 @@
#include "cconfig/cconfig-util.h"
#include "hooklib/config-adapter.h"
#include "util/log.h"
#define HOOKLIB_CONFIG_ADAPTER_OVERRIDE_IP_KEY "adapter.override_ip"
#define HOOKLIB_CONFIG_ADAPTER_DEFAULT_OVERRIDE_IP_VALUE ""
void hooklib_config_adapter_init(struct cconfig *config)
{
cconfig_util_set_str(
config,
HOOKLIB_CONFIG_ADAPTER_OVERRIDE_IP_KEY,
HOOKLIB_CONFIG_ADAPTER_DEFAULT_OVERRIDE_IP_VALUE,
"IP of adapter to force override with");
}
void hooklib_config_adapter_get(
struct hooklib_config_adapter *config_adapter, struct cconfig *config)
{
if (!cconfig_util_get_str(
config,
HOOKLIB_CONFIG_ADAPTER_OVERRIDE_IP_KEY,
config_adapter->override_ip,
sizeof(config_adapter->override_ip),
HOOKLIB_CONFIG_ADAPTER_DEFAULT_OVERRIDE_IP_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%s'",
HOOKLIB_CONFIG_ADAPTER_OVERRIDE_IP_KEY,
HOOKLIB_CONFIG_ADAPTER_DEFAULT_OVERRIDE_IP_VALUE);
}
}

View File

@@ -0,0 +1,18 @@
#ifndef HOOKLIB_CONFIG_ADAPTER_H
#define HOOKLIB_CONFIG_ADAPTER_H
#include <windows.h>
#include "cconfig/cconfig.h"
struct hooklib_config_adapter {
// this is larger on purpose, in case ppl enter the wrong stuff here
char override_ip[32];
};
void hooklib_config_adapter_init(struct cconfig *config);
void hooklib_config_adapter_get(
struct hooklib_config_adapter *config_adapter, struct cconfig *config);
#endif

View File

@@ -20,6 +20,8 @@
"gfx.scale_back_buffer_height"
#define IIDXHOOK_CONFIG_GFX_SCALE_BACK_BUFFER_FILTER_KEY \
"gfx.scale_back_buffer_filter"
#define IIDXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY "gfx.forced_refresh_rate"
#define IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY "gfx.device_adapter"
#define IIDXHOOK_CONFIG_GFX_DEFAULT_BGVIDEO_UV_FIX_VALUE false
#define IIDXHOOK_CONFIG_GFX_DEFAULT_FRAMED_VALUE false
@@ -32,6 +34,8 @@
#define IIDXHOOK_CONFIG_GFX_DEFAULT_SCALE_BACK_BUFFER_WIDTH_VALUE 0
#define IIDXHOOK_CONFIG_GFX_DEFAULT_SCALE_BACK_BUFFER_HEIGHT_VALUE 0
#define IIDXHOOK_CONFIG_GFX_DEFAULT_SCALE_BACK_BUFFER_FILTER_VALUE "none"
#define IIDXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE -1
#define IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE -1
void iidxhook_config_gfx_init(struct cconfig *config)
{
@@ -141,6 +145,20 @@ void iidxhook_config_gfx_init(struct cconfig *config)
"linear, point (refer to "
"D3DTEXTUREFILTERTYPE "
" for explanation).");
cconfig_util_set_int(
config,
IIDXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE,
"Forced refresh rate, -1 to not force any (try 59 or 60 if monitor "
"check fails to lock on high refresh rate monitors)");
cconfig_util_set_int(
config,
IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE,
"D3D9 device adapter (monitor), -1 to use default, "
"0, 1, 2 etc. to use specified adapter");
}
void iidxhook_config_gfx_get(
@@ -325,4 +343,28 @@ void iidxhook_config_gfx_get(
IIDXHOOK_CONFIG_GFX_SCALE_BACK_BUFFER_FILTER_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_SCALE_BACK_BUFFER_FILTER_VALUE);
}
if (!cconfig_util_get_int(
config,
IIDXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
&config_gfx->forced_refresh_rate,
IIDXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
IIDXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE);
}
if (!cconfig_util_get_int(
config,
IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
&config_gfx->device_adapter,
IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
IIDXHOOK_CONFIG_GFX_DEVICE_ADAPTER_KEY,
IIDXHOOK_CONFIG_GFX_DEFAULT_DEVICE_ADAPTER_VALUE);
}
}

View File

@@ -5,6 +5,7 @@
#include "iidxhook-util/d3d9.h"
// see struct iidxhook_util_d3d9_config for more info
struct iidxhook_config_gfx {
bool bgvideo_uv_fix;
bool framed;
@@ -18,6 +19,8 @@ struct iidxhook_config_gfx {
uint16_t scale_back_buffer_width;
uint16_t scale_back_buffer_height;
enum iidxhook_util_d3d9_back_buffer_scale_filter scale_back_buffer_filter;
int32_t forced_refresh_rate;
int32_t device_adapter;
};
void iidxhook_config_gfx_init(struct cconfig *config);

View File

@@ -262,10 +262,29 @@ static void iidxhook_util_d3d9_fix_create_device_apply_window_mode(
{
log_assert(irp);
log_assert(irp->op == HOOK_D3D9_IRP_OP_CTX_CREATE_DEVICE);
D3DPRESENT_PARAMETERS *pp = irp->args.ctx_create_device.pp;
if (iidxhook_util_d3d9_config.windowed) {
irp->args.ctx_create_device.pp->Windowed = TRUE;
irp->args.ctx_create_device.pp->FullScreen_RefreshRateInHz = 0;
pp->Windowed = TRUE;
pp->FullScreen_RefreshRateInHz = 0;
} else {
if (iidxhook_util_d3d9_config.forced_refresh_rate > 0) {
log_info(
"Forcing refresh rate %d -> %d",
pp->FullScreen_RefreshRateInHz,
iidxhook_util_d3d9_config.forced_refresh_rate);
pp->FullScreen_RefreshRateInHz =
iidxhook_util_d3d9_config.forced_refresh_rate;
}
}
if (iidxhook_util_d3d9_config.device_adapter >= 0) {
log_info(
"Forcing adapter %d -> %d",
irp->args.ctx_create_device.adapter,
iidxhook_util_d3d9_config.device_adapter);
irp->args.ctx_create_device.adapter =
iidxhook_util_d3d9_config.device_adapter;
}
}
@@ -904,7 +923,9 @@ iidxhook_util_d3d9_log_config(const struct iidxhook_util_d3d9_config *config)
"iidx14_to_19_nvidia_fix: %d\n"
"scale_back_buffer_width: %d\n"
"scale_back_buffer_height: %d\n"
"scale_back_buffer_filter: %d",
"scale_back_buffer_filter: %d\n"
"forced_refresh_rate: %d\n"
"device_adapter: %d",
config->windowed,
config->framed,
config->override_window_width,
@@ -919,7 +940,9 @@ iidxhook_util_d3d9_log_config(const struct iidxhook_util_d3d9_config *config)
config->iidx14_to_19_nvidia_fix,
config->scale_back_buffer_width,
config->scale_back_buffer_height,
config->scale_back_buffer_filter);
config->scale_back_buffer_filter,
config->forced_refresh_rate,
config->device_adapter);
}
static void iidxhook_util_d3d9_validate_config(
@@ -983,6 +1006,8 @@ void iidxhook_util_d3d9_init_config(struct iidxhook_util_d3d9_config *config)
config->scale_back_buffer_height = 0;
config->scale_back_buffer_filter =
IIDXHOOK_UTIL_D3D9_BACK_BUFFER_SCALE_FILTER_NONE;
config->forced_refresh_rate = -1;
config->device_adapter = -1;
}
void iidxhook_util_d3d9_configure(
@@ -1046,9 +1071,10 @@ iidxhook_util_d3d9_irp_handler(struct hook_d3d9_irp *irp)
hr = hook_d3d9_irp_invoke_next(irp);
if (hr == S_OK) {
iidxhook_util_d3d9_log_result_create_device(hr);
iidxhook_util_d3d9_setup_back_buffer_scaling_post(irp);
iidxhook_util_d3d9_execute_monitor_check(irp);
} else {
iidxhook_util_d3d9_log_result_create_device(hr);
}
return hr;

View File

@@ -159,6 +159,20 @@ struct iidxhook_util_d3d9_config {
* for full doc.
*/
enum iidxhook_util_d3d9_back_buffer_scale_filter scale_back_buffer_filter;
/**
* Forced refresh rate
* -1 to not force any (try 59 or 60 if monitor check fails to lock on high
* refresh rate monitors)
*/
int32_t forced_refresh_rate;
/**
* override device adapter (monitor)
* -1 to use default (whatever the game sends)
* 0, 1, 2 etc. to use specified adapter
*/
int32_t device_adapter;
};
/**

View File

@@ -95,6 +95,8 @@ static void iidxhook1_setup_d3d9_hooks(
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@@ -94,6 +94,8 @@ static void iidxhook2_setup_d3d9_hooks(
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@@ -91,6 +91,8 @@ iidxhook3_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@@ -72,6 +72,8 @@ iidxhook4_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
if (config_gfx->monitor_check == 0) {
log_info("Auto monitor check enabled");

View File

@@ -70,6 +70,8 @@ iidxhook5_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
iidxhook_util_d3d9_configure(&d3d9_config);

View File

@@ -68,6 +68,8 @@ iidxhook6_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
iidxhook_util_d3d9_configure(&d3d9_config);

View File

@@ -68,6 +68,8 @@ iidxhook7_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
iidxhook_util_d3d9_configure(&d3d9_config);

View File

@@ -37,7 +37,7 @@
#include "util/thread.h"
#define IIDXHOOK8_INFO_HEADER \
"iidxhook for Cannon Ballers" \
"iidxhook for Cannon Ballers/Rootage" \
", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) "\n"
#define IIDXHOOK8_CMD_USAGE \
"Usage: launcher.exe -K iidxhook8.dll <bm2dx.dll> [options...]"
@@ -68,6 +68,8 @@ iidxhook8_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
d3d9_config.scale_back_buffer_width = config_gfx->scale_back_buffer_width;
d3d9_config.scale_back_buffer_height = config_gfx->scale_back_buffer_height;
d3d9_config.scale_back_buffer_filter = config_gfx->scale_back_buffer_filter;
d3d9_config.forced_refresh_rate = config_gfx->forced_refresh_rate;
d3d9_config.device_adapter = config_gfx->device_adapter;
iidxhook_util_d3d9_configure(&d3d9_config);
@@ -75,6 +77,7 @@ iidxhook8_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
}
struct iidxhook8_config_io iidxhook8_config_io;
struct camhook_config_cam config_cam;
static struct bio2emu_port bio2_emu = {
.port = "COM4",
@@ -87,7 +90,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
struct cconfig *config;
struct iidxhook_config_gfx config_gfx;
struct camhook_config_cam config_cam;
// log_server_init is required due to IO occuring in a non avs_thread
log_server_init();
@@ -181,6 +183,10 @@ static bool my_dll_entry_main(void)
result = app_hook_invoke_main();
if (!config_cam.disable_emu) {
camhook_fini();
}
if (!iidxhook8_config_io.disable_card_reader_emu) {
log_misc("Shutting down card reader backend");
eam_io_fini();
@@ -197,7 +203,7 @@ static bool my_dll_entry_main(void)
}
/**
* Hook library Resort Anthem onwards
* Hook library CB/Rootage
*/
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
{

View File

@@ -17,6 +17,7 @@
#include "util/codepage.h"
#include "util/defs.h"
#include "util/fs.h"
#include "util/log.h"
#include "util/mem.h"
#include "util/str.h"
@@ -243,7 +244,15 @@ int main(int argc, const char **argv)
/* Invoke dll_entry_init */
app_config = boot_property_load(options.app_config_path);
if (path_exists(options.app_config_path)) {
app_config = boot_property_load(options.app_config_path);
} else {
log_warning(
"%s: app config file missing, using empty",
options.app_config_path);
app_config = boot_property_load_cstring("<param>dummy</param>");
}
app_config_root = property_search(app_config, 0, "/param");
if (app_config_root == NULL) {

View File

@@ -20,6 +20,26 @@ static int boot_property_fread(uint32_t context, void *bytes, size_t nbytes)
return fread(bytes, 1, nbytes, f);
}
struct cstring_read_handle {
const char *buffer;
size_t buffer_len;
size_t offset;
};
static int
boot_property_cstring_read(uint32_t context, void *bytes, size_t nbytes)
{
int result = 0;
struct cstring_read_handle *h = TlsGetValue(context);
if (h->offset < h->buffer_len) {
result = min(nbytes, h->buffer_len - h->offset);
memcpy(bytes, (const void *) (h->buffer + h->offset), result);
h->offset += result;
}
return result;
}
struct property *boot_property_load(const char *filename)
{
struct property *prop;
@@ -65,6 +85,45 @@ struct property *boot_property_load(const char *filename)
return prop;
}
struct property *boot_property_load_cstring(const char *cstring)
{
struct property *prop;
void *buffer;
int nbytes;
uint32_t s_keyhole;
// see above
struct cstring_read_handle read_handle;
read_handle.buffer = cstring;
read_handle.buffer_len = strlen(cstring);
read_handle.offset = 0;
s_keyhole = TlsAlloc();
TlsSetValue(s_keyhole, &read_handle);
nbytes = property_read_query_memsize(
boot_property_cstring_read, s_keyhole, 0, 0);
if (nbytes < 0) {
log_fatal("Error querying configuration string");
}
buffer = xmalloc(nbytes);
prop = property_create(
PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE |
PROPERTY_FLAG_APPEND,
buffer,
nbytes);
read_handle.offset = 0;
if (!property_insert_read(prop, 0, boot_property_cstring_read, s_keyhole)) {
log_fatal("Error inserting configuration string");
}
TlsFree(s_keyhole);
return prop;
}
void boot_property_free(struct property *prop)
{

View File

@@ -4,6 +4,7 @@
#include "imports/avs.h"
struct property *boot_property_load(const char *filename);
struct property *boot_property_load_cstring(const char *cstring);
void boot_property_free(struct property *prop);
#endif

View File

@@ -0,0 +1,29 @@
avsdlls += sdvxhook2-cn
ldflags_sdvxhook2-cn := \
-liphlpapi \
-lsetupapi \
-lcfgmgr32 \
-lmf \
-lmfplat \
-lole32 \
deplibs_sdvxhook2-cn := \
avs \
libs_sdvxhook2-cn := \
acioemu \
camhook \
d3d9exhook \
sdvxio \
hook \
hooklib \
cconfig \
util \
src_sdvxhook2-cn := \
acio.c \
kfca.c \
dllmain.c \
config-cn.c \
unis-version.c \

View File

@@ -0,0 +1,92 @@
// clang-format off
// Don't format because the order is important here
#include <windows.h>
#include <devioctl.h>
#include <ntdef.h>
#include <ntddser.h>
// clang-format on
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "acioemu/addr.h"
#include "acioemu/emu.h"
#include "hook/iohook.h"
#include "hooklib/rs232.h"
#include "sdvxhook2-cn/acio.h"
#include "sdvxhook2-cn/kfca.h"
#include "imports/avs.h"
#include "util/defs.h"
#include "util/iobuf.h"
#include "util/log.h"
#include "util/str.h"
static struct ac_io_emu ac_io_emu;
void ac_io_port_init(void)
{
ac_io_emu_init(&ac_io_emu, L"\\\\.\\COM2");
kfca_init(&ac_io_emu);
rs232_hook_add_fd(ac_io_emu.fd);
}
void ac_io_port_fini(void)
{
ac_io_emu_fini(&ac_io_emu);
}
HRESULT ac_io_port_dispatch_irp(struct irp *irp)
{
const struct ac_io_message *msg;
HRESULT hr;
log_assert(irp != NULL);
if (!ac_io_emu_match_irp(&ac_io_emu, irp)) {
return irp_invoke_next(irp);
}
for (;;) {
hr = ac_io_emu_dispatch_irp(&ac_io_emu, irp);
if (hr != S_OK) {
return hr;
}
msg = ac_io_emu_request_peek(&ac_io_emu);
switch (msg->addr) {
case 0:
ac_io_emu_cmd_assign_addrs(&ac_io_emu, msg, 1);
log_warning("ac_io_emu_cmd_assign_addrs");
break;
case 1:
kfca_dispatch_request(msg);
break;
case AC_IO_BROADCAST:
log_warning("Broadcast? (0x70) message on ACIO bus");
break;
default:
log_warning(
"ACIO message on unhandled bus address: %d", msg->addr);
break;
}
ac_io_emu_request_pop(&ac_io_emu);
}
}

View File

@@ -0,0 +1,14 @@
#ifndef SDVXHOOK2_5_AC_IO_H
#define SDVXHOOK2_5_AC_IO_H
#include <windows.h>
#include <stdbool.h>
#include "hook/iohook.h"
void ac_io_port_init(void);
void ac_io_port_fini(void);
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
#endif

View File

@@ -0,0 +1,55 @@
#include "cconfig/cconfig-util.h"
#include "sdvxhook2-cn/config-cn.h"
#include "util/log.h"
#define SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY "io.disable_io_emu"
#define SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY "cn.unis_path"
#define SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE false
#define SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE "prop/unis.xml"
void sdvxhook2_cn_config_init(struct cconfig *config)
{
cconfig_util_set_bool(
config,
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE,
"Disable IO emulation and enable usage of real KFCA hardware");
cconfig_util_set_str(
config,
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE,
"Path to unis version file under the prop.s folder");
}
void sdvxhook2_cn_config_get(
struct sdvxhook2_cn_config *cn_config, struct cconfig *config)
{
if (!cconfig_util_get_bool(
config,
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
&cn_config->disable_io_emu,
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
SDVXHOOK2_CN_CONFIG_DISABLE_IO_EMU_KEY,
SDVXHOOK2_CN_CONFIG_DEFAULT_DISABLE_IO_EMU_VALUE);
}
if (!cconfig_util_get_str(
config,
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
cn_config->unis_path,
sizeof(cn_config->unis_path),
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%s'",
SDVXHOOK2_CN_CONFIG_UNIS_PATH_KEY,
SDVXHOOK2_CN_CONFIG_DEFAULT_UNIS_PATH_VALUE);
}
}

View File

@@ -0,0 +1,18 @@
#ifndef SDVXHOOK2_CN_CONFIG_H
#define SDVXHOOK2_CN_CONFIG_H
#include <windows.h>
#include "cconfig/cconfig.h"
struct sdvxhook2_cn_config {
bool disable_io_emu;
char unis_path[256];
};
void sdvxhook2_cn_config_init(struct cconfig *config);
void sdvxhook2_cn_config_get(
struct sdvxhook2_cn_config *cn_config, struct cconfig *config);
#endif

View File

@@ -0,0 +1,151 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "bemanitools/eamio.h"
#include "bemanitools/sdvxio.h"
#include "cconfig/cconfig-hook.h"
#include "hooklib/acp.h"
#include "hooklib/adapter.h"
#include "hooklib/app.h"
#include "hooklib/rs232.h"
#include "sdvxhook2-cn/acio.h"
#include "sdvxhook2-cn/config-cn.h"
#include "sdvxhook2-cn/unis-version.h"
#include "camhook/cam.h"
#include "camhook/config-cam.h"
#include "d3d9exhook/config-gfx.h"
#include "d3d9exhook/d3d9ex.h"
#include "imports/avs.h"
#include "util/log.h"
#include "util/str.h"
#include "util/thread.h"
#define SDVXHOOK2_CN_INFO_HEADER \
"sdvxhook for VW CN" \
", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) "\n"
#define SDVXHOOK2_CN_CMD_USAGE \
"Usage: launcher.exe -K sdvxhook2.dll <soundvoltex.dll> [options...]"
static const irp_handler_t sdvxhook_handlers[] = {
ac_io_port_dispatch_irp,
};
struct sdvxhook2_cn_config config_cn;
struct camhook_config_cam config_cam;
struct d3d9exhook_config_gfx config_gfx;
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
{
struct cconfig *config;
log_info("--- Begin sdvxhook dll_entry_init ---");
config = cconfig_init();
sdvxhook2_cn_config_init(config);
d3d9exhook_config_gfx_init(config);
camhook_config_cam_init(config, 1);
if (!cconfig_hook_config_init(
config,
SDVXHOOK2_CN_INFO_HEADER "\n" SDVXHOOK2_CN_CMD_USAGE,
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
cconfig_finit(config);
exit(EXIT_FAILURE);
}
sdvxhook2_cn_config_get(&config_cn, config);
camhook_config_cam_get(&config_cam, config, 1);
d3d9exhook_config_gfx_get(&config_gfx, config);
cconfig_finit(config);
log_info(SDVXHOOK2_CN_INFO_HEADER);
log_info("Initializing sdvxhook2-cn...");
d3d9ex_configure(&config_gfx);
/* Start up sdvxio.DLL */
if (!config_cn.disable_io_emu) {
log_info("Starting sdvx IO backend");
sdvx_io_set_loggers(
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
if (!sdvx_io_init(
avs_thread_create, avs_thread_join, avs_thread_destroy)) {
log_fatal("Initializing sdvx IO backend failed");
}
}
/* iohooks are okay, even if emu is diabled since the fake handlers won't be
* used */
iohook_init(sdvxhook_handlers, lengthof(sdvxhook_handlers));
rs232_hook_init();
rs232_hook_limit_hooks();
if (!config_cn.disable_io_emu) {
ac_io_port_init();
}
// camera hooks
if (!config_cam.disable_emu) {
camhook_init(&config_cam);
}
unis_version_hook_init(config_cn.unis_path);
log_info("--- End sdvxhook dll_entry_init ---");
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 (!config_cn.disable_io_emu) {
log_misc("Shutting down sdvx IO backend");
sdvx_io_fini();
}
return result;
}
/**
* Hook library SDVX5 CN
*/
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
{
if (reason != DLL_PROCESS_ATTACH) {
goto end;
}
log_to_external(
log_body_misc, log_body_info, log_body_warning, log_body_fatal);
app_hook_init(my_dll_entry_init, my_dll_entry_main);
acp_hook_init();
adapter_hook_init();
d3d9ex_hook_init();
end:
return TRUE;
}

View File

@@ -0,0 +1,196 @@
#include <windows.h>
#include <stdint.h>
#include <string.h>
#include "acio/acio.h"
#include "acioemu/emu.h"
#include "bemanitools/sdvxio.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/time.h"
static void kfca_send_version(const struct ac_io_message *req);
static void kfca_report_status(const struct ac_io_message *req, uint8_t status);
static void kfca_report_0128(const struct ac_io_message *req);
static void kfca_poll(const struct ac_io_message *req);
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp);
static struct ac_io_emu *kfca_ac_io_emu;
void kfca_init(struct ac_io_emu *emu)
{
log_assert(emu != NULL);
kfca_ac_io_emu = emu;
}
void kfca_dispatch_request(const struct ac_io_message *req)
{
uint16_t cmd_code;
cmd_code = ac_io_u16(req->cmd.code);
switch (cmd_code) {
case AC_IO_CMD_GET_VERSION:
log_misc("AC_IO_CMD_GET_VERSION(%d)", req->addr);
kfca_send_version(req);
break;
case AC_IO_CMD_START_UP:
log_misc("AC_IO_CMD_START_UP(%d)", req->addr);
kfca_report_status(req, 0x00);
break;
case AC_IO_CMD_KFCA_POLL:
kfca_poll(req);
break;
case AC_IO_CMD_KFCA_WATCHDOG:
log_misc("AC_IO_CMD_KFCA_WATCHDOG(%d)", req->addr);
kfca_report_status(req, 0x00);
break;
case AC_IO_CMD_KFCA_AMP_CONTROL:
log_misc("AC_IO_CMD_KFCA_AMP_CONTROL(%d)", req->addr);
kfca_report_0128(req);
break;
default:
log_warning(
"Unknown ACIO message %04x on KFCA mode, addr=%d",
cmd_code,
req->addr);
break;
}
}
static void kfca_send_version(const struct ac_io_message *req)
{
struct ac_io_message resp;
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
resp.cmd.code = req->cmd.code;
resp.cmd.seq_no = req->cmd.seq_no;
resp.cmd.nbytes = sizeof(resp.cmd.version);
resp.cmd.version.type = ac_io_u32(AC_IO_NODE_TYPE_KFCA);
resp.cmd.version.flag = 0x00;
resp.cmd.version.major = 0x01;
resp.cmd.version.minor = 0x01;
resp.cmd.version.revision = 0x00;
memcpy(
resp.cmd.version.product_code,
"KFCA",
sizeof(resp.cmd.version.product_code));
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
}
static void kfca_report_status(const struct ac_io_message *req, uint8_t status)
{
struct ac_io_message resp;
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
resp.cmd.code = req->cmd.code;
resp.cmd.seq_no = req->cmd.seq_no;
resp.cmd.nbytes = sizeof(resp.cmd.status);
resp.cmd.status = status;
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
}
static void kfca_report_0128(const struct ac_io_message *req)
{
struct ac_io_message resp;
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
resp.cmd.code = req->cmd.code;
resp.cmd.seq_no = req->cmd.seq_no;
resp.cmd.nbytes = req->cmd.nbytes;
memcpy(resp.cmd.raw, req->cmd.raw, req->cmd.nbytes);
ac_io_emu_response_push(kfca_ac_io_emu, &resp, 0);
}
static void kfca_poll(const struct ac_io_message *req)
{
static uint32_t last_poll = 0;
uint64_t delay;
const struct ac_io_kfca_poll_out *pout;
uintptr_t ctx;
size_t i;
/* Handle lighting output immediately */
pout = &req->cmd.kfca_poll_out;
sdvx_io_set_gpio_lights(ac_io_u32(pout->gpio));
for (i = 0; i < lengthof(pout->pwm); i++) {
sdvx_io_set_pwm_light(i, pout->pwm[i]);
}
sdvx_io_write_output();
/* SDVX expects only one poll response per frame.
We use a thunk here to defer polling until right before the response
is due. */
delay = time_get_elapsed_ms(last_poll) < 16 ? 16000 : 0;
last_poll = time_get_counter();
ctx = req->addr | (req->cmd.code << 8) | (req->cmd.seq_no << 24);
ac_io_emu_response_push_thunk(
kfca_ac_io_emu, kfca_poll_thunk, (void *) ctx, delay);
}
static void kfca_poll_thunk(void *ctx_ptr, struct ac_io_message *resp)
{
struct ac_io_kfca_poll_in *pin;
uintptr_t ctx;
uint8_t req_addr;
uint16_t req_code;
uint8_t req_seq_no;
/* Unpack context "pointer" for relevant response information */
ctx = (uintptr_t) ctx_ptr;
req_addr = ctx;
req_code = ctx >> 8;
req_seq_no = ctx >> 24;
/* Poll input now and construct an immediate response */
pin = &resp->cmd.kfca_poll_in;
resp->addr = req_addr | AC_IO_RESPONSE_FLAG;
resp->cmd.code = req_code;
resp->cmd.seq_no = req_seq_no;
resp->cmd.nbytes = sizeof(*pin);
sdvx_io_read_input();
memset(pin, 0, sizeof(*pin));
pin->adc[0] = sdvx_io_get_spinner_pos(0) << 6;
pin->adc[1] = sdvx_io_get_spinner_pos(1) << 6;
pin->gpio_sys |= sdvx_io_get_input_gpio_sys() & 0x3F;
pin->adc[0] = ac_io_u16(pin->adc[0]);
pin->adc[1] = ac_io_u16(pin->adc[1]);
pin->gpio[0] = ac_io_u16(sdvx_io_get_input_gpio(0));
pin->gpio[1] = ac_io_u16(sdvx_io_get_input_gpio(1));
}

View File

@@ -0,0 +1,11 @@
#ifndef SDVXHOOK_KFCA_H
#define SDVXHOOK_KFCA_H
#include "acio/acio.h"
#include "acioemu/emu.h"
void kfca_init(struct ac_io_emu *emu);
void kfca_dispatch_request(const struct ac_io_message *req);
#endif

View File

@@ -0,0 +1,4 @@
LIBRARY sdvxhook2-cn
EXPORTS
DllMain@12 @1 NONAME

View File

@@ -0,0 +1,84 @@
#define LOG_MODULE "unis-version"
// clang-format off
// Don't format because the order is important here
#include <windows.h>
#include <shellapi.h>
// clang-format on
#include <stdio.h>
#include "hook/com-proxy.h"
#include "hook/table.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
#include "util/time.h"
LPWSTR *(*real_CommandLineToArgvW)(LPCWSTR lpCmdLine, int *pNumArgs);
LPWSTR *my_CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs);
static const struct hook_symbol unis_shell32_syms[] = {
{.name = "CommandLineToArgvW",
.patch = my_CommandLineToArgvW,
.link = (void **) &real_CommandLineToArgvW},
};
bool (*real_IsInComm)(void);
bool my_IsInComm(void);
bool (*real_IsConnectServer)(void);
bool my_IsConnectServer(void);
bool (*real_IsPlayerForbidState)(int pnum);
bool my_IsPlayerForbidState(int pnum);
static wchar_t unis_cmd_path[256 + 16];
static const struct hook_symbol unis_unisintr_syms[] = {
{.name = "IsInComm",
.patch = my_IsInComm,
.link = (void **) &real_IsInComm},
{.name = "IsConnectServer",
.patch = my_IsConnectServer,
.link = (void **) &real_IsConnectServer},
{.name = "IsPlayerForbidState",
.patch = my_IsPlayerForbidState,
.link = (void **) &real_IsPlayerForbidState},
};
LPWSTR *my_CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs)
{
return real_CommandLineToArgvW(unis_cmd_path, pNumArgs);
}
bool my_IsInComm(void)
{
return true;
}
bool my_IsConnectServer(void)
{
return true;
}
bool my_IsPlayerForbidState(int pnum)
{
return false;
}
void unis_version_hook_init(const char* unis_path)
{
hook_table_apply(
NULL, "Shell32.dll", unis_shell32_syms, lengthof(unis_shell32_syms));
hook_table_apply(
NULL, "unisintr.dll", unis_unisintr_syms, lengthof(unis_unisintr_syms));
wcscpy(unis_cmd_path, L"launcher.exe ");
wchar_t *end = wcsrchr(unis_cmd_path, L'\0');
mbstowcs(end, unis_path, 256);
log_info("Inserted hooks for unis version detection");
}

View File

@@ -0,0 +1,14 @@
#ifndef SDVXHOOK2_5_UNIS_VERSION_H
#define SDVXHOOK2_5_UNIS_VERSION_H
/**
* Hooks UNIS support functions
*
* patches:
* - unis config path
* - unis network functions
*
*/
void unis_version_hook_init(const char* unis_path);
#endif

View File

@@ -13,6 +13,7 @@
#include "hooklib/acp.h"
#include "hooklib/adapter.h"
#include "hooklib/app.h"
#include "hooklib/config-adapter.h"
#include "hooklib/rs232.h"
#include "bio2emu/emu.h"
@@ -47,6 +48,7 @@ static const irp_handler_t sdvxhook_handlers[] = {
struct sdvxhook2_config_io config_io;
struct camhook_config_cam config_cam;
struct d3d9exhook_config_gfx config_gfx;
struct hooklib_config_adapter config_adapter;
static struct bio2emu_port bio2_emu = {
.port = "COM4",
@@ -65,6 +67,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
sdvxhook2_config_io_init(config);
d3d9exhook_config_gfx_init(config);
camhook_config_cam_init(config, 1);
hooklib_config_adapter_init(config);
if (!cconfig_hook_config_init(
config,
@@ -77,6 +80,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
sdvxhook2_config_io_get(&config_io, config);
camhook_config_cam_get(&config_cam, config, 1);
d3d9exhook_config_gfx_get(&config_gfx, config);
hooklib_config_adapter_get(&config_adapter, config);
cconfig_finit(config);
@@ -129,6 +133,8 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
camhook_init(&config_cam);
}
adapter_hook_override(config_adapter.override_ip);
log_info("--- End sdvxhook dll_entry_init ---");
return app_hook_invoke_init(sidcode, param);
@@ -140,6 +146,10 @@ static bool my_dll_entry_main(void)
result = app_hook_invoke_main();
if (!config_cam.disable_emu) {
camhook_fini();
}
if (!config_io.disable_card_reader_emu) {
log_misc("Shutting down card reader backend");
eam_io_fini();
@@ -154,7 +164,7 @@ static bool my_dll_entry_main(void)
}
/**
* Hook library Resort Anthem onwards
* Hook library SDVX5+
*/
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
{