mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 11:55:10 -05:00
Compare commits
37 Commits
pr316
...
example_li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a00e3b82c7 | ||
|
|
2a71845df7 | ||
|
|
58bf2e6bb8 | ||
|
|
c67053f3d3 | ||
|
|
ccbd47428f | ||
|
|
8b89748ccf | ||
|
|
9a7285bb91 | ||
|
|
366f0090a9 | ||
|
|
d781905d83 | ||
|
|
e0ff83f664 | ||
|
|
972acb5f0e | ||
|
|
233df32372 | ||
|
|
d07b2094e9 | ||
|
|
7e1e9dabdb | ||
|
|
6146f53ad5 | ||
|
|
05d55024b6 | ||
|
|
cc5c35064c | ||
|
|
844286fde0 | ||
|
|
50aa6226a3 | ||
|
|
ea29b44b70 | ||
|
|
3090b9a029 | ||
|
|
a85ce4bc96 | ||
|
|
b7d1659a46 | ||
|
|
b64dea0849 | ||
|
|
64381a84c5 | ||
|
|
48668837a8 | ||
|
|
8307837995 | ||
|
|
a03c4e0d93 | ||
|
|
ca42257fa2 | ||
|
|
f7142df84d | ||
|
|
7d397dc54c | ||
|
|
2d4d5fa535 | ||
|
|
e81bd6f9cd | ||
|
|
a4b3f92935 | ||
|
|
6a98ce1f59 | ||
|
|
5833197b03 | ||
|
|
7ee9a2e219 |
2
.github/workflows/build-master.yaml
vendored
2
.github/workflows/build-master.yaml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: "actions/upload-artifact@v2"
|
uses: "actions/upload-artifact@v4"
|
||||||
with:
|
with:
|
||||||
name: bemanitools-${{ github.sha }}
|
name: bemanitools-${{ github.sha }}
|
||||||
retention-days: 90
|
retention-days: 90
|
||||||
|
|||||||
2
.github/workflows/build-tag.yaml
vendored
2
.github/workflows/build-tag.yaml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: "actions/upload-artifact@v2"
|
uses: "actions/upload-artifact@v4"
|
||||||
with:
|
with:
|
||||||
name: bemanitools-${{ github.sha }}
|
name: bemanitools-${{ github.sha }}
|
||||||
retention-days: 90
|
retention-days: 90
|
||||||
|
|||||||
21
Dockerfile.dev
Normal file
21
Dockerfile.dev
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
FROM --platform=amd64 debian:11.6-slim@sha256:f7d141c1ec6af549958a7a2543365a7829c2cdc4476308ec2e182f8a7c59b519
|
||||||
|
|
||||||
|
LABEL description="Development environment for bemanitools"
|
||||||
|
|
||||||
|
# mingw-w64-gcc has 32-bit and 64-bit toolchains
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
mingw-w64 \
|
||||||
|
mingw-w64-common \
|
||||||
|
make \
|
||||||
|
zip \
|
||||||
|
git \
|
||||||
|
clang-format \
|
||||||
|
python3-pip \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN pip3 install mdformat
|
||||||
|
|
||||||
|
RUN mkdir /bemanitools
|
||||||
|
WORKDIR /bemanitools
|
||||||
|
|
||||||
|
ENV SHELL /bin/bash
|
||||||
38
GNUmakefile
38
GNUmakefile
@@ -13,8 +13,10 @@ BUILDDIR ?= build
|
|||||||
|
|
||||||
builddir_docker := $(BUILDDIR)/docker
|
builddir_docker := $(BUILDDIR)/docker
|
||||||
|
|
||||||
docker_container_name := "bemanitools-build"
|
docker_build_container_name := "bemanitools-build"
|
||||||
docker_image_name := "bemanitools-build:latest"
|
docker_build_image_name := "bemanitools-build:latest"
|
||||||
|
docker_dev_container_name := "bemanitools-dev"
|
||||||
|
docker_dev_image_name := "bemanitools-dev:latest"
|
||||||
|
|
||||||
depdir := $(BUILDDIR)/dep
|
depdir := $(BUILDDIR)/dep
|
||||||
objdir := $(BUILDDIR)/obj
|
objdir := $(BUILDDIR)/obj
|
||||||
@@ -41,6 +43,7 @@ FORCE:
|
|||||||
|
|
||||||
.PHONY: \
|
.PHONY: \
|
||||||
build-docker \
|
build-docker \
|
||||||
|
dev-docker \
|
||||||
clean \
|
clean \
|
||||||
code-format \
|
code-format \
|
||||||
doc-format \
|
doc-format \
|
||||||
@@ -89,21 +92,38 @@ version:
|
|||||||
$(V)echo "$(gitrev)" > version
|
$(V)echo "$(gitrev)" > version
|
||||||
|
|
||||||
build-docker:
|
build-docker:
|
||||||
$(V)docker rm -f $(docker_container_name) 2> /dev/null || true
|
$(V)docker rm -f $(docker_build_container_name) 2> /dev/null || true
|
||||||
$(V)docker \
|
$(V)docker \
|
||||||
build \
|
build \
|
||||||
-t $(docker_image_name) \
|
-t $(docker_build_image_name) \
|
||||||
-f Dockerfile \
|
-f Dockerfile.build \
|
||||||
.
|
.
|
||||||
$(V)docker \
|
$(V)docker \
|
||||||
run \
|
run \
|
||||||
--volume $(shell pwd):/bemanitools \
|
--volume $(shell pwd):/bemanitools \
|
||||||
--name $(docker_container_name) \
|
--name $(docker_build_container_name) \
|
||||||
$(docker_image_name)
|
$(docker_build_image_name)
|
||||||
|
|
||||||
|
dev-docker:
|
||||||
|
$(V)docker rm -f $(docker_dev_container_name) 2> /dev/null || true
|
||||||
|
$(V)docker \
|
||||||
|
build \
|
||||||
|
-t $(docker_dev_image_name) \
|
||||||
|
-f Dockerfile.dev \
|
||||||
|
.
|
||||||
|
$(V)docker \
|
||||||
|
run \
|
||||||
|
--interactive \
|
||||||
|
--tty \
|
||||||
|
--volume $(shell pwd):/bemanitools \
|
||||||
|
--name $(docker_dev_container_name) \
|
||||||
|
$(docker_dev_image_name)
|
||||||
|
|
||||||
clean-docker:
|
clean-docker:
|
||||||
$(V)docker rm -f $(docker_container_name) || true
|
$(V)docker rm -f $(docker_dev_container_name) || true
|
||||||
$(V)docker image rm -f $(docker_image_name) || true
|
$(V)docker image rm -f $(docker_dev_image_name) || true
|
||||||
|
$(V)docker rm -f $(docker_build_container_name) || true
|
||||||
|
$(V)docker image rm -f $(docker_build_image_name) || true
|
||||||
$(V)rm -rf $(BUILDDIR)
|
$(V)rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
27
Module.mk
27
Module.mk
@@ -100,6 +100,8 @@ include src/main/bstio/Module.mk
|
|||||||
include src/main/camhook/Module.mk
|
include src/main/camhook/Module.mk
|
||||||
include src/main/cconfig/Module.mk
|
include src/main/cconfig/Module.mk
|
||||||
include src/main/config/Module.mk
|
include src/main/config/Module.mk
|
||||||
|
include src/main/d3d9-frame-graph-hook/Module.mk
|
||||||
|
include src/main/d3d9-monitor-check/Module.mk
|
||||||
include src/main/d3d9-util/Module.mk
|
include src/main/d3d9-util/Module.mk
|
||||||
include src/main/d3d9exhook/Module.mk
|
include src/main/d3d9exhook/Module.mk
|
||||||
include src/main/ddrhook-util/Module.mk
|
include src/main/ddrhook-util/Module.mk
|
||||||
@@ -154,9 +156,11 @@ include src/main/iidxhook6/Module.mk
|
|||||||
include src/main/iidxhook7/Module.mk
|
include src/main/iidxhook7/Module.mk
|
||||||
include src/main/iidxhook8/Module.mk
|
include src/main/iidxhook8/Module.mk
|
||||||
include src/main/iidxhook9/Module.mk
|
include src/main/iidxhook9/Module.mk
|
||||||
|
include src/main/iidxio-async/Module.mk
|
||||||
include src/main/iidxio-bio2/Module.mk
|
include src/main/iidxio-bio2/Module.mk
|
||||||
include src/main/iidxio-ezusb/Module.mk
|
include src/main/iidxio-ezusb/Module.mk
|
||||||
include src/main/iidxio-ezusb2/Module.mk
|
include src/main/iidxio-ezusb2/Module.mk
|
||||||
|
include src/main/iidxio-lightning/Module.mk
|
||||||
include src/main/iidxio/Module.mk
|
include src/main/iidxio/Module.mk
|
||||||
include src/main/iidxiotest/Module.mk
|
include src/main/iidxiotest/Module.mk
|
||||||
include src/main/imgui/Module.mk
|
include src/main/imgui/Module.mk
|
||||||
@@ -192,6 +196,8 @@ include src/main/sdvxhook2-cn/Module.mk
|
|||||||
include src/main/sdvxhook2/Module.mk
|
include src/main/sdvxhook2/Module.mk
|
||||||
include src/main/sdvxio-bio2/Module.mk
|
include src/main/sdvxio-bio2/Module.mk
|
||||||
include src/main/sdvxio-kfca/Module.mk
|
include src/main/sdvxio-kfca/Module.mk
|
||||||
|
include src/main/sdvxio-tbs/Module.mk
|
||||||
|
include src/main/sdvxio-valk/Module.mk
|
||||||
include src/main/sdvxio/Module.mk
|
include src/main/sdvxio/Module.mk
|
||||||
include src/main/security/Module.mk
|
include src/main/security/Module.mk
|
||||||
include src/main/unicorntail/Module.mk
|
include src/main/unicorntail/Module.mk
|
||||||
@@ -238,6 +244,8 @@ $(zipdir)/tools.zip: \
|
|||||||
build/bin/indep-32/ezusb2-tool.exe \
|
build/bin/indep-32/ezusb2-tool.exe \
|
||||||
build/bin/indep-32/ezusb-tool.exe \
|
build/bin/indep-32/ezusb-tool.exe \
|
||||||
build/bin/indep-32/nvgpu.exe \
|
build/bin/indep-32/nvgpu.exe \
|
||||||
|
build/bin/indep-32/d3d9-frame-graph-hook.dll \
|
||||||
|
build/bin/indep-32/d3d9-monitor-check.exe \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
@@ -253,6 +261,8 @@ $(zipdir)/tools-x64.zip: \
|
|||||||
build/bin/indep-64/jbiotest.exe \
|
build/bin/indep-64/jbiotest.exe \
|
||||||
build/bin/indep-64/mempatch-hook.dll \
|
build/bin/indep-64/mempatch-hook.dll \
|
||||||
build/bin/indep-64/nvgpu.exe \
|
build/bin/indep-64/nvgpu.exe \
|
||||||
|
build/bin/indep-64/d3d9-frame-graph-hook.dll \
|
||||||
|
build/bin/indep-64/d3d9-monitor-check.exe \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
@@ -299,7 +309,7 @@ $(zipdir)/iidx-13.zip: \
|
|||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/iidx-14-to-17.zip: \
|
$(zipdir)/iidx-14-to-17.zip: \
|
||||||
build/bin/avs2_0-32/iidxhook3.dll \
|
build/bin/avs2_803-32/iidxhook3.dll \
|
||||||
build/bin/indep-32/config.exe \
|
build/bin/indep-32/config.exe \
|
||||||
build/bin/indep-32/eamio.dll \
|
build/bin/indep-32/eamio.dll \
|
||||||
build/bin/indep-32/geninput.dll \
|
build/bin/indep-32/geninput.dll \
|
||||||
@@ -438,7 +448,7 @@ $(zipdir)/iidx-25-to-26.zip: \
|
|||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/iidx-27-to-30.zip: \
|
$(zipdir)/iidx-27-to-31.zip: \
|
||||||
build/bin/avs2_1700-64/iidxhook9.dll \
|
build/bin/avs2_1700-64/iidxhook9.dll \
|
||||||
build/bin/avs2_1700-64/launcher.exe \
|
build/bin/avs2_1700-64/launcher.exe \
|
||||||
build/bin/indep-64/config.exe \
|
build/bin/indep-64/config.exe \
|
||||||
@@ -451,10 +461,12 @@ $(zipdir)/iidx-27-to-30.zip: \
|
|||||||
dist/iidx/gamestart-28.bat \
|
dist/iidx/gamestart-28.bat \
|
||||||
dist/iidx/gamestart-29.bat \
|
dist/iidx/gamestart-29.bat \
|
||||||
dist/iidx/gamestart-30.bat \
|
dist/iidx/gamestart-30.bat \
|
||||||
|
dist/iidx/gamestart-31.bat \
|
||||||
dist/iidx/iidxhook-27.conf \
|
dist/iidx/iidxhook-27.conf \
|
||||||
dist/iidx/iidxhook-28.conf \
|
dist/iidx/iidxhook-28.conf \
|
||||||
dist/iidx/iidxhook-29.conf \
|
dist/iidx/iidxhook-29.conf \
|
||||||
dist/iidx/iidxhook-30.conf \
|
dist/iidx/iidxhook-30.conf \
|
||||||
|
dist/iidx/iidxhook-31.conf \
|
||||||
dist/iidx/vefx.txt \
|
dist/iidx/vefx.txt \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
@@ -463,6 +475,7 @@ $(zipdir)/iidx-27-to-30.zip: \
|
|||||||
$(zipdir)/iidx-hwio-x86.zip: \
|
$(zipdir)/iidx-hwio-x86.zip: \
|
||||||
build/bin/indep-32/aciomgr.dll \
|
build/bin/indep-32/aciomgr.dll \
|
||||||
build/bin/indep-32/eamio-icca.dll \
|
build/bin/indep-32/eamio-icca.dll \
|
||||||
|
build/bin/indep-32/iidxio-async.dll \
|
||||||
build/bin/indep-32/iidxio-bio2.dll \
|
build/bin/indep-32/iidxio-bio2.dll \
|
||||||
build/bin/indep-32/iidxio-ezusb.dll \
|
build/bin/indep-32/iidxio-ezusb.dll \
|
||||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||||
@@ -476,9 +489,11 @@ $(zipdir)/iidx-hwio-x86.zip: \
|
|||||||
$(zipdir)/iidx-hwio-x64.zip: \
|
$(zipdir)/iidx-hwio-x64.zip: \
|
||||||
build/bin/indep-64/aciomgr.dll \
|
build/bin/indep-64/aciomgr.dll \
|
||||||
build/bin/indep-64/eamio-icca.dll \
|
build/bin/indep-64/eamio-icca.dll \
|
||||||
|
build/bin/indep-64/iidxio-async.dll \
|
||||||
build/bin/indep-64/iidxio-bio2.dll \
|
build/bin/indep-64/iidxio-bio2.dll \
|
||||||
build/bin/indep-64/iidxio-ezusb.dll \
|
build/bin/indep-64/iidxio-ezusb.dll \
|
||||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||||
|
build/bin/indep-64/iidxio-lightning.dll \
|
||||||
dist/iidx/iidxio-bio2.conf \
|
dist/iidx/iidxio-bio2.conf \
|
||||||
build/bin/indep-64/vigem-iidxio.exe \
|
build/bin/indep-64/vigem-iidxio.exe \
|
||||||
dist/iidx/vigem-iidxio.conf \
|
dist/iidx/vigem-iidxio.conf \
|
||||||
@@ -633,6 +648,8 @@ $(zipdir)/sdvx-hwio-x64.zip: \
|
|||||||
build/bin/indep-64/eamio-icca.dll \
|
build/bin/indep-64/eamio-icca.dll \
|
||||||
build/bin/indep-64/sdvxio-kfca.dll \
|
build/bin/indep-64/sdvxio-kfca.dll \
|
||||||
build/bin/indep-64/sdvxio-bio2.dll \
|
build/bin/indep-64/sdvxio-bio2.dll \
|
||||||
|
build/bin/indep-64/sdvxio-tbs.dll \
|
||||||
|
build/bin/indep-64/sdvxio-valk.dll \
|
||||||
build/bin/indep-64/vigem-sdvxio.exe \
|
build/bin/indep-64/vigem-sdvxio.exe \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
@@ -717,6 +734,8 @@ $(zipdir)/ddr-14-to-18.zip: \
|
|||||||
build/bin/indep-32/eamio.dll \
|
build/bin/indep-32/eamio.dll \
|
||||||
build/bin/indep-32/geninput.dll \
|
build/bin/indep-32/geninput.dll \
|
||||||
dist/ddr/config.bat \
|
dist/ddr/config.bat \
|
||||||
|
dist/ddr/gamestart-17.bat \
|
||||||
|
dist/ddr/gamestart-18.bat \
|
||||||
dist/ddr/gamestart-14.bat \
|
dist/ddr/gamestart-14.bat \
|
||||||
dist/ddr/gamestart-15.bat \
|
dist/ddr/gamestart-15.bat \
|
||||||
dist/ddr/gamestart-16.bat \
|
dist/ddr/gamestart-16.bat \
|
||||||
@@ -735,6 +754,8 @@ $(zipdir)/ddr-16-to-18-x64.zip: \
|
|||||||
build/bin/indep-64/eamio.dll \
|
build/bin/indep-64/eamio.dll \
|
||||||
build/bin/indep-64/geninput.dll \
|
build/bin/indep-64/geninput.dll \
|
||||||
dist/ddr/config.bat \
|
dist/ddr/config.bat \
|
||||||
|
dist/ddr/gamestart-17.bat \
|
||||||
|
dist/ddr/gamestart-18.bat \
|
||||||
dist/ddr/gamestart-16.bat \
|
dist/ddr/gamestart-16.bat \
|
||||||
dist/ddr/gamestart-17.bat \
|
dist/ddr/gamestart-17.bat \
|
||||||
dist/ddr/gamestart-18.bat \
|
dist/ddr/gamestart-18.bat \
|
||||||
@@ -854,7 +875,7 @@ $(BUILDDIR)/bemanitools.zip: \
|
|||||||
$(zipdir)/iidx-20-cn.zip \
|
$(zipdir)/iidx-20-cn.zip \
|
||||||
$(zipdir)/iidx-21-to-24.zip \
|
$(zipdir)/iidx-21-to-24.zip \
|
||||||
$(zipdir)/iidx-25-to-26.zip \
|
$(zipdir)/iidx-25-to-26.zip \
|
||||||
$(zipdir)/iidx-27-to-30.zip \
|
$(zipdir)/iidx-27-to-31.zip \
|
||||||
$(zipdir)/iidx-hwio-x86.zip \
|
$(zipdir)/iidx-hwio-x86.zip \
|
||||||
$(zipdir)/iidx-hwio-x64.zip \
|
$(zipdir)/iidx-hwio-x64.zip \
|
||||||
$(zipdir)/jb-01.zip \
|
$(zipdir)/jb-01.zip \
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ The following games are supported with their corresponding hook-libraries.
|
|||||||
- Beatmania IIDX 28 BISTROVER (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
- Beatmania IIDX 28 BISTROVER (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
- Beatmania IIDX 29 CASTHOUR (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
- Beatmania IIDX 29 CASTHOUR (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
- Beatmania IIDX 30 RESIDENT (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
- Beatmania IIDX 30 RESIDENT (`iidx-27-to-30.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
|
- Beatmania IIDX 31 EPOLIS (`iidx-27-to-31.zip`): [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
- [jubeat](doc/jbhook/README.md)
|
- [jubeat](doc/jbhook/README.md)
|
||||||
- jubeat (`jb-01.zip`): [jbhook1](doc/jbhook/jbhook1.md)
|
- jubeat (`jb-01.zip`): [jbhook1](doc/jbhook/jbhook1.md)
|
||||||
- jubeat ripples (`jb-02.zip`): [jbhook1](doc/jbhook/jbhook1.md)
|
- jubeat ripples (`jb-02.zip`): [jbhook1](doc/jbhook/jbhook1.md)
|
||||||
@@ -119,6 +120,8 @@ The following games are supported with their corresponding hook-libraries.
|
|||||||
- [extiotest](doc/tools/extiotest.md)
|
- [extiotest](doc/tools/extiotest.md)
|
||||||
- [aciotest](doc/tools/aciotest.md): Command line tool to quickly test ACIO devices
|
- [aciotest](doc/tools/aciotest.md): Command line tool to quickly test ACIO devices
|
||||||
- config: UI input/output configuration tool when using the default bemanitools API (geninput)
|
- config: UI input/output configuration tool when using the default bemanitools API (geninput)
|
||||||
|
- [d3d9-monitor-check](doc/tools/d3d9-monitor-check.md): Command line tool to check the monitor refresh rate of the
|
||||||
|
current GPU + monitor configuration
|
||||||
- ir-beat-patch-9/10: Patch the IR beat phase on IIDX 9 and 10
|
- ir-beat-patch-9/10: Patch the IR beat phase on IIDX 9 and 10
|
||||||
- [mempatch-hook](doc/tools/mempatch-hook.md): Patch raw memory locations in the target process
|
- [mempatch-hook](doc/tools/mempatch-hook.md): Patch raw memory locations in the target process
|
||||||
based on the provided configuration
|
based on the provided configuration
|
||||||
|
|||||||
16
dist/iidx/gamestart-31.bat
vendored
Normal file
16
dist/iidx/gamestart-31.bat
vendored
Normal file
@@ -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
|
||||||
|
)
|
||||||
|
|
||||||
|
modules\launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-31.conf %*
|
||||||
3
dist/iidx/iidxhook-27.conf
vendored
3
dist/iidx/iidxhook-27.conf
vendored
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
|
|||||||
# Disables the camera emulation
|
# Disables the camera emulation
|
||||||
cam.disable_emu=true
|
cam.disable_emu=true
|
||||||
|
|
||||||
|
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
|
||||||
|
cam.port_layout=1
|
||||||
|
|
||||||
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
||||||
cam.disable_camera1=false
|
cam.disable_camera1=false
|
||||||
|
|
||||||
|
|||||||
3
dist/iidx/iidxhook-28.conf
vendored
3
dist/iidx/iidxhook-28.conf
vendored
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
|
|||||||
# Disables the camera emulation
|
# Disables the camera emulation
|
||||||
cam.disable_emu=true
|
cam.disable_emu=true
|
||||||
|
|
||||||
|
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
|
||||||
|
cam.port_layout=1
|
||||||
|
|
||||||
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
||||||
cam.disable_camera1=false
|
cam.disable_camera1=false
|
||||||
|
|
||||||
|
|||||||
3
dist/iidx/iidxhook-29.conf
vendored
3
dist/iidx/iidxhook-29.conf
vendored
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
|
|||||||
# Disables the camera emulation
|
# Disables the camera emulation
|
||||||
cam.disable_emu=true
|
cam.disable_emu=true
|
||||||
|
|
||||||
|
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
|
||||||
|
cam.port_layout=1
|
||||||
|
|
||||||
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
||||||
cam.disable_camera1=true
|
cam.disable_camera1=true
|
||||||
|
|
||||||
|
|||||||
3
dist/iidx/iidxhook-30.conf
vendored
3
dist/iidx/iidxhook-30.conf
vendored
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
|
|||||||
# Disables the camera emulation
|
# Disables the camera emulation
|
||||||
cam.disable_emu=true
|
cam.disable_emu=true
|
||||||
|
|
||||||
|
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
|
||||||
|
cam.port_layout=1
|
||||||
|
|
||||||
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
||||||
cam.disable_camera1=true
|
cam.disable_camera1=true
|
||||||
|
|
||||||
|
|||||||
84
dist/iidx/iidxhook-31.conf
vendored
Normal file
84
dist/iidx/iidxhook-31.conf
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (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=true
|
||||||
|
|
||||||
|
# Disables the built in file hooks, requiring manual file creation
|
||||||
|
io.disable_file_hooks=false
|
||||||
|
|
||||||
|
# Turntable sensitivity multiplier (1.0 is default)
|
||||||
|
io.tt_multiplier=1.0
|
||||||
|
|
||||||
|
# Disables the camera emulation
|
||||||
|
cam.disable_emu=true
|
||||||
|
|
||||||
|
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
|
||||||
|
cam.disable_camera1=true
|
||||||
|
|
||||||
|
# Disable camera 2. Use, i.e., if you have more than one camera but only want to map camera 1 ingame.
|
||||||
|
cam.disable_camera2=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 cursor 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
|
||||||
|
|
||||||
|
# Windowed X, -1 for default X position
|
||||||
|
gfx.window_x=-1
|
||||||
|
|
||||||
|
# Windowed Y, -1 for default Y position
|
||||||
|
gfx.window_y=-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
|
||||||
|
|
||||||
|
# Force a screen resolution (width), -1 to disable. Use this if the game does not auto detect your monitor's resolution properly, e.g. 1368x768 instead of 1280x720.
|
||||||
|
gfx.force_screen_res.width=-1
|
||||||
|
|
||||||
|
# Force a screen resolution (height), -1 to disable. Use this if the game does not auto detect your monitor's resolution properly, e.g. 1368x768 instead of 1280x720.
|
||||||
|
gfx.force_screen_res.height=-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)
|
||||||
|
|
||||||
@@ -48,6 +48,8 @@ Available implementations that can be swapped out depending on which kind of IO
|
|||||||
use:
|
use:
|
||||||
|
|
||||||
- `iidxio`: Default implementation supporting keyboard, mouse and USB game controllers
|
- `iidxio`: Default implementation supporting keyboard, mouse and USB game controllers
|
||||||
|
- [iidxio-async](iidxhook/iidxio-async.md): Shim implementation that runs another iidxio implementation in a dedicated
|
||||||
|
thread
|
||||||
- [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
- [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
||||||
- [iidxio-ezusb](iidxhook/iidxio-ezusb.md): Support C02 ezusb FX hardware
|
- [iidxio-ezusb](iidxhook/iidxio-ezusb.md): Support C02 ezusb FX hardware
|
||||||
- [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
- [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ The following games are compatible with this version of iidxhook:
|
|||||||
- BISTROVER
|
- BISTROVER
|
||||||
- CASTHOUR
|
- CASTHOUR
|
||||||
- RESIDENT
|
- RESIDENT
|
||||||
|
- EPOLIS
|
||||||
|
|
||||||
The games must be bootstrapped using [launcher](../launcher.md).
|
The games must be bootstrapped using [launcher](../launcher.md).
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ unpacked data looks like this:
|
|||||||
- Unpack the package containing iidxhook9 into the root folder so iidxhook9.dll and all other
|
- 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.
|
files are located in the same folder as *data*, *prop*, *bm2dx.dll*, etc.
|
||||||
|
|
||||||
- For version 30
|
- For version 30-31
|
||||||
|
|
||||||
- Unpack the package containing iidxhook9 into the `modules` folder so iidxhook9.dll and all other
|
- Unpack the package containing iidxhook9 into the `modules` folder so iidxhook9.dll and all other
|
||||||
files are located in the same folder as the game's DLLs, e.g. *bm2dx.dll*, etc.
|
files are located in the same folder as the game's DLLs, e.g. *bm2dx.dll*, etc.
|
||||||
@@ -93,6 +94,12 @@ The syntax for the "key=value" is the same as in the config file. Make sure to h
|
|||||||
However, if a parameter is specifed in the configuration file and as a command line argument, the
|
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.
|
command line argument overrides the config file's value.
|
||||||
|
|
||||||
|
# Note on camhook
|
||||||
|
|
||||||
|
The cammera hook (camhook) is used to allow other class compliant cameras to be used. Depending on the variant of the game, you will need to select the correct camera port layout.
|
||||||
|
|
||||||
|
For original LDJ, this is always 0, for conversion kit LDJ and original TDJ-JA, this is 1, and for TDJ-JB this will be 2 (this case is rare / you will know if this is needed on your setup).
|
||||||
|
|
||||||
# Eamuse network setup
|
# Eamuse network setup
|
||||||
|
|
||||||
If you want to run the games online, you need a valid PCBID and the service URL. Open
|
If you want to run the games online, you need a valid PCBID and the service URL. Open
|
||||||
|
|||||||
22
doc/iidxhook/iidxio-async.md
Normal file
22
doc/iidxhook/iidxio-async.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# IIDXIO async API implementation
|
||||||
|
|
||||||
|
This implementation of the iidxio API is a shim library that takes another iidxio library and
|
||||||
|
runs the functions `iidx_io_ep1_send`, `iidx_io_ep2_recv` and `iidx_io_ep3_write_16seg` in a
|
||||||
|
dedicated thread. State synchronization to the getter and setter functions is also handled
|
||||||
|
transparently.
|
||||||
|
|
||||||
|
Usage of this **may** improve performance of certain iidxio implementations or when using them
|
||||||
|
in certain integrations, e.g. the send and receive functions of a iidxio implementation for some
|
||||||
|
target IO hardware calls are synchronous and expensive.
|
||||||
|
|
||||||
|
This is not a fix/solution to a badly implemented iidxio library with poor performance as it cannot
|
||||||
|
make it go faster and address potential latency issues, for example.
|
||||||
|
|
||||||
|
Use with caution and know why and when you need to use it.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
* Add `iidxio-async.dll` in the same folder as your `iidxhookX.dll`
|
||||||
|
* Rename your `iidxio.dll` to `iidxio-async-child.dll`
|
||||||
|
* Rename `iidxio-async.dll` to `iidxio.dll`
|
||||||
|
* Run the game
|
||||||
27
doc/tools/d3d9-monitor-check.md
Normal file
27
doc/tools/d3d9-monitor-check.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# D3D9 Monitor Check
|
||||||
|
|
||||||
|
A separate application to run the infamous IIDX “monitor check” without having to run the actual
|
||||||
|
game. The tool can be used to test measure the current avg. monitor refresh rate or debug/check if
|
||||||
|
that value is fluctuating for some reason.
|
||||||
|
|
||||||
|
The final avg. value that is provided at the end of the test can be used as input for other tooling
|
||||||
|
or settings (e.g. patching charts to a different refresh rate on older games with bemanitools).
|
||||||
|
|
||||||
|
Simply run the tool without any arguments to get a full synopsis with usage instructions.
|
||||||
|
|
||||||
|
## "Accuracy" remarks
|
||||||
|
|
||||||
|
The tool has been tested on an actual cabinet with `nvgpu` setting different custom timings. The
|
||||||
|
accuracy seems to be even higher than what IIDX’s monitor check is actually showing. For example,
|
||||||
|
with a custom timing of 59.900 hz, this tool yields fairly accurate and stable avg. 59.902 hz.
|
||||||
|
|
||||||
|
The monitor check of IIDX 29 shows results of 59.8981 hz to 59.8997 hz on screen. As these are the
|
||||||
|
only visible values to the user, determining a specific (avg.) value that can be used as input for
|
||||||
|
other tooling or settings (e.g. patching charts to a different refresh rate on older games with
|
||||||
|
bemanitools) is difficult. This doesn't mean that the game's monitor checks are actually
|
||||||
|
inaccurate or wrong. Modern games with a built-in monitor check (starting IIDX 20) are syncing up
|
||||||
|
fine and don't need any further patching or modifications.
|
||||||
|
|
||||||
|
For older games, picking a value that is not as close as possible to an accurate avg. value can
|
||||||
|
easily lead to issues with sync. So it's recommended to use the d3d9-monitor-check tool to get the
|
||||||
|
most accurate value.
|
||||||
@@ -28,7 +28,6 @@ micro stuttering.
|
|||||||
* Create a custom profile: `nvgpu profile create launcher`
|
* Create a custom profile: `nvgpu profile create launcher`
|
||||||
* Add the launcher application to the profile: `nvgpu profile application-add launcher launcher.exe`
|
* Add the launcher application to the profile: `nvgpu profile application-add launcher launcher.exe`
|
||||||
* This will apply to any (IIDX) game running with `launcher.exe`
|
* This will apply to any (IIDX) game running with `launcher.exe`
|
||||||
* Disable G-SYNC for the profile: `nvgpu profile gsync-disable launcher`
|
|
||||||
* Set GPU power state to maximum for the profile: `nvgpu profile gpu-power-state-max launcher`
|
* Set GPU power state to maximum for the profile: `nvgpu profile gpu-power-state-max launcher`
|
||||||
|
|
||||||
### Custom timing
|
### Custom timing
|
||||||
@@ -41,7 +40,7 @@ micro stuttering.
|
|||||||
first
|
first
|
||||||
* For example, for IIDX 31 which runs in native 1920x1080 with a monitor also having that as its native resolution,
|
* For example, for IIDX 31 which runs in native 1920x1080 with a monitor also having that as its native resolution,
|
||||||
having the monitor id `0x12345678` and the monitor check yielding a value of ~`59.9345`, run
|
having the monitor id `0x12345678` and the monitor check yielding a value of ~`59.9345`, run
|
||||||
`nvgpu display custom-resolution-test 1920 1080 59.9345 10`
|
`nvgpu display custom-resolution-test 1920 1080 59.9345`
|
||||||
* Observe if the test is successful and the display doesn't turn blank or displays a glitched image for ~10 seconds
|
* Observe if the test is successful and the display doesn't turn blank or displays a glitched image for ~10 seconds
|
||||||
* Run `nvgpu display custom-resolution-set` with the previously tested settings to apply the custom display mode
|
* Run `nvgpu display custom-resolution-set` with the previously tested settings to apply the custom display mode
|
||||||
* For example, `nvgpu display custom-resolution-set 0x12345678 1920 1080 59.9345`
|
* For example, `nvgpu display custom-resolution-set 0x12345678 1920 1080 59.9345`
|
||||||
@@ -61,7 +60,6 @@ micro stuttering.
|
|||||||
* Create a custom profile: `nvgpu profile create bm2dx`
|
* Create a custom profile: `nvgpu profile create bm2dx`
|
||||||
* Add the launcher application to the profile: `nvgpu profile application-add bm2dx bm2dx.exe`
|
* Add the launcher application to the profile: `nvgpu profile application-add bm2dx bm2dx.exe`
|
||||||
* This will apply to any (IIDX) game running with an executable named `bm2fx.exe`
|
* This will apply to any (IIDX) game running with an executable named `bm2fx.exe`
|
||||||
* Disable G-SYNC for the profile: `nvgpu profile gsync-disable bm2dx`
|
|
||||||
* Set GPU power state to maximum for the profile: `nvgpu profile gpu-power-state-max bm2dx`
|
* Set GPU power state to maximum for the profile: `nvgpu profile gpu-power-state-max bm2dx`
|
||||||
|
|
||||||
### Custom timing
|
### Custom timing
|
||||||
@@ -74,7 +72,7 @@ micro stuttering.
|
|||||||
first
|
first
|
||||||
* For example, for IIDX 31 which runs in native 1920x1080 with a monitor also having that as its native resolution,
|
* For example, for IIDX 31 which runs in native 1920x1080 with a monitor also having that as its native resolution,
|
||||||
having the monitor id `0x12345678` and the monitor check yielding a value of ~`59.9345`, run
|
having the monitor id `0x12345678` and the monitor check yielding a value of ~`59.9345`, run
|
||||||
`nvgpu display custom-resolution-test 1920 1080 59.9345 10`
|
`nvgpu display custom-resolution-test 1920 1080 59.9345`
|
||||||
* Observe if the test is successful and the display doesn't turn blank or displays a glitched image for ~10 seconds
|
* Observe if the test is successful and the display doesn't turn blank or displays a glitched image for ~10 seconds
|
||||||
* Run `nvgpu display custom-resolution-set` with the previously tested settings to apply the custom display mode
|
* Run `nvgpu display custom-resolution-set` with the previously tested settings to apply the custom display mode
|
||||||
* For example, `nvgpu display custom-resolution-set 0x12345678 1920 1080 59.9345`
|
* For example, `nvgpu display custom-resolution-set 0x12345678 1920 1080 59.9345`
|
||||||
@@ -220,6 +220,9 @@ void property_file_write(struct property *prop, const char *path);
|
|||||||
int property_set_flag(struct property *prop, int flags, int mask);
|
int property_set_flag(struct property *prop, int flags, int mask);
|
||||||
void property_destroy(struct property *prop);
|
void property_destroy(struct property *prop);
|
||||||
|
|
||||||
|
avs_error property_get_error(struct property *prop);
|
||||||
|
void property_clear_error(struct property *prop);
|
||||||
|
|
||||||
int property_psmap_import(
|
int property_psmap_import(
|
||||||
struct property *prop,
|
struct property *prop,
|
||||||
struct property_node *root,
|
struct property_node *root,
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ EXPORTS
|
|||||||
property_destroy
|
property_destroy
|
||||||
property_file_write
|
property_file_write
|
||||||
property_insert_read
|
property_insert_read
|
||||||
|
property_clear_error
|
||||||
|
property_get_error
|
||||||
property_mem_write
|
property_mem_write
|
||||||
property_read_query_memsize
|
property_read_query_memsize
|
||||||
property_search
|
property_search
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ EXPORTS
|
|||||||
property_destroy
|
property_destroy
|
||||||
property_file_write
|
property_file_write
|
||||||
property_insert_read
|
property_insert_read
|
||||||
|
property_clear_error
|
||||||
|
property_get_error
|
||||||
property_mem_write
|
property_mem_write
|
||||||
property_read_query_memsize
|
property_read_query_memsize
|
||||||
property_search
|
property_search
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @246 NONAME
|
property_desc_to_buffer @246 NONAME
|
||||||
property_destroy @247 NONAME
|
property_destroy @247 NONAME
|
||||||
property_insert_read @255 NONAME
|
property_insert_read @255 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @266 NONAME
|
property_node_create @266 NONAME
|
||||||
property_node_datasize @267 NONAME
|
property_node_datasize @267 NONAME
|
||||||
property_node_name @274 NONAME
|
property_node_name @274 NONAME
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @201 NONAME
|
property_desc_to_buffer @201 NONAME
|
||||||
property_destroy @264 NONAME
|
property_destroy @264 NONAME
|
||||||
property_insert_read @23 NONAME
|
property_insert_read @23 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @316 NONAME
|
property_node_create @316 NONAME
|
||||||
property_node_datasize @249 NONAME
|
property_node_datasize @249 NONAME
|
||||||
property_node_name @255 NONAME
|
property_node_name @255 NONAME
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @201 NONAME == XC058ba50000cd
|
property_desc_to_buffer @201 NONAME == XC058ba50000cd
|
||||||
property_destroy @264 NONAME == XC058ba500010f
|
property_destroy @264 NONAME == XC058ba500010f
|
||||||
property_insert_read @23 NONAME == XC058ba5000016
|
property_insert_read @23 NONAME == XC058ba5000016
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @316 NONAME == XC058ba5000143
|
property_node_create @316 NONAME == XC058ba5000143
|
||||||
property_node_datasize @249 NONAME == XC058ba5000100
|
property_node_datasize @249 NONAME == XC058ba5000100
|
||||||
property_node_name @255 NONAME == XC058ba5000106
|
property_node_name @255 NONAME == XC058ba5000106
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @131 NONAME
|
property_desc_to_buffer @131 NONAME
|
||||||
property_destroy @130 NONAME
|
property_destroy @130 NONAME
|
||||||
property_insert_read @133 NONAME
|
property_insert_read @133 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_name @573 NONAME ==
|
property_node_name @573 NONAME ==
|
||||||
property_node_read @573 NONAME ==
|
property_node_read @573 NONAME ==
|
||||||
property_node_remove @148 NONAME
|
property_node_remove @148 NONAME
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @129 NONAME
|
property_desc_to_buffer @129 NONAME
|
||||||
property_destroy @128 NONAME
|
property_destroy @128 NONAME
|
||||||
property_insert_read @131 NONAME
|
property_insert_read @131 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @145 NONAME
|
property_node_create @145 NONAME
|
||||||
property_node_name @150 NONAME
|
property_node_name @150 NONAME
|
||||||
property_node_read @154 NONAME == XCd229cc0000f3
|
property_node_read @154 NONAME == XCd229cc0000f3
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ EXPORTS
|
|||||||
property_destroy @125 NONAME
|
property_destroy @125 NONAME
|
||||||
property_desc_to_buffer @126 NONAME
|
property_desc_to_buffer @126 NONAME
|
||||||
property_insert_read @128 NONAME
|
property_insert_read @128 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_search @141 NONAME
|
property_search @141 NONAME
|
||||||
property_node_create @142 NONAME
|
property_node_create @142 NONAME
|
||||||
property_node_name @147 NONAME == XCnbrep7000092
|
property_node_name @147 NONAME == XCnbrep7000092
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ EXPORTS
|
|||||||
property_destroy @146 NONAME
|
property_destroy @146 NONAME
|
||||||
property_desc_to_buffer @147 NONAME
|
property_desc_to_buffer @147 NONAME
|
||||||
property_insert_read @149 NONAME
|
property_insert_read @149 NONAME
|
||||||
|
property_clear_error @158 NONAME == XCnbrep700009d
|
||||||
|
property_get_error @159 NONAME == XCnbrep700009e
|
||||||
property_search @162 NONAME
|
property_search @162 NONAME
|
||||||
property_node_create @163 NONAME
|
property_node_create @163 NONAME
|
||||||
property_node_name @168 NONAME == XCnbrep70000a7
|
property_node_name @168 NONAME == XCnbrep70000a7
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ EXPORTS
|
|||||||
property_destroy @146 NONAME
|
property_destroy @146 NONAME
|
||||||
property_desc_to_buffer @147 NONAME
|
property_desc_to_buffer @147 NONAME
|
||||||
property_insert_read @149 NONAME
|
property_insert_read @149 NONAME
|
||||||
|
property_clear_error @158 NONAME == XCgsqzn000009d
|
||||||
|
property_get_error @159 NONAME == XCgsqzn000009e
|
||||||
property_search @162 NONAME
|
property_search @162 NONAME
|
||||||
property_node_create @163 NONAME
|
property_node_create @163 NONAME
|
||||||
property_node_name @168 NONAME == XCgsqzn00000a7
|
property_node_name @168 NONAME == XCgsqzn00000a7
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ EXPORTS
|
|||||||
property_destroy
|
property_destroy
|
||||||
property_file_write
|
property_file_write
|
||||||
property_insert_read
|
property_insert_read
|
||||||
|
property_clear_error
|
||||||
|
property_get_error
|
||||||
property_mem_write
|
property_mem_write
|
||||||
property_read_query_memsize
|
property_read_query_memsize
|
||||||
property_search
|
property_search
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @129 NONAME
|
property_desc_to_buffer @129 NONAME
|
||||||
property_destroy @128 NONAME
|
property_destroy @128 NONAME
|
||||||
property_insert_read @131 NONAME
|
property_insert_read @131 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @145 NONAME
|
property_node_create @145 NONAME
|
||||||
property_node_name @150 NONAME
|
property_node_name @150 NONAME
|
||||||
property_node_read @154 NONAME == XCd229cc0000f3
|
property_node_read @154 NONAME == XCd229cc0000f3
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ EXPORTS
|
|||||||
property_desc_to_buffer @129 NONAME
|
property_desc_to_buffer @129 NONAME
|
||||||
property_destroy @128 NONAME
|
property_destroy @128 NONAME
|
||||||
property_insert_read @131 NONAME
|
property_insert_read @131 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_node_create @145 NONAME
|
property_node_create @145 NONAME
|
||||||
property_node_name @573 NONAME ==
|
property_node_name @573 NONAME ==
|
||||||
property_node_read @573 NONAME ==
|
property_node_read @573 NONAME ==
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ EXPORTS
|
|||||||
property_destroy @125 NONAME
|
property_destroy @125 NONAME
|
||||||
property_desc_to_buffer @126 NONAME
|
property_desc_to_buffer @126 NONAME
|
||||||
property_insert_read @128 NONAME
|
property_insert_read @128 NONAME
|
||||||
|
property_clear_error @573 NONAME
|
||||||
|
property_get_error @573 NONAME
|
||||||
property_search @141 NONAME
|
property_search @141 NONAME
|
||||||
property_node_create @142 NONAME
|
property_node_create @142 NONAME
|
||||||
property_node_name @147 NONAME == XCnbrep7000092
|
property_node_name @147 NONAME == XCnbrep7000092
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ EXPORTS
|
|||||||
property_destroy @146 NONAME
|
property_destroy @146 NONAME
|
||||||
property_desc_to_buffer @147 NONAME
|
property_desc_to_buffer @147 NONAME
|
||||||
property_insert_read @149 NONAME
|
property_insert_read @149 NONAME
|
||||||
|
property_clear_error @158 NONAME == XCnbrep700009d
|
||||||
|
property_get_error @159 NONAME == XCnbrep700009e
|
||||||
property_search @162 NONAME
|
property_search @162 NONAME
|
||||||
property_node_create @163 NONAME
|
property_node_create @163 NONAME
|
||||||
property_node_name @168 NONAME == XCnbrep70000a7
|
property_node_name @168 NONAME == XCnbrep70000a7
|
||||||
property_node_remove @164 NONAME
|
property_node_remove @164 NONAME
|
||||||
property_node_type @169 NONAME == XCnbrep70000a8
|
property_node_type @169 NONAME == XCnbrep70000a8
|
||||||
property_node_clone @165 NONAME
|
property_node_clone @165 NONAME == XCnbrep70000a4
|
||||||
property_node_traversal @167 NONAME
|
property_node_traversal @167 NONAME
|
||||||
property_node_refdata @166 NONAME == XCnbrep70000a5
|
property_node_refdata @166 NONAME == XCnbrep70000a5
|
||||||
property_node_datasize @171 NONAME == XCnbrep70000aa
|
property_node_datasize @171 NONAME == XCnbrep70000aa
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ EXPORTS
|
|||||||
property_destroy @146 NONAME
|
property_destroy @146 NONAME
|
||||||
property_desc_to_buffer @147 NONAME
|
property_desc_to_buffer @147 NONAME
|
||||||
property_insert_read @149 NONAME
|
property_insert_read @149 NONAME
|
||||||
|
property_clear_error @158 NONAME == XCgsqzn000009d
|
||||||
|
property_get_error @159 NONAME == XCgsqzn000009e
|
||||||
property_search @162 NONAME
|
property_search @162 NONAME
|
||||||
property_node_create @163 NONAME
|
property_node_create @163 NONAME
|
||||||
property_node_name @168 NONAME == XCgsqzn00000a7
|
property_node_name @168 NONAME == XCgsqzn00000a7
|
||||||
|
|||||||
@@ -96,4 +96,14 @@ const char *avs_util_error_str(avs_error error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return avs_util_error_unknown;
|
return avs_util_error_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *avs_util_property_error_get_and_clear(struct property *prop)
|
||||||
|
{
|
||||||
|
avs_error error;
|
||||||
|
|
||||||
|
error = property_get_error(prop);
|
||||||
|
property_clear_error(prop);
|
||||||
|
|
||||||
|
return avs_util_error_str(error);
|
||||||
}
|
}
|
||||||
@@ -5,4 +5,6 @@
|
|||||||
|
|
||||||
const char *avs_util_error_str(avs_error error);
|
const char *avs_util_error_str(avs_error error);
|
||||||
|
|
||||||
#endif
|
const char *avs_util_property_error_get_and_clear(struct property *prop);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ libs_camhook := \
|
|||||||
|
|
||||||
src_camhook := \
|
src_camhook := \
|
||||||
cam.c \
|
cam.c \
|
||||||
|
cam-detect.c \
|
||||||
config-cam.c \
|
config-cam.c \
|
||||||
|
|||||||
402
src/main/camhook/cam-detect.c
Normal file
402
src/main/camhook/cam-detect.c
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
#define LOG_MODULE "cam-hook"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// Don't format because the order is important here
|
||||||
|
#include <windows.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#include <mfapi.h>
|
||||||
|
#include <mfidl.h>
|
||||||
|
#include <mfobjects.h>
|
||||||
|
|
||||||
|
#include <cfgmgr32.h>
|
||||||
|
#include <setupapi.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "camhook/cam-detect.h"
|
||||||
|
|
||||||
|
#include "util/defs.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/str.h"
|
||||||
|
|
||||||
|
EXTERN_GUID(
|
||||||
|
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
||||||
|
0xc60ac5fe,
|
||||||
|
0x252a,
|
||||||
|
0x478f,
|
||||||
|
0xa0,
|
||||||
|
0xef,
|
||||||
|
0xbc,
|
||||||
|
0x8f,
|
||||||
|
0xa5,
|
||||||
|
0xf7,
|
||||||
|
0xca,
|
||||||
|
0xd3);
|
||||||
|
EXTERN_GUID(
|
||||||
|
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID,
|
||||||
|
0x8ac3587a,
|
||||||
|
0x4ae7,
|
||||||
|
0x42d8,
|
||||||
|
0x99,
|
||||||
|
0xe0,
|
||||||
|
0x0a,
|
||||||
|
0x60,
|
||||||
|
0x13,
|
||||||
|
0xee,
|
||||||
|
0xf9,
|
||||||
|
0x0f);
|
||||||
|
EXTERN_GUID(
|
||||||
|
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
|
||||||
|
0x58f0aad8,
|
||||||
|
0x22bf,
|
||||||
|
0x4f8a,
|
||||||
|
0xbb,
|
||||||
|
0x3d,
|
||||||
|
0xd2,
|
||||||
|
0xc4,
|
||||||
|
0x97,
|
||||||
|
0x8c,
|
||||||
|
0x6e,
|
||||||
|
0x2f);
|
||||||
|
// define ourselves cause mingw has these wrong
|
||||||
|
|
||||||
|
|
||||||
|
bool check_four(const char inA[4], const char inB[4])
|
||||||
|
{
|
||||||
|
return (*(uint32_t *) inA == *(uint32_t *) inB);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *grab_next_camera_id(char *buffer, size_t bsz)
|
||||||
|
{
|
||||||
|
static size_t gotten = 0;
|
||||||
|
|
||||||
|
IMFAttributes *pAttributes = NULL;
|
||||||
|
IMFActivate **ppDevices = NULL;
|
||||||
|
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
|
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
log_info("MFCreateAttributes failed: %ld", hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pAttributes->lpVtbl->SetGUID(
|
||||||
|
pAttributes,
|
||||||
|
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
||||||
|
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
log_info("SetGUID failed: %ld", hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 count;
|
||||||
|
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
log_info("MFEnumDeviceSources failed: %ld", hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count <= gotten) {
|
||||||
|
log_info("gotten failed: %d < %d", count, (int) gotten);
|
||||||
|
// not enough remaining
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t wSymLink[CAMERA_DATA_STRING_SIZE];
|
||||||
|
UINT32 sz;
|
||||||
|
|
||||||
|
hr = ppDevices[gotten]->lpVtbl->GetString(
|
||||||
|
ppDevices[gotten],
|
||||||
|
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
|
||||||
|
wSymLink,
|
||||||
|
CAMERA_DATA_STRING_SIZE,
|
||||||
|
&sz);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
log_info("GetString failed: %ld", hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcstombs(buffer, wSymLink, bsz);
|
||||||
|
log_info("Detected webcam: %s\n", buffer);
|
||||||
|
++gotten;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (pAttributes) {
|
||||||
|
pAttributes->lpVtbl->Release(pAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < count; i++) {
|
||||||
|
if (ppDevices != NULL && ppDevices[i]) {
|
||||||
|
ppDevices[i]->lpVtbl->Release(ppDevices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoTaskMemFree(ppDevices);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool convert_sym_to_path(const char *sym, char *path)
|
||||||
|
{
|
||||||
|
HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
|
||||||
|
|
||||||
|
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
|
||||||
|
log_info("Could not open SetupDiCreateDeviceInfoList\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = {0};
|
||||||
|
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||||
|
|
||||||
|
if (!SetupDiOpenDeviceInterfaceA(
|
||||||
|
DeviceInfoSet, sym, 0, &DeviceInterfaceData)) {
|
||||||
|
log_info("Could not SetupDiOpenDeviceInterfaceA\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_DEVINFO_DATA DeviceInfoData = {0};
|
||||||
|
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||||
|
|
||||||
|
if (!SetupDiGetDeviceInterfaceDetailA(
|
||||||
|
DeviceInfoSet,
|
||||||
|
&DeviceInterfaceData,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&DeviceInfoData)) {
|
||||||
|
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
log_info("Could not SetupDiGetDeviceInterfaceDetailA\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD sz;
|
||||||
|
|
||||||
|
if (!SetupDiGetDeviceInstanceIdA(
|
||||||
|
DeviceInfoSet,
|
||||||
|
&DeviceInfoData,
|
||||||
|
path,
|
||||||
|
CAMERA_DATA_STRING_SIZE,
|
||||||
|
&sz)) {
|
||||||
|
log_info("Could not SetupDiGetDeviceInstanceIdA\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
|
||||||
|
if (!SetupDiDeleteDeviceInterfaceData(
|
||||||
|
DeviceInfoSet, &DeviceInterfaceData)) {
|
||||||
|
log_info("Could not SetupDiDeleteDeviceInterfaceData\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void strtolower(char *str)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; str[i]; i++) {
|
||||||
|
str[i] = tolower(str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool convert_path_to_fakesym(const char *path, wchar_t *sym, char *extra_o)
|
||||||
|
{
|
||||||
|
char root[16] = {0};
|
||||||
|
char vidstr[16] = {0};
|
||||||
|
char pidstr[16] = {0};
|
||||||
|
char mistr[16] = {0};
|
||||||
|
char extra[64] = {0};
|
||||||
|
sscanf(
|
||||||
|
path,
|
||||||
|
"%[^\\]\\%[^&]&%[^&]&%[^\\]\\%s",
|
||||||
|
root,
|
||||||
|
vidstr,
|
||||||
|
pidstr,
|
||||||
|
mistr,
|
||||||
|
extra);
|
||||||
|
strcpy(extra_o, extra);
|
||||||
|
|
||||||
|
strtolower(root);
|
||||||
|
strtolower(vidstr);
|
||||||
|
strtolower(pidstr);
|
||||||
|
strtolower(mistr);
|
||||||
|
strtolower(extra);
|
||||||
|
|
||||||
|
char buffer[CAMERA_DATA_STRING_SIZE];
|
||||||
|
snprintf(
|
||||||
|
buffer,
|
||||||
|
CAMERA_DATA_STRING_SIZE,
|
||||||
|
"\\\\?\\%s#%s&%s&%s#%s",
|
||||||
|
root,
|
||||||
|
vidstr,
|
||||||
|
pidstr,
|
||||||
|
mistr,
|
||||||
|
extra);
|
||||||
|
|
||||||
|
mbstowcs(sym, buffer, CAMERA_DATA_STRING_SIZE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_cam_struct(struct camera_data *data, const char *devid)
|
||||||
|
{
|
||||||
|
char buffer[CAMERA_DATA_STRING_SIZE];
|
||||||
|
|
||||||
|
data->setup = false;
|
||||||
|
|
||||||
|
if (!devid || strlen(devid) == 0) {
|
||||||
|
devid = grab_next_camera_id(buffer, CAMERA_DATA_STRING_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!devid || strlen(devid) == 0) {
|
||||||
|
// no more cameras remain?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(devid) >= CAMERA_DATA_STRING_SIZE) {
|
||||||
|
// error probably log something?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect input type
|
||||||
|
if (check_four(devid, "\\\\?\\")) {
|
||||||
|
// SYMBOLIC_LINK
|
||||||
|
if (!convert_sym_to_path(devid, data->deviceInstancePath)) {
|
||||||
|
log_info("Could not convert %s to path", devid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (check_four(devid, "USB\\")) {
|
||||||
|
// Device instance path
|
||||||
|
strcpy(data->deviceInstancePath, devid);
|
||||||
|
// continue
|
||||||
|
} else {
|
||||||
|
// UNKNOWN ENTRY
|
||||||
|
log_info("UNK: %s", devid);
|
||||||
|
log_info("Please enter the device instance path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!convert_path_to_fakesym(
|
||||||
|
data->deviceInstancePath,
|
||||||
|
data->deviceSymbolicLink,
|
||||||
|
data->extra_upper)) {
|
||||||
|
log_info("Could not convert %s to sym", data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info("dev path: %s", data->deviceInstancePath);
|
||||||
|
|
||||||
|
char* vid_str = strstr(data->deviceInstancePath, "VID_");
|
||||||
|
char* pid_str = strstr(data->deviceInstancePath, "PID_");
|
||||||
|
|
||||||
|
if (!vid_str || !pid_str) {
|
||||||
|
log_info("Could not parse VID/PID in %s", data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->vid = strtol(vid_str + 4, NULL, 16);
|
||||||
|
data->pid = strtol(pid_str + 4, NULL, 16);
|
||||||
|
|
||||||
|
log_info("vid: %04x", data->vid);
|
||||||
|
log_info("pid: %04x", data->pid);
|
||||||
|
|
||||||
|
|
||||||
|
// locate device nodes
|
||||||
|
DEVINST dnDevInst;
|
||||||
|
DEVINST parentDev;
|
||||||
|
CONFIGRET cmret;
|
||||||
|
|
||||||
|
cmret = CM_Locate_DevNodeA(
|
||||||
|
&dnDevInst, data->deviceInstancePath, CM_LOCATE_DEVNODE_NORMAL);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info("CM_Locate_DevNodeA fail: %s", data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmret = CM_Get_Parent(&parentDev, dnDevInst, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info("CM_Get_Parent fail: %s", data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cmret = CM_Get_Device_IDA(
|
||||||
|
parentDev, data->parent_deviceInstancePath, CAMERA_DATA_STRING_SIZE, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info("CM_Get_Device_IDA parent fail: %s", data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG szAddr;
|
||||||
|
ULONG szDesc;
|
||||||
|
ULONG szDriverKey;
|
||||||
|
|
||||||
|
szAddr = 4;
|
||||||
|
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||||
|
dnDevInst, CM_DRP_ADDRESS, NULL, &data->address, &szAddr, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info(
|
||||||
|
"CM_Get_DevNode_Registry_PropertyA CM_DRP_ADDRESS fail: %s",
|
||||||
|
data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||||
|
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||||
|
dnDevInst, CM_DRP_DEVICEDESC, NULL, &data->name, &szDesc, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info(
|
||||||
|
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DEVICEDESC fail: %s",
|
||||||
|
data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
szAddr = 4;
|
||||||
|
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||||
|
parentDev, CM_DRP_ADDRESS, NULL, &data->parent_address, &szAddr, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info(
|
||||||
|
"CM_Get_DevNode_Registry_PropertyA CM_DRP_ADDRESS parent fail: %s",
|
||||||
|
data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||||
|
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||||
|
parentDev, CM_DRP_DEVICEDESC, NULL, &data->parent_name, &szDesc, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info(
|
||||||
|
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DEVICEDESC parent fail: %s",
|
||||||
|
data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
szDriverKey = CAMERA_DATA_STRING_SIZE;
|
||||||
|
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||||
|
parentDev, CM_DRP_DRIVER, NULL, &data->parent_driverKey, &szDriverKey, 0);
|
||||||
|
|
||||||
|
if (cmret != CR_SUCCESS) {
|
||||||
|
log_info(
|
||||||
|
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DRIVER parent fail: %s",
|
||||||
|
data->deviceInstancePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info("Found %s @ %d", data->name, data->address);
|
||||||
|
log_info("Parent %s @ %d %s", data->parent_name, data->parent_address, data->parent_driverKey);
|
||||||
|
data->setup = true;
|
||||||
|
}
|
||||||
34
src/main/camhook/cam-detect.h
Normal file
34
src/main/camhook/cam-detect.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef CAMHOOK_CAM_DETECT_H
|
||||||
|
#define CAMHOOK_CAM_DETECT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#define CAMERA_DATA_STRING_SIZE 0x100
|
||||||
|
|
||||||
|
struct camera_data {
|
||||||
|
bool setup;
|
||||||
|
char name[CAMERA_DATA_STRING_SIZE];
|
||||||
|
char deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
||||||
|
wchar_t deviceSymbolicLink[CAMERA_DATA_STRING_SIZE];
|
||||||
|
char extra_upper[CAMERA_DATA_STRING_SIZE];
|
||||||
|
int address;
|
||||||
|
char parent_name[CAMERA_DATA_STRING_SIZE];
|
||||||
|
char parent_driverKey[CAMERA_DATA_STRING_SIZE];
|
||||||
|
char parent_deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
||||||
|
int parent_address;
|
||||||
|
|
||||||
|
int16_t vid;
|
||||||
|
int16_t pid;
|
||||||
|
|
||||||
|
bool fake_addressed;
|
||||||
|
int fake_address;
|
||||||
|
|
||||||
|
bool fake_located;
|
||||||
|
size_t fake_located_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
void fill_cam_struct(struct camera_data *data, const char *devid);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
// Don't format because the order is important here
|
// Don't format because the order is important here
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
|
#include <winioctl.h>
|
||||||
|
#include <usbioctl.h>
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
#include <mfapi.h>
|
#include <mfapi.h>
|
||||||
@@ -19,80 +21,25 @@
|
|||||||
#include "hook/table.h"
|
#include "hook/table.h"
|
||||||
|
|
||||||
#include "camhook/cam.h"
|
#include "camhook/cam.h"
|
||||||
|
#include "camhook/cam-detect.h"
|
||||||
|
|
||||||
#include "util/defs.h"
|
#include "util/defs.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
#include "util/time.h"
|
|
||||||
|
|
||||||
#define CAMERA_DATA_STRING_SIZE 0x100
|
#define CAMHOOK_NUM_LAYOUTS 3
|
||||||
|
|
||||||
EXTERN_GUID(
|
static struct camera_data camData[CAMHOOK_CONFIG_CAM_MAX];
|
||||||
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
int camAddresses[CAMHOOK_NUM_LAYOUTS][CAMHOOK_CONFIG_CAM_MAX] = {
|
||||||
0xc60ac5fe,
|
{1, 7},
|
||||||
0x252a,
|
{4, 9},
|
||||||
0x478f,
|
{4, 3},
|
||||||
0xa0,
|
|
||||||
0xef,
|
|
||||||
0xbc,
|
|
||||||
0x8f,
|
|
||||||
0xa5,
|
|
||||||
0xf7,
|
|
||||||
0xca,
|
|
||||||
0xd3);
|
|
||||||
EXTERN_GUID(
|
|
||||||
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID,
|
|
||||||
0x8ac3587a,
|
|
||||||
0x4ae7,
|
|
||||||
0x42d8,
|
|
||||||
0x99,
|
|
||||||
0xe0,
|
|
||||||
0x0a,
|
|
||||||
0x60,
|
|
||||||
0x13,
|
|
||||||
0xee,
|
|
||||||
0xf9,
|
|
||||||
0x0f);
|
|
||||||
EXTERN_GUID(
|
|
||||||
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
|
|
||||||
0x58f0aad8,
|
|
||||||
0x22bf,
|
|
||||||
0x4f8a,
|
|
||||||
0xbb,
|
|
||||||
0x3d,
|
|
||||||
0xd2,
|
|
||||||
0xc4,
|
|
||||||
0x97,
|
|
||||||
0x8c,
|
|
||||||
0x6e,
|
|
||||||
0x2f);
|
|
||||||
// define ourselves cause mingw has these wrong
|
|
||||||
|
|
||||||
struct CameraData {
|
|
||||||
bool setup;
|
|
||||||
char name[CAMERA_DATA_STRING_SIZE];
|
|
||||||
char deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
|
||||||
wchar_t deviceSymbolicLink[CAMERA_DATA_STRING_SIZE];
|
|
||||||
char extra_upper[CAMERA_DATA_STRING_SIZE];
|
|
||||||
int address;
|
|
||||||
char parent_name[CAMERA_DATA_STRING_SIZE];
|
|
||||||
char parent_deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
|
||||||
int parent_address;
|
|
||||||
|
|
||||||
bool fake_addressed;
|
|
||||||
int fake_address;
|
|
||||||
|
|
||||||
bool fake_located;
|
|
||||||
size_t fake_located_node;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct CameraData camData[CAMHOOK_CONFIG_CAM_MAX];
|
|
||||||
int camAddresses[CAMHOOK_CONFIG_CAM_MAX] = {
|
|
||||||
1,
|
|
||||||
7,
|
|
||||||
};
|
};
|
||||||
static size_t num_addressed_cams = 0;
|
static size_t num_addressed_cams = 0;
|
||||||
static size_t num_located_cams = 0;
|
static size_t num_located_cams = 0;
|
||||||
|
static int camhook_port_layout = 0;
|
||||||
|
|
||||||
|
static enum camhook_version camhook_version = CAMHOOK_VERSION_OLD;
|
||||||
|
|
||||||
static CONFIGRET my_CM_Locate_DevNodeA(
|
static CONFIGRET my_CM_Locate_DevNodeA(
|
||||||
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
|
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
|
||||||
@@ -156,6 +103,26 @@ static HDEVINFO my_SetupDiGetClassDevsA(
|
|||||||
static HDEVINFO (*real_SetupDiGetClassDevsA)(
|
static HDEVINFO (*real_SetupDiGetClassDevsA)(
|
||||||
CONST GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags);
|
CONST GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags);
|
||||||
|
|
||||||
|
static BOOL STDCALL my_DeviceIoControl(
|
||||||
|
HANDLE hFile,
|
||||||
|
uint32_t dwIoControlCode,
|
||||||
|
void *lpInBuffer,
|
||||||
|
uint32_t nInBufferSize,
|
||||||
|
void *lpOutBuffer,
|
||||||
|
uint32_t nOutBufferSize,
|
||||||
|
uint32_t *lpBytesReturned,
|
||||||
|
OVERLAPPED *lpOverlapped);
|
||||||
|
|
||||||
|
static BOOL(STDCALL *real_DeviceIoControl)(
|
||||||
|
HANDLE fd,
|
||||||
|
uint32_t code,
|
||||||
|
void *in_bytes,
|
||||||
|
uint32_t in_nbytes,
|
||||||
|
void *out_bytes,
|
||||||
|
uint32_t out_nbytes,
|
||||||
|
uint32_t *out_returned,
|
||||||
|
OVERLAPPED *ovl);
|
||||||
|
|
||||||
static const struct hook_symbol camhook_cfgmgr32_syms[] = {
|
static const struct hook_symbol camhook_cfgmgr32_syms[] = {
|
||||||
{.name = "CM_Locate_DevNodeA",
|
{.name = "CM_Locate_DevNodeA",
|
||||||
.patch = my_CM_Locate_DevNodeA,
|
.patch = my_CM_Locate_DevNodeA,
|
||||||
@@ -180,12 +147,24 @@ static const struct hook_symbol camhook_cfgmgr32_syms[] = {
|
|||||||
.link = (void **) &real_SetupDiGetClassDevsA},
|
.link = (void **) &real_SetupDiGetClassDevsA},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct hook_symbol camhook_cfgmgr32_syms_new[] = {
|
||||||
|
{.name = "CM_Locate_DevNodeA",
|
||||||
|
.patch = my_CM_Locate_DevNodeA,
|
||||||
|
.link = (void **) &real_CM_Locate_DevNodeA},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct hook_symbol camhook_mf_syms[] = {
|
static const struct hook_symbol camhook_mf_syms[] = {
|
||||||
{.name = "MFEnumDeviceSources",
|
{.name = "MFEnumDeviceSources",
|
||||||
.patch = my_MFEnumDeviceSources,
|
.patch = my_MFEnumDeviceSources,
|
||||||
.link = (void **) &real_MFEnumDeviceSources},
|
.link = (void **) &real_MFEnumDeviceSources},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct hook_symbol camhook_ioctl_syms[] = {
|
||||||
|
{.name = "DeviceIoControl",
|
||||||
|
.patch = my_DeviceIoControl,
|
||||||
|
.link = (void *) &real_DeviceIoControl},
|
||||||
|
};
|
||||||
|
|
||||||
DEVINST camhook_custom_nodes[CAMHOOK_CONFIG_CAM_MAX] = {
|
DEVINST camhook_custom_nodes[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||||
0x04040004,
|
0x04040004,
|
||||||
0x04040008,
|
0x04040008,
|
||||||
@@ -209,25 +188,42 @@ my_CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
|
|||||||
log_info("seeking: %s", pDeviceID);
|
log_info("seeking: %s", pDeviceID);
|
||||||
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
|
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
|
||||||
if (camData[i].setup) {
|
if (camData[i].setup) {
|
||||||
snprintf(
|
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||||
builtString,
|
snprintf(
|
||||||
CAMERA_DATA_STRING_SIZE,
|
builtString,
|
||||||
"USB\\VID_288C&PID_0002&MI_00\\%s",
|
CAMERA_DATA_STRING_SIZE,
|
||||||
camData[i].extra_upper);
|
"USB\\VID_288C&PID_0002&MI_00\\%s",
|
||||||
|
camData[i].extra_upper);
|
||||||
|
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||||
|
snprintf(
|
||||||
|
builtString,
|
||||||
|
CAMERA_DATA_STRING_SIZE,
|
||||||
|
"USB\\VID_05A3&PID_9230&MI_00\\%s",
|
||||||
|
camData[i].extra_upper);
|
||||||
|
}
|
||||||
|
|
||||||
log_info("built: %s", builtString);
|
log_info("built: %s", builtString);
|
||||||
if (strcmp(pDeviceID, builtString) == 0) {
|
if (strcmp(pDeviceID, builtString) == 0) {
|
||||||
if (!camData[i].fake_located) {
|
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||||
camData[i].fake_located_node = num_located_cams;
|
if (!camData[i].fake_located) {
|
||||||
camData[i].fake_located = true;
|
camData[i].fake_located_node = num_located_cams;
|
||||||
++num_located_cams;
|
camData[i].fake_located = true;
|
||||||
|
++num_located_cams;
|
||||||
|
}
|
||||||
|
log_info(
|
||||||
|
"Injecting custom device %d to node %x",
|
||||||
|
(int) i,
|
||||||
|
(int) camData[i].fake_located_node);
|
||||||
|
*pdnDevInst =
|
||||||
|
camhook_custom_nodes[camData[i].fake_located_node];
|
||||||
|
return CR_SUCCESS;
|
||||||
|
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||||
|
// inject original device
|
||||||
|
log_info(
|
||||||
|
"Injecting original device %d %s -> %s",
|
||||||
|
(int) i, pDeviceID, camData[i].deviceInstancePath);
|
||||||
|
pDeviceID = camData[i].deviceInstancePath;
|
||||||
}
|
}
|
||||||
log_info(
|
|
||||||
"Injecting custom device %d to node %x",
|
|
||||||
(int) i,
|
|
||||||
(int) camData[i].fake_located_node);
|
|
||||||
*pdnDevInst =
|
|
||||||
camhook_custom_nodes[camData[i].fake_located_node];
|
|
||||||
return CR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,9 +274,9 @@ HRESULT my_GetAllocatedString(
|
|||||||
IMFActivate *self, REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength)
|
IMFActivate *self, REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength)
|
||||||
{
|
{
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
log_info("Inside: %s", __FUNCTION__);
|
// log_info("Inside: %s", __FUNCTION__);
|
||||||
|
|
||||||
// should probably check GUID, oh well
|
// should probably check GUID == MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, oh well
|
||||||
ret = real_GetAllocatedString(self, guidKey, ppwszValue, pcchLength);
|
ret = real_GetAllocatedString(self, guidKey, ppwszValue, pcchLength);
|
||||||
char *pMBBuffer = (char *) malloc(0x100);
|
char *pMBBuffer = (char *) malloc(0x100);
|
||||||
wcstombs(pMBBuffer, *ppwszValue, 0x100);
|
wcstombs(pMBBuffer, *ppwszValue, 0x100);
|
||||||
@@ -299,19 +295,35 @@ HRESULT my_GetAllocatedString(
|
|||||||
|
|
||||||
// if matches, replace with target device ID
|
// if matches, replace with target device ID
|
||||||
if (pwc) {
|
if (pwc) {
|
||||||
// \\?\usb#vid_288c&pid_0002&mi_00
|
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||||
pwc[12] = L'2';
|
// \\?\usb#vid_288c&pid_0002&mi_00
|
||||||
pwc[13] = L'8';
|
pwc[12] = L'2';
|
||||||
pwc[14] = L'8';
|
pwc[13] = L'8';
|
||||||
pwc[15] = L'c';
|
pwc[14] = L'8';
|
||||||
|
pwc[15] = L'c';
|
||||||
|
|
||||||
pwc[21] = L'0';
|
pwc[21] = L'0';
|
||||||
pwc[22] = L'0';
|
pwc[22] = L'0';
|
||||||
pwc[23] = L'0';
|
pwc[23] = L'0';
|
||||||
pwc[24] = L'2';
|
pwc[24] = L'2';
|
||||||
|
|
||||||
pwc[29] = L'0';
|
pwc[29] = L'0';
|
||||||
pwc[30] = L'0';
|
pwc[30] = L'0';
|
||||||
|
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||||
|
// \\?\usb#vid_05a3&pid_9230&mi_00
|
||||||
|
pwc[12] = L'0';
|
||||||
|
pwc[13] = L'5';
|
||||||
|
pwc[14] = L'a';
|
||||||
|
pwc[15] = L'3';
|
||||||
|
|
||||||
|
pwc[21] = L'9';
|
||||||
|
pwc[22] = L'2';
|
||||||
|
pwc[23] = L'3';
|
||||||
|
pwc[24] = L'0';
|
||||||
|
|
||||||
|
pwc[29] = L'0';
|
||||||
|
pwc[30] = L'0';
|
||||||
|
}
|
||||||
|
|
||||||
wcstombs(pMBBuffer, *ppwszValue, 0x100);
|
wcstombs(pMBBuffer, *ppwszValue, 0x100);
|
||||||
log_info("Replaced: %s", pMBBuffer);
|
log_info("Replaced: %s", pMBBuffer);
|
||||||
@@ -334,7 +346,7 @@ static HRESULT my_MFEnumDeviceSources(
|
|||||||
|
|
||||||
HRESULT ret;
|
HRESULT ret;
|
||||||
|
|
||||||
log_info("Inside: %s", __FUNCTION__);
|
// log_info("Inside: %s", __FUNCTION__);
|
||||||
ret = real_MFEnumDeviceSources(
|
ret = real_MFEnumDeviceSources(
|
||||||
pAttributes, pppSourceActivate, pcSourceActivate);
|
pAttributes, pppSourceActivate, pcSourceActivate);
|
||||||
nsrcs = *pcSourceActivate;
|
nsrcs = *pcSourceActivate;
|
||||||
@@ -437,8 +449,9 @@ static BOOL my_SetupDiGetDeviceRegistryPropertyA(
|
|||||||
if (camData[i].setup) {
|
if (camData[i].setup) {
|
||||||
if (addr == camData[i].parent_address) {
|
if (addr == camData[i].parent_address) {
|
||||||
if (!camData[i].fake_addressed) {
|
if (!camData[i].fake_addressed) {
|
||||||
|
// old style always uses set 0
|
||||||
camData[i].fake_address =
|
camData[i].fake_address =
|
||||||
camAddresses[num_addressed_cams];
|
camAddresses[0][num_addressed_cams];
|
||||||
camData[i].fake_addressed = true;
|
camData[i].fake_addressed = true;
|
||||||
++num_addressed_cams;
|
++num_addressed_cams;
|
||||||
}
|
}
|
||||||
@@ -491,315 +504,180 @@ static HDEVINFO my_SetupDiGetClassDevsA(
|
|||||||
return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
|
return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_four(const char inA[4], const char inB[4])
|
ULONG get_matching_device_replacement_id(
|
||||||
|
HANDLE hFile,
|
||||||
|
ULONG ConnectionIndex,
|
||||||
|
USB_DEVICE_DESCRIPTOR* desc)
|
||||||
{
|
{
|
||||||
return (*(uint32_t *) inA == *(uint32_t *) inB);
|
ULONG replacement_id = 0;
|
||||||
}
|
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
|
||||||
|
if (camData[i].setup) {
|
||||||
|
// log_info("Checking %lu %04x %04x vs %lu %04x %04x",
|
||||||
|
// ConnectionIndex, desc->idVendor, desc->idProduct,
|
||||||
|
// camData[i].address, camData[i].vid, camData[i].pid);
|
||||||
|
if (
|
||||||
|
ConnectionIndex == camData[i].parent_address &&
|
||||||
|
desc->idVendor == camData[i].vid &&
|
||||||
|
desc->idProduct == camData[i].pid
|
||||||
|
) {
|
||||||
|
// do secondary check for driver key using
|
||||||
|
// IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME
|
||||||
|
USB_NODE_CONNECTION_DRIVERKEY_NAME req;
|
||||||
|
req.ActualLength = 0;
|
||||||
|
req.ConnectionIndex = ConnectionIndex;
|
||||||
|
req.DriverKeyName[0] = '\0';
|
||||||
|
|
||||||
char *grab_next_camera_id(char *buffer, size_t bsz)
|
DWORD nBytes;
|
||||||
{
|
|
||||||
static size_t gotten = 0;
|
|
||||||
|
|
||||||
IMFAttributes *pAttributes = NULL;
|
if (!DeviceIoControl(
|
||||||
IMFActivate **ppDevices = NULL;
|
hFile,
|
||||||
|
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
|
||||||
|
&req,
|
||||||
|
sizeof(req),
|
||||||
|
&req,
|
||||||
|
sizeof(req),
|
||||||
|
&nBytes,
|
||||||
|
0LL
|
||||||
|
)) {
|
||||||
|
log_warning(
|
||||||
|
"Failed to get driver key name size for device %04x %04x",
|
||||||
|
desc->idVendor,
|
||||||
|
desc->idProduct);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
buffer[0] = '\0';
|
if (req.ActualLength <= sizeof(req)) {
|
||||||
|
log_warning(
|
||||||
|
"Driver key name size too small for device %04x %04x",
|
||||||
|
desc->idVendor,
|
||||||
|
desc->idProduct);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
|
nBytes = req.ActualLength;
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
USB_NODE_CONNECTION_DRIVERKEY_NAME *driverKeyNameW = malloc(nBytes);
|
||||||
log_info("MFCreateAttributes failed: %ld", hr);
|
if (!driverKeyNameW) {
|
||||||
goto done;
|
log_warning("Failed to allocate driver key name buffer for device %04x %04x",
|
||||||
}
|
desc->idVendor,
|
||||||
|
desc->idProduct);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
driverKeyNameW->ActualLength = 0;
|
||||||
|
driverKeyNameW->ConnectionIndex = ConnectionIndex;
|
||||||
|
driverKeyNameW->DriverKeyName[0] = '\0';
|
||||||
|
|
||||||
hr = pAttributes->lpVtbl->SetGUID(
|
if (!DeviceIoControl(
|
||||||
pAttributes,
|
hFile,
|
||||||
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
|
||||||
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
|
driverKeyNameW,
|
||||||
if (FAILED(hr)) {
|
nBytes,
|
||||||
log_info("SetGUID failed: %ld", hr);
|
driverKeyNameW,
|
||||||
goto done;
|
nBytes,
|
||||||
}
|
&nBytes,
|
||||||
|
0LL
|
||||||
|
)) {
|
||||||
|
log_warning(
|
||||||
|
"Failed to get driver key name for device %04x %04x",
|
||||||
|
desc->idVendor,
|
||||||
|
desc->idProduct);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 count;
|
|
||||||
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
|
char *driverKeyNameA = NULL;
|
||||||
|
wstr_narrow(driverKeyNameW->DriverKeyName, &driverKeyNameA);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
free(driverKeyNameW);
|
||||||
log_info("MFEnumDeviceSources failed: %ld", hr);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count <= gotten) {
|
|
||||||
log_info("gotten failed: %d < %d", count, (int) gotten);
|
|
||||||
// not enough remaining
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t wSymLink[CAMERA_DATA_STRING_SIZE];
|
if (strcmp(driverKeyNameA, camData[i].parent_driverKey) != 0) {
|
||||||
UINT32 sz;
|
// log just in case?
|
||||||
|
log_info(
|
||||||
|
"Driver key name mismatch for device %04x %04x %s != %s",
|
||||||
|
desc->idVendor,
|
||||||
|
desc->idProduct,
|
||||||
|
driverKeyNameA,
|
||||||
|
camData[i].parent_driverKey);
|
||||||
|
if (driverKeyNameA) {
|
||||||
|
free(driverKeyNameA);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hr = ppDevices[gotten]->lpVtbl->GetString(
|
log_info(
|
||||||
ppDevices[gotten],
|
"Replacing device @ %lu with %d for %04x %04x %s",
|
||||||
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
|
ConnectionIndex,
|
||||||
wSymLink,
|
camAddresses[camhook_port_layout][i],
|
||||||
CAMERA_DATA_STRING_SIZE,
|
desc->idVendor,
|
||||||
&sz);
|
desc->idProduct,
|
||||||
|
driverKeyNameA);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (driverKeyNameA) {
|
||||||
log_info("GetString failed: %ld", hr);
|
free(driverKeyNameA);
|
||||||
goto done;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
wcstombs(buffer, wSymLink, bsz);
|
replacement_id = camAddresses[camhook_port_layout][i];
|
||||||
log_info("Detected webcam: %s\n", buffer);
|
break;
|
||||||
++gotten;
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
if (pAttributes) {
|
|
||||||
pAttributes->lpVtbl->Release(pAttributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DWORD i = 0; i < count; i++) {
|
|
||||||
if (ppDevices != NULL && ppDevices[i]) {
|
|
||||||
ppDevices[i]->lpVtbl->Release(ppDevices[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoTaskMemFree(ppDevices);
|
return replacement_id;
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool convert_sym_to_path(const char *sym, char *path)
|
static BOOL STDCALL my_DeviceIoControl(
|
||||||
|
HANDLE hFile,
|
||||||
|
uint32_t dwIoControlCode,
|
||||||
|
void *lpInBuffer,
|
||||||
|
uint32_t nInBufferSize,
|
||||||
|
void *lpOutBuffer,
|
||||||
|
uint32_t nOutBufferSize,
|
||||||
|
uint32_t *lpBytesReturned,
|
||||||
|
OVERLAPPED *lpOverlapped)
|
||||||
{
|
{
|
||||||
HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
|
BOOL res;
|
||||||
|
|
||||||
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
|
res = real_DeviceIoControl(
|
||||||
log_info("Could not open SetupDiCreateDeviceInfoList\n");
|
hFile,
|
||||||
return 0;
|
dwIoControlCode,
|
||||||
|
lpInBuffer,
|
||||||
|
nInBufferSize,
|
||||||
|
lpOutBuffer,
|
||||||
|
nOutBufferSize,
|
||||||
|
lpBytesReturned,
|
||||||
|
lpOverlapped);
|
||||||
|
|
||||||
|
// if error just return
|
||||||
|
if (!res) {
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = {0};
|
// detect IOCTL_USB_GET_NODE_CONNECTION_INFORMATION (_EX)
|
||||||
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
// we don't bother faking the rest as it's never read
|
||||||
|
if (dwIoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION) {
|
||||||
|
USB_NODE_CONNECTION_INFORMATION *connectionInfo = lpOutBuffer;
|
||||||
|
|
||||||
if (!SetupDiOpenDeviceInterfaceA(
|
ULONG replacement_id = get_matching_device_replacement_id(
|
||||||
DeviceInfoSet, sym, 0, &DeviceInterfaceData)) {
|
hFile, connectionInfo->ConnectionIndex, &connectionInfo->DeviceDescriptor);
|
||||||
log_info("Could not SetupDiOpenDeviceInterfaceA\n");
|
if (replacement_id > 0) {
|
||||||
return 0;
|
connectionInfo->ConnectionIndex = replacement_id;
|
||||||
}
|
}
|
||||||
|
} else if (dwIoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX) {
|
||||||
|
USB_NODE_CONNECTION_INFORMATION_EX *connectionInfoEx = lpOutBuffer;
|
||||||
|
|
||||||
SP_DEVINFO_DATA DeviceInfoData = {0};
|
ULONG replacement_id = get_matching_device_replacement_id(
|
||||||
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
hFile, connectionInfoEx->ConnectionIndex, &connectionInfoEx->DeviceDescriptor);
|
||||||
|
if (replacement_id > 0) {
|
||||||
if (!SetupDiGetDeviceInterfaceDetailA(
|
connectionInfoEx->ConnectionIndex = replacement_id;
|
||||||
DeviceInfoSet,
|
|
||||||
&DeviceInterfaceData,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&DeviceInfoData)) {
|
|
||||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
|
||||||
log_info("Could not SetupDiGetDeviceInterfaceDetailA\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD sz;
|
return res;
|
||||||
|
|
||||||
if (!SetupDiGetDeviceInstanceIdA(
|
|
||||||
DeviceInfoSet,
|
|
||||||
&DeviceInfoData,
|
|
||||||
path,
|
|
||||||
CAMERA_DATA_STRING_SIZE,
|
|
||||||
&sz)) {
|
|
||||||
log_info("Could not SetupDiGetDeviceInstanceIdA\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
|
|
||||||
if (!SetupDiDeleteDeviceInterfaceData(
|
|
||||||
DeviceInfoSet, &DeviceInterfaceData)) {
|
|
||||||
log_info("Could not SetupDiDeleteDeviceInterfaceData\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void strtolower(char *str)
|
void camhook_set_version(enum camhook_version version) {
|
||||||
{
|
camhook_version = version;
|
||||||
for (size_t i = 0; str[i]; i++) {
|
|
||||||
str[i] = tolower(str[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool convert_path_to_fakesym(const char *path, wchar_t *sym, char *extra_o)
|
|
||||||
{
|
|
||||||
char root[16] = {0};
|
|
||||||
char vidstr[16] = {0};
|
|
||||||
char pidstr[16] = {0};
|
|
||||||
char mistr[16] = {0};
|
|
||||||
char extra[64] = {0};
|
|
||||||
sscanf(
|
|
||||||
path,
|
|
||||||
"%[^\\]\\%[^&]&%[^&]&%[^\\]\\%s",
|
|
||||||
root,
|
|
||||||
vidstr,
|
|
||||||
pidstr,
|
|
||||||
mistr,
|
|
||||||
extra);
|
|
||||||
strcpy(extra_o, extra);
|
|
||||||
|
|
||||||
strtolower(root);
|
|
||||||
strtolower(vidstr);
|
|
||||||
strtolower(pidstr);
|
|
||||||
strtolower(mistr);
|
|
||||||
strtolower(extra);
|
|
||||||
|
|
||||||
char buffer[CAMERA_DATA_STRING_SIZE];
|
|
||||||
snprintf(
|
|
||||||
buffer,
|
|
||||||
CAMERA_DATA_STRING_SIZE,
|
|
||||||
"\\\\?\\%s#%s&%s&%s#%s",
|
|
||||||
root,
|
|
||||||
vidstr,
|
|
||||||
pidstr,
|
|
||||||
mistr,
|
|
||||||
extra);
|
|
||||||
|
|
||||||
mbstowcs(sym, buffer, CAMERA_DATA_STRING_SIZE);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fill_cam_struct(struct CameraData *data, const char *devid)
|
|
||||||
{
|
|
||||||
char buffer[CAMERA_DATA_STRING_SIZE];
|
|
||||||
|
|
||||||
data->setup = false;
|
|
||||||
|
|
||||||
if (!devid || strlen(devid) == 0) {
|
|
||||||
devid = grab_next_camera_id(buffer, CAMERA_DATA_STRING_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!devid || strlen(devid) == 0) {
|
|
||||||
// no more cameras remain?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(devid) >= CAMERA_DATA_STRING_SIZE) {
|
|
||||||
// error probably log something?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// detect input type
|
|
||||||
if (check_four(devid, "\\\\?\\")) {
|
|
||||||
// SYMBOLIC_LINK
|
|
||||||
if (!convert_sym_to_path(devid, data->deviceInstancePath)) {
|
|
||||||
log_info("Could not convert %s to path", devid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (check_four(devid, "USB\\")) {
|
|
||||||
// Device instance path
|
|
||||||
strcpy(data->deviceInstancePath, devid);
|
|
||||||
// continue
|
|
||||||
} else {
|
|
||||||
// UNKNOWN ENTRY
|
|
||||||
log_info("UNK: %s", devid);
|
|
||||||
log_info("Please enter the device instance path");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!convert_path_to_fakesym(
|
|
||||||
data->deviceInstancePath,
|
|
||||||
data->deviceSymbolicLink,
|
|
||||||
data->extra_upper)) {
|
|
||||||
log_info("Could not convert %s to sym", data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("dev path: %s", data->deviceInstancePath);
|
|
||||||
|
|
||||||
// locate device nodes
|
|
||||||
DEVINST dnDevInst;
|
|
||||||
DEVINST parentDev;
|
|
||||||
CONFIGRET cmret;
|
|
||||||
|
|
||||||
cmret = CM_Locate_DevNodeA(
|
|
||||||
&dnDevInst, data->deviceInstancePath, CM_LOCATE_DEVNODE_NORMAL);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info("CM_Locate_DevNodeA fail: %s", data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmret = CM_Get_Parent(&parentDev, dnDevInst, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info("CM_Get_Parent fail: %s", data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cmret = CM_Get_Device_IDA(
|
|
||||||
parentDev, data->parent_deviceInstancePath, CAMERA_DATA_STRING_SIZE, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info("CM_Get_Device_IDA parent fail: %s", data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG szAddr;
|
|
||||||
ULONG szDesc;
|
|
||||||
|
|
||||||
szAddr = 4;
|
|
||||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
|
||||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
|
||||||
dnDevInst, CM_DRP_ADDRESS, NULL, &data->address, &szAddr, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info(
|
|
||||||
"CM_Get_DevNode_Registry_PropertyA fail: %s",
|
|
||||||
data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
|
||||||
dnDevInst, CM_DRP_DEVICEDESC, NULL, &data->name, &szDesc, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info(
|
|
||||||
"CM_Get_DevNode_Registry_PropertyA fail: %s",
|
|
||||||
data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
szAddr = 4;
|
|
||||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
|
||||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
|
||||||
parentDev, CM_DRP_ADDRESS, NULL, &data->parent_address, &szAddr, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info(
|
|
||||||
"CM_Get_DevNode_Registry_PropertyA parent fail: %s",
|
|
||||||
data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
|
||||||
parentDev, CM_DRP_DEVICEDESC, NULL, &data->parent_name, &szDesc, 0);
|
|
||||||
|
|
||||||
if (cmret != CR_SUCCESS) {
|
|
||||||
log_info(
|
|
||||||
"CM_Get_DevNode_Registry_PropertyA parent fail: %s",
|
|
||||||
data->deviceInstancePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("Found %s @ %d", data->name, data->address);
|
|
||||||
log_info("Parent %s @ %d", data->parent_name, data->parent_address);
|
|
||||||
data->setup = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void camhook_init(struct camhook_config_cam *config_cam)
|
void camhook_init(struct camhook_config_cam *config_cam)
|
||||||
@@ -827,15 +705,42 @@ void camhook_init(struct camhook_config_cam *config_cam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
camhook_port_layout = config_cam->port_layout;
|
||||||
|
if (camhook_port_layout < 0 || camhook_port_layout >= CAMHOOK_NUM_LAYOUTS) {
|
||||||
|
camhook_port_layout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (num_setup > 0) {
|
if (num_setup > 0) {
|
||||||
hook_table_apply(
|
// always
|
||||||
NULL,
|
|
||||||
"setupapi.dll",
|
|
||||||
camhook_cfgmgr32_syms,
|
|
||||||
lengthof(camhook_cfgmgr32_syms));
|
|
||||||
hook_table_apply(
|
hook_table_apply(
|
||||||
NULL, "Mf.dll", camhook_mf_syms, lengthof(camhook_mf_syms));
|
NULL, "Mf.dll", camhook_mf_syms, lengthof(camhook_mf_syms));
|
||||||
|
|
||||||
|
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"cfgmgr32.dll",
|
||||||
|
camhook_cfgmgr32_syms,
|
||||||
|
lengthof(camhook_cfgmgr32_syms));
|
||||||
|
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||||
|
// for CAMHOOK_VERSION_NEW we restore original VID/PID
|
||||||
|
// so the parent lookup succeeds later
|
||||||
|
// yes the DLL moved???
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"setupapi.dll",
|
||||||
|
camhook_cfgmgr32_syms_new,
|
||||||
|
lengthof(camhook_cfgmgr32_syms_new));
|
||||||
|
|
||||||
|
// they copied / forked usb/usbview/enum.c
|
||||||
|
// however they don't use most of it
|
||||||
|
// so we only need DeviceIoControl to inject port #
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"kernel32.dll",
|
||||||
|
camhook_ioctl_syms,
|
||||||
|
lengthof(camhook_ioctl_syms));
|
||||||
|
}
|
||||||
|
|
||||||
log_info("Inserted cam hooks for %d cams", (int) num_setup);
|
log_info("Inserted cam hooks for %d cams", (int) num_setup);
|
||||||
// If the user has manually disabled all cams, don't print this in the
|
// If the user has manually disabled all cams, don't print this in the
|
||||||
// log
|
// log
|
||||||
|
|||||||
@@ -3,6 +3,15 @@
|
|||||||
|
|
||||||
#include "camhook/config-cam.h"
|
#include "camhook/config-cam.h"
|
||||||
|
|
||||||
|
// unused to control which camhook version is being used
|
||||||
|
// defaults to CAMHOOK_VERSION_OLD
|
||||||
|
enum camhook_version {
|
||||||
|
CAMHOOK_VERSION_OLD,
|
||||||
|
CAMHOOK_VERSION_NEW,
|
||||||
|
};
|
||||||
|
|
||||||
|
void camhook_set_version(enum camhook_version version);
|
||||||
|
|
||||||
void camhook_init(struct camhook_config_cam *config_cam);
|
void camhook_init(struct camhook_config_cam *config_cam);
|
||||||
|
|
||||||
void camhook_fini(void);
|
void camhook_fini(void);
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
#define CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY "cam.disable_emu"
|
#define CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY "cam.disable_emu"
|
||||||
#define CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE false
|
#define CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE false
|
||||||
|
|
||||||
|
#define CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY "cam.port_layout"
|
||||||
|
#define CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE 0
|
||||||
|
|
||||||
// the following four arrays are based on CAMHOOK_CONFIG_CAM_MAX
|
// the following four arrays are based on CAMHOOK_CONFIG_CAM_MAX
|
||||||
// please insert more elements if more cams are added
|
// please insert more elements if more cams are added
|
||||||
const char *camhook_config_disable_camera[CAMHOOK_CONFIG_CAM_MAX] = {
|
const char *camhook_config_disable_camera[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||||
@@ -30,7 +33,7 @@ const char *camhook_config_device_default_values[CAMHOOK_CONFIG_CAM_MAX] = {
|
|||||||
"",
|
"",
|
||||||
};
|
};
|
||||||
|
|
||||||
void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
void camhook_config_cam_init(struct cconfig *config, size_t num_cams, bool use_port_layout)
|
||||||
{
|
{
|
||||||
cconfig_util_set_bool(
|
cconfig_util_set_bool(
|
||||||
config,
|
config,
|
||||||
@@ -38,6 +41,14 @@ void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
|||||||
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE,
|
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE,
|
||||||
"Disables the camera emulation");
|
"Disables the camera emulation");
|
||||||
|
|
||||||
|
if (use_port_layout) {
|
||||||
|
cconfig_util_set_int(
|
||||||
|
config,
|
||||||
|
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||||
|
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE,
|
||||||
|
"Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)");
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < num_cams; ++i) {
|
for (size_t i = 0; i < num_cams; ++i) {
|
||||||
cconfig_util_set_bool(
|
cconfig_util_set_bool(
|
||||||
config,
|
config,
|
||||||
@@ -56,7 +67,8 @@ void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
|||||||
void camhook_config_cam_get(
|
void camhook_config_cam_get(
|
||||||
struct camhook_config_cam *config_cam,
|
struct camhook_config_cam *config_cam,
|
||||||
struct cconfig *config,
|
struct cconfig *config,
|
||||||
size_t num_cams)
|
size_t num_cams,
|
||||||
|
bool use_port_layout)
|
||||||
{
|
{
|
||||||
config_cam->num_devices = num_cams;
|
config_cam->num_devices = num_cams;
|
||||||
|
|
||||||
@@ -71,6 +83,21 @@ void camhook_config_cam_get(
|
|||||||
CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY,
|
CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY,
|
||||||
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE);
|
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_port_layout) {
|
||||||
|
if (!cconfig_util_get_int(
|
||||||
|
config,
|
||||||
|
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||||
|
&config_cam->port_layout,
|
||||||
|
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||||
|
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < num_cams; ++i) {
|
for (size_t i = 0; i < num_cams; ++i) {
|
||||||
if (!cconfig_util_get_bool(
|
if (!cconfig_util_get_bool(
|
||||||
config,
|
config,
|
||||||
|
|||||||
@@ -10,15 +10,20 @@
|
|||||||
struct camhook_config_cam {
|
struct camhook_config_cam {
|
||||||
bool disable_emu;
|
bool disable_emu;
|
||||||
size_t num_devices;
|
size_t num_devices;
|
||||||
|
int port_layout;
|
||||||
char device_id[CAMHOOK_CONFIG_CAM_MAX][MAX_PATH];
|
char device_id[CAMHOOK_CONFIG_CAM_MAX][MAX_PATH];
|
||||||
bool disable_camera[CAMHOOK_CONFIG_CAM_MAX];
|
bool disable_camera[CAMHOOK_CONFIG_CAM_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
void camhook_config_cam_init(struct cconfig *config, size_t num_cams);
|
void camhook_config_cam_init(
|
||||||
|
struct cconfig *config,
|
||||||
|
size_t num_cams,
|
||||||
|
bool use_port_layout);
|
||||||
|
|
||||||
void camhook_config_cam_get(
|
void camhook_config_cam_get(
|
||||||
struct camhook_config_cam *config_cam,
|
struct camhook_config_cam *config_cam,
|
||||||
struct cconfig *config,
|
struct cconfig *config,
|
||||||
size_t num_cams);
|
size_t num_cams,
|
||||||
|
bool use_port_layout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
16
src/main/d3d9-frame-graph-hook/Module.mk
Normal file
16
src/main/d3d9-frame-graph-hook/Module.mk
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
dlls += d3d9-frame-graph-hook
|
||||||
|
|
||||||
|
ldflags_d3d9-frame-graph-hook := \
|
||||||
|
-ld3d9 \
|
||||||
|
-ldwmapi\
|
||||||
|
-lgdi32 \
|
||||||
|
|
||||||
|
libs_d3d9-frame-graph-hook := \
|
||||||
|
hook \
|
||||||
|
imgui-bt \
|
||||||
|
imgui-debug \
|
||||||
|
imgui \
|
||||||
|
util \
|
||||||
|
|
||||||
|
src_d3d9-frame-graph-hook := \
|
||||||
|
main.c \
|
||||||
4
src/main/d3d9-frame-graph-hook/d3d9-frame-graph-hook.def
Normal file
4
src/main/d3d9-frame-graph-hook/d3d9-frame-graph-hook.def
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
LIBRARY d3d9-frame-graph-hook
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
DllMain@12 @1 NONAME
|
||||||
32
src/main/d3d9-frame-graph-hook/main.c
Normal file
32
src/main/d3d9-frame-graph-hook/main.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "hook/d3d9.h"
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "imgui-bt/imgui-d3d9-hook.h"
|
||||||
|
|
||||||
|
#include "imgui-debug/frame-perf-graph.h"
|
||||||
|
|
||||||
|
#include "util/defs.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
static const hook_d3d9_irp_handler_t d3d9_frame_graph_hook_handlers[] = {
|
||||||
|
imgui_hook_d3d9_irp_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||||
|
{
|
||||||
|
imgui_bt_component_t debug_frame_graph_component;
|
||||||
|
|
||||||
|
if (reason == DLL_PROCESS_ATTACH) {
|
||||||
|
log_to_writer(log_writer_null, NULL);
|
||||||
|
|
||||||
|
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
||||||
|
|
||||||
|
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
||||||
|
|
||||||
|
hook_d3d9_init(d3d9_frame_graph_hook_handlers, lengthof(d3d9_frame_graph_hook_handlers));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
22
src/main/d3d9-monitor-check/Module.mk
Normal file
22
src/main/d3d9-monitor-check/Module.mk
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
exes += d3d9-monitor-check \
|
||||||
|
|
||||||
|
ldflags_d3d9-monitor-check := \
|
||||||
|
-ld3d9 \
|
||||||
|
-ldwmapi \
|
||||||
|
-lgdi32 \
|
||||||
|
-ld3dx9 \
|
||||||
|
|
||||||
|
libs_d3d9-monitor-check := \
|
||||||
|
util \
|
||||||
|
|
||||||
|
src_d3d9-monitor-check := \
|
||||||
|
cmdline.c \
|
||||||
|
font.c \
|
||||||
|
gfx.c \
|
||||||
|
input.c \
|
||||||
|
interactive.c \
|
||||||
|
main.c \
|
||||||
|
menu.c \
|
||||||
|
refresh-rate-test.c \
|
||||||
|
response-time-test.c \
|
||||||
|
vsync-test.c
|
||||||
534
src/main/d3d9-monitor-check/cmdline.c
Normal file
534
src/main/d3d9-monitor-check/cmdline.c
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/input.h"
|
||||||
|
#include "d3d9-monitor-check/print-console.h"
|
||||||
|
#include "d3d9-monitor-check/refresh-rate-test.h"
|
||||||
|
#include "d3d9-monitor-check/response-time-test.h"
|
||||||
|
#include "d3d9-monitor-check/vsync-test.h"
|
||||||
|
|
||||||
|
static void _print_synopsis()
|
||||||
|
{
|
||||||
|
printfln_err("D3D9 monitor check tool command line mode");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err("Usage:");
|
||||||
|
printfln_err(" d3d9-monitor-check cmdline <command> <args>");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err("Available commands:");
|
||||||
|
printfln_err(" adapter: Query adapter information");
|
||||||
|
printfln_err(" modes: Query adapter modes. Use this to get supported mandatory parameters for width, height and refresh rate for the tests.");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err(" refresh-rate-test <width> <height> <refresh_rate> [--warm-up-secs n] [--total-secs n] [--results-timeout-secs n] [--windowed] [--vsync-off]: Run a display refresh rate test (i.e. IIDX monitor check).");
|
||||||
|
printfln_err(" width: Width of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" height: Height of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" refresh_rate: Target refresh rate to run the test at");
|
||||||
|
printfln_err(" warm-up-secs: Optional. Number of seconds to warm-up before executing the main run that counts towards the measurement results");
|
||||||
|
printfln_err(" total-secs: Optional. Total number of seconds to run the test for that count towards the measurement results");
|
||||||
|
printfln_err(" results-timeout-secs: Optional. Number of seconds to display final result after the test before exiting");
|
||||||
|
printfln_err(" windowed: Optional. Run the test in windowed mode (not recommended)");
|
||||||
|
printfln_err(" vsync-off: Optional. Run the test with vsync off (not recommended)");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err(" response-time-test <width> <height> <refresh_rate> [--total-secs n] [--windowed] [--vsync-off]: Run a test to visually inspect the display's response times.");
|
||||||
|
printfln_err(" width: Width of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" height: Height of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" refresh_rate: Target refresh rate to run the test at");
|
||||||
|
printfln_err(" total-secs: Optional. Total number of seconds to run the test for that count towards the measurement results");
|
||||||
|
printfln_err(" windowed: Optional. Run the test in windowed mode (not recommended)");
|
||||||
|
printfln_err(" vsync-off: Optional. Run the test with vsync off (not recommended)");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err(" vsync-test <width> <height> <refresh_rate> [--total-secs n] [--windowed]: Run a test to visually inspect the display's vsync behavior.");
|
||||||
|
printfln_err(" width: Width of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" height: Height of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" refresh_rate: Target refresh rate to run the test at");
|
||||||
|
printfln_err(" total-secs: Optional. Total number of seconds to run the test for that count towards the measurement results");
|
||||||
|
printfln_err(" windowed: Optional. Run the test in windowed mode (not recommended)");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _adapter()
|
||||||
|
{
|
||||||
|
D3DADAPTER_IDENTIFIER9 identifier;
|
||||||
|
|
||||||
|
if (!gfx_adapter_info_get(&identifier)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printfln_out("Driver: %s", identifier.Driver);
|
||||||
|
printfln_out("Description: %s", identifier.Description);
|
||||||
|
printfln_out("DeviceName: %s", identifier.DeviceName);
|
||||||
|
#ifdef _WIN32
|
||||||
|
printfln_out("DriverVersion: %lld", identifier.DriverVersion.QuadPart);
|
||||||
|
#else
|
||||||
|
printfln_out("DriverVersion: %lu.%lu", identifier.DriverVersionHighPart, identifier.DriverVersionLowPart);
|
||||||
|
#endif
|
||||||
|
printfln_out("VendorId: %lu", identifier.VendorId);
|
||||||
|
printfln_out("DeviceId: %lu", identifier.DeviceId);
|
||||||
|
printfln_out("SubSysId: %lu", identifier.SubSysId);
|
||||||
|
printfln_out("Revision: %lu", identifier.Revision);
|
||||||
|
printfln_out("DeviceIdentifier: {%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
||||||
|
identifier.DeviceIdentifier.Data1,
|
||||||
|
identifier.DeviceIdentifier.Data2,
|
||||||
|
identifier.DeviceIdentifier.Data3,
|
||||||
|
identifier.DeviceIdentifier.Data4[0],
|
||||||
|
identifier.DeviceIdentifier.Data4[1],
|
||||||
|
identifier.DeviceIdentifier.Data4[2],
|
||||||
|
identifier.DeviceIdentifier.Data4[3],
|
||||||
|
identifier.DeviceIdentifier.Data4[4],
|
||||||
|
identifier.DeviceIdentifier.Data4[5],
|
||||||
|
identifier.DeviceIdentifier.Data4[6],
|
||||||
|
identifier.DeviceIdentifier.Data4[7]);
|
||||||
|
printfln_out("WHQLLevel: %lu", identifier.WHQLLevel);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _modes()
|
||||||
|
{
|
||||||
|
gfx_adapter_modes_t modes;
|
||||||
|
|
||||||
|
if (!gfx_adapter_modes_get(&modes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < modes.count; i++) {
|
||||||
|
printfln_out("%d: %d x %d @ %d hz", i, modes.modes[i].Width, modes.modes[i].Height, modes.modes[i].RefreshRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _refresh_rate_test(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
uint32_t warm_up_frame_count,
|
||||||
|
uint32_t sample_frame_count,
|
||||||
|
uint32_t result_timeout_frame_count,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync)
|
||||||
|
{
|
||||||
|
gfx_t *gfx;
|
||||||
|
input_t *input;
|
||||||
|
refresh_rate_test_t *test;
|
||||||
|
gfx_info_t gfx_info;
|
||||||
|
refresh_rate_test_results_t results;
|
||||||
|
uint32_t results_timeout_seconds;
|
||||||
|
|
||||||
|
input_init(&input);
|
||||||
|
|
||||||
|
if (!gfx_init(width, height, refresh_rate, windowed, vsync, &gfx)) {
|
||||||
|
input_fini(input);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!refresh_rate_test_init(gfx, warm_up_frame_count, sample_frame_count, &test)) {
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
input_update(input);
|
||||||
|
|
||||||
|
if (input_key_esc_pushed(input)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (refresh_rate_test_frame_update(test) &&
|
||||||
|
gfx_last_frame_count_get(gfx) < warm_up_frame_count + sample_frame_count);
|
||||||
|
|
||||||
|
results_timeout_seconds = result_timeout_frame_count / refresh_rate;
|
||||||
|
|
||||||
|
// Display final results
|
||||||
|
for (uint32_t i = 0; i < result_timeout_frame_count; i++) {
|
||||||
|
input_update(input);
|
||||||
|
|
||||||
|
if (input_key_esc_pushed(input)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!refresh_rate_test_results_frame_update(test, results_timeout_seconds)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx_info_get(gfx, &gfx_info);
|
||||||
|
refresh_rate_test_results_get(test, &results);
|
||||||
|
|
||||||
|
printfln_err("Final results");
|
||||||
|
printfln_out("GPU: %s", gfx_info.adapter_identifier);
|
||||||
|
printfln_out("Spec: %d x %d @ %d hz, %s, vsync %s", gfx_info.width, gfx_info.height, gfx_info.refresh_rate,
|
||||||
|
gfx_info.windowed ? "windowed" : "fullscreen", gfx_info.vsync ? "on" : "off");
|
||||||
|
printfln_out("Total warm-up frame count: %d", results.total_warm_up_frame_count);
|
||||||
|
printfln_out("Total sample frame count: %d", results.total_sample_frame_count);
|
||||||
|
printfln_out("Avg frame time (ms): %.3f", results.avg_frame_time_ms);
|
||||||
|
printfln_out("Avg refresh rate (hz): %.3f", results.avg_refresh_rate_hz);
|
||||||
|
|
||||||
|
refresh_rate_test_fini(test);
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _response_time_test(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
uint32_t total_frame_count,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync)
|
||||||
|
{
|
||||||
|
gfx_t *gfx;
|
||||||
|
input_t *input;
|
||||||
|
response_time_test_t *test;
|
||||||
|
|
||||||
|
input_init(&input);
|
||||||
|
|
||||||
|
// Force vsync on, off option doesn't make sense for this test
|
||||||
|
if (!gfx_init(width, height, refresh_rate, windowed, vsync, &gfx)) {
|
||||||
|
input_fini(input);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response_time_test_init(gfx, &test)) {
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
input_update(input);
|
||||||
|
|
||||||
|
if (input_key_esc_pushed(input)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (response_time_test_frame_update(test) &&
|
||||||
|
gfx_last_frame_count_get(gfx) < total_frame_count);
|
||||||
|
|
||||||
|
response_time_test_fini(test);
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _vsync_test(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
uint32_t total_frame_count,
|
||||||
|
bool windowed)
|
||||||
|
{
|
||||||
|
gfx_t *gfx;
|
||||||
|
input_t *input;
|
||||||
|
vsync_test_t *test;
|
||||||
|
|
||||||
|
input_init(&input);
|
||||||
|
|
||||||
|
// Force vsync on, off option doesn't make sense for this test
|
||||||
|
if (!gfx_init(width, height, refresh_rate, windowed, true, &gfx)) {
|
||||||
|
input_fini(input);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vsync_test_init(gfx, &test)) {
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
input_update(input);
|
||||||
|
|
||||||
|
if (input_key_esc_pushed(input)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (vsync_test_frame_update(test) &&
|
||||||
|
gfx_last_frame_count_get(gfx) < total_frame_count);
|
||||||
|
|
||||||
|
vsync_test_fini(test);
|
||||||
|
input_fini(input);
|
||||||
|
gfx_fini(gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _cmd_refresh_rate_test(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
uint32_t warm_up_seconds;
|
||||||
|
uint32_t sample_seconds;
|
||||||
|
uint32_t results_timeout_seconds;
|
||||||
|
bool windowed;
|
||||||
|
bool vsync;
|
||||||
|
|
||||||
|
uint32_t total_warm_up_frame_count;
|
||||||
|
uint32_t total_sample_frame_count;
|
||||||
|
uint32_t result_timeout_frame_count;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = atoi(argv[0]);
|
||||||
|
|
||||||
|
if (width == 0 || width > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid width: %d", width);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = atoi(argv[1]);
|
||||||
|
|
||||||
|
if (height == 0 || height > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid height: %d", height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_rate = atoi(argv[2]);
|
||||||
|
|
||||||
|
if (refresh_rate == 0 || refresh_rate > 1000) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid refresh rate: %d", refresh_rate);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sane defaults
|
||||||
|
warm_up_seconds = 10;
|
||||||
|
sample_seconds = 20;
|
||||||
|
results_timeout_seconds = 5;
|
||||||
|
windowed = false;
|
||||||
|
vsync = true;
|
||||||
|
|
||||||
|
for (int i = 3; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "--warm-up-secs")) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
warm_up_seconds = atoi(argv[++i]);
|
||||||
|
|
||||||
|
if (warm_up_seconds == 0) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid warm-up seconds: %d", warm_up_seconds);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Missing argument for --warm-up-secs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--sample-secs")) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
sample_seconds = atoi(argv[++i]);
|
||||||
|
|
||||||
|
if (sample_seconds == 0) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid sample seconds: %d", sample_seconds);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Missing argument for --total-secs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--results-timeout-secs")) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
results_timeout_seconds = atoi(argv[++i]);
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Missing argument for --results-timeout-secs");
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--windowed")) {
|
||||||
|
windowed = true;
|
||||||
|
} else if (!strcmp(argv[i], "--vsync-off")) {
|
||||||
|
vsync = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_warm_up_frame_count = warm_up_seconds * refresh_rate;
|
||||||
|
total_sample_frame_count = sample_seconds * refresh_rate;
|
||||||
|
result_timeout_frame_count = results_timeout_seconds * refresh_rate;
|
||||||
|
|
||||||
|
return _refresh_rate_test(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
refresh_rate,
|
||||||
|
total_warm_up_frame_count,
|
||||||
|
total_sample_frame_count,
|
||||||
|
result_timeout_frame_count,
|
||||||
|
windowed,
|
||||||
|
vsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _cmd_response_time_test(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
uint32_t total_seconds;
|
||||||
|
bool windowed;
|
||||||
|
bool vsync;
|
||||||
|
|
||||||
|
uint32_t total_frame_count;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = atoi(argv[0]);
|
||||||
|
|
||||||
|
if (width == 0 || width > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid width: %d", width);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = atoi(argv[1]);
|
||||||
|
|
||||||
|
if (height == 0 || height > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid height: %d", height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_rate = atoi(argv[2]);
|
||||||
|
|
||||||
|
if (refresh_rate == 0 || refresh_rate > 1000) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid refresh rate: %d", refresh_rate);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sane defaults
|
||||||
|
total_seconds = 30;
|
||||||
|
windowed = false;
|
||||||
|
vsync = true;
|
||||||
|
for (int i = 3; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "--total-secs")) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
total_seconds = atoi(argv[++i]);
|
||||||
|
|
||||||
|
if (total_seconds == 0) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid total seconds: %d", total_seconds);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Missing argument for --total-secs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--windowed")) {
|
||||||
|
windowed = true;
|
||||||
|
} else if (!strcmp(argv[i], "--vsync-off")) {
|
||||||
|
vsync = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_frame_count = total_seconds * refresh_rate;
|
||||||
|
|
||||||
|
return _response_time_test(width, height, refresh_rate, total_frame_count, windowed, vsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _cmd_vsync_test(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
uint32_t total_seconds;
|
||||||
|
bool windowed;
|
||||||
|
|
||||||
|
uint32_t total_frame_count;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = atoi(argv[0]);
|
||||||
|
|
||||||
|
if (width == 0 || width > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid width: %d", width);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = atoi(argv[1]);
|
||||||
|
|
||||||
|
if (height == 0 || height > 16384) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid height: %d", height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_rate = atoi(argv[2]);
|
||||||
|
|
||||||
|
if (refresh_rate == 0 || refresh_rate > 1000) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid refresh rate: %d", refresh_rate);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sane defaults
|
||||||
|
total_seconds = 30;
|
||||||
|
windowed = false;
|
||||||
|
|
||||||
|
for (int i = 3; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "--total-secs")) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
total_seconds = atoi(argv[++i]);
|
||||||
|
|
||||||
|
if (total_seconds == 0) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Invalid total seconds: %d", total_seconds);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Missing argument for --total-secs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(argv[i], "--windowed")) {
|
||||||
|
windowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
total_frame_count = total_seconds * refresh_rate;
|
||||||
|
|
||||||
|
return _vsync_test(width, height, refresh_rate, total_frame_count, windowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmdline_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *command;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = argv[0];
|
||||||
|
|
||||||
|
if (!strcmp(command, "adapter")) {
|
||||||
|
return _adapter();
|
||||||
|
} else if (!strcmp(command, "modes")) {
|
||||||
|
return _modes();
|
||||||
|
} else if (!strcmp(command, "refresh-rate-test")) {
|
||||||
|
return _cmd_refresh_rate_test(argc - 1, argv + 1);
|
||||||
|
} else if (!strcmp(command, "response-time-test")) {
|
||||||
|
return _cmd_response_time_test(argc - 1, argv + 1);
|
||||||
|
} else if (!strcmp(command, "vsync-test")) {
|
||||||
|
return _cmd_vsync_test(argc - 1, argv + 1);
|
||||||
|
} else {
|
||||||
|
_print_synopsis(argv[0]);
|
||||||
|
printfln_err("ERROR: Unknown command: %s", command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/main/d3d9-monitor-check/cmdline.h
Normal file
8
src/main/d3d9-monitor-check/cmdline.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_CMDLINE_H
|
||||||
|
#define D3D9_MONITOR_CHECK_CMDLINE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool cmdline_main(int argc, char **argv);
|
||||||
|
|
||||||
|
#endif
|
||||||
207
src/main/d3d9-monitor-check/font.c
Normal file
207
src/main/d3d9-monitor-check/font.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <d3dx9.h>
|
||||||
|
#include <d3dx9core.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/font.h"
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
|
||||||
|
#define BASE_RESOLUTION_WIDTH 640.0f
|
||||||
|
#define BASE_RESOLUTION_HEIGHT 480.0f
|
||||||
|
#define BASE_FONT_SIZE 20.0f
|
||||||
|
#define BASE_MARGIN 1.0f
|
||||||
|
// Standard Windows DPI
|
||||||
|
#define BASE_DPI 96.0f
|
||||||
|
|
||||||
|
typedef struct font {
|
||||||
|
gfx_t *gfx;
|
||||||
|
ID3DXFont *font;
|
||||||
|
float scale_x;
|
||||||
|
float scale_y;
|
||||||
|
float dpi_scale;
|
||||||
|
uint32_t font_height;
|
||||||
|
uint32_t line_height;
|
||||||
|
uint32_t base_offset_x;
|
||||||
|
uint32_t base_offset_y;
|
||||||
|
} font_t;
|
||||||
|
|
||||||
|
static void _font_text_draw(font_t *font, uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b, const char *text)
|
||||||
|
{
|
||||||
|
uint32_t scaled_x;
|
||||||
|
uint32_t scaled_y;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
|
assert(font);
|
||||||
|
assert(text);
|
||||||
|
|
||||||
|
// Scale position based on both resolution and DPI
|
||||||
|
scaled_x = (uint32_t)(x * font->scale_x * font->dpi_scale) + font->base_offset_x;
|
||||||
|
scaled_y = (uint32_t)(y * font->scale_y * font->dpi_scale) + font->base_offset_y;
|
||||||
|
|
||||||
|
rect.left = scaled_x;
|
||||||
|
rect.top = scaled_y;
|
||||||
|
// Scale text box width based on both resolution and DPI
|
||||||
|
rect.right = scaled_x + (uint32_t)(BASE_RESOLUTION_WIDTH * font->scale_x * font->dpi_scale);
|
||||||
|
rect.bottom = scaled_y + font->line_height;
|
||||||
|
|
||||||
|
ID3DXFont_DrawText(
|
||||||
|
font->font,
|
||||||
|
NULL,
|
||||||
|
text,
|
||||||
|
-1,
|
||||||
|
&rect,
|
||||||
|
DT_LEFT | DT_TOP | DT_NOCLIP,
|
||||||
|
D3DCOLOR_XRGB(r, g, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool font_init(gfx_t *gfx, uint32_t size, font_t **font)
|
||||||
|
{
|
||||||
|
IDirect3DDevice9 *device;
|
||||||
|
HRESULT hr;
|
||||||
|
HDC hdc;
|
||||||
|
int dpi;
|
||||||
|
|
||||||
|
assert(gfx);
|
||||||
|
assert(font);
|
||||||
|
|
||||||
|
*font = xmalloc(sizeof(font_t));
|
||||||
|
memset(*font, 0, sizeof(font_t));
|
||||||
|
|
||||||
|
(*font)->gfx = gfx;
|
||||||
|
|
||||||
|
// Get the system DPI
|
||||||
|
hdc = GetDC(NULL);
|
||||||
|
dpi = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||||
|
ReleaseDC(NULL, hdc);
|
||||||
|
|
||||||
|
// Calculate DPI scale relative to base DPI
|
||||||
|
(*font)->dpi_scale = dpi / BASE_DPI;
|
||||||
|
|
||||||
|
// Calculate resolution scaling factors
|
||||||
|
(*font)->scale_x = gfx_width_get(gfx) / BASE_RESOLUTION_WIDTH;
|
||||||
|
(*font)->scale_y = gfx_height_get(gfx) / BASE_RESOLUTION_HEIGHT;
|
||||||
|
|
||||||
|
// Scale font height based on both DPI and resolution
|
||||||
|
// This ensures text maintains physical size across different resolutions
|
||||||
|
(*font)->font_height = (uint32_t)(size * (*font)->dpi_scale);
|
||||||
|
|
||||||
|
// Line height matches font height
|
||||||
|
(*font)->line_height = (*font)->font_height;
|
||||||
|
|
||||||
|
// Scale margins based on DPI and resolution
|
||||||
|
(*font)->base_offset_x = (uint32_t)(BASE_MARGIN * (*font)->scale_x * (*font)->dpi_scale);
|
||||||
|
(*font)->base_offset_y = (uint32_t)(BASE_MARGIN * (*font)->scale_y * (*font)->dpi_scale);
|
||||||
|
|
||||||
|
device = gfx_device_get(gfx);
|
||||||
|
|
||||||
|
hr = D3DXCreateFont(
|
||||||
|
device,
|
||||||
|
(*font)->font_height,
|
||||||
|
0,
|
||||||
|
FW_BOLD,
|
||||||
|
1,
|
||||||
|
FALSE,
|
||||||
|
DEFAULT_CHARSET,
|
||||||
|
OUT_DEFAULT_PRECIS,
|
||||||
|
ANTIALIASED_QUALITY, // Changed to antialiased for better readability
|
||||||
|
DEFAULT_PITCH | FF_DONTCARE,
|
||||||
|
"Arial",
|
||||||
|
&(*font)->font);
|
||||||
|
|
||||||
|
if (hr != D3D_OK) {
|
||||||
|
free(*font);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_fini(font_t *font)
|
||||||
|
{
|
||||||
|
assert(font);
|
||||||
|
|
||||||
|
ID3DXFont_Release(font->font);
|
||||||
|
|
||||||
|
free(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_begin(font_t *font, uint32_t line_spacing, uint32_t origin_x, uint32_t origin_y, font_text_t *text)
|
||||||
|
{
|
||||||
|
assert(font);
|
||||||
|
assert(text);
|
||||||
|
|
||||||
|
text->font = font;
|
||||||
|
text->line_spacing = line_spacing;
|
||||||
|
text->origin_x = origin_x;
|
||||||
|
text->origin_y = origin_y;
|
||||||
|
text->current_x = origin_x;
|
||||||
|
text->current_y = origin_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_white_draw(font_text_t *text, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buffer[4096];
|
||||||
|
|
||||||
|
assert(text);
|
||||||
|
assert(fmt);
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsprintf(buffer, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
_font_text_draw(text->font, text->current_x, text->current_y, 255, 255, 255, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_red_draw(font_text_t *text, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buffer[4096];
|
||||||
|
|
||||||
|
assert(text);
|
||||||
|
assert(fmt);
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsprintf(buffer, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
_font_text_draw(text->font, text->current_x, text->current_y, 255, 0, 0, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_cyan_draw(font_text_t *text, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buffer[4096];
|
||||||
|
|
||||||
|
assert(text);
|
||||||
|
assert(fmt);
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsprintf(buffer, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
_font_text_draw(text->font, text->current_x, text->current_y, 0, 255, 255, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_newline(font_text_t *text)
|
||||||
|
{
|
||||||
|
assert(text);
|
||||||
|
|
||||||
|
text->current_x = text->origin_x;
|
||||||
|
text->current_y += text->font->line_height + text->line_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_text_end(font_text_t *text)
|
||||||
|
{
|
||||||
|
assert(text);
|
||||||
|
|
||||||
|
memset(text, 0, sizeof(font_text_t));
|
||||||
|
}
|
||||||
37
src/main/d3d9-monitor-check/font.h
Normal file
37
src/main/d3d9-monitor-check/font.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_FONT_H
|
||||||
|
#define D3D9_MONITOR_CHECK_FONT_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
typedef struct font font_t;
|
||||||
|
|
||||||
|
typedef struct font_text {
|
||||||
|
font_t *font;
|
||||||
|
uint32_t line_spacing;
|
||||||
|
uint32_t origin_x;
|
||||||
|
uint32_t origin_y;
|
||||||
|
uint32_t current_x;
|
||||||
|
uint32_t current_y;
|
||||||
|
} font_text_t;
|
||||||
|
|
||||||
|
bool font_init(gfx_t *gfx, uint32_t size, font_t **font);
|
||||||
|
|
||||||
|
void font_fini(font_t *font);
|
||||||
|
|
||||||
|
void font_text_begin(font_t *font, uint32_t line_spacing, uint32_t origin_x, uint32_t origin_y, font_text_t *text);
|
||||||
|
|
||||||
|
void font_text_white_draw(font_text_t *text, const char *fmt, ...);
|
||||||
|
|
||||||
|
void font_text_red_draw(font_text_t *text, const char *fmt, ...);
|
||||||
|
|
||||||
|
void font_text_cyan_draw(font_text_t *text, const char *fmt, ...);
|
||||||
|
|
||||||
|
void font_text_newline(font_text_t *text);
|
||||||
|
|
||||||
|
void font_text_end(font_text_t *text);
|
||||||
|
|
||||||
|
#endif
|
||||||
430
src/main/d3d9-monitor-check/gfx.c
Normal file
430
src/main/d3d9-monitor-check/gfx.c
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <d3d9.h>
|
||||||
|
#include <d3dx9core.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/print-console.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
|
typedef struct gfx_ctx_t {
|
||||||
|
HWND hwnd;
|
||||||
|
IDirect3D9 *d3d;
|
||||||
|
IDirect3DDevice9 *device;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
bool windowed;
|
||||||
|
bool vsync;
|
||||||
|
} gfx_ctx_t;
|
||||||
|
|
||||||
|
typedef struct gfx_render_state_t {
|
||||||
|
uint64_t frame_current;
|
||||||
|
uint64_t frame_start_time;
|
||||||
|
uint64_t last_frame_time_us;
|
||||||
|
} gfx_render_state_t;
|
||||||
|
|
||||||
|
typedef struct gfx {
|
||||||
|
gfx_ctx_t ctx;
|
||||||
|
gfx_render_state_t render_state;
|
||||||
|
} gfx_t;
|
||||||
|
|
||||||
|
static const D3DFORMAT _gfx_d3dformat = D3DFMT_X8R8G8B8;
|
||||||
|
|
||||||
|
static bool _gfx_d3d_context_create(IDirect3D9 **d3d)
|
||||||
|
{
|
||||||
|
// Initialize D3D
|
||||||
|
*d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||||
|
|
||||||
|
if (!*d3d) {
|
||||||
|
printfln_winerr("Creating d3d context failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _gfx_adapter_identifier_query(IDirect3D9 *d3d, D3DADAPTER_IDENTIFIER9 *identifier)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, identifier);
|
||||||
|
|
||||||
|
if (hr != D3D_OK) {
|
||||||
|
printfln_winerr("GetAdapterIdentifier failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _gfx_window_create(uint32_t width, uint32_t height, HWND *hwnd)
|
||||||
|
{
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
|
||||||
|
memset(&wc, 0, sizeof(wc));
|
||||||
|
|
||||||
|
wc.cbSize = sizeof(wc);
|
||||||
|
wc.lpfnWndProc = DefWindowProc;
|
||||||
|
wc.hInstance = GetModuleHandle(NULL);
|
||||||
|
wc.lpszClassName = "D3D9MonitorCheck";
|
||||||
|
|
||||||
|
RegisterClassExA(&wc);
|
||||||
|
|
||||||
|
// Create window
|
||||||
|
*hwnd = CreateWindowA(
|
||||||
|
wc.lpszClassName,
|
||||||
|
"D3D9 Monitor Check",
|
||||||
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
wc.hInstance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!*hwnd) {
|
||||||
|
printfln_winerr("Failed to create window");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _gfx_d3d_device_create(
|
||||||
|
HWND hwnd,
|
||||||
|
IDirect3D9 *d3d,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync,
|
||||||
|
IDirect3DDevice9 **device)
|
||||||
|
{
|
||||||
|
D3DPRESENT_PARAMETERS pp;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
memset(&pp, 0, sizeof(pp));
|
||||||
|
|
||||||
|
if (windowed) {
|
||||||
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
|
|
||||||
|
pp.Windowed = TRUE;
|
||||||
|
pp.FullScreen_RefreshRateInHz = 0;
|
||||||
|
} else {
|
||||||
|
ShowCursor(FALSE);
|
||||||
|
|
||||||
|
pp.Windowed = FALSE;
|
||||||
|
pp.FullScreen_RefreshRateInHz = refresh_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vsync) {
|
||||||
|
pp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
||||||
|
} else {
|
||||||
|
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp.BackBufferWidth = width;
|
||||||
|
pp.BackBufferHeight = height;
|
||||||
|
pp.BackBufferFormat = _gfx_d3dformat;
|
||||||
|
pp.BackBufferCount = 2;
|
||||||
|
pp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||||
|
pp.MultiSampleQuality = 0;
|
||||||
|
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||||
|
pp.hDeviceWindow = hwnd;
|
||||||
|
pp.EnableAutoDepthStencil = TRUE;
|
||||||
|
pp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||||
|
pp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
||||||
|
|
||||||
|
// Create D3D device
|
||||||
|
hr = IDirect3D9_CreateDevice(
|
||||||
|
d3d,
|
||||||
|
D3DADAPTER_DEFAULT,
|
||||||
|
D3DDEVTYPE_HAL,
|
||||||
|
hwnd,
|
||||||
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||||
|
&pp,
|
||||||
|
device);
|
||||||
|
|
||||||
|
if (hr != D3D_OK) {
|
||||||
|
printfln_winerr("Creating d3d device failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfx_adapter_info_get(D3DADAPTER_IDENTIFIER9 *adapter)
|
||||||
|
{
|
||||||
|
IDirect3D9 *d3d;
|
||||||
|
|
||||||
|
assert(adapter);
|
||||||
|
|
||||||
|
memset(adapter, 0, sizeof(D3DADAPTER_IDENTIFIER9));
|
||||||
|
|
||||||
|
if (!_gfx_d3d_context_create(&d3d)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_gfx_adapter_identifier_query(d3d, adapter)) {
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfx_adapter_modes_get(gfx_adapter_modes_t *modes)
|
||||||
|
{
|
||||||
|
IDirect3D9 *d3d;
|
||||||
|
HRESULT hr;
|
||||||
|
UINT mode_count;
|
||||||
|
|
||||||
|
assert(modes);
|
||||||
|
|
||||||
|
memset(modes, 0, sizeof(gfx_adapter_modes_t));
|
||||||
|
|
||||||
|
if (!_gfx_d3d_context_create(&d3d)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_count = IDirect3D9_GetAdapterModeCount(d3d, D3DADAPTER_DEFAULT, _gfx_d3dformat);
|
||||||
|
|
||||||
|
if (mode_count > sizeof(modes->modes)) {
|
||||||
|
mode_count = sizeof(modes->modes);
|
||||||
|
printfln_err("WARNING: Available adapter modes (total %d) is greater than the maximum supported modes in structure (%zu)", mode_count, sizeof(modes->modes));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UINT i = 0; i < mode_count; i++) {
|
||||||
|
hr = IDirect3D9_EnumAdapterModes(d3d, D3DADAPTER_DEFAULT, _gfx_d3dformat, i, &modes->modes[i]);
|
||||||
|
|
||||||
|
if (hr != D3D_OK) {
|
||||||
|
printfln_winerr("EnumAdapterMode index %d failed", i);
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modes->count = mode_count;
|
||||||
|
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfx_init(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync,
|
||||||
|
gfx_t **gfx)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
IDirect3D9 *d3d;
|
||||||
|
D3DADAPTER_IDENTIFIER9 identifier;
|
||||||
|
IDirect3DDevice9 *device;
|
||||||
|
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
printfln_err("Creating d3d context ...");
|
||||||
|
|
||||||
|
if (!_gfx_d3d_context_create(&d3d)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printfln_err("Querying adapter identifier ...");
|
||||||
|
|
||||||
|
if (!_gfx_adapter_identifier_query(d3d, &identifier)) {
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printfln_err("Adapter:");
|
||||||
|
printfln_err("Driver: %s", identifier.Driver);
|
||||||
|
printfln_err("Description: %s", identifier.Description);
|
||||||
|
printfln_err("DeviceName: %s", identifier.DeviceName);
|
||||||
|
#ifdef _WIN32
|
||||||
|
printfln_err("DriverVersion: %lld", identifier.DriverVersion.QuadPart);
|
||||||
|
#else
|
||||||
|
printfln_err("DriverVersion: %lu.%lu", identifier.DriverVersionHighPart, identifier.DriverVersionLowPart);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printfln_err("Creating window with %dx%d ...", width, height);
|
||||||
|
|
||||||
|
if (!_gfx_window_create(width, height, &hwnd)) {
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printfln_err("Creating d3d device %d x %d @ %d hz %s vsync %s ...",
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
refresh_rate,
|
||||||
|
windowed ? "windowed" : "fullscreen",
|
||||||
|
vsync ? "on" : "off");
|
||||||
|
|
||||||
|
if (!_gfx_d3d_device_create(
|
||||||
|
hwnd,
|
||||||
|
d3d,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
refresh_rate,
|
||||||
|
windowed,
|
||||||
|
vsync,
|
||||||
|
&device)) {
|
||||||
|
IDirect3D9_Release(d3d);
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*gfx = xmalloc(sizeof(gfx_t));
|
||||||
|
memset(*gfx, 0, sizeof(gfx_t));
|
||||||
|
|
||||||
|
(*gfx)->ctx.hwnd = hwnd;
|
||||||
|
(*gfx)->ctx.d3d = d3d;
|
||||||
|
(*gfx)->ctx.device = device;
|
||||||
|
(*gfx)->ctx.width = width;
|
||||||
|
(*gfx)->ctx.height = height;
|
||||||
|
(*gfx)->ctx.refresh_rate = refresh_rate;
|
||||||
|
(*gfx)->ctx.windowed = windowed;
|
||||||
|
(*gfx)->ctx.vsync = vsync;
|
||||||
|
|
||||||
|
(*gfx)->render_state.frame_current = 0;
|
||||||
|
(*gfx)->render_state.frame_start_time = 0;
|
||||||
|
(*gfx)->render_state.last_frame_time_us = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gfx_width_get(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
return gfx->ctx.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gfx_height_get(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
return gfx->ctx.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfx_info_get(gfx_t *gfx, gfx_info_t *info)
|
||||||
|
{
|
||||||
|
D3DADAPTER_IDENTIFIER9 identifier;
|
||||||
|
|
||||||
|
assert(gfx);
|
||||||
|
assert(info);
|
||||||
|
|
||||||
|
if (!_gfx_adapter_identifier_query(gfx->ctx.d3d, &identifier)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(info->adapter_identifier, identifier.Description, sizeof(info->adapter_identifier));
|
||||||
|
|
||||||
|
info->width = gfx->ctx.width;
|
||||||
|
info->height = gfx->ctx.height;
|
||||||
|
info->refresh_rate = gfx->ctx.refresh_rate;
|
||||||
|
info->windowed = gfx->ctx.windowed;
|
||||||
|
info->vsync = gfx->ctx.vsync;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirect3DDevice9 *gfx_device_get(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
return gfx->ctx.device;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gfx_frame_begin(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
// Required to not make windows think we are stuck and not responding
|
||||||
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
|
if (msg.message == WM_QUIT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDirect3DDevice9_Clear(
|
||||||
|
gfx->ctx.device,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
D3DCLEAR_TARGET,
|
||||||
|
D3DCOLOR_XRGB(0, 0, 0),
|
||||||
|
1.0f,
|
||||||
|
0);
|
||||||
|
IDirect3DDevice9_BeginScene(gfx->ctx.device);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_frame_end(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
uint64_t end_time;
|
||||||
|
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
IDirect3DDevice9_EndScene(gfx->ctx.device);
|
||||||
|
IDirect3DDevice9_Present(gfx->ctx.device, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// End previous frame time measurement after the frame has been presented (which might include waiting for vsync)
|
||||||
|
// and start a new frame time measurement immediately
|
||||||
|
// This ensures that anything that comes after ending the frame and still before starting a new frame, e.g. IO
|
||||||
|
// processing, is included in the total frame time measurement
|
||||||
|
// However, this can not include the very first frame
|
||||||
|
if (gfx->render_state.frame_current > 0) {
|
||||||
|
end_time = time_get_counter();
|
||||||
|
gfx->render_state.last_frame_time_us = time_get_elapsed_us(end_time - gfx->render_state.frame_start_time);
|
||||||
|
gfx->render_state.frame_start_time = end_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx->render_state.frame_start_time = time_get_counter();
|
||||||
|
|
||||||
|
gfx->render_state.frame_current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t gfx_last_frame_count_get(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
return gfx->render_state.frame_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t gfx_last_frame_time_us_get(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
return gfx->render_state.last_frame_time_us;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_fini(gfx_t *gfx)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
|
||||||
|
IDirect3DDevice9_Release(gfx->ctx.device);
|
||||||
|
IDirect3D9_Release(gfx->ctx.d3d);
|
||||||
|
DestroyWindow(gfx->ctx.hwnd);
|
||||||
|
|
||||||
|
free(gfx);
|
||||||
|
}
|
||||||
59
src/main/d3d9-monitor-check/gfx.h
Normal file
59
src/main/d3d9-monitor-check/gfx.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_GFX_H
|
||||||
|
#define D3D9_MONITOR_CHECK_GFX_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <d3d9.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct gfx gfx_t;
|
||||||
|
struct IDirect3DDevice9;
|
||||||
|
|
||||||
|
typedef struct gfx_adapter_modes {
|
||||||
|
D3DDISPLAYMODE modes[1024];
|
||||||
|
uint32_t count;
|
||||||
|
} gfx_adapter_modes_t;
|
||||||
|
|
||||||
|
typedef struct gfx_info {
|
||||||
|
char adapter_identifier[1024];
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
bool windowed;
|
||||||
|
bool vsync;
|
||||||
|
} gfx_info_t;
|
||||||
|
|
||||||
|
bool gfx_adapter_info_get(D3DADAPTER_IDENTIFIER9 *adapter);
|
||||||
|
|
||||||
|
bool gfx_adapter_modes_get(gfx_adapter_modes_t *modes);
|
||||||
|
|
||||||
|
bool gfx_init(uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync,
|
||||||
|
gfx_t **gfx);
|
||||||
|
|
||||||
|
uint32_t gfx_width_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
uint32_t gfx_height_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
bool gfx_info_get(gfx_t *gfx, gfx_info_t *info);
|
||||||
|
|
||||||
|
IDirect3DDevice9 *gfx_device_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
bool gfx_frame_begin(gfx_t *gfx);
|
||||||
|
|
||||||
|
void gfx_frame_end(gfx_t *gfx);
|
||||||
|
|
||||||
|
uint64_t gfx_last_frame_count_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
uint64_t gfx_last_frame_time_us_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
bool gfx_adpater_info_get(gfx_t *gfx);
|
||||||
|
|
||||||
|
void gfx_fini(gfx_t *gfx);
|
||||||
|
|
||||||
|
#endif
|
||||||
90
src/main/d3d9-monitor-check/input.c
Normal file
90
src/main/d3d9-monitor-check/input.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
|
||||||
|
typedef struct input_key_state {
|
||||||
|
bool previous_update_state;
|
||||||
|
bool current_update_state;
|
||||||
|
} input_key_state_t;
|
||||||
|
|
||||||
|
typedef struct input {
|
||||||
|
input_key_state_t esc;
|
||||||
|
input_key_state_t up;
|
||||||
|
input_key_state_t down;
|
||||||
|
input_key_state_t left;
|
||||||
|
input_key_state_t right;
|
||||||
|
input_key_state_t enter;
|
||||||
|
} input_t;
|
||||||
|
|
||||||
|
void input_init(input_t **input)
|
||||||
|
{
|
||||||
|
assert(input);
|
||||||
|
|
||||||
|
*input = xmalloc(sizeof(input_t));
|
||||||
|
memset(*input, 0, sizeof(input_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void input_update(input_t *input)
|
||||||
|
{
|
||||||
|
assert(input);
|
||||||
|
|
||||||
|
input->esc.previous_update_state = input->esc.current_update_state;
|
||||||
|
input->esc.current_update_state = GetAsyncKeyState(VK_ESCAPE) & 0x8000;
|
||||||
|
|
||||||
|
input->up.previous_update_state = input->up.current_update_state;
|
||||||
|
input->up.current_update_state = GetAsyncKeyState(VK_UP) & 0x8000;
|
||||||
|
|
||||||
|
input->down.previous_update_state = input->down.current_update_state;
|
||||||
|
input->down.current_update_state = GetAsyncKeyState(VK_DOWN) & 0x8000;
|
||||||
|
|
||||||
|
input->left.previous_update_state = input->left.current_update_state;
|
||||||
|
input->left.current_update_state = GetAsyncKeyState(VK_LEFT) & 0x8000;
|
||||||
|
|
||||||
|
input->right.previous_update_state = input->right.current_update_state;
|
||||||
|
input->right.current_update_state = GetAsyncKeyState(VK_RIGHT) & 0x8000;
|
||||||
|
|
||||||
|
input->enter.previous_update_state = input->enter.current_update_state;
|
||||||
|
input->enter.current_update_state = GetAsyncKeyState(VK_RETURN) & 0x8000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_esc_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->esc.previous_update_state == false && input->esc.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_up_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->up.previous_update_state == false && input->up.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_down_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->down.previous_update_state == false && input->down.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_left_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->left.previous_update_state == false && input->left.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_right_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->right.previous_update_state == false && input->right.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool input_key_enter_pushed(input_t *input)
|
||||||
|
{
|
||||||
|
return input->enter.previous_update_state == false && input->enter.current_update_state == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void input_fini(input_t *input)
|
||||||
|
{
|
||||||
|
assert(input);
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
}
|
||||||
26
src/main/d3d9-monitor-check/input.h
Normal file
26
src/main/d3d9-monitor-check/input.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_INPUT_H
|
||||||
|
#define D3D9_MONITOR_CHECK_INPUT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct input input_t;
|
||||||
|
|
||||||
|
void input_init(input_t **input);
|
||||||
|
|
||||||
|
void input_update(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_esc_pushed(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_up_pushed(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_down_pushed(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_left_pushed(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_right_pushed(input_t *input);
|
||||||
|
|
||||||
|
bool input_key_enter_pushed(input_t *input);
|
||||||
|
|
||||||
|
void input_fini(input_t *input);
|
||||||
|
|
||||||
|
#endif
|
||||||
196
src/main/d3d9-monitor-check/interactive.c
Normal file
196
src/main/d3d9-monitor-check/interactive.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/input.h"
|
||||||
|
#include "d3d9-monitor-check/menu.h"
|
||||||
|
#include "d3d9-monitor-check/print-console.h"
|
||||||
|
#include "d3d9-monitor-check/refresh-rate-test.h"
|
||||||
|
#include "d3d9-monitor-check/response-time-test.h"
|
||||||
|
#include "d3d9-monitor-check/vsync-test.h"
|
||||||
|
|
||||||
|
typedef enum INTERACTIVE_SCREEN {
|
||||||
|
INTERACTIVE_SCREEN_MENU = 0,
|
||||||
|
INTERACTIVE_SCREEN_REFRESH_RATE_TEST = 1,
|
||||||
|
INTERACTIVE_SCREEN_RESPONSE_TIME_TEST = 2,
|
||||||
|
INTERACTIVE_SCREEN_VSYNC_TEST = 3,
|
||||||
|
} interactive_screen_t;
|
||||||
|
|
||||||
|
static void _print_synopsis()
|
||||||
|
{
|
||||||
|
printfln_err("D3D9 monitor check tool interactive mode");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err("Usage:");
|
||||||
|
printfln_err(" d3d9-monitor-check interactive <width> <height> <refresh-rate> [--windowed] [--vsync-off]");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err(" width: Width of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" height: Height of the rendering resolution to run the test at");
|
||||||
|
printfln_err(" refresh-rate: Target refresh rate to run the test at");
|
||||||
|
printfln_err(" windowed: Optional. Run the test in windowed mode (not recommended)");
|
||||||
|
printfln_err(" vsync-off: Optional. Run the test with vsync off (not recommended)");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _interactive(
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t refresh_rate,
|
||||||
|
bool windowed,
|
||||||
|
bool vsync)
|
||||||
|
{
|
||||||
|
gfx_t *gfx;
|
||||||
|
input_t *input;
|
||||||
|
bool loop_running;
|
||||||
|
interactive_screen_t current_screen;
|
||||||
|
menu_item_t selected_menu_item;
|
||||||
|
|
||||||
|
menu_t *menu;
|
||||||
|
refresh_rate_test_t *refresh_rate_test;
|
||||||
|
response_time_test_t *response_time_test;
|
||||||
|
vsync_test_t *vsync_test;
|
||||||
|
|
||||||
|
input_init(&input);
|
||||||
|
|
||||||
|
if (!gfx_init(width, height, refresh_rate, windowed, vsync, &gfx)) {
|
||||||
|
input_fini(input);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu_init(gfx, &menu)) {
|
||||||
|
gfx_fini(gfx);
|
||||||
|
input_fini(input);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_running = true;
|
||||||
|
current_screen = INTERACTIVE_SCREEN_MENU;
|
||||||
|
|
||||||
|
while (loop_running) {
|
||||||
|
input_update(input);
|
||||||
|
|
||||||
|
switch (current_screen) {
|
||||||
|
case INTERACTIVE_SCREEN_MENU:
|
||||||
|
if (input_key_esc_pushed(input)) {
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
} else if (input_key_up_pushed(input)) {
|
||||||
|
menu_select_cursor_move_up(menu);
|
||||||
|
} else if (input_key_down_pushed(input)) {
|
||||||
|
menu_select_cursor_move_down(menu);
|
||||||
|
} else if (input_key_enter_pushed(input)) {
|
||||||
|
selected_menu_item = menu_item_selected_get(menu);
|
||||||
|
|
||||||
|
switch (selected_menu_item) {
|
||||||
|
case MENU_ITEM_REFRESH_RATE_TEST:
|
||||||
|
if (!refresh_rate_test_init(gfx, 600, 1200 ,&refresh_rate_test)) {
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_screen = INTERACTIVE_SCREEN_REFRESH_RATE_TEST;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_ITEM_RESPONSE_TIME_TEST:
|
||||||
|
if (!response_time_test_init(gfx, &response_time_test)) {
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_screen = INTERACTIVE_SCREEN_RESPONSE_TIME_TEST;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_ITEM_VSYNC_TEST:
|
||||||
|
if (!vsync_test_init(gfx, &vsync_test)) {
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_screen = INTERACTIVE_SCREEN_VSYNC_TEST;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MENU_ITEM_EXIT:
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu_frame_update(menu)) {
|
||||||
|
loop_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTERACTIVE_SCREEN_REFRESH_RATE_TEST:
|
||||||
|
if ( input_key_esc_pushed(input) ||
|
||||||
|
!refresh_rate_test_frame_update(refresh_rate_test)) {
|
||||||
|
current_screen = INTERACTIVE_SCREEN_MENU;
|
||||||
|
refresh_rate_test_fini(refresh_rate_test);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTERACTIVE_SCREEN_RESPONSE_TIME_TEST:
|
||||||
|
if ( input_key_esc_pushed(input) ||
|
||||||
|
!response_time_test_frame_update(response_time_test)) {
|
||||||
|
current_screen = INTERACTIVE_SCREEN_MENU;
|
||||||
|
response_time_test_fini(response_time_test);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTERACTIVE_SCREEN_VSYNC_TEST:
|
||||||
|
if ( input_key_esc_pushed(input) ||
|
||||||
|
!vsync_test_frame_update(vsync_test)) {
|
||||||
|
current_screen = INTERACTIVE_SCREEN_MENU;
|
||||||
|
vsync_test_fini(vsync_test);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_fini(menu);
|
||||||
|
|
||||||
|
gfx_fini(gfx);
|
||||||
|
input_fini(input);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool interactive_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t refresh_rate;
|
||||||
|
bool windowed;
|
||||||
|
bool vsync;
|
||||||
|
|
||||||
|
assert(argv);
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = atoi(argv[0]);
|
||||||
|
height = atoi(argv[1]);
|
||||||
|
refresh_rate = atoi(argv[2]);
|
||||||
|
windowed = false;
|
||||||
|
vsync = true;
|
||||||
|
|
||||||
|
for (int i = 3; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "--windowed")) {
|
||||||
|
windowed = true;
|
||||||
|
} else if (!strcmp(argv[i], "--vsync-off")) {
|
||||||
|
vsync = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _interactive(width, height, refresh_rate, windowed, vsync);
|
||||||
|
}
|
||||||
8
src/main/d3d9-monitor-check/interactive.h
Normal file
8
src/main/d3d9-monitor-check/interactive.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_INTERACTIVE_H
|
||||||
|
#define D3D9_MONITOR_CHECK_INTERACTIVE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool interactive_main(int argc, char **argv);
|
||||||
|
|
||||||
|
#endif
|
||||||
41
src/main/d3d9-monitor-check/main.c
Normal file
41
src/main/d3d9-monitor-check/main.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/cmdline.h"
|
||||||
|
#include "d3d9-monitor-check/interactive.h"
|
||||||
|
#include "d3d9-monitor-check/print-console.h"
|
||||||
|
|
||||||
|
static void _print_synopsis()
|
||||||
|
{
|
||||||
|
printfln_err("D3D9 monitor check tool");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err("A versatile tool for running various (music game relevant) monitor tests using the D3D9 rendering API");
|
||||||
|
printfln_err("");
|
||||||
|
printfln_err("Available commands:");
|
||||||
|
printfln_err(" cmdline: Run the tool in command line mode");
|
||||||
|
printfln_err(" interactive: Run the tool in interactive mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *command;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
_print_synopsis();
|
||||||
|
printfln_err("ERROR: Insufficient arguments");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
command = argv[1];
|
||||||
|
|
||||||
|
if (!strcmp(command, "cmdline")) {
|
||||||
|
success = cmdline_main(argc - 2, argv + 2);
|
||||||
|
} else if (!strcmp(command, "interactive")) {
|
||||||
|
success = interactive_main(argc - 2, argv + 2);
|
||||||
|
} else {
|
||||||
|
_print_synopsis();
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success ? 0 : 1;
|
||||||
|
}
|
||||||
114
src/main/d3d9-monitor-check/menu.c
Normal file
114
src/main/d3d9-monitor-check/menu.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/font.h"
|
||||||
|
#include "d3d9-monitor-check/menu.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
|
||||||
|
typedef struct menu {
|
||||||
|
gfx_t *gfx;
|
||||||
|
font_t *font;
|
||||||
|
menu_item_t current_selected_item;
|
||||||
|
} menu_t;
|
||||||
|
|
||||||
|
bool menu_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
menu_t **menu)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
*menu = xmalloc(sizeof(menu_t));
|
||||||
|
(*menu)->gfx = gfx;
|
||||||
|
(*menu)->current_selected_item = MENU_ITEM_REFRESH_RATE_TEST;
|
||||||
|
|
||||||
|
if (!font_init(gfx, 20, &(*menu)->font)) {
|
||||||
|
free(*menu);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void menu_select_cursor_move_up(menu_t *menu)
|
||||||
|
{
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_REFRESH_RATE_TEST) {
|
||||||
|
menu->current_selected_item = MENU_ITEM_EXIT;
|
||||||
|
} else {
|
||||||
|
menu->current_selected_item--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void menu_select_cursor_move_down(menu_t *menu)
|
||||||
|
{
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_EXIT) {
|
||||||
|
menu->current_selected_item = MENU_ITEM_REFRESH_RATE_TEST;
|
||||||
|
} else {
|
||||||
|
menu->current_selected_item++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_item_t menu_item_selected_get(menu_t *menu)
|
||||||
|
{
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
return menu->current_selected_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool menu_frame_update(menu_t *menu)
|
||||||
|
{
|
||||||
|
font_text_t text;
|
||||||
|
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(menu->gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_begin(menu->font, 10, 10, 10, &text);
|
||||||
|
font_text_white_draw(&text, "D3D9 Monitor Check - Main Menu");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_newline(&text);
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_REFRESH_RATE_TEST) {
|
||||||
|
font_text_white_draw(&text, "-> 1. Refresh Rate Test");
|
||||||
|
} else {
|
||||||
|
font_text_white_draw(&text, " 1. Refresh Rate Test");
|
||||||
|
}
|
||||||
|
font_text_newline(&text);
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_RESPONSE_TIME_TEST) {
|
||||||
|
font_text_white_draw(&text, "-> 2. Response Time Test");
|
||||||
|
} else {
|
||||||
|
font_text_white_draw(&text, " 2. Response Time Test");
|
||||||
|
}
|
||||||
|
font_text_newline(&text);
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_VSYNC_TEST) {
|
||||||
|
font_text_white_draw(&text, "-> 3. VSync Test");
|
||||||
|
} else {
|
||||||
|
font_text_white_draw(&text, " 3. VSync Test");
|
||||||
|
}
|
||||||
|
font_text_newline(&text);
|
||||||
|
if (menu->current_selected_item == MENU_ITEM_EXIT) {
|
||||||
|
font_text_white_draw(&text, "-> 4. Exit");
|
||||||
|
} else {
|
||||||
|
font_text_white_draw(&text, " 4. Exit");
|
||||||
|
}
|
||||||
|
font_text_end(&text);
|
||||||
|
|
||||||
|
gfx_frame_end(menu->gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void menu_fini(menu_t *menu)
|
||||||
|
{
|
||||||
|
assert(menu);
|
||||||
|
|
||||||
|
font_fini(menu->font);
|
||||||
|
|
||||||
|
free(menu);
|
||||||
|
}
|
||||||
32
src/main/d3d9-monitor-check/menu.h
Normal file
32
src/main/d3d9-monitor-check/menu.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_MENU_H
|
||||||
|
#define D3D9_MONITOR_CHECK_MENU_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
typedef enum MENU_ITEM {
|
||||||
|
MENU_ITEM_REFRESH_RATE_TEST = 0,
|
||||||
|
MENU_ITEM_RESPONSE_TIME_TEST = 1,
|
||||||
|
MENU_ITEM_VSYNC_TEST = 2,
|
||||||
|
MENU_ITEM_EXIT = 3,
|
||||||
|
} menu_item_t;
|
||||||
|
|
||||||
|
typedef struct menu menu_t;
|
||||||
|
|
||||||
|
bool menu_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
menu_t **menu);
|
||||||
|
|
||||||
|
void menu_select_cursor_move_up(menu_t *menu);
|
||||||
|
|
||||||
|
void menu_select_cursor_move_down(menu_t *menu);
|
||||||
|
|
||||||
|
menu_item_t menu_item_selected_get(menu_t *menu);
|
||||||
|
|
||||||
|
bool menu_frame_update(menu_t *menu);
|
||||||
|
|
||||||
|
void menu_fini(menu_t *menu);
|
||||||
|
|
||||||
|
#endif
|
||||||
22
src/main/d3d9-monitor-check/print-console.h
Normal file
22
src/main/d3d9-monitor-check/print-console.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef PRINT_CONSOLE_H
|
||||||
|
#define PRINT_CONSOLE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "util/winerr.h"
|
||||||
|
|
||||||
|
#define printf_out(fmt, ...) \
|
||||||
|
fprintf(stdout, fmt, ##__VA_ARGS__)
|
||||||
|
#define printf_err(fmt, ...) \
|
||||||
|
fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||||
|
#define printfln_out(fmt, ...) \
|
||||||
|
fprintf(stdout, fmt "\n", ##__VA_ARGS__)
|
||||||
|
#define printfln_err(fmt, ...) \
|
||||||
|
fprintf(stderr, fmt "\n", ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define printfln_winerr(fmt, ...) \
|
||||||
|
char *winerr = util_winerr_format_last_error_code(); \
|
||||||
|
fprintf(stderr, fmt ": %s\n", ##__VA_ARGS__, winerr); \
|
||||||
|
free(winerr);
|
||||||
|
|
||||||
|
#endif
|
||||||
304
src/main/d3d9-monitor-check/refresh-rate-test.c
Normal file
304
src/main/d3d9-monitor-check/refresh-rate-test.c
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/font.h"
|
||||||
|
#include "d3d9-monitor-check/refresh-rate-test.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
|
||||||
|
typedef enum refresh_rate_test_phase {
|
||||||
|
REFRESH_RATE_TEST_PHASE_WARM_UP = 0,
|
||||||
|
REFRESH_RATE_TEST_PHASE_MEASURE = 1,
|
||||||
|
REFRESH_RATE_TEST_PHASE_DONE = 2
|
||||||
|
} refresh_rate_test_phase_t;
|
||||||
|
|
||||||
|
typedef struct refresh_rate_test_ctx {
|
||||||
|
gfx_t *gfx;
|
||||||
|
font_t *font;
|
||||||
|
uint32_t total_warm_up_frame_count;
|
||||||
|
uint32_t total_sample_frame_count;
|
||||||
|
} refresh_rate_test_ctx_t;
|
||||||
|
|
||||||
|
typedef struct refresh_rate_test_state {
|
||||||
|
gfx_info_t gfx_info;
|
||||||
|
refresh_rate_test_phase_t phase;
|
||||||
|
uint64_t last_frame_time_us;
|
||||||
|
uint32_t warm_up_frame_count;
|
||||||
|
uint32_t sample_frame_count;
|
||||||
|
uint64_t warm_up_elapsed_us;
|
||||||
|
uint64_t sample_elapsed_us;
|
||||||
|
} refresh_rate_test_state_t;
|
||||||
|
|
||||||
|
typedef struct refresh_rate_test {
|
||||||
|
refresh_rate_test_ctx_t ctx;
|
||||||
|
refresh_rate_test_state_t state;
|
||||||
|
} refresh_rate_test_t;
|
||||||
|
|
||||||
|
static refresh_rate_test_phase_t _refresh_rate_test_phase_evaluate(const refresh_rate_test_t *test)
|
||||||
|
{
|
||||||
|
switch (test->state.phase) {
|
||||||
|
case REFRESH_RATE_TEST_PHASE_WARM_UP:
|
||||||
|
if (test->state.warm_up_frame_count < test->ctx.total_warm_up_frame_count) {
|
||||||
|
return REFRESH_RATE_TEST_PHASE_WARM_UP;
|
||||||
|
} else {
|
||||||
|
return REFRESH_RATE_TEST_PHASE_MEASURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REFRESH_RATE_TEST_PHASE_MEASURE:
|
||||||
|
if (test->state.sample_frame_count < test->ctx.total_sample_frame_count) {
|
||||||
|
return REFRESH_RATE_TEST_PHASE_MEASURE;
|
||||||
|
} else {
|
||||||
|
return REFRESH_RATE_TEST_PHASE_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case REFRESH_RATE_TEST_PHASE_DONE:
|
||||||
|
return REFRESH_RATE_TEST_PHASE_DONE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return REFRESH_RATE_TEST_PHASE_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool refresh_rate_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
uint32_t total_warm_up_frame_count,
|
||||||
|
uint32_t total_sample_frame_count,
|
||||||
|
refresh_rate_test_t **test)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
*test = xmalloc(sizeof(refresh_rate_test_t));
|
||||||
|
memset(*test, 0, sizeof(refresh_rate_test_t));
|
||||||
|
|
||||||
|
if (!font_init(gfx, 20, &(*test)->ctx.font)) {
|
||||||
|
free(*test);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_init(gfx, 20, &(*test)->ctx.font);
|
||||||
|
|
||||||
|
(*test)->ctx.gfx = gfx;
|
||||||
|
(*test)->ctx.total_warm_up_frame_count = total_warm_up_frame_count;
|
||||||
|
(*test)->ctx.total_sample_frame_count = total_sample_frame_count;
|
||||||
|
|
||||||
|
(*test)->state.phase = REFRESH_RATE_TEST_PHASE_WARM_UP;
|
||||||
|
(*test)->state.last_frame_time_us = 0;
|
||||||
|
(*test)->state.warm_up_frame_count = 0;
|
||||||
|
(*test)->state.sample_frame_count = 0;
|
||||||
|
(*test)->state.warm_up_elapsed_us = 0;
|
||||||
|
(*test)->state.sample_elapsed_us = 0;
|
||||||
|
|
||||||
|
gfx_info_get(gfx, &(*test)->state.gfx_info);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _refresh_rate_test_phase_warm_up_frame_update(refresh_rate_test_t *test)
|
||||||
|
{
|
||||||
|
font_text_t text;
|
||||||
|
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(test->ctx.gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_begin(test->ctx.font, 0, 10, 10, &text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Refresh Rate Test");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "GPU: %s", test->state.gfx_info.adapter_identifier);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Spec: %d x %d @ %d hz, %s, vsync %s", test->state.gfx_info.width, test->state.gfx_info.height, test->state.gfx_info.refresh_rate,
|
||||||
|
test->state.gfx_info.windowed ? "windowed" : "fullscreen", test->state.gfx_info.vsync ? "on" : "off");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
// First frame won't have any data available causing division by zero in the stats
|
||||||
|
if (test->state.warm_up_frame_count != 0) {
|
||||||
|
font_text_white_draw(&text, "Status: Warm-up in progress ...");
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Frame: %d / %d", test->state.warm_up_frame_count, test->ctx.total_warm_up_frame_count);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Last frame time: %.3f ms", test->state.last_frame_time_us / 1000.0f);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg frame time: %.3f ms", test->state.warm_up_elapsed_us / test->state.warm_up_frame_count / 1000.0f);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Last refresh rate: %.3f Hz", 1000.0f / (test->state.last_frame_time_us / 1000.0f));
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg refresh rate: %.3f Hz", 1000.0f / (test->state.warm_up_elapsed_us / test->state.warm_up_frame_count / 1000.0f));
|
||||||
|
font_text_newline(&text);
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Press ESC to exit early");
|
||||||
|
|
||||||
|
font_text_end(&text);
|
||||||
|
|
||||||
|
gfx_frame_end(test->ctx.gfx);
|
||||||
|
|
||||||
|
test->state.last_frame_time_us = gfx_last_frame_time_us_get(test->ctx.gfx);
|
||||||
|
test->state.warm_up_elapsed_us += test->state.last_frame_time_us;
|
||||||
|
test->state.warm_up_frame_count++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _refresh_rate_test_phase_measure_frame_update(refresh_rate_test_t *test)
|
||||||
|
{
|
||||||
|
font_text_t text;
|
||||||
|
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(test->ctx.gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_begin(test->ctx.font, 0, 10, 10, &text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Refresh Rate Test");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "GPU: %s", test->state.gfx_info.adapter_identifier);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Spec: %d x %d @ %d hz, %s, vsync %s", test->state.gfx_info.width, test->state.gfx_info.height, test->state.gfx_info.refresh_rate,
|
||||||
|
test->state.gfx_info.windowed ? "windowed" : "fullscreen", test->state.gfx_info.vsync ? "on" : "off");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
// First frame won't have any data available causing division by zero in the stats
|
||||||
|
if (test->state.sample_frame_count != 0) {
|
||||||
|
font_text_white_draw(&text, "Status: Measuring in progress ...");
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Frame: %d / %d", test->state.sample_frame_count, test->ctx.total_sample_frame_count);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Last frame time: %.3f ms", test->state.last_frame_time_us / 1000.0f);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg frame time: %.3f ms", test->state.sample_elapsed_us / test->state.sample_frame_count / 1000.0f);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Last refresh rate: %.3f Hz", 1000.0f / (test->state.last_frame_time_us / 1000.0f));
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg refresh rate: %.3f Hz", 1000.0f / (test->state.sample_elapsed_us / test->state.sample_frame_count / 1000.0f));
|
||||||
|
font_text_newline(&text);
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Press ESC to exit early");
|
||||||
|
|
||||||
|
font_text_end(&text);
|
||||||
|
|
||||||
|
gfx_frame_end(test->ctx.gfx);
|
||||||
|
|
||||||
|
test->state.last_frame_time_us = gfx_last_frame_time_us_get(test->ctx.gfx);
|
||||||
|
test->state.sample_elapsed_us += test->state.last_frame_time_us;
|
||||||
|
test->state.sample_frame_count++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool refresh_rate_test_frame_update(refresh_rate_test_t *test)
|
||||||
|
{
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
test->state.phase = _refresh_rate_test_phase_evaluate(test);
|
||||||
|
|
||||||
|
switch (test->state.phase) {
|
||||||
|
case REFRESH_RATE_TEST_PHASE_WARM_UP:
|
||||||
|
return _refresh_rate_test_phase_warm_up_frame_update(test);
|
||||||
|
|
||||||
|
case REFRESH_RATE_TEST_PHASE_MEASURE:
|
||||||
|
return _refresh_rate_test_phase_measure_frame_update(test);
|
||||||
|
|
||||||
|
case REFRESH_RATE_TEST_PHASE_DONE:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh_rate_test_results_get(const refresh_rate_test_t *test, refresh_rate_test_results_t *results)
|
||||||
|
{
|
||||||
|
assert(test);
|
||||||
|
assert(results);
|
||||||
|
|
||||||
|
results->total_warm_up_frame_count = test->state.warm_up_frame_count;
|
||||||
|
results->total_sample_frame_count = test->state.sample_frame_count;
|
||||||
|
|
||||||
|
if (test->state.sample_elapsed_us > 0 && test->state.sample_frame_count > 0) {
|
||||||
|
results->avg_frame_time_ms = test->state.sample_elapsed_us / test->state.sample_frame_count / 1000.0f;
|
||||||
|
results->avg_refresh_rate_hz = 1000.0f / results->avg_frame_time_ms;
|
||||||
|
} else {
|
||||||
|
results->avg_frame_time_ms = 0;
|
||||||
|
results->avg_refresh_rate_hz = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool refresh_rate_test_results_frame_update(refresh_rate_test_t *test, uint32_t results_timeout_seconds)
|
||||||
|
{
|
||||||
|
refresh_rate_test_results_t results;
|
||||||
|
font_text_t text;
|
||||||
|
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(test->ctx.gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_rate_test_results_get(test, &results);
|
||||||
|
|
||||||
|
font_text_begin(test->ctx.font, 0, 10, 10, &text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Refresh Rate Test");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "GPU: %s", test->state.gfx_info.adapter_identifier);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Spec: %d x %d @ %d hz, %s, vsync %s", test->state.gfx_info.width, test->state.gfx_info.height, test->state.gfx_info.refresh_rate,
|
||||||
|
test->state.gfx_info.windowed ? "windowed" : "fullscreen", test->state.gfx_info.vsync ? "on" : "off");
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
if (test->ctx.total_warm_up_frame_count != test->state.warm_up_frame_count ||
|
||||||
|
test->ctx.total_sample_frame_count != test->state.sample_frame_count) {
|
||||||
|
font_text_white_draw(&text, "Status: Warning, exited early");
|
||||||
|
} else {
|
||||||
|
font_text_white_draw(&text, "Status: Completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Total warm-up frame count: %d", results.total_warm_up_frame_count);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Total sample frame count: %d", results.total_sample_frame_count);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg frame time: %.3f ms", results.avg_frame_time_ms);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Avg refresh rate: %.3f Hz", results.avg_refresh_rate_hz);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_newline(&text);
|
||||||
|
|
||||||
|
font_text_white_draw(&text, "Exiting in %d seconds ...", results_timeout_seconds);
|
||||||
|
font_text_newline(&text);
|
||||||
|
font_text_white_draw(&text, "Press ESC to exit immediately");
|
||||||
|
|
||||||
|
font_text_end(&text);
|
||||||
|
|
||||||
|
gfx_frame_end(test->ctx.gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh_rate_test_fini(refresh_rate_test_t *test)
|
||||||
|
{
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
font_fini(test->ctx.font);
|
||||||
|
|
||||||
|
free(test);
|
||||||
|
}
|
||||||
32
src/main/d3d9-monitor-check/refresh-rate-test.h
Normal file
32
src/main/d3d9-monitor-check/refresh-rate-test.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_REFRESH_RATE_TEST_H
|
||||||
|
#define D3D9_MONITOR_CHECK_REFRESH_RATE_TEST_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
typedef struct refresh_rate_test_results_t {
|
||||||
|
uint32_t total_warm_up_frame_count;
|
||||||
|
uint32_t total_sample_frame_count;
|
||||||
|
double avg_frame_time_ms;
|
||||||
|
double avg_refresh_rate_hz;
|
||||||
|
} refresh_rate_test_results_t;
|
||||||
|
|
||||||
|
typedef struct refresh_rate_test refresh_rate_test_t;
|
||||||
|
|
||||||
|
bool refresh_rate_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
uint32_t total_warm_up_frame_count,
|
||||||
|
uint32_t total_sample_frame_count,
|
||||||
|
refresh_rate_test_t **test);
|
||||||
|
|
||||||
|
bool refresh_rate_test_frame_update(refresh_rate_test_t *test);
|
||||||
|
|
||||||
|
void refresh_rate_test_results_get(const refresh_rate_test_t *test, refresh_rate_test_results_t *results);
|
||||||
|
|
||||||
|
bool refresh_rate_test_results_frame_update(refresh_rate_test_t *test, uint32_t results_timeout_seconds);
|
||||||
|
|
||||||
|
void refresh_rate_test_fini(refresh_rate_test_t *test);
|
||||||
|
|
||||||
|
#endif
|
||||||
123
src/main/d3d9-monitor-check/response-time-test.c
Normal file
123
src/main/d3d9-monitor-check/response-time-test.c
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <d3d9.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
|
#define DEFAULT_SCROLL_SPEED_PX_PER_SEC 200.0f
|
||||||
|
#define DEFAULT_BLOCK_DISTANCE_PX 50
|
||||||
|
#define RECT_WIDTH_PX 80
|
||||||
|
#define RECT_HEIGHT_PX 20
|
||||||
|
|
||||||
|
typedef struct response_time_test {
|
||||||
|
gfx_t *gfx;
|
||||||
|
float scroll_speed_px_per_sec;
|
||||||
|
uint32_t block_distance_px;
|
||||||
|
float current_y_pos;
|
||||||
|
} response_time_test_t;
|
||||||
|
|
||||||
|
bool response_time_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
response_time_test_t **test)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
*test = xmalloc(sizeof(response_time_test_t));
|
||||||
|
|
||||||
|
(*test)->gfx = gfx;
|
||||||
|
(*test)->scroll_speed_px_per_sec = DEFAULT_SCROLL_SPEED_PX_PER_SEC;
|
||||||
|
(*test)->block_distance_px = DEFAULT_BLOCK_DISTANCE_PX;
|
||||||
|
(*test)->current_y_pos = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool response_time_test_frame_update(response_time_test_t *test)
|
||||||
|
{
|
||||||
|
IDirect3DDevice9 *device;
|
||||||
|
uint32_t screen_height;
|
||||||
|
uint32_t screen_width;
|
||||||
|
float delta_time;
|
||||||
|
D3DRECT rect_white;
|
||||||
|
D3DRECT rect_blue;
|
||||||
|
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
device = gfx_device_get(test->gfx);
|
||||||
|
screen_width = gfx_width_get(test->gfx);
|
||||||
|
screen_height = gfx_height_get(test->gfx);
|
||||||
|
|
||||||
|
delta_time = gfx_last_frame_time_us_get(test->gfx) / 1000000.0f;
|
||||||
|
|
||||||
|
// Update position
|
||||||
|
test->current_y_pos += test->scroll_speed_px_per_sec * delta_time;
|
||||||
|
|
||||||
|
// Loop position when rectangles are off screen
|
||||||
|
if (test->current_y_pos > screen_height + RECT_HEIGHT_PX) {
|
||||||
|
test->current_y_pos = -RECT_HEIGHT_PX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate rectangle positions
|
||||||
|
rect_white.x1 = (screen_width / 2) - RECT_WIDTH_PX - 10;
|
||||||
|
rect_white.x2 = rect_white.x1 + RECT_WIDTH_PX;
|
||||||
|
rect_white.y1 = (int) test->current_y_pos;
|
||||||
|
rect_white.y2 = rect_white.y1 + RECT_HEIGHT_PX;
|
||||||
|
|
||||||
|
rect_blue.x1 = (screen_width / 2) + 10;
|
||||||
|
rect_blue.x2 = rect_blue.x1 + RECT_WIDTH_PX;
|
||||||
|
rect_blue.y1 = (int) test->current_y_pos + test->block_distance_px;
|
||||||
|
rect_blue.y2 = rect_blue.y1 + RECT_HEIGHT_PX;
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(test->gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background
|
||||||
|
IDirect3DDevice9_Clear(
|
||||||
|
device,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
D3DCLEAR_TARGET,
|
||||||
|
D3DCOLOR_XRGB(128, 128, 128),
|
||||||
|
1.0f,
|
||||||
|
0);
|
||||||
|
|
||||||
|
// White rectangle
|
||||||
|
IDirect3DDevice9_Clear(
|
||||||
|
device,
|
||||||
|
1,
|
||||||
|
&rect_white,
|
||||||
|
D3DCLEAR_TARGET,
|
||||||
|
D3DCOLOR_XRGB(255, 255, 255),
|
||||||
|
1.0f,
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Blue rectangle
|
||||||
|
IDirect3DDevice9_Clear(
|
||||||
|
device,
|
||||||
|
1,
|
||||||
|
&rect_blue,
|
||||||
|
D3DCLEAR_TARGET,
|
||||||
|
D3DCOLOR_XRGB(0, 0, 255),
|
||||||
|
1.0f,
|
||||||
|
0);
|
||||||
|
|
||||||
|
gfx_frame_end(test->gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void response_time_test_fini(response_time_test_t *test)
|
||||||
|
{
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
free(test);
|
||||||
|
}
|
||||||
19
src/main/d3d9-monitor-check/response-time-test.h
Normal file
19
src/main/d3d9-monitor-check/response-time-test.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_RESPONSE_TIME_TEST_H
|
||||||
|
#define D3D9_MONITOR_CHECK_RESPONSE_TIME_TEST_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
typedef struct response_time_test response_time_test_t;
|
||||||
|
|
||||||
|
bool response_time_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
response_time_test_t **test);
|
||||||
|
|
||||||
|
bool response_time_test_frame_update(response_time_test_t *test);
|
||||||
|
|
||||||
|
void response_time_test_fini(response_time_test_t *test);
|
||||||
|
|
||||||
|
#endif // D3D9_MONITOR_CHECK_RESPONSE_TIME_TEST_H
|
||||||
69
src/main/d3d9-monitor-check/vsync-test.c
Normal file
69
src/main/d3d9-monitor-check/vsync-test.c
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
#include "d3d9-monitor-check/font.h"
|
||||||
|
|
||||||
|
#include "util/mem.h"
|
||||||
|
|
||||||
|
typedef struct vsync_test {
|
||||||
|
gfx_t *gfx;
|
||||||
|
font_t *font;
|
||||||
|
} vsync_test_t;
|
||||||
|
|
||||||
|
bool vsync_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
vsync_test_t **test)
|
||||||
|
{
|
||||||
|
assert(gfx);
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
*test = xmalloc(sizeof(vsync_test_t));
|
||||||
|
memset(*test, 0, sizeof(vsync_test_t));
|
||||||
|
|
||||||
|
if (!font_init(gfx, 160, &(*test)->font)) {
|
||||||
|
free(*test);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*test)->gfx = gfx;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vsync_test_frame_update(vsync_test_t *test)
|
||||||
|
{
|
||||||
|
uint64_t frame_count;
|
||||||
|
font_text_t text;
|
||||||
|
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
frame_count = gfx_last_frame_count_get(test->gfx);
|
||||||
|
|
||||||
|
if (!gfx_frame_begin(test->gfx)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_begin(test->font, 0, 80, 80, &text);
|
||||||
|
|
||||||
|
if (frame_count % 2 == 0) {
|
||||||
|
font_text_red_draw(&text, "VSYNC");
|
||||||
|
} else {
|
||||||
|
font_text_cyan_draw(&text, "VSYNC");
|
||||||
|
}
|
||||||
|
|
||||||
|
font_text_end(&text);
|
||||||
|
|
||||||
|
gfx_frame_end(test->gfx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vsync_test_fini(vsync_test_t *test)
|
||||||
|
{
|
||||||
|
assert(test);
|
||||||
|
|
||||||
|
font_fini(test->font);
|
||||||
|
free(test);
|
||||||
|
}
|
||||||
19
src/main/d3d9-monitor-check/vsync-test.h
Normal file
19
src/main/d3d9-monitor-check/vsync-test.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef D3D9_MONITOR_CHECK_VSYNC_TEST_H
|
||||||
|
#define D3D9_MONITOR_CHECK_VSYNC_TEST_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "d3d9-monitor-check/gfx.h"
|
||||||
|
|
||||||
|
typedef struct vsync_test vsync_test_t;
|
||||||
|
|
||||||
|
bool vsync_test_init(
|
||||||
|
gfx_t *gfx,
|
||||||
|
vsync_test_t **test);
|
||||||
|
|
||||||
|
bool vsync_test_frame_update(vsync_test_t *test);
|
||||||
|
|
||||||
|
void vsync_test_fini(vsync_test_t *test);
|
||||||
|
|
||||||
|
#endif // D3D9_MONITOR_CHECK_VSYNC_TEST_H
|
||||||
@@ -15,12 +15,21 @@ static const size_t apiset_prefix_len = sizeof(apiset_prefix) - 1;
|
|||||||
static void hook_table_apply_to_all(
|
static void hook_table_apply_to_all(
|
||||||
const char *depname, const struct hook_symbol *syms, size_t nsyms);
|
const char *depname, const struct hook_symbol *syms, size_t nsyms);
|
||||||
|
|
||||||
|
static void hook_table_revert_to_all(
|
||||||
|
const char *depname, const struct hook_symbol *syms, size_t nsyms);
|
||||||
|
|
||||||
static void hook_table_apply_to_iid(
|
static void hook_table_apply_to_iid(
|
||||||
HMODULE target,
|
HMODULE target,
|
||||||
const pe_iid_t *iid,
|
const pe_iid_t *iid,
|
||||||
const struct hook_symbol *syms,
|
const struct hook_symbol *syms,
|
||||||
size_t nsyms);
|
size_t nsyms);
|
||||||
|
|
||||||
|
static void hook_table_revert_to_iid(
|
||||||
|
HMODULE target,
|
||||||
|
const pe_iid_t *iid,
|
||||||
|
const struct hook_symbol *syms,
|
||||||
|
size_t nsyms);
|
||||||
|
|
||||||
static bool hook_table_match_module(
|
static bool hook_table_match_module(
|
||||||
HMODULE target, const char *iid_name, const char *depname);
|
HMODULE target, const char *iid_name, const char *depname);
|
||||||
|
|
||||||
@@ -44,6 +53,23 @@ static void hook_table_apply_to_all(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hook_table_revert_to_all(
|
||||||
|
const char *depname, const struct hook_symbol *syms, size_t nsyms)
|
||||||
|
{
|
||||||
|
const peb_dll_t *dll;
|
||||||
|
HMODULE pe;
|
||||||
|
|
||||||
|
for (dll = peb_dll_get_first(); dll != NULL; dll = peb_dll_get_next(dll)) {
|
||||||
|
pe = peb_dll_get_base(dll);
|
||||||
|
|
||||||
|
if (pe == NULL) {
|
||||||
|
continue; /* ?? Happens sometimes. */
|
||||||
|
}
|
||||||
|
|
||||||
|
hook_table_revert(pe, depname, syms, nsyms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void hook_table_apply(
|
void hook_table_apply(
|
||||||
HMODULE target,
|
HMODULE target,
|
||||||
const char *depname,
|
const char *depname,
|
||||||
@@ -73,6 +99,35 @@ void hook_table_apply(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hook_table_revert(
|
||||||
|
HMODULE target,
|
||||||
|
const char *depname,
|
||||||
|
const struct hook_symbol *syms,
|
||||||
|
size_t nsyms)
|
||||||
|
{
|
||||||
|
const pe_iid_t *iid;
|
||||||
|
const char *iid_name;
|
||||||
|
|
||||||
|
assert(depname != NULL);
|
||||||
|
assert(syms != NULL || nsyms == 0);
|
||||||
|
|
||||||
|
if (target == NULL) {
|
||||||
|
/* Call out, which will then call us back repeatedly. Awkward, but
|
||||||
|
viewed from the outside it's good for usability. */
|
||||||
|
|
||||||
|
hook_table_revert_to_all(depname, syms, nsyms);
|
||||||
|
} else {
|
||||||
|
for (iid = pe_iid_get_first(target); iid != NULL;
|
||||||
|
iid = pe_iid_get_next(target, iid)) {
|
||||||
|
iid_name = pe_iid_get_name(target, iid);
|
||||||
|
|
||||||
|
if (hook_table_match_module(target, iid_name, depname)) {
|
||||||
|
hook_table_revert_to_iid(target, iid, syms, nsyms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void hook_table_apply_to_iid(
|
static void hook_table_apply_to_iid(
|
||||||
HMODULE target,
|
HMODULE target,
|
||||||
const pe_iid_t *iid,
|
const pe_iid_t *iid,
|
||||||
@@ -101,6 +156,33 @@ static void hook_table_apply_to_iid(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hook_table_revert_to_iid(
|
||||||
|
HMODULE target,
|
||||||
|
const pe_iid_t *iid,
|
||||||
|
const struct hook_symbol *syms,
|
||||||
|
size_t nsyms)
|
||||||
|
{
|
||||||
|
struct pe_iat_entry iate;
|
||||||
|
size_t i;
|
||||||
|
size_t j;
|
||||||
|
const struct hook_symbol *sym;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (pe_iid_get_iat_entry(target, iid, i++, &iate) == S_OK) {
|
||||||
|
for (j = 0; j < nsyms; j++) {
|
||||||
|
sym = &syms[j];
|
||||||
|
|
||||||
|
if (hook_table_match_proc(&iate, sym)) {
|
||||||
|
// Only revert-able if the original pointer was stored previously
|
||||||
|
if (sym->link != NULL && *sym->link != NULL) {
|
||||||
|
pe_patch(iate.ppointer, sym->link, sizeof(*sym->link));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool hook_table_match_module(
|
static bool hook_table_match_module(
|
||||||
HMODULE target, const char *iid_name, const char *depname)
|
HMODULE target, const char *iid_name, const char *depname)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ src_iidxhook-util := \
|
|||||||
acio.c \
|
acio.c \
|
||||||
chart-patch.c \
|
chart-patch.c \
|
||||||
clock.c \
|
clock.c \
|
||||||
config-debug.c \
|
|
||||||
config-eamuse.c \
|
config-eamuse.c \
|
||||||
config-ezusb.c \
|
config-ezusb.c \
|
||||||
config-gfx.c \
|
config-gfx.c \
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#include "cconfig/cconfig-util.h"
|
|
||||||
|
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
|
|
||||||
#include "util/log.h"
|
|
||||||
|
|
||||||
#define IIDXHOOK_CONFIG_DEBUG_ENABLE_FRAME_PERF_GRAPH_KEY "debug.enable_frame_perf_graph"
|
|
||||||
|
|
||||||
#define IIDXHOOK_CONFIG_DEBUG_DEFAULT_ENABLE_FRAME_PERF_GRAPH_VALUE false
|
|
||||||
|
|
||||||
void iidxhook_config_debug_init(struct cconfig *config)
|
|
||||||
{
|
|
||||||
cconfig_util_set_bool(
|
|
||||||
config,
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_ENABLE_FRAME_PERF_GRAPH_KEY,
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_DEFAULT_ENABLE_FRAME_PERF_GRAPH_VALUE,
|
|
||||||
"Enable frame performance graph overlay");
|
|
||||||
}
|
|
||||||
|
|
||||||
void iidxhook_config_debug_get(
|
|
||||||
struct iidxhook_config_debug *config_debug, struct cconfig *config)
|
|
||||||
{
|
|
||||||
if (!cconfig_util_get_bool(
|
|
||||||
config,
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_ENABLE_FRAME_PERF_GRAPH_KEY,
|
|
||||||
&config_debug->enable_frame_perf_graph,
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_DEFAULT_ENABLE_FRAME_PERF_GRAPH_VALUE)) {
|
|
||||||
log_warning(
|
|
||||||
"Invalid value for key '%s' specified, fallback "
|
|
||||||
"to default '%d'",
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_ENABLE_FRAME_PERF_GRAPH_KEY,
|
|
||||||
IIDXHOOK_CONFIG_DEBUG_DEFAULT_ENABLE_FRAME_PERF_GRAPH_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#ifndef IIDXHOOK_CONFIG_DEBUG_H
|
|
||||||
#define IIDXHOOK_CONFIG_DEBUG_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "cconfig/cconfig.h"
|
|
||||||
|
|
||||||
struct iidxhook_config_debug {
|
|
||||||
bool enable_frame_perf_graph;
|
|
||||||
};
|
|
||||||
|
|
||||||
void iidxhook_config_debug_init(struct cconfig *config);
|
|
||||||
|
|
||||||
void iidxhook_config_debug_get(
|
|
||||||
struct iidxhook_config_debug *config_debug, struct cconfig *config);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -232,7 +232,7 @@ iidxhook_util_d3d9_log_create_device_params(struct hook_d3d9_irp *irp)
|
|||||||
"hDeviceWindow %p, Windowed %d, "
|
"hDeviceWindow %p, Windowed %d, "
|
||||||
"EnableAutoDepthStencil "
|
"EnableAutoDepthStencil "
|
||||||
"%d, AutoDepthStencilFormat %d, Flags %lX, "
|
"%d, AutoDepthStencilFormat %d, Flags %lX, "
|
||||||
"FullScreen_RefreshRateInHz %d",
|
"FullScreen_RefreshRateInHz %d, PresentationInterval %d",
|
||||||
irp->args.ctx_create_device.pp->BackBufferWidth,
|
irp->args.ctx_create_device.pp->BackBufferWidth,
|
||||||
irp->args.ctx_create_device.pp->BackBufferHeight,
|
irp->args.ctx_create_device.pp->BackBufferHeight,
|
||||||
irp->args.ctx_create_device.pp->BackBufferFormat,
|
irp->args.ctx_create_device.pp->BackBufferFormat,
|
||||||
@@ -244,7 +244,13 @@ iidxhook_util_d3d9_log_create_device_params(struct hook_d3d9_irp *irp)
|
|||||||
irp->args.ctx_create_device.pp->EnableAutoDepthStencil,
|
irp->args.ctx_create_device.pp->EnableAutoDepthStencil,
|
||||||
irp->args.ctx_create_device.pp->AutoDepthStencilFormat,
|
irp->args.ctx_create_device.pp->AutoDepthStencilFormat,
|
||||||
irp->args.ctx_create_device.pp->Flags,
|
irp->args.ctx_create_device.pp->Flags,
|
||||||
irp->args.ctx_create_device.pp->FullScreen_RefreshRateInHz);
|
irp->args.ctx_create_device.pp->FullScreen_RefreshRateInHz,
|
||||||
|
irp->args.ctx_create_device.pp->PresentationInterval);
|
||||||
|
|
||||||
|
if (irp->args.ctx_create_device.pp->PresentationInterval != D3DPRESENT_INTERVAL_ONE) {
|
||||||
|
log_warning("PresentationInterval is not 1, i.e. VSYNC is OFF (!): %d",
|
||||||
|
irp->args.ctx_create_device.pp->PresentationInterval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -18,12 +18,10 @@
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static unsigned long STDCALL my_inet_addr(const char *cp);
|
|
||||||
static int STDCALL
|
static int STDCALL
|
||||||
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen);
|
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen);
|
||||||
static struct hostent FAR *STDCALL my_gethostbyname(const char *nameB);
|
static struct hostent FAR *STDCALL my_gethostbyname(const char *nameB);
|
||||||
|
|
||||||
static unsigned long(STDCALL *real_inet_addr)(const char *cp);
|
|
||||||
static int(STDCALL *real_connect)(
|
static int(STDCALL *real_connect)(
|
||||||
SOCKET s, const struct sockaddr *addr, int addrlen);
|
SOCKET s, const struct sockaddr *addr, int addrlen);
|
||||||
static struct hostent FAR *(STDCALL *real_gethostbyname)(const char *nameB);
|
static struct hostent FAR *(STDCALL *real_gethostbyname)(const char *nameB);
|
||||||
@@ -33,10 +31,6 @@ static const struct hook_symbol eamuse_hook_syms[] = {
|
|||||||
/* WS2_32.DLL's SDK import lib generates ordinal imports, so these
|
/* WS2_32.DLL's SDK import lib generates ordinal imports, so these
|
||||||
ordinals are a frozen aspect of the Win32 ABI. */
|
ordinals are a frozen aspect of the Win32 ABI. */
|
||||||
|
|
||||||
{.name = "inet_addr",
|
|
||||||
.ordinal = 11,
|
|
||||||
.patch = my_inet_addr,
|
|
||||||
.link = (void **) &real_inet_addr},
|
|
||||||
{.name = "connect",
|
{.name = "connect",
|
||||||
.ordinal = 4,
|
.ordinal = 4,
|
||||||
.patch = my_connect,
|
.patch = my_connect,
|
||||||
@@ -54,26 +48,6 @@ static struct net_addr eamuse_server_addr_resolved;
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static unsigned long STDCALL my_inet_addr(const char *cp)
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
|
|
||||||
/* for a stock machine connected to the eamuse router,
|
|
||||||
the game wants to connect to the standard domain
|
|
||||||
services.konami.eamuse.fun
|
|
||||||
depending on the router you got, it will be services.hostname.my.router
|
|
||||||
so we catch that and turn it into any ip we want */
|
|
||||||
|
|
||||||
/* bugfix win10: don't just catch services.konami... because
|
|
||||||
win10 is doing some weird stuff and this call also contains
|
|
||||||
various IP addresses. Always return the server address */
|
|
||||||
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
|
|
||||||
log_misc("my_inet_addr: '%s' -> %s", cp, tmp);
|
|
||||||
free(tmp);
|
|
||||||
|
|
||||||
return eamuse_server_addr_resolved.ipv4.addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int STDCALL
|
static int STDCALL
|
||||||
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
|
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
|
||||||
{
|
{
|
||||||
@@ -102,14 +76,13 @@ my_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
|
|||||||
|
|
||||||
static struct hostent FAR *STDCALL my_gethostbyname(const char *name)
|
static struct hostent FAR *STDCALL my_gethostbyname(const char *name)
|
||||||
{
|
{
|
||||||
|
// IIDX 9-13 use the `services` domain (not `services.eamuse.konami.fun`).
|
||||||
|
if (strcmp(name, "services") != 0) {
|
||||||
|
return real_gethostbyname(name);
|
||||||
|
}
|
||||||
|
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
/* for doc, checkout the other detour of inetaddr above
|
|
||||||
this call is used starting GOLD (not used on pre GOLD) */
|
|
||||||
|
|
||||||
/* bugfix win10: don't just catch services.konami... because
|
|
||||||
win10 is doing some weird stuff and this call also contains
|
|
||||||
various IP addresses. Always return the server address */
|
|
||||||
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
|
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
|
||||||
log_misc("my_gethostbyname: '%s' to ip %s", name, tmp);
|
log_misc("my_gethostbyname: '%s' to ip %s", name, tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook various calls resolving the service address to connect to
|
* Hook various calls resolving the service address to connect to
|
||||||
* the eamuse server for the old IIDX games (9th to Sirius)
|
* the eamuse server for the old IIDX games (9th to DistorteD)
|
||||||
*/
|
*/
|
||||||
void eamuse_hook_init(void);
|
void eamuse_hook_init(void);
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ dlls += iidxhook1
|
|||||||
ldflags_iidxhook1 := \
|
ldflags_iidxhook1 := \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
libs_iidxhook1 := \
|
libs_iidxhook1 := \
|
||||||
iidxhook-util \
|
iidxhook-util \
|
||||||
@@ -21,9 +18,6 @@ libs_iidxhook1 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook1 := \
|
src_iidxhook1 := \
|
||||||
config-iidxhook1.c \
|
config-iidxhook1.c \
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/clock.h"
|
#include "iidxhook-util/clock.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-eamuse.h"
|
#include "iidxhook-util/config-eamuse.h"
|
||||||
#include "iidxhook-util/config-ezusb.h"
|
#include "iidxhook-util/config-ezusb.h"
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
@@ -42,10 +41,6 @@
|
|||||||
#include "iidxhook1/ezusb-mon.h"
|
#include "iidxhook1/ezusb-mon.h"
|
||||||
#include "iidxhook1/log-ezusb.h"
|
#include "iidxhook1/log-ezusb.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "util/defs.h"
|
#include "util/defs.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
@@ -58,7 +53,6 @@
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
||||||
@@ -74,17 +68,6 @@ static const struct hook_symbol init_hook_syms[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void iidxhook1_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iidxhook1_setup_d3d9_hooks(
|
static void iidxhook1_setup_d3d9_hooks(
|
||||||
const struct iidxhook_config_gfx *config_gfx,
|
const struct iidxhook_config_gfx *config_gfx,
|
||||||
const struct iidxhook_config_iidxhook1 *config_iidxhook1)
|
const struct iidxhook_config_iidxhook1 *config_iidxhook1)
|
||||||
@@ -142,7 +125,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_util_config_ezusb config_ezusb;
|
struct iidxhook_util_config_ezusb config_ezusb;
|
||||||
struct iidxhook_util_config_eamuse config_eamuse;
|
struct iidxhook_util_config_eamuse config_eamuse;
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
@@ -162,7 +144,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_util_config_ezusb_init(config);
|
iidxhook_util_config_ezusb_init(config);
|
||||||
iidxhook_util_config_eamuse_init(config);
|
iidxhook_util_config_eamuse_init(config);
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
@@ -178,7 +159,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_util_config_ezusb_get(&config_ezusb, config);
|
iidxhook_util_config_ezusb_get(&config_ezusb, config);
|
||||||
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
@@ -222,8 +202,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
settings_hook_set_path(config_misc.settings_path);
|
settings_hook_set_path(config_misc.settings_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook1_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
/* Direct3D and USER32 hooks */
|
/* Direct3D and USER32 hooks */
|
||||||
|
|
||||||
iidxhook1_setup_d3d9_hooks(&config_gfx, &config_iidxhook1);
|
iidxhook1_setup_d3d9_hooks(&config_gfx, &config_iidxhook1);
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ avsdlls += iidxhook2
|
|||||||
ldflags_iidxhook2 := \
|
ldflags_iidxhook2 := \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
libs_iidxhook2 := \
|
libs_iidxhook2 := \
|
||||||
iidxhook-util \
|
iidxhook-util \
|
||||||
@@ -21,9 +18,6 @@ libs_iidxhook2 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook2 := \
|
src_iidxhook2 := \
|
||||||
config-iidxhook2.c \
|
config-iidxhook2.c \
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/clock.h"
|
#include "iidxhook-util/clock.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-eamuse.h"
|
#include "iidxhook-util/config-eamuse.h"
|
||||||
#include "iidxhook-util/config-ezusb.h"
|
#include "iidxhook-util/config-ezusb.h"
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
@@ -42,10 +41,6 @@
|
|||||||
|
|
||||||
#include "iidxhook2/config-iidxhook2.h"
|
#include "iidxhook2/config-iidxhook2.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
|
||||||
@@ -57,7 +52,6 @@
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
||||||
@@ -71,17 +65,6 @@ static const struct hook_symbol init_hook_syms[] = {
|
|||||||
.link = (void **) &real_OpenProcess},
|
.link = (void **) &real_OpenProcess},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void iidxhook2_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iidxhook2_setup_d3d9_hooks(
|
static void iidxhook2_setup_d3d9_hooks(
|
||||||
const struct iidxhook_config_gfx *config_gfx,
|
const struct iidxhook_config_gfx *config_gfx,
|
||||||
const struct iidxhook_config_iidxhook2 *config_iidxhook2)
|
const struct iidxhook_config_iidxhook2 *config_iidxhook2)
|
||||||
@@ -139,7 +122,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_util_config_ezusb config_ezusb;
|
struct iidxhook_util_config_ezusb config_ezusb;
|
||||||
struct iidxhook_util_config_eamuse config_eamuse;
|
struct iidxhook_util_config_eamuse config_eamuse;
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
@@ -159,7 +141,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_util_config_ezusb_init(config);
|
iidxhook_util_config_ezusb_init(config);
|
||||||
iidxhook_util_config_eamuse_init(config);
|
iidxhook_util_config_eamuse_init(config);
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
@@ -175,7 +156,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_util_config_ezusb_get(&config_ezusb, config);
|
iidxhook_util_config_ezusb_get(&config_ezusb, config);
|
||||||
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
@@ -214,8 +194,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
settings_hook_set_path(config_misc.settings_path);
|
settings_hook_set_path(config_misc.settings_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook2_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
/* Direct3D and USER32 hooks */
|
/* Direct3D and USER32 hooks */
|
||||||
|
|
||||||
iidxhook2_setup_d3d9_hooks(&config_gfx, &config_iidxhook2);
|
iidxhook2_setup_d3d9_hooks(&config_gfx, &config_iidxhook2);
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ avsdlls += iidxhook3
|
|||||||
ldflags_iidxhook3 := \
|
ldflags_iidxhook3 := \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
deplibs_iidxhook3 := \
|
||||||
-lgdi32 \
|
avs \
|
||||||
|
|
||||||
libs_iidxhook3 := \
|
libs_iidxhook3 := \
|
||||||
iidxhook-util \
|
iidxhook-util \
|
||||||
iidxhook-d3d9 \
|
|
||||||
ezusb-emu \
|
ezusb-emu \
|
||||||
ezusb-iidx-16seg-emu \
|
ezusb-iidx-16seg-emu \
|
||||||
ezusb2-emu \
|
ezusb2-emu \
|
||||||
@@ -24,9 +23,7 @@ libs_iidxhook3 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook3 := \
|
src_iidxhook3 := \
|
||||||
|
avs-boot.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
178
src/main/iidxhook3/avs-boot.c
Normal file
178
src/main/iidxhook3/avs-boot.c
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
#define LOG_MODULE "avs-boot"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "imports/avs.h"
|
||||||
|
|
||||||
|
#include "iidxhook3/avs-boot.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
static void (*real_avs_boot)(
|
||||||
|
struct property_node *config,
|
||||||
|
void *std_heap,
|
||||||
|
size_t sz_std_heap,
|
||||||
|
void *avs_heap,
|
||||||
|
size_t sz_avs_heap,
|
||||||
|
avs_log_writer_t log_writer,
|
||||||
|
void *log_context);
|
||||||
|
static int (*real_ea3_boot_avs)(struct property_node *config);
|
||||||
|
static int (*real_ea3_boot)(struct property_node *config);
|
||||||
|
|
||||||
|
static void my_avs_boot(
|
||||||
|
struct property_node *config,
|
||||||
|
void *std_heap,
|
||||||
|
size_t sz_std_heap,
|
||||||
|
void *avs_heap,
|
||||||
|
size_t sz_avs_heap,
|
||||||
|
avs_log_writer_t log_writer,
|
||||||
|
void *log_context);
|
||||||
|
static int my_ea3_boot_avs(struct property_node *config);
|
||||||
|
static int my_ea3_boot(struct property_node *config);
|
||||||
|
|
||||||
|
static struct net_addr iidxhook3_avs_boot_eamuse_server_addr;
|
||||||
|
|
||||||
|
static const struct hook_symbol iidxhook3_avs_hook_syms[] = {
|
||||||
|
{.name = "avs_boot",
|
||||||
|
.patch = my_avs_boot,
|
||||||
|
.link = (void **) &real_avs_boot},
|
||||||
|
{.name = "ea3_boot",
|
||||||
|
.patch = my_ea3_boot_avs,
|
||||||
|
.link = (void **) &real_ea3_boot_avs},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct hook_symbol iidxhook3_ea3_hook_syms[] = {
|
||||||
|
{.name = "ea3_boot",
|
||||||
|
.patch = my_ea3_boot,
|
||||||
|
.link = (void **) &real_ea3_boot},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void avs_boot_replace_property_uint32(
|
||||||
|
struct property_node *node, const char *name, uint32_t val)
|
||||||
|
{
|
||||||
|
struct property_node *tmp;
|
||||||
|
|
||||||
|
tmp = property_search(NULL, node, name);
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
property_node_remove(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
property_node_create(NULL, node, PSMAP_TYPE_U32, name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void avs_boot_replace_property_str(
|
||||||
|
struct property_node *node, const char *name, const char *val)
|
||||||
|
{
|
||||||
|
struct property_node *tmp;
|
||||||
|
|
||||||
|
tmp = property_search(NULL, node, name);
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
property_node_remove(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = property_node_create(NULL, node, PROPERTY_TYPE_STR, name, val);
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
property_node_datasize(tmp);
|
||||||
|
} else {
|
||||||
|
log_fatal("Could not avs_boot_replace_property_str(%s, %s)", name, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void my_avs_boot(
|
||||||
|
struct property_node *config,
|
||||||
|
void *std_heap,
|
||||||
|
size_t sz_std_heap,
|
||||||
|
void *avs_heap,
|
||||||
|
size_t sz_avs_heap,
|
||||||
|
avs_log_writer_t log_writer,
|
||||||
|
void *log_context)
|
||||||
|
{
|
||||||
|
log_info("Called my_avs_boot");
|
||||||
|
|
||||||
|
avs_boot_replace_property_uint32(config, "log/level", 4);
|
||||||
|
|
||||||
|
real_avs_boot(
|
||||||
|
config,
|
||||||
|
std_heap,
|
||||||
|
sz_std_heap,
|
||||||
|
avs_heap,
|
||||||
|
sz_avs_heap,
|
||||||
|
log_writer_debug,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insert_eamuse_addr(struct property_node *config)
|
||||||
|
{
|
||||||
|
char *server_addr;
|
||||||
|
|
||||||
|
if (iidxhook3_avs_boot_eamuse_server_addr.type != NET_ADDR_TYPE_INVALID) {
|
||||||
|
log_misc("Injecting network server address");
|
||||||
|
|
||||||
|
server_addr = net_addr_to_str(&iidxhook3_avs_boot_eamuse_server_addr);
|
||||||
|
|
||||||
|
// Remove protocol to avoid errors during ea3_boot.
|
||||||
|
if (!strncmp(server_addr, "http://", strlen("http://"))) {
|
||||||
|
server_addr += strlen("http://");
|
||||||
|
} else if (!strncmp(server_addr, "https://", strlen("https://"))) {
|
||||||
|
server_addr += strlen("https://");
|
||||||
|
}
|
||||||
|
|
||||||
|
avs_boot_replace_property_str(config, "network/services", server_addr);
|
||||||
|
|
||||||
|
free(server_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int my_ea3_boot_avs(struct property_node *config)
|
||||||
|
{
|
||||||
|
log_info("Called my_ea3_boot_avs");
|
||||||
|
insert_eamuse_addr(config);
|
||||||
|
return real_ea3_boot_avs(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int my_ea3_boot(struct property_node *config)
|
||||||
|
{
|
||||||
|
log_info("Called my_ea3_boot");
|
||||||
|
insert_eamuse_addr(config);
|
||||||
|
return real_ea3_boot(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iidxhook3_avs_boot_init()
|
||||||
|
{
|
||||||
|
// IIDX 14 and 15 have the ea3_boot in libavs-win32.dll.
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"libavs-win32.dll",
|
||||||
|
iidxhook3_avs_hook_syms,
|
||||||
|
lengthof(iidxhook3_avs_hook_syms));
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"libavs-win32-ea3.dll",
|
||||||
|
iidxhook3_ea3_hook_syms,
|
||||||
|
lengthof(iidxhook3_ea3_hook_syms));
|
||||||
|
|
||||||
|
memset(&iidxhook3_avs_boot_eamuse_server_addr, 0, sizeof(struct net_addr));
|
||||||
|
|
||||||
|
log_info("Inserted avs log hooks");
|
||||||
|
}
|
||||||
|
|
||||||
|
void iidxhook3_avs_boot_set_eamuse_addr(const struct net_addr *server_addr)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = net_addr_to_str(server_addr);
|
||||||
|
log_info("Setting eamuse server: %s", str);
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
memcpy(
|
||||||
|
&iidxhook3_avs_boot_eamuse_server_addr,
|
||||||
|
server_addr,
|
||||||
|
sizeof(struct net_addr));
|
||||||
|
}
|
||||||
19
src/main/iidxhook3/avs-boot.h
Normal file
19
src/main/iidxhook3/avs-boot.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef IIDXHOOK3_AVS_BOOT_H
|
||||||
|
#define IIDXHOOK3_AVS_BOOT_H
|
||||||
|
|
||||||
|
#include "util/net.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize hooking of avs_boot and ea3_boot. This re-enables avs logging
|
||||||
|
* and injects a few important settings.
|
||||||
|
*/
|
||||||
|
void iidxhook3_avs_boot_init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the target eamuse server address.
|
||||||
|
*
|
||||||
|
* @param server_addr Address to target eamuse server.
|
||||||
|
*/
|
||||||
|
void iidxhook3_avs_boot_set_eamuse_addr(const struct net_addr *server_addr);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -27,22 +27,18 @@
|
|||||||
#include "hooklib/rs232.h"
|
#include "hooklib/rs232.h"
|
||||||
#include "hooklib/setupapi.h"
|
#include "hooklib/setupapi.h"
|
||||||
|
|
||||||
|
#include "iidxhook3/avs-boot.h"
|
||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/clock.h"
|
#include "iidxhook-util/clock.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-eamuse.h"
|
#include "iidxhook-util/config-eamuse.h"
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-misc.h"
|
#include "iidxhook-util/config-misc.h"
|
||||||
#include "iidxhook-util/config-sec.h"
|
#include "iidxhook-util/config-sec.h"
|
||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/eamuse.h"
|
|
||||||
#include "iidxhook-util/settings.h"
|
#include "iidxhook-util/settings.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "security/rp-sign-key.h"
|
#include "security/rp-sign-key.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -57,7 +53,6 @@
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
static HANDLE STDCALL my_OpenProcess(DWORD, BOOL, DWORD);
|
||||||
@@ -70,17 +65,6 @@ static const struct hook_symbol init_hook_syms[] = {
|
|||||||
.link = (void **) &real_OpenProcess},
|
.link = (void **) &real_OpenProcess},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void iidxhook3_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook3_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook3_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -137,7 +121,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_util_config_eamuse config_eamuse;
|
struct iidxhook_util_config_eamuse config_eamuse;
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook_config_misc config_misc;
|
struct iidxhook_config_misc config_misc;
|
||||||
@@ -155,7 +138,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_util_config_eamuse_init(config);
|
iidxhook_util_config_eamuse_init(config);
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_misc_init(config);
|
iidxhook_config_misc_init(config);
|
||||||
@@ -169,7 +151,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_misc_get(&config_misc, config);
|
iidxhook_config_misc_get(&config_misc, config);
|
||||||
@@ -196,10 +177,8 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
||||||
ezusb_iidx_emu_node_security_plug_set_eamid(&config_eamuse.eamid);
|
ezusb_iidx_emu_node_security_plug_set_eamid(&config_eamuse.eamid);
|
||||||
|
|
||||||
/* eAmusement server IP */
|
iidxhook3_avs_boot_init();
|
||||||
|
iidxhook3_avs_boot_set_eamuse_addr(&config_eamuse.server);
|
||||||
eamuse_set_addr(&config_eamuse.server);
|
|
||||||
eamuse_check_connection();
|
|
||||||
|
|
||||||
/* Settings paths */
|
/* Settings paths */
|
||||||
|
|
||||||
@@ -207,8 +186,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
settings_hook_set_path(config_misc.settings_path);
|
settings_hook_set_path(config_misc.settings_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook3_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
/* Direct3D and USER32 hooks */
|
/* Direct3D and USER32 hooks */
|
||||||
|
|
||||||
iidxhook3_setup_d3d9_hooks(&config_gfx);
|
iidxhook3_setup_d3d9_hooks(&config_gfx);
|
||||||
@@ -281,7 +258,6 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
|||||||
|
|
||||||
acp_hook_init();
|
acp_hook_init();
|
||||||
adapter_hook_init();
|
adapter_hook_init();
|
||||||
eamuse_hook_init();
|
|
||||||
settings_hook_init();
|
settings_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ avsdlls += iidxhook4-cn
|
|||||||
ldflags_iidxhook4-cn := \
|
ldflags_iidxhook4-cn := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook4-cn := \
|
deplibs_iidxhook4-cn := \
|
||||||
avs \
|
avs \
|
||||||
@@ -23,9 +20,6 @@ libs_iidxhook4-cn := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook4-cn := \
|
src_iidxhook4-cn := \
|
||||||
avs-boot.c \
|
avs-boot.c \
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "iidxhook4-cn/path.h"
|
#include "iidxhook4-cn/path.h"
|
||||||
|
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-eamuse.h"
|
#include "iidxhook-util/config-eamuse.h"
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
@@ -34,10 +33,6 @@
|
|||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/settings.h"
|
#include "iidxhook-util/settings.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "security/rp-sign-key.h"
|
#include "security/rp-sign-key.h"
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
@@ -56,7 +51,6 @@ static bool iidxhook_init_check;
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hook_symbol init_hook_syms[] = {
|
static const struct hook_symbol init_hook_syms[] = {
|
||||||
@@ -67,17 +61,6 @@ static const struct hook_symbol init_hook_syms[] = {
|
|||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook4_cn_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook4_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook4_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -134,7 +117,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_util_config_eamuse config_eamuse;
|
struct iidxhook_util_config_eamuse config_eamuse;
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook_config_sec config_sec;
|
struct iidxhook_config_sec config_sec;
|
||||||
@@ -152,7 +134,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_util_config_eamuse_init(config);
|
iidxhook_util_config_eamuse_init(config);
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
@@ -167,7 +148,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
@@ -194,8 +174,6 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
|||||||
&config_sec.black_plug_mcode);
|
&config_sec.black_plug_mcode);
|
||||||
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
||||||
|
|
||||||
iidxhook4_cn_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook4_cn_setup_d3d9_hooks(&config_gfx);
|
iidxhook4_cn_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (strlen(config_misc.settings_path) > 0) {
|
if (strlen(config_misc.settings_path) > 0) {
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ avsdlls += iidxhook4
|
|||||||
|
|
||||||
ldflags_iidxhook4 := \
|
ldflags_iidxhook4 := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook4 := \
|
deplibs_iidxhook4 := \
|
||||||
avs \
|
avs \
|
||||||
@@ -25,9 +22,6 @@ libs_iidxhook4 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook4 := \
|
src_iidxhook4 := \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
#include "iidxhook-util/config-misc.h"
|
#include "iidxhook-util/config-misc.h"
|
||||||
@@ -35,10 +34,6 @@
|
|||||||
#include "iidxhook-util/log-server.h"
|
#include "iidxhook-util/log-server.h"
|
||||||
#include "iidxhook-util/settings.h"
|
#include "iidxhook-util/settings.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -53,22 +48,10 @@
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook4_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook4_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook4_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -118,7 +101,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook_config_misc config_misc;
|
struct iidxhook_config_misc config_misc;
|
||||||
|
|
||||||
@@ -129,7 +111,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
iidxhook_config_misc_init(config);
|
iidxhook_config_misc_init(config);
|
||||||
@@ -143,7 +124,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
iidxhook_config_misc_get(&config_misc, config);
|
iidxhook_config_misc_get(&config_misc, config);
|
||||||
@@ -153,8 +133,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
log_info(IIDXHOOK4_INFO_HEADER);
|
log_info(IIDXHOOK4_INFO_HEADER);
|
||||||
log_info("Initializing iidxhook...");
|
log_info("Initializing iidxhook...");
|
||||||
|
|
||||||
iidxhook4_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook4_setup_d3d9_hooks(&config_gfx);
|
iidxhook4_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (strlen(config_misc.settings_path) > 0) {
|
if (strlen(config_misc.settings_path) > 0) {
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ avsdlls += iidxhook5-cn
|
|||||||
ldflags_iidxhook5-cn := \
|
ldflags_iidxhook5-cn := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook5-cn := \
|
deplibs_iidxhook5-cn := \
|
||||||
avs \
|
avs \
|
||||||
@@ -23,9 +20,6 @@ libs_iidxhook5-cn := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook5-cn := \
|
src_iidxhook5-cn := \
|
||||||
avs-boot.c \
|
avs-boot.c \
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include "iidxhook5-cn/avs-boot.h"
|
#include "iidxhook5-cn/avs-boot.h"
|
||||||
#include "iidxhook5-cn/path.h"
|
#include "iidxhook5-cn/path.h"
|
||||||
|
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-eamuse.h"
|
#include "iidxhook-util/config-eamuse.h"
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
@@ -34,10 +33,6 @@
|
|||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/settings.h"
|
#include "iidxhook-util/settings.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "security/rp-sign-key.h"
|
#include "security/rp-sign-key.h"
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
@@ -56,7 +51,6 @@ static bool iidxhook_init_check;
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hook_symbol init_hook_user32_syms[] = {
|
static const struct hook_symbol init_hook_user32_syms[] = {
|
||||||
@@ -67,17 +61,6 @@ static const struct hook_symbol init_hook_user32_syms[] = {
|
|||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook5_cn_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook5_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook5_cn_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -114,7 +97,6 @@ static ATOM WINAPI my_RegisterClassA(const WNDCLASSA *lpWndClass)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_util_config_eamuse config_eamuse;
|
struct iidxhook_util_config_eamuse config_eamuse;
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook_config_sec config_sec;
|
struct iidxhook_config_sec config_sec;
|
||||||
@@ -132,7 +114,6 @@ static ATOM WINAPI my_RegisterClassA(const WNDCLASSA *lpWndClass)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_util_config_eamuse_init(config);
|
iidxhook_util_config_eamuse_init(config);
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
@@ -147,7 +128,6 @@ static ATOM WINAPI my_RegisterClassA(const WNDCLASSA *lpWndClass)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
iidxhook_util_config_eamuse_get(&config_eamuse, config);
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
@@ -174,8 +154,6 @@ static ATOM WINAPI my_RegisterClassA(const WNDCLASSA *lpWndClass)
|
|||||||
&config_sec.black_plug_mcode);
|
&config_sec.black_plug_mcode);
|
||||||
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
|
||||||
|
|
||||||
iidxhook5_cn_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook5_cn_setup_d3d9_hooks(&config_gfx);
|
iidxhook5_cn_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (strlen(config_misc.settings_path) > 0) {
|
if (strlen(config_misc.settings_path) > 0) {
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ avsdlls += iidxhook5
|
|||||||
|
|
||||||
ldflags_iidxhook5 := \
|
ldflags_iidxhook5 := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook5 := \
|
deplibs_iidxhook5 := \
|
||||||
avs \
|
avs \
|
||||||
@@ -25,9 +22,6 @@ libs_iidxhook5 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook5 := \
|
src_iidxhook5 := \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/chart-patch.h"
|
#include "iidxhook-util/chart-patch.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
#include "iidxhook-util/config-misc.h"
|
#include "iidxhook-util/config-misc.h"
|
||||||
@@ -35,10 +34,6 @@
|
|||||||
#include "iidxhook-util/log-server.h"
|
#include "iidxhook-util/log-server.h"
|
||||||
#include "iidxhook-util/settings.h"
|
#include "iidxhook-util/settings.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -55,22 +50,10 @@
|
|||||||
|
|
||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook5_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook5_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook5_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -120,7 +103,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
struct iidxhook_config_misc config_misc;
|
struct iidxhook_config_misc config_misc;
|
||||||
|
|
||||||
@@ -131,7 +113,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
iidxhook_config_misc_init(config);
|
iidxhook_config_misc_init(config);
|
||||||
@@ -145,7 +126,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
iidxhook_config_misc_get(&config_misc, config);
|
iidxhook_config_misc_get(&config_misc, config);
|
||||||
@@ -155,8 +135,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
log_info(IIDXHOOK5_INFO_HEADER);
|
log_info(IIDXHOOK5_INFO_HEADER);
|
||||||
log_info("Initializing iidxhook...");
|
log_info("Initializing iidxhook...");
|
||||||
|
|
||||||
iidxhook5_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook5_setup_d3d9_hooks(&config_gfx);
|
iidxhook5_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (strlen(config_misc.settings_path) > 0) {
|
if (strlen(config_misc.settings_path) > 0) {
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ avsdlls += iidxhook6
|
|||||||
|
|
||||||
ldflags_iidxhook6 := \
|
ldflags_iidxhook6 := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook6 := \
|
deplibs_iidxhook6 := \
|
||||||
avs \
|
avs \
|
||||||
@@ -26,9 +23,6 @@ libs_iidxhook6 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook6 := \
|
src_iidxhook6 := \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -28,16 +28,11 @@
|
|||||||
#include "iidxhook-d3d9/bb-scale-hd.h"
|
#include "iidxhook-d3d9/bb-scale-hd.h"
|
||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/log-server.h"
|
#include "iidxhook-util/log-server.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -53,22 +48,10 @@
|
|||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook6_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook6_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook6_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -104,7 +87,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
|
|
||||||
log_server_init();
|
log_server_init();
|
||||||
@@ -114,7 +96,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
|
|
||||||
@@ -127,7 +108,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
|
|
||||||
@@ -136,8 +116,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
log_info(IIDXHOOK6_INFO_HEADER);
|
log_info(IIDXHOOK6_INFO_HEADER);
|
||||||
log_info("Initializing iidxhook...");
|
log_info("Initializing iidxhook...");
|
||||||
|
|
||||||
iidxhook6_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook6_setup_d3d9_hooks(&config_gfx);
|
iidxhook6_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (!config_io.disable_io_emu) {
|
if (!config_io.disable_io_emu) {
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ avsdlls += iidxhook7
|
|||||||
ldflags_iidxhook7 := \
|
ldflags_iidxhook7 := \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
-ld3d9 \
|
-ld3d9 \
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook7 := \
|
deplibs_iidxhook7 := \
|
||||||
avs \
|
avs \
|
||||||
@@ -26,9 +24,6 @@ libs_iidxhook7 := \
|
|||||||
iidxio \
|
iidxio \
|
||||||
util \
|
util \
|
||||||
ezusb \
|
ezusb \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook7 := \
|
src_iidxhook7 := \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -28,16 +28,11 @@
|
|||||||
#include "iidxhook-d3d9/bb-scale-hd.h"
|
#include "iidxhook-d3d9/bb-scale-hd.h"
|
||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/config-io.h"
|
#include "iidxhook-util/config-io.h"
|
||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/log-server.h"
|
#include "iidxhook-util/log-server.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
@@ -53,22 +48,10 @@
|
|||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct iidxhook_config_io config_io;
|
static struct iidxhook_config_io config_io;
|
||||||
|
|
||||||
static void iidxhook7_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iidxhook7_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook7_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -104,7 +87,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
|
|
||||||
log_server_init();
|
log_server_init();
|
||||||
@@ -114,7 +96,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook_config_io_init(config);
|
iidxhook_config_io_init(config);
|
||||||
|
|
||||||
@@ -127,11 +108,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
|
||||||
iidxhook_config_io_init(config);
|
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook_config_io_get(&config_io, config);
|
iidxhook_config_io_get(&config_io, config);
|
||||||
|
|
||||||
@@ -140,8 +116,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
log_info(IIDXHOOK7_INFO_HEADER);
|
log_info(IIDXHOOK7_INFO_HEADER);
|
||||||
log_info("Initializing iidxhook...");
|
log_info("Initializing iidxhook...");
|
||||||
|
|
||||||
iidxhook7_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook7_setup_d3d9_hooks(&config_gfx);
|
iidxhook7_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
if (!config_io.disable_io_emu) {
|
if (!config_io.disable_io_emu) {
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ ldflags_iidxhook8 := \
|
|||||||
-lmf \
|
-lmf \
|
||||||
-lmfplat \
|
-lmfplat \
|
||||||
-lole32 \
|
-lole32 \
|
||||||
-ld3d9 \
|
|
||||||
-ldwmapi\
|
|
||||||
-lgdi32 \
|
|
||||||
|
|
||||||
deplibs_iidxhook8 := \
|
deplibs_iidxhook8 := \
|
||||||
avs \
|
avs \
|
||||||
@@ -27,10 +24,7 @@ libs_iidxhook8 := \
|
|||||||
cconfig \
|
cconfig \
|
||||||
util \
|
util \
|
||||||
eamio \
|
eamio \
|
||||||
imgui-bt \
|
|
||||||
imgui-debug \
|
|
||||||
imgui \
|
|
||||||
|
|
||||||
src_iidxhook8 := \
|
src_iidxhook8 := \
|
||||||
config-io.c \
|
config-io.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -21,15 +21,10 @@
|
|||||||
#include "iidxhook-d3d9/bb-scale-hd.h"
|
#include "iidxhook-d3d9/bb-scale-hd.h"
|
||||||
|
|
||||||
#include "iidxhook-util/acio.h"
|
#include "iidxhook-util/acio.h"
|
||||||
#include "iidxhook-util/config-debug.h"
|
|
||||||
#include "iidxhook-util/config-gfx.h"
|
#include "iidxhook-util/config-gfx.h"
|
||||||
#include "iidxhook-util/d3d9.h"
|
#include "iidxhook-util/d3d9.h"
|
||||||
#include "iidxhook-util/log-server.h"
|
#include "iidxhook-util/log-server.h"
|
||||||
|
|
||||||
#include "imgui-bt/imgui-d3d9-hook.h"
|
|
||||||
|
|
||||||
#include "imgui-debug/frame-perf-graph.h"
|
|
||||||
|
|
||||||
#include "bio2emu-iidx/bi2a.h"
|
#include "bio2emu-iidx/bi2a.h"
|
||||||
#include "bio2emu/emu.h"
|
#include "bio2emu/emu.h"
|
||||||
|
|
||||||
@@ -52,19 +47,8 @@
|
|||||||
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
static const hook_d3d9_irp_handler_t iidxhook_d3d9_handlers[] = {
|
||||||
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
iidxhook_d3d9_bb_scale_hd_d3d9_irp_handler,
|
||||||
iidxhook_util_d3d9_irp_handler,
|
iidxhook_util_d3d9_irp_handler,
|
||||||
imgui_hook_d3d9_irp_handler,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void iidxhook8_setup_imgui_debug_components(const struct iidxhook_config_debug *config_debug)
|
|
||||||
{
|
|
||||||
imgui_bt_component_t debug_frame_graph_component;
|
|
||||||
|
|
||||||
if (config_debug->enable_frame_perf_graph) {
|
|
||||||
imgui_debug_frame_perf_graph_init(60.0f, &debug_frame_graph_component);
|
|
||||||
|
|
||||||
imgui_d3d9_hook_init(&debug_frame_graph_component, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void
|
static void
|
||||||
iidxhook8_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
iidxhook8_setup_d3d9_hooks(const struct iidxhook_config_gfx *config_gfx)
|
||||||
{
|
{
|
||||||
@@ -109,7 +93,6 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
{
|
{
|
||||||
struct cconfig *config;
|
struct cconfig *config;
|
||||||
|
|
||||||
struct iidxhook_config_debug config_debug;
|
|
||||||
struct iidxhook_config_gfx config_gfx;
|
struct iidxhook_config_gfx config_gfx;
|
||||||
|
|
||||||
// log_server_init is required due to IO occuring in a non avs_thread
|
// log_server_init is required due to IO occuring in a non avs_thread
|
||||||
@@ -121,10 +104,9 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook_config_debug_init(config);
|
|
||||||
iidxhook_config_gfx_init(config);
|
iidxhook_config_gfx_init(config);
|
||||||
iidxhook8_config_io_init(config);
|
iidxhook8_config_io_init(config);
|
||||||
camhook_config_cam_init(config, 2);
|
camhook_config_cam_init(config, 2, false);
|
||||||
|
|
||||||
if (!cconfig_hook_config_init(
|
if (!cconfig_hook_config_init(
|
||||||
config,
|
config,
|
||||||
@@ -135,18 +117,15 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iidxhook_config_debug_get(&config_debug, config);
|
|
||||||
iidxhook_config_gfx_get(&config_gfx, config);
|
iidxhook_config_gfx_get(&config_gfx, config);
|
||||||
iidxhook8_config_io_get(&iidxhook8_config_io, config);
|
iidxhook8_config_io_get(&iidxhook8_config_io, config);
|
||||||
camhook_config_cam_get(&config_cam, config, 2);
|
camhook_config_cam_get(&config_cam, config, 2, false);
|
||||||
|
|
||||||
cconfig_finit(config);
|
cconfig_finit(config);
|
||||||
|
|
||||||
log_info(IIDXHOOK8_INFO_HEADER);
|
log_info(IIDXHOOK8_INFO_HEADER);
|
||||||
log_info("Initializing iidxhook...");
|
log_info("Initializing iidxhook...");
|
||||||
|
|
||||||
iidxhook8_setup_imgui_debug_components(&config_debug);
|
|
||||||
|
|
||||||
iidxhook8_setup_d3d9_hooks(&config_gfx);
|
iidxhook8_setup_d3d9_hooks(&config_gfx);
|
||||||
|
|
||||||
/* Start up IIDXIO.DLL */
|
/* Start up IIDXIO.DLL */
|
||||||
|
|||||||
@@ -29,4 +29,6 @@ libs_iidxhook9 := \
|
|||||||
|
|
||||||
src_iidxhook9 := \
|
src_iidxhook9 := \
|
||||||
config-io.c \
|
config-io.c \
|
||||||
|
fs-hook.c \
|
||||||
|
reverbfix.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include "bio2emu-iidx/bi2a.h"
|
#include "bio2emu-iidx/bi2a.h"
|
||||||
|
|
||||||
#include "iidxhook9/config-io.h"
|
#include "iidxhook9/config-io.h"
|
||||||
|
#include "iidxhook9/fs-hook.h"
|
||||||
|
#include "iidxhook9/reverbfix.h"
|
||||||
|
|
||||||
#include "camhook/cam.h"
|
#include "camhook/cam.h"
|
||||||
#include "camhook/config-cam.h"
|
#include "camhook/config-cam.h"
|
||||||
@@ -67,7 +69,7 @@ static bool load_configs()
|
|||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
iidxhook9_config_io_init(config);
|
iidxhook9_config_io_init(config);
|
||||||
camhook_config_cam_init(config, 2);
|
camhook_config_cam_init(config, 2, true);
|
||||||
|
|
||||||
d3d9exhook_config_gfx_init(config);
|
d3d9exhook_config_gfx_init(config);
|
||||||
|
|
||||||
@@ -83,7 +85,7 @@ static bool load_configs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
iidxhook9_config_io_get(&iidxhook9_config_io, config);
|
iidxhook9_config_io_get(&iidxhook9_config_io, config);
|
||||||
camhook_config_cam_get(&config_cam, config, 2);
|
camhook_config_cam_get(&config_cam, config, 2, true);
|
||||||
|
|
||||||
d3d9exhook_config_gfx_get(&config_gfx, config);
|
d3d9exhook_config_gfx_get(&config_gfx, config);
|
||||||
|
|
||||||
@@ -159,8 +161,13 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
} else {
|
} else {
|
||||||
memfile_hook_add_fd("d:\\\\001rom.txt", ABSOLUTE_MATCH, "LDJ", 3);
|
memfile_hook_add_fd("d:\\\\001rom.txt", ABSOLUTE_MATCH, "LDJ", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redirect F:\ drive to vfs (used for video recording)
|
||||||
|
iidxhook9_fs_hooks_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reverbfixhook_init();
|
||||||
|
|
||||||
rs232_hook_init();
|
rs232_hook_init();
|
||||||
rs232_hook_limit_hooks();
|
rs232_hook_limit_hooks();
|
||||||
|
|
||||||
@@ -184,6 +191,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
|
|
||||||
// camera hooks
|
// camera hooks
|
||||||
if (!config_cam.disable_emu) {
|
if (!config_cam.disable_emu) {
|
||||||
|
camhook_set_version(CAMHOOK_VERSION_NEW);
|
||||||
camhook_init(&config_cam);
|
camhook_init(&config_cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
59
src/main/iidxhook9/fs-hook.c
Normal file
59
src/main/iidxhook9/fs-hook.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#define LOG_MODULE "fs-hook"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "imports/avs.h"
|
||||||
|
|
||||||
|
#include "iidxhook9/fs-hook.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/str.h"
|
||||||
|
|
||||||
|
static void *(*real_avs_fs_mount)(const char *dest, const char *src, const char *fs_type, const char *options);
|
||||||
|
static void *my_avs_fs_mount(const char *dest, const char *src, const char *fs_type, const char *options);
|
||||||
|
|
||||||
|
static const struct hook_symbol avs_fs_hook_syms[] = {
|
||||||
|
{.name = "XCgsqzn000004b", // avs_fs_mount
|
||||||
|
.ordinal = 76,
|
||||||
|
.patch = my_avs_fs_mount,
|
||||||
|
.link = (void **) &real_avs_fs_mount},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *my_avs_fs_mount(const char *dest, const char *src, const char *fs_type, const char *options)
|
||||||
|
{
|
||||||
|
// quick check for "F:\"
|
||||||
|
if (src[0] == 'F' && src[1] == ':' && src[2] == '\0') {
|
||||||
|
const char* dev_folder_drive = "dev/vfs/drive_f/";
|
||||||
|
log_misc("Redirecting %s to %s", src, dev_folder_drive);
|
||||||
|
|
||||||
|
CreateDirectoryA("dev/vfs/", NULL);
|
||||||
|
CreateDirectoryA("dev/vfs/drive_f/", NULL);
|
||||||
|
|
||||||
|
return real_avs_fs_mount(dest, dev_folder_drive, fs_type, options);
|
||||||
|
}
|
||||||
|
if (src[0] == 'e' && src[1] == ':' && src[2] == '/' && src[3] == '\0') {
|
||||||
|
const char* dev_folder_drive = "dev/vfs/drive_e/";
|
||||||
|
log_misc("Redirecting %s to %s", src, dev_folder_drive);
|
||||||
|
|
||||||
|
CreateDirectoryA("dev/vfs/", NULL);
|
||||||
|
CreateDirectoryA("dev/vfs/drive_e/", NULL);
|
||||||
|
|
||||||
|
return real_avs_fs_mount(dest, dev_folder_drive, fs_type, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return real_avs_fs_mount(dest, src, fs_type, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iidxhook9_fs_hooks_init()
|
||||||
|
{
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"avs2-core.dll",
|
||||||
|
avs_fs_hook_syms,
|
||||||
|
lengthof(avs_fs_hook_syms));
|
||||||
|
|
||||||
|
log_info("Inserted avs fs hooks");
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user