## 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
I don't have a repro but a user reported that the cursor doesn't wrap
around on one side. Correctly account for windows bleeding over to other
monitors.
## Link to GitHub Issue or related Pull Request, if one exists
#251
## Description of change
CCJ registers for rawinput mouse. We allowed the rawinput registration
to go through to the OS, which prevents spice's rawinput stack from
using the mouse. This caused the overlay to not accept mouse input. Fix
it by not letting the rawinput registration through. Luckily, mouse
input continues to work properly in CCJ (for touch).
Also, fix a bug in DX11 overlay when toggling the main menu.
## 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
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
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
Refuse to load if `libaio.dll` exists but `<spec>` is set incorrectly
(almost certainly because the user copied old prop files from downlevel
version)
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#154
## Description of change
Patch the game to skip over special holo printing logic and redirect to
the normal printer, resolving the soft lock + printer failure.
## Testing
Tested `NCG-2019012900`. Other versions might not work though since this
is patch-based not hook-based.
## 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
#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
## 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.
## 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
Continuation of #682
## Description of change
RB uses SleepEx, so it was missed during the search while working on
#682.
## Testing
Plays about the same on a 200Hz touch monitor.
## 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
continuation of #677
## Description of change
When overlay was hidden, when mouse buttons were clicked, they were
queued up and replayed when overlay became visible again.
This is due to improper usage of `GetAsyncKeyState`, per documentation.
## Testing
## 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
## 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
#181
## Description of change
Use millisecond-based calculation to add artificial delay to the TT
input.
## Testing
Tested 64 bit TDJ and LDJ.
## 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
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Currently, all analogs are treated as circular values that wrap around.
This works for knobs and turntables, but can get weird for linear values
(like tilt sensors and sliders) especially once analog options are
enabled, such as sensitivity.
This PR groups analogs into 3 buckets: circular, linear (centered), and
linear (positive). Linear types get different algorithms applied to it
when options are set (e.g., sensitivity caps out at 0, 1 instead of
wrapping around).
In linear mode:
* Sensitivity value applies an exponential response curve (power curve)
to the original value.
* Multiplier/divisor serves as a linear cut-off.
* Relative mode works as you expect, but of course, values don't wrap
around.
* Invert and deadzone work as you expect (since they applied to the
controller input anyway)
* Smoothing is removed from the UI and has no effect.
* Delay is unaffected.
Also, fix a small bug with -/+ button not working for analog `Delay`
option.
## Testing
WIP
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Some crappy DDR soft mats (either USB-based or console pads with crappy
adapters that lack a dedicated "DDR pad mode") use X and Y analog axis
for arrows, which means they cannot cleanly report Up+Down or Left+Right
input.
According to some ancient Stepmania code, a lot of these report a middle
value (value between center and right, for example, for left+right).
Borrow this hack from Stepmania and implement it in spice as analog
input for DDR.
Also, for rawinput/xinput automatic bind scenario, update the logic so
that face buttons are always detected before analog axis / dpads for
consistency. This would help with binding any DDR pads that
simultaneously input face buttons / dpad / analog axis, so that we can
prefer face buttons when detected.
## Testing
I don't have any soft mats that have this, but it was tested with an
xbox controller.
As noted in #567, a filesystem path that contains non-ascii will break a
lot if using a clang toolchain.
Luckily, fmtlib has a lossy utf8 convert when you use it to print a path
(after including `fmt/std.h`). The vast majority of this diff is just
removing `.string()` from paths inside loggings calls.
There are some callsites I _didn't_ touch, mainly the options, because
it would be an ABI break to change those to be wide strings and I cbf
looking into settings upgrades. There are also some spots (avs mountpath
remapping, for example) where the path is guaranteed to be ascii, so I
didn't modify them.
ImGui doesn't appear to easily support wide strings (I mean, surely it
does, but I'm not gonna look too far into it) so I mostly just left
those alone too, with a few spots modified to re-use fmtlib's lossy
utf8.
Some of the changes are basically never gonna be hit IRL, like who would
put a file with a non-ascii _extension_ along with their modules? But
the diff is (I hope) pretty easy to validate as OK.
Testing has been somewhat minimal, I fired up the GCC build of spice2x
in a dodgy folder name, got mojibake (running via wine in linux so take
that as you will), ran the unmodified clang spice and crashed the same
way the reporter did. After modification, I get the exact same mojibake
so I assume if the terminal enjoys utf8 it'll display OK.
Claude (only used for review) thinks the commit is fine but is annoyed
that I use `fmt::detail` in the appdata censoring, which is part of the
private API; personally I don't care because it's pretty stable.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Add rest of the LED strip lights.
## Testing
Tested U region.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Wire up coin and more lights to bi3a_hook.
## Testing
Tested on U region
## 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
The game insists on having two monitors. Hook various DX9 and Win32
monitor APIs to fake a monitor if the user only has one. This correctly
convinces the game that it needs to draw two screens instead of just
one.
## Testing
WIP
## 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
Basic support for lights - subwoofer RGB and button lights.
## Testing
Tested on title screen and in-game.
Tested beat pop as well since that lights up the colors in white/blue.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Turns out running this with bi2x doesn't process buttons properly, so we
have to use bi3a.
## Testing
Seems playable now.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
Implement BI2X hook I/O for service/test/coin/headphones and the deka
pop-kuns.
## Link to GitHub Issue or related Pull Request, if one exists
#618
## Description of change
The game expects the main display to be *not* HDMI, and at port 2.
Hooking DisplayConfigGetDeviceInfo allows us to boot the game on any
monitor.
Add basic I/O hook. It gets stuck in `USB I/O Checking...` for a couple
minutes but it'll eventually skip and boot to title screen.
## Testing
ugh.
## 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.
## Link to GitHub Issue or related Pull Request, if one exists
#0
## Description of change
Fix random crashes with CCJ.
This should remove the need to add `d3d10warp.dll` to `
preload_libraries` in `ee-config.xml`.
## Testing
Tried a couple games and didn't run into the crash..
## Link to GitHub Issue or related Pull Request, if one exists
N/A
## Description of change
Move `dirs_created` flag assignment before `dir_create_recursive` calls
in `CreateFileW_Hook` to prevent stack overflow. `dir_create_recursive`
calls `_wstat64` (ucrtbase), which internally calls `CreateFileW`,
re-entering the hook before the flag is set. GCC 13 preserved the source
order, but GCC 15 reorders the flag store after the function calls,
causing infinite recursion.
Note: I'm not fully confident the root cause is specific to GCC version
differences. Also, I cannot determine whether this directory creation
hook is truly necessary. Without these directories the game boots but
quizzes won't load, making gameplay impossible. It may be worth removing
this hook entirely, but for now this fix is needed to prevent the crash.
## Testing
Verified title screen transition on LMA-2019022700. Crashes on the
latest build without this fix.