## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Similar to #797, draw an overlay to debug touch issues for reflec beat.
For rb, we draw on the ImGui surface. Draw horizontal and vertical line
for triggered sensors, and also a bounding box if scaling is in use.
Make small tweaks to how scaling works.
## Testing
Verified volzza 2 / reflesia / 1st game (landscape KBR)
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Debouce option for touch input. Applies to all touch handlers (rawinput,
win8, win7) since it sits at the touch layer, and then consumed by jb
touch logic.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
related to #697
## Description of change
Add a new option that paints touch targets and touch points for jubeat;
gets enabled if there is a touch screen connected. This is to help
explain / debug issues when users have their touch screen issues, which
is usually due to misalignment.
Fix the touch targets being off by 1 pixel (center gap is 1px wider in
both directions).
Also, simplify the `improved` algorithm to simulate a finger and trigger
nearest-neighbor for the AC dimensions. In terms of touch performance
this is near identical to what we had before, but it allows us to draw a
nice debug overlay instead of just grids.
## Testing
Tested portrait and landscape versions of jb.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Two changes:
1. Handle all HID events in `WM_INPUT` and not just the first one. This
only really affects 4000Hz / 8000Hz HID devices.
2. Go back to `3x3` as the default for rb IR touch emulation and remove
`1x1` as an option as it does not perform as well as I expected.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#697
## Description of change
Adds aspect-ratio compensation for raw input touch handler.
This addresses the problem with playing rawinput touch games - namely
jubeat and reflec beat - on a display that is not 16:9, and user chose
to preserve the aspect ratio. This happens a lot on:
* 16:10 touch screens
* touch screen laptops (which range from 3:2, 16:10, and so on).
Root cause is a **Windows Raw Input limitation**. Unlike
`WM_POINTER`/`WM_TOUCH`, where the OS already maps digitizer coordinates
to screen space (applying the display's calibration/scaling), Raw Input
delivers the HID digitizer's *raw* logical coordinates, spanning the
whole physical panel, with **no calibration or display-mapping data
attached**. We have to reconstruct that mapping ourselves.
When a game runs at a display mode whose aspect ratio differs from the
panel's native resolution, Windows scales the image with
letterboxing/pillarboxing (black bars). That is standard OS/GPU
behavior. Because Raw Input gives us no mapping to account for those
bars, touches land off-target. This change detects the mismatch and
remaps each touch from panel-space into the displayed image region;
touches inside the black bars are treated as released.
Adds new launcher option **`-rawtouchaspect`**.
Notes:
- Native resolution is the largest-area mode from `EnumDisplaySettings`
on the **primary** display, consistent with the existing primary-only
touch pipeline.
- Math assumes centered, aspect-preserving scaling; only one axis is
ever inset.
- A small epsilon (0.01) makes near-matched panels (e.g. 1366×768 vs
true 16:9) a no-op.
- If the user forces a stretched image, then the touches will be off
again. In this case, the user needs to use the `force off` setting.
## Testing
On my tiny Surface Go tablet,
* checked that jubeat squares align correctly
* good enough to full combo level 11 for reflec beat
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Adds an option to disable Live2D. Can be disabled everywhere, or just
during a song.
## Testing
Tested EG final and recent Nabla.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Adds an overlay window widget for controlling OBS over WebSocket.
Add new lines to the FPS widget that shows recording / streaming timers.
Show notifications for major state changes (stream started/stopped,
recording started/paused/resumed/stopped)
## Testing
DLL hook options (-k and -z) allow multiple flags being specified in
both spicecfg and via command line; they never conflict as they are
additive. Remove the warning about option conflicts.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Similar to how it is on SDVX, turning this on can cause graphical
glitches depending on the GPU, so it needs to be an option that users
can toggle.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#762
## Description of change
Fix -nolegacy causing input to be not processed in spicecfg
Need to fix `run_cfg` and `CONFIGURATOR_STANDALONE` for real soon.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
For cab usage, when `-exec bm2dx.dll` is used without `-iidx` then
SOUND_OUTPUT_DEVICE never gets set.
Change this so that `SOUND_OUTPUT_DEVICE` gets set unconditionally if
`-iidxsounddevice` is set.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
This new option, `-wasapishared`, detects when the game opens WASAPI
Exclusive stream and forcibly opens a shared mode stream instead on the
real device.
#### Benefits of this:
1. No need for `force wasapi shared` patches
2. No need to change sample rate of audio devices before starting up
games
3. Adds ability to boot in shared mode even for games that do not have
shared wasapi changes (old GITADORA, popn HC)
As a result, this option is strictly better than `shared wasapi` patches
available for many games.
#### Downsides:
1. OS resampling will add a small latency, but not big enough to be
noticeable.
2. Using shared mode instead of exclusive mode adds latency, of course.
(If you cared about latency, you would use the low latency option, or
use exclusive or asio)
Basically it's the "make things work" button for audio that should work
for almost all games that we support.
The option has no effect if the game opens in shared mode.
## Testing
SDVX7 - ok
GITADORA GW - ok
popn HC - ok
IIDX - ok
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Create three distinct layers for the overlay:
1. Bottommost persistent layer - non-interactable layer that is always
on. This was only for notifications, but now the FPS widget lives here
as well.
2. Overlay windows layer - most interactable windows go here.
3. Topmost main menu - this is reserved for the main menu (escape key)
and this is a modal dialog that occludes the layers below.
Why?
- `toggle overlay` behavior with FPS widget *also* toggling on/off was a
bit confusing (now they're two separate keys)
- FPS widget is popular, but it caused the entire overlay to be active,
which affects how input is handled
- the main menu being a standalone window was a little awkward (now it's
a modal)
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
#730
## Description of change
Add an option that extracts channels from 7.1 ASIO and presents to 2-ch
ASIO. Same idea as the SDVX 2ch fix except for gitadora we are
duplicating the center channel to front.
## Testing
Tested SDVX and GFDM Arena.
## Link to GitHub Issue or related Pull Request, if one exists
#730
## Description of change
Flip the option - enable the Realtek hack by default, unless the user
chooses not to.
## Testing
Tested ASIO path and WASAPI path. WASAPI path should be unaffected as
the game just picks the default audio device.
## Link to GitHub Issue or related Pull Request, if one exists
#730, #718
## Description of change
Part 1)
When ASIO is in use, the game also looks for a Realtek device so that it
can open a WASAPI Exclusive mode stream for headphones.
Add an option to fake that, in case the user doesn't have a Realtek
device.
Part 2)
`-gdaasio` wasn't workign properly - fix the logic.
## Testing
Seems to work with FlexASIO, and Xonar with no real Realtek device.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Create `WrappedAsio`, similar to how we wrap `IAudioEndpoint`
So far, the wrapper does these things:
1. logging (for diagnosis, since iidx and gfdm don't produce any logs
when asio succeeds)
2. iidx32+ hack to work around refcount mismatch issue
3. sdvx valk cab hack to force 2-channel audio ("downmixing" by taking
only the front channels)
4. honor volume boost
As a result of `#2` the mempatch was removed from `iidx.cpp` since we
can tackle it cleanly in the hook. `#3` also removes the need for manual
patches.
Real downmixing is hard & expensive on the CPU so it was not
implemented.
## Testing
Tested iidx/sdvx/gfdm with xonar and flexasio
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Resampler:
Implement resampler for exclusive mode streams, as we are seeing more
and more devices - not just laptops but onboard audio devices - that
only support 48khz and not 44.1khz. Should work with volume boost (gain
calculated inside resample) and also downmixer (hands off intermediate
scratch buffers).
Buffer size increase:
By default many of these games request a tiny buffer when in shared mode
(TDJ uses 3ms). On some audio setup this results in crackling due to
underflow. Add an option to forcibly increase the buffer size.
## Testing
With resampler set to 48kHz and buffer set to 20ms I can reliably boot
and play IIDX on my display port monitor's speakers; previously this
wasn't possible. IIDX is event-driven.
Tested SDVX7 as well at 48kHz, which opens timer-driven streams.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#717, fixes#647
## Description of change
Adds an option to downmix surround sound (5.1, 7.1, etc) down to stereo
(2 speakers). This can be used in most WASAPI games, including Gitadora
and FTT.
How it works: when the game tries to open surround format (say, 7.1) we
create a fake buffer and tell the game that it is supported. In reality
we open a 2-channel stream with the real sound card. When the stream
begins, we downmix the channels down to two (using one of many
algorithms) and output to the sound card.
While we're here, implement an option to boost the game volume by some
decibel value, which is a feature often requested by SDVX players. This
was needed since downmixing can sometimes result in quieter audio.
## Testing
Tested GW Delta and FTT.
Downmix doesn't work on IIDX (32 bits) but volume boost works.
## Link to GitHub Issue or related Pull Request, if one exists
N/A
## Description of change
Adds GITADORA Arena windowed monitor layout options for the GITADORA,
LEFT, RIGHT, and SMALL windows.
This also applies the selected window border style to all four GITADORA
Arena windows, and allows the SMALL touch window to be resized in
windowed mode while keeping touch coordinates updated.
## Testing
- Manually tested GITADORA Arena windowed mode:
- default, resizable, and borderless window styles
- per-window monitor placement
- SMALL resize
- SMALL touch coordinate mapping after resize
## Link to GitHub Issue or related Pull Request, if one exists
#717
## Description of change
Add an option to override the ASIO device.
By default the game will try to use any ASIO driver that contains the
string `XONAR` in it.
## Testing
Tested with FlexASIO.
## Link to GitHub Issue or related Pull Request, if one exists
#0
## Description of change
Combine the two layout options into one
## Testing
- [x] windowed, x4
- [x] windowed, x2
- [x] windowed, x1 with sub
- [x] fs
## Description of change
Added an option to only disable the left/right screens of gitadora gw
delta while exposing the touch panel screen.
## Testing
Tested by hand on CachyOS + hyprland + gamescope + wine + vnc + phone +
cat 🐈⬛
<img width="2560" height="1707" alt="image"
src="https://github.com/user-attachments/assets/a2ef0172-68e2-43c2-89c3-4863698f2f00"
/>
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Adds toast notifications to the overlay.
Toast notifications are transient windows (shown for about 4 seconds).
These are drawn on top of the game even when the overlay is inactive
(i.e., when no window is open), and does not cause any input sink
behavior.
Add toasts for some common user-driven actions that could use a
notification, such as:
* screenshot
* card insert
* PIN macro
* API client connect/disconnect
* virtual printer
* screen resize toggle / scene switch
Add an option to change where the toasts are displayed, or to turn it
off entirely.
Add SDK function for it, and add it to the samples.
## Testing
Tested DDR (shown at bottom right, as is for most games) and RB (shown
top right by default).
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Add two options:
1. option to adjust poll rate
2. option to change emulation size
Also, the default configuration is changing from:
* ~1000Hz ish to 120Hz (default)
* 3x3 point to 1x1 point
In theory this does not make a meaningful change to how the game plays.
But if people want the old behavior they can change it.
## Testing
Tested on Volzza2 and Reflesia.
## Description of change
Adds a way to automatically use the PIN Macro for P1, P2 or both when
Auto Card Insert is used.
### Launcher changes:
- Added a checkbox to enable/disable the feature
- Added a textbox for each player to set what to look for in the logs.
### How it works:
The feature requires Auto Card Insert and PIN Macro to be enabled and
set.
It uses the Auto Card Insert value to enable the feature for P1, P2 or
both, with a "master" checkbox to completely disable the feature. It
then relies on the current PIN Macro code to send the PIN to the games.
The games logs send a message when a new scene is loaded with the name
of the scene. By hooking on the logs, we can see when a PIN is required
and send the relevant macro. Games have different scene names, and
sometimes one for each player, so the field is configurable per game per
player. These could be hard-coded in a lookup table but I didn't want to
recompile the project every time I wanted to test, and I don't have all
the games to get this info from.
The PIN Macro thread is used to hook to the logs and check if the
defined string appears, which triggers the PIN macro just like a button
press would.
Setting nothing for the log trigger disables the feature for that
player. It's useful if someone wants to have Auto Card Insert enabled
for both players but only Auto Pin on 1 player, but is mainly there so
the check won't happen if nothing is set.
## Testing
I used SDVX and DDR to have a single and a two player test with the
feature both enabled and disabled. I also tested multiple combinations
of PIN Macro settings and Auto Card Insert settings with no apparent
issues. The PIN is automatically entered as soon as the game requests
it.
## Discussion
I know that hooking to the logs might not be the best solution. I'm very
open to discussions about this, and understand that this might be a deal
breaker for this feature. I made this to use with my setup and thought
I'd try opening this PR to see if the feature would be useful for
others.
I haven't found another way to make sure we're on the correct screen to
launch the PIN Macro, and sending the macro every time the Auto Card
Insert finishes had sync issues where the end of the PIN would actually
be registered by the game.
It would also be much more convenient for the users to hardcode a lookup
table for every games' log-trigger but I don't have the games currently
so I can't check the logs to see what would be best.
---------
Co-authored-by: Maxime St-Pierre <maxime.stpierre@ticketmaster.com>
## Link to GitHub Issue or related Pull Request, if one exists
#477
## Description of change
By default the game needs 4 monitors.
With the new option to disable subscreens, you can now boot fullscreen
with a single 4K monitor, with subscreen overlay enabled. Side monitors
are not shown in the overlay; only the touch screen is emulated.
## Future work
- [ ] custom resolution (-forceres) doesn't work properly (hooking
ResetEx does allow the game to boot but will render incorrectly;
probably needs hex edits)
- [x] enable this automatically if the user has fewer than 4 monitors
- [ ] ability to boot with a 4k main screen + small subscreen (with no
side screens which do nothing gameplay wise), but this whole display
emulation is a nightmare to work with & test thoroughly so it'll have to
be in the future.
## Testing
Checklist:
- [x] fs on 1 monitor with option set
- [x] fs on 2 monitor with option set
- [x] windowed - default (4 windows, no overlay)
- [x] windowed - with option set (1 window, overlay)
- [x] fs with 4 monitors?
- [x] check popn hc for regression
## Link to GitHub Issue or related Pull Request, if one exists
#694
## Description of change
Before this change, we have it set in the executable manifest to always
ask for UAC elevation.
This change removes that and instead attempts to prompt for elevation
when we launch, depending on the new developer option that is being
added here to run as current user instead of elevating.
The default behavior continues to run as admin. This is still the safest
in terms of regression risk.
A bit of history on this: while spicecfg never technically needed to
elevate, we continue to do so to avoid difference in behavior when the
game is launched. For example, if the user is using an input remapper
running without elevation, it would inject input into spicecfg running
as user but fail to do so if the game runs elevated.
WinXP builds are unaffected (there is no UAC).
Some features will straight up fail without elevation so this will
remain as a debug option. To name a few (not a complete list):
* reboot/shutdown of PC
* running at realtime process priority
* `-nvprofile` option
* ...
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
#0
## Description of change
Add `-icmphook` option under spicecfg Development/Network for emulating
keepalive ping replies in user mode, so games do not need to open
privileged raw ICMP sockets. This makes connecting to networks possible
on macOS under Whisky, and on Windows with ICMP firewalled or spice
running without Administrator privileges.
## Testing
Tested DDR and SDVX on Windows 10 and macOS Tahoe. Network check status
in test menu shows `CONNECTED` when -icmphook is enabled, and `NOT
CONNECTED` when it is disabled. Actual network functionality works as
expected (under previously impossible conditions).
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Add a new option under `Monitor` group to change the monitor resolution
before booting the game, very similar to how orientation / refresh rate
options work.
This would be useful for games like Polaris Chord that boots at current
resolution but manages to have graphical issues when not in 1080p.
## Testing
## Description of change
There was enough feedback that the current algorithm is not ideal for
most touch screens because most touch screens are not 24". In the
current algorithm touching the gap is no-op, so people think the game is
dropping touches.
This PR introduces a new algorithm that inspect touches on the gap and
triggers the nearest square.
## Testing
Tested landscape and portrait jubeat.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#681
## Description of change
`Sleep` and `sleep_for()` can be very inaccurate and varies depending on
what the OS gives us...
### `timeBeginPeriod(1)`
On boot, we are now calling `timeBeginPeriod(1)`, which affects the
whole process but makes `Sleep` more accurate. There is some risk here
if any game was relying on doing things like `Sleep(1)` and expecting it
to run for 15.6ms. Most games already call `timeBeginPeriod(1)` in the
game engine, though not the whole time, so I'm hoping that this is not
too impactful.
### Opt out of Win11 power throttling
Ensure that timer resolution change above is respected even when the
window is occluded / minimized by opting out of throttling via
`PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION`.
### Use Win10 high resolution timer instead of Sleep
On Win10 1803 and above, there is a new OS-level API for high resolution
timers; if this is available, use it
(`CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`). Worth noting that WINE
doesn't support this currently.
If not, fall back to `Sleep`, which is significantly better than
`sleep_for()` in my experiments.
Callers of Sleep / sleep_for were replaced with this new timer. Most of
them anyway; calls to Sleep() with more than 100ms+ was left alone.
### Add an option as a chicken bit
To opt out I'm adding a new option called `Use Legacy Timers` which will
revert to behavior before this PR. The code paths that switched from
`sleep_for` to `Sleep` will remain in place though, not affected by the
option.
## Expected changes
In some I/O emulation modules, poll threads may run more frequently,
resulting in lower latency.
It also means that spice overall may use more CPU resources and power.
If you don't like this, you can always enable the option to opt out;
e.g., if you're on old arcade cab PC.
## Testing
DDR p4io - ok
drs touch hook - ok
IIDX camera hook - ok
CCJ trackball - ok
## Description of change
Seems to be an oversight when it was initially implemented; hooks should
not load when launching `spicecfg` (or `spice -cfg` or `spice64 -cfg`).
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Adds a flat-C, headers-only library for writing DLL plugins with spice.
This is meant to be an alternative to writing applications over spice
API which doesn't suit some scenarios like writing custom
high-performance I/O modules.
All you have to do is:
1. Create a 32-bit or 64-bit DLL with `spice_sdk_entry_point` as a
DLLExport
1. Include `spicesdk.h`, and optionally `spicesdk_io.h` (see
`extras\sdk\include`)
1. `spice_sdk_entry_point` will be called when hooks get initialized.
Call `init` with valid parameters.
1. When `init` returns, `SPICE_SDK_V0` will be filled out with a series
of function pointers; your DLL can now start calling into it.
1. Compile your DLL and add it as a DLL hook (`-k`) in spice when
launching the game.
See `v0_cpp.cpp` for an example.
V0 implements the following functions:
```
log;
get_game_info;
get_avs_info;
get_button;
set_button;
get_analog;
set_analog;
get_light;
set_light;
set_touch;
clear_touch;
insert_card;
set_keypad;
```
V0 is focused on providing common utility functions needed in a lot of
DLL hooks (get AVS info, log messages to file), and implementing I/O.
In the future, we could have more interesting things like:
* scanning and modifying memory
* installing DLL hooks
* having direct hooks into I/O emulation modules
* getting full tape LEDs
* having a callback into DX9 `Present` call
* drawing an ImGui window
More detailed documentation is coming soon in form of a wiki page.
## Testing
See included sample DLL.
## Link to GitHub Issue or related Pull Request, if one exists
#181
## Description of change
Implement analog relative mode and delay option using a new
millisecond-based algorithm.
## Testing
WIP
## Link to GitHub Issue or related Pull Request, if one exists
Re-implements fix for #181 as it was removed by #668
## Description of change
Add two options to add artificial delay to turntable input. These
operate directly on the input logic (`get_tt`) which is called by I/O
emulation code.
Functionally, it's **identical** to the `Delay (experimental)` option we
had in the analog tab, just moved to Options tab.
## Testing
64 bit tdj: ok
64 bit ldj bi2a: ok
32 bit ldj ezusb: ok
Worth noting that TDJ bi2x_hook polls at 120Hz, bi2a at ~500Hz, and
ezusb at ~170Hz
## Description of change
This code adds a window title to FutureTomTom when running in windowed
mode and allows the windowed graphics hooks to take effect.
## Testing
I ran the game and made sure fullscreen mode still worked as well as all
window move/resize functionality.
## Description of change
This adds a toggleable option to remove the rounded window corners when
running a game, or a subscreen, in a window on Windows 11 and upwards.
## Testing
On Windows 11: Resort Anthem, MÚSECA and EPOLIS were tested and the
window corners were removed from both main windows and the TDJ subscreen
when running in windowed mode, with no change in fullscreen mode.
On Windows 7: IIDX18 was tested with no change, the call to
`DwmSetWindowAttribute` is ignored as `DWMWA_WINDOW_CORNER_PREFERENCE`
doesn't exist.
For XP builds, the call is compiled out to avoid linking against dwmapi
and windows_dll_compat_checker returns successfully when testing against
the XP Embedded image. I can't test it on XP, but it ran on Vista.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Take the monitor hooks added for IIDX/SDVX #612 and apply it to popn as
well now that popn has a subscreen.
There is a debug option in game that actually uses three monitors, which
can be activated via hex edits. This will prevent that from working.
## Testing
Tested with 3 monitors, fs and windowed.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Add overlay for subscreen.
Add an option for no subscreen window.
Use the same "force redraw subscreen" logic we used in SDVX to fix the
same issue.
Known issues:
* still crashing when running windowed if there is only one monitor
* having only one monitor causes sunscreen overlay to not work
(NumberOfAdaptersInGroup issue?)
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Get windowed mode to work.
## Testing
tbd... i/o doesn't work right now but it launches two windows at
least...
## Link to GitHub Issue or related Pull Request, if one exists
#345
Hoping that #180 is also addressed by this change, but I can't test it.
## Description of change
IIDX (TDJ) and SDVX (Valk) will now be able to boot in full screen even
with 3 or more monitors attached.
spice will "hide" from the game any monitors other than the primary
monitor and one other monitor for subscreen, allowing it to boot without
crashing - accomplished by clearing `DISPLAY_DEVICE_ATTACHED_TO_DESKTOP`
flag when monitors are enumerated over `EnumDisplayDevicesA`, and
fortunately both games seem to respect that flag.
Add options (one for IIDX, another for SDVX) that lets you specify the
monitor ID of the second monitor.
When the option is set, user-specified monitor will be used as the
subscreen. When the option is not set, spice will just pick the
lowest-indexed monitor as the subscreen, not counting the primary one of
course.
## Testing
Tested both games with three monitors. Should probably work for four or
more.
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.