This was a lot more background work than expected, but that is the
nature of unnecessary hobbies I guess. Most things in here are obvious,
so here's the non-obvious thoughts and notes:
1. All the XP stuff is optional, if the toolchain isn't available it
won't even try
2. The docker build is the "known good" build and now has all the
required tools for XP and checking binaries
a. If you're OK with it, can add the XP_MUST_BUILD flag to
build_docker.sh
4. New `SPICE_XP` flag to comment out blocks
5. We could technically build using the Docker image I've made for my XP
compatible LLVM toolchain, but combining the binaries into a single zip
at the end of it is somewhat tedious, so I've chosen to grab the
binaries from my release
6. I also wrote a DLL checker to make sure the final binaries are
_actually_ XP compatible, which found some issues on x86_64 (I don't
know a single game that runs on 64 bit XP, but it wasn't too much effort
so whatever). This also won't run if missing, just to save the trouble.
7. The build script is still pretty shit, I've made some minor
improvements
a. `/usr/bin/env bash` instead of `/bin/bash` as it's more correct
b. Adding `-it` to the docker build, so Ctrl+C actually halts it
c. Main issue is that failures don't halt, because of the custom error
catching function. This has caused a lot of frustration, maybe we can
change that
## Testing
It runs on 32 and 64 bit installs of XP. My jubeat cab is on Win10 these
days and I haven't got around to testing an actual game, but I've
distributed test builds of this to people who *have* confirmed it works
as expected.
## Description of change
Adds `-mainmonitor` option which changes the monitor layout before
launching the game. This is much more reliable than the old `-monitor`
option which operated at DX9 level. This works for TDJ/UFC subscreens,
for example.
Rename `-monitor` option to `-dx9mainadapter` to discourage use.
`-monitor` will continue to work, of course.
Changing of primary monitor happens first before any orientation changes
/ refresh rate changes, which means those options will result in the
logically correct configuration.
Create a new option category for `Monitor` (rotate, refresh rate, etc).
Add a monitor selection widget for `-mainmonitor` option in the
configurator.
Improve how we log names of monitors in the log during boot - should be
less of "Generic PnP Monitor" after this.
## Description of change
Rotate monitor & change the refresh rate **well before** the game is
launched.
This is much faster and more reliable compared to what we do now, which
is trying to do monitor changes during CreateWindow hooks. For example,
SDVX makes a bunch of OS / NVAPI calls to figure out monitor geometry
while it's booting, and by the time CreateWindow is called, the game
already made up its mind, which leads to weird graphical issues.
This affects both windowed mode and full screen.
In addition, add options for normal orientation (landscape) and upside
down (landscape, flipped) options. This can be used if the monitor is
normally rotated to portrait, but the game needs to be in landscape.
Fix stale frame returned by capture API on rapid successive calls
> [!NOTE]
> Before submitting code changes...
> * Please do note that this is a GPL v3.0 open source project.
> * Please read the
[CONTRIBUTING](https://github.com/spice2x/spice2x.github.io/blob/main/CONTRIBUTING.md)
guide.
> * Maintainers reserve the right to reject or modify your submission
without reason.
> * No new compiler warnings must be introduced. Check the CI build
results.
>
> Feel free to remove this section after you have read it.
## Link to GitHub Issue or related Pull Request, if one exists
https://github.com/spice2x/spice2x.github.io/issues/582
## Description of change
When using the SpiceAPI `capture` endpoint for taking screenshots, if
you call multiple times in a row in a short period, there's a good
chance for duplicate / stale data to be returned, and you end up with
multiple identical screenshots. This is due to a race condition in the
graphics capture pipeline because the capture data is never reset to
null between invocations.
`graphics_capture_receive_jpeg()` never resets the capture buffer's data
pointer to `nullptr` after consuming it. The condition variable wait
predicate checks `data != nullptr`, so subsequent calls find the
predicate already satisfied and return immediately with the previous
frame instead of waiting for the render thread to produce a fresh one.
Fix: null out `capture.data` after copying the shared_ptr (which keeps
the pixel data alive via refcount) but before releasing the lock.
## Testing
Tested this locally and invoked the capture API 10+ times in a row
without any duplicates. Previously, every other invocation would be a
duplicate, basically.
- Include order and forward decls were breaking button.h because a
declared but not defined struct can't be initiated (honestly this file
was cooked, crazy include order).
- `MAXINT` is GCC specific, `INT_MAX` is portable.
- InterlockedDecrement takes a LONG, not ULONG
- an imgui printf-style call using a direct string instead of %s (let's
ignore the fact that it's actually safe based on how the str is
constructed)
- missing `override` on a virtual subclass
- `CALLBACK` on a lambda threw me for a loop, but I believe moving it
after the arg list is the correct approach (see if it builds on gcc I
guess)
- `std::result_of` was removed in C++20, which the project is built with
## Link to GitHub Issue or related Pull Request, if one exists
## Description of change
Deprecate backend conversion options and replace with one unified option
for enabling WASAPI exclusive conversion to ASIO.
The new option takes in a string (ASIO driver name) and when filled out,
it automatically enables the ASIO backend.
This is to avoid confusion that was caused by the previous option - the
fact that it was split into two (one to enable the conversion, another
to optionally pick which ASIO driver to use) and that user needed to
specify an integer as opposed to the driver name.
## Testing
Tested on IIDX33. Old options should continue to work.
## Link to GitHub Issue, if one exists
n/a
## Description of change
Allow user to specify a custom resolution for the sub monitor, in
addition to the existing refresh rate option
This would allow practically any touch monitor (including ones with
weird resolution / aspect ratio / refresh rate) to be used with
IIDX/SDVX.
## Testing
Tested with various resolution / refresh rate combinations on IIDX /
SDVX.
## Link to GitHub Issue, if one exists
n/a
## Description of change
Disable all window options that change dimensions or position as they
cause problems with touch overlay in windowed mode. Always On Top is the
only thing that's still possible.
## Testing
## Link to GitHub Issue, if one exists
n/a
## Description of change
Need to filter out system-created windows (such as `CicMarshalWnd`) when
looking up which window to mess with when user interacts with F11 menu.
While I'm here, clean up the hack for gfdm arena model that remembers
the main window.
## Testing
Tested:
DDR
gfdm arena 4 / 1 window modes
iidx (windowed mode, with/without nosub option)
sdvx with sub windows
Need to check:
full screen games
## Link to GitHub Issue, if one exists
n/a
## Description of change
Gitadora (pre-Delta) tends to soft lock, have graphical issues (menu bg
render as black), or take a long time (minutes) between scene
transitions when window is resized.
## Link to GitHub Issue, if one exists
Fixes#341
## Description of change
fix monitor auto-rotate for reflec beat
## Testing
Tested KBR, LBR, MBR (volzza2), MBR (reflesia)
## Link to GitHub Issue, if one exists
#477
## Description of change
This is a work in progress.
What works:
- [x] subscreen overlay shows the touch screen image (in windowed mode)
- [x] touch works in the overlay
- [x] only the main window is shown, other windows are not launched
What doesn't:
- [ ] game occasionally crashes when entering test menu?
- [ ] full screen mode is not tested at all due to monitor requirements
- [ ] need more polish (various options to control the behavior)
## Link to GitHub Issue, if one exists
Fixes#509
## Description of change
Implement `WrappedIAudioClient3`.
For now, we have only seen SDVX use it (EG final) and only when the
shared mode patch is enabled. Exclusive still goes through version 1.
This means that for V3 we can forego implementing backend conversion
logic (for now).
Only significant addition is `InitializeSharedAudioStream` and this IS
called by SDVX when shared mode patch is enabled.
## Testing
Tested EG final, tested year 1 data, also IIDX shared/exclusive wasapi.
## Description of change
Add an option that forces requested refresh rate value for the second
monitor; i.e., instead of 60Hz allow the user to override the adapter to
be 70Hz.
Useful for people who have a touch screen that can't do 60Hz.
I don't know if this would cause any timing issues in IIDX or SDVX, but
it seems to boot and monitor check is unaffected.
## Testing
Tested TDJ And UFC mode with a submonitor that can only do 61Hz.
## Link to GitHub Issue, if one exists
Regressed by #401
## Description of change
Two things from testing SDVX Live2D -
1. ColorFill is almost always too expensive and will lead to drops
1. Scale factor of 0.5 causes GPU to sync and causes drops
(ARGB/XRGB doesn't matter, linear filtering doesn't matter)
1 is fixed by removing ColorFill calls on every frame - instead only do
this once when the user changes the duplicate option (on the next frame)
2 is fixed by updating the UI (limit the slider) though people can
ctrl+click to override these slider limits.
The warning label will be kept with slightly reworded text.
## Testing
tested in sdvx eg final (sudden death) - on my RTX 4070, my FPS is rock
solid 120 fps even with image resize on now.
## Link to GitHub Issue, if one exists
#477
## Description of change
F11 menu (window settings) did not work for arena model because the game
engine races to create many windows, so our logic of grabbing the first
window created doesn't always get the main window.
## Testing
## Link to GitHub Issue, if one exists
n/a
## Description of change
Get rid of log messages when adapter modes are removed, since these have
never been all that useful.
## Link to GitHub Issue, if one exists
#477
## Description of change
Fix Japanese text broken in the game UI when system ACP is not
SHIFT-JIS.
## Testing
Checked song select and in-game title display.
## Link to GitHub Issue, if one exists
#477
## Description of change
Arena cab has two sound cards and it uses `WrappedIMMDeviceCollection`
to set the volume to 100% on boot on both, instead of the typical
`GetDefaultAudioEndpoint`.
## Testing
Testing Delta, testing other games as well as they are affected.
## Link to GitHub Issue, if one exists
None
## Description of change
- Added bi2x_hook
- Added J32D (drum) and J33I (guitar) emulations
- AMI2000 card reader (this game uses this instead of ICCA)
## Testing
Played through a 15-minute session on Drummania.
Guitar mode works with keyboard input.
## Link to GitHub Issue, if one exists
https://codeberg.org/nixac/spicetools/issues/4
## Description of change
Inspired by the Linux issue above in the fork, cache lstat calls for
thumbnail. IIDX 32 and 33 make a call for this every frame which can
cause significant overhead on Linux.
This is being enabled for all versions and not just the Linux variant of
the executables since it provides some marginal performance gain on
Windows.
## Testing
Tested IIDX 32/33, with the option on/off, and with AVS verbose logging
on/off.
Tested with ifs_layeredfs hook as well just to verify functionality.
## Link to GitHub Issue, if one exists
n/a
## Description of change
`acmFormatSuggest` is known to cause significant perf issues on Linux;
add a hook to return cached results.
The fix is only active in the Linux variant.
For discussion, see
* https://codeberg.org/nixac/spicetools/issues/2
* https://codeberg.org/nixac/spicetools/issues/4
## Testing
I've only tested this on Windows, checking if iidx and popn can boot,
play songs without audio issues.
## Link to GitHub Issue, if one exists
#345
## Description of change
Most games will fail show a network error if there is no network adapter
with a valid IPv4 address
Detect this case in netfix code and show a warning message in log +
deferred error message.
## Testing
Tested with no network adapters, with IPv6 only adapter, and a
disconnected NIC.
## Link to GitHub Issue, if one exists
#442
## Description of change
Adds a new option that intentionally fails the recording functionality.
## Testing
Tested on iidx32.
## Link to GitHub Issue, if one exists
fixes#442
## Description of change
New NVIDIA driver update (591.44) dropped support for older NVENC API.
Specifically,
* TDJ uses `NV_ENC_PRESET_HQ_GUID` but this is no longer supported; must
be swapped with new encoder presets
* `NvEncGetEncodePresetConfig` does not take new encoder presets, the
-Ex version must be used
All of this happens because bm2dx.dll takes code from an older NVENC
sample.
To address this,
* Install additional hooks for NVENC API
* Hijack calls to `NvEncGetEncodePresetConfig` and instead swap with
`NvEncGetEncodePresetConfigEx` (only if the initial call fails, which is
how we detect old vs new driver), replacing `NV_ENC_PRESET_HQ_GUID` with
`NV_ENC_PRESET_P4_GUID` and `NV_ENC_TUNING_INFO_HIGH_QUALITY`
(functionally equivalent according to NVIDIA docs -
https://docs.nvidia.com/video-technologies/video-codec-sdk/11.1/nvenc-preset-migration-guide/index.html)
* When calling `nvEncInitializeEncoder`, hijack and swap in the preset
GUID again.
## Testing
Tested on 591.44 driver on a RTX 4070.
The resulting videos were compared as well, and they are practically
identical from encoder perspective.
## Link to GitHub Issue, if one exists
n/a
## Description of change
HG cabinet uses wintouch and it requires TOUCHEVENTF_PRIMARY flag in
order to accept touch inputs.
Added wintouchemu on game hook and TOUCHEVENTF_PRIMARY flag on
wintouchemu.
## Testing
The game boots into test menu, touch now works. (tested in I/O TEST ->
TOUCH PANEL CHECK with '-s' flag)
TDJ subscreen overlay and nostalgia seems works fine regardless added
TOUCHEVENTF_PRIMARY flag but more testing required.
## Link to GitHub Issue, if one exists
user-reported
## Description of change
When the system non-Unicode language is not set to Japanese, TDJ
subscreen katakana keyboard was broken (weird behavior with characters
not erasing, ending with corrupt characters, etc)
To fix this, add a hook for `IsDBCSLeadByte`. `IsDBCSLeadByte` assumes
system ACP (which may not be SHIFT_JIS). Instead, redirect bm2dx.dll to
use `IsDBCSLeadByteEx` instead with SHIFT_JIS explicitly specified as a
parameter.
Presumably the game was using IsDBCSLeadByte to manage the keyboard
typing logic.... which is weird because SDVX doesn't do the same.
## Testing
Tested iidx 31 and tried to do searches.
## Link to GitHub Issue, if one exists
#345
## Description of change
Add auto-troubleshooter messages for when audio hooks are disabled, and
when 9on12 is turned on by user.
## Testing
Manual verification
## Link to GitHub Issue, if one exists
#399
## Description of change
Add image duplication option to screen resize, allowing overflow images
to wrap around the other side.
## Testing
Tested with DDR, IIDX (windowed and full screen TDJ), SDVX (orientation
swap)
## Description of change
iidx: 9on12 crashes iidx31+
popn: special message for createdevice failures (resolution issue)
## Testing
manually test both cases
## Description of change
Various fixes to deferred logger -
* Rename to "auto troubleshooter"
* Fix potential deadlock
* Reword the error messages to fit in a narrower column
## Testing
tested all the error cases
## Link to GitHub Issue, if one exists
#388
## Description of change
Instead of setting flags in `signal` and logging when we crash, create a
class for logging deferred semi-fatal messages, and dump them to the log
immediately before crashing or shutting down.
## Testing
Tested each failure case by injection.
## Link to GitHub Issue, if one exists
#345
## Description of change
Show a block of warning text if the game crashes after CreateDevice(Ex)
fails.
## Testing
Tested by injecting invalid resolution into spicecfg.
## Link to GitHub Issue, if one exists
Fixes#362
## Description of change
Add a hook for `GetLocaleInfoEx` and return `ja-JP` to fix the
"translation not found" issue in XIF.
## Testing
Tested with/without Disable ACP option.
## Link to GitHub Issue, if one exists
n/a
## Description of change
Mark the option as "sensitive" which censors the option value (adapter's
IP address)
Remove the log entry from spice
This isn't perfect because most of the games like to log the IP address
and subnet anyway, but at least spice itself will stop doing it.
## Testing
Tested 64 bit LDJ with parameter set.
## Link to GitHub Issue, if one exists
Fixes#307
## Description of change
Add an option for making TDJ/UFC subscreen window borderless in windowed
mode
Add another option for keeping the subscreen "always on top".
Add size / position arguments to SDVX windowed subscreen, exactly the
same as what is allowed for IIDX.
## Testing
Seems to work....
## Link to GitHub Issue, if one exists
Fixes#276
## Description of change
Note: this change is not compatible with previous screen resize config;
i.e., if you had the zoom setting dialed into a certain view, after this
change it won't be the same area, so you'll have to set up a scene
again. I think this is a worthwhile cost since the old logic is just
broken in weird ways, and preserving old settings is really tedious math
(for a feature that not many people use). Besides, this change will only
use the new Scenes values from the JSON.
Rewrite the DX9 image scaler logic.
* Previously, the rendering surface was fixed at `4096*4096 px`. Now,
this is relative to the backbuffer dimensions, which depends on the game
& respects user provided `-forceres`.
* Remove "center" option, make it the default.
Above two changes fix the aspect ratio issue (scaling in portrait games
not respecting screen ratio) and things breaking at higher res (1080p
when zoomed out far enough, or when forced to run at 4k resolution for
example)
* Use `scenes` leaf of screen resize JSON config for Scene 1 as well,
completely removing ourselves from being compatible with older spice2x
versions for these values.
* Add additional bounds check before calling `StretchRect` to avoid
users getting stuck with a bad layout, which can kill performance.
## Compiling
🦾
## Testing
Tested 32 bit (popn / ddr), 64 bit (ldj), portrait and landscape modes
(kfc)
## Link to GitHub Issue, if one exists
n/a
## Description of change
Add `SDVX Landscape Mode` option, allowing you to play SDVX in landscape
monitor orientation, with black borders on left and right - similar to
how EAC does it. This is meant to be an alternative to what people do
today, which is launching in windowed mode.
By default, with just `-sdvxlandscape` enabled, EG will launch at
1920x1080 (transposed from the original 1080x1920 resolution).
It is possible to combine with `-forceres` to launch at higher
resolutions. At some point though, when rendering at large resolutions
past 1440p, at some point scaling may break due to #276.
Disabled on 32-bit SDVX since dx9 `CreateDeviceEx` call is required;
`CreateDevice` won't work. For the same reason this isn't being made a
generic option for museca/rb/etc. In theory you can supply
`-sdvxlandscape` to games like IIDX and play landscape games in portrait
mode, although again, scaling my break due to #276.
Also, add new options (bottomleft/right) for subscreen overlay position
so that they don't overlap with the main screen in landscape mode.
## Compiling
🙂
## Testing
Tested a couple versions of VW and EG.
## Link to GitHub Issue, if one exists
n/a
## Description of change
Adds a new option to forcibly set the full screen resolution.
Same idea as -windowscale.
## Compiling
🔺
## Testing
Seems to be showing similar results as -windowscale:
* Works GREAT for IIDX/SDVX
* popn launches at correct resolution but only draws a small image (at
native res) - can be scaled with F11 menu
* nostalgia is broken in weird ways, image is drawn correctly but bottom
`credits` text draws at wrong offset, game's wintouch logic broken
(perhaps expectedly)
## Other notes
In theory this could enable "play sdvx in landscape mode" option but the
image scaling doesn't quite work with extreme values.