## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
- Replace unnecessary precision timers with standard sleeps to reduce
wakeups and background CPU usage.
- Reuse buffers in raw input, touchscreen, and HID output paths to
eliminate steady-state allocations.
- Pre-index HID button groups and correctly process batched HID reports.
No functional changes.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#840
## Description of change
Currently, for subscreen games, mouse events are still delivered even
when the subscreen overlay window is not visible.
Change this so that the subscreen overlay must be active and under the
mouse cursor for the mouse-to-touch transformation to occur. Applies to
both native and wintouchemu.
## Testing
Needs to test everything again..
iidx:
- [ ] full screen with overlay
- [ ] single window with overlay
- [ ] two window
Test: mouse, poke, api, real touch screen
sdvx:
- [ ] full screen with overlay
- [ ] windowed
popn
- [x] full screen with overlay
- [x] window with overlay
- [x] dedicated window
gitadora
- [x] single window with overlay
- [x] dedicated sub window
nostalgia
- [x] fullscreen
- [x] windowed
test: poke
wintouchemu
- [ ] Do all of the above again with wintouchemu
## Link to GitHub Issue or related Pull Request, if one exists
#201
## Description of change
- Adds MJPEG camera support using Media Foundation decoding.
- Moves camera capture to asynchronous Source Reader callbacks.
- Supports native NV12 and YUY2 capture, preferring target-sized native
formats over MJPEG when possible.
- Improves capture and rendering performance through callback-paced
reads, bulk frame uploads, optimized row-based flips, and lazy
allocation of flip textures.
- Makes runtime media-type changes interrupt pending reads and safely
flush and reconfigure the Source Reader.
- Improves automatic mode selection based on aspect ratio, proximity to
1280x720, frame rate, and capture format.
- Hardens camera shutdown, flush handling, media-type changes, and
repeated capture failures.
## Testing
Tested with two cameras in tdj
## Link to GitHub Issue or related Pull Request, if one exists
Regressed by #657
## Description of change
Workaround for SDVX4 was applied too broadly and caused sdvx 1/2/3 to
not boot, depending on contents of avs-config.xml.
`property_search_safe` throws a fatal error if the node is not present.
What we wanted to do was to check for presence.
## Testing
sanity checked sdvx 1/2/3/4
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
ImGui filebrowser extension crashes due to MinGW quirk about UNC path
handling.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#833
## Description of change
Last couple PRs - such as #820#827#828 - made the native touch hook &
touch injection using `InjectTouchInput` the default path, since it
performs much more reliably with both real touch screens and mouse (or
any other synthetic source).
However, user has reported that WINE lacks `InjectTouchInput` which
means this won't work.
As a fix, revive the old wintouchemu code. Native touch is still the
default, but under following circumstances:
1. if `-touchemuforce` is set, or
2. if any of the required Windows touch APIs are unavailable
then we fail over from native touch to wintouchemu code.
For Linux, condition #2 would be hit during init, and gracefully switch
over.
Caveat: the poke code for IIDX and Nost will continue to require native
touch, I do not want to maintain two paths for this. This means that
iidx poke will stop working on Linux, unfortunately.
## Testing
Tested on Windows with `-touchemuforce` set. This is mostly reverting
Linux code path back to where we were last release, so this should just
work with wine.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Touch piano mode. Allows piano keys to be played with the touch screen.
Since the touch screen is still needed for menu navigation (including
during songs) a toggle switch is added so that the user can flip between
navigation mode and piano mode.
The touch targets are pixel-perfect. Don't let the game's piano
animations fool you.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Prevent the game from launching a blank window when launching fullscreen
with sub disabled.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
#814
## Description of change
Make gitadora arena model use native touch instead of wintouchemu. Only
single window mode with overlay is affected.
This removes the last consumer of `INJECT_MOUSE_AS_WM_TOUCH` so all of
that code can be deleted.
## Testing
Tested touch screen and mouse interaction with single window mode.
## Link to GitHub Issue or related Pull Request, if one exists
#814
## Description of change
Switch over Nostalgia from wintouchemu to native touch hook.
Nostalgia has some strict timing requirements (touches must be updated
on every acio poll) so this takes a slightly different path to maintain
mouse holds.
Only a handful of consumers of wintouchemu remain:
1. beatstream - but it's off by default, only enabled as errata for
buggy touchscreens, or if the user forces it on (for Show Cursor)
2. gitadora single-window overlay - this is just for mouse so not a big
deal.
3. MFC HG mode - not a priority to fix.
## Testing
Tested full screen and windowed mode with touch / mouse / poke.
## Link to GitHub Issue or related Pull Request, if one exists
Another bug reported by a sea creature
## Description of change
Fix keyboard navigation in Controllers sub tabs.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Reported by a certain sea reptile
## Description of change
Fix the + / - buttons for number patches not working. Regressed by one
of the ImGui version updates.
## Testing
seems fine now
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#814
## Description of change
Touches via the API wasn't being delivered to native touch hook;
implement this, which closes the last gap we have vs. wintouchemu.
While we're here, implement popn subscreen support for companion as
well.
## Testing
Tested for iidx/sdvx/popn
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#822
## Description of change
Add hooks for `libxact.dll` which only Nostalgia uses for audio. Detect
cases where the game would fail to launch (wrong number of channels) and
log a warning / deferred log.
## Testing
tested 2024102200
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#814
## Description of change
Remove iidx/sdvx/popon `native touch` options.
Remove dead code in wintouchemu that deals with these games.
Native touch is now at feature-parity with wintouchemu. Native touch
options work better with touch screens, while rawinput-based wintouchemu
has compat issues on some touchscreens. For these subscreen games
deprecate the usage of wintouchemu and make them use native touch stack
by default.
### For future consideration
Gitadora - not sure what to do with this one. We only use wintouchemu
for the single window case. For all other configurations, the game
accepts mouse and touch input without any hooks, so perhaps nothing
needs to be done here.
Nostalgia - consider moving away from wintouchemu and adopt native touch
hook here as well.
## Testing
WIP
## Link to GitHub Issue or related Pull Request, if one exists
User reported
## Description of change
Sometimes the game moved the main window after `CreateWindowExA`
returned but before D3D initialization called
`graphics_capture_initial_window`. During this gap,
`GRAPHICS_HOOKED_WINDOW` was not set, so the placement hooks could not
identify the main window and preserve its monitor override. GITADORA
main, LEFT, and RIGHT windows are now registered immediately after
creation so later placement calls cannot undo their overrides.
This also adds `-gdwsmallsize` and `-gdwsmallpos` for explicitly setting
the SMALL window size and position. Explicit values override the
corresponding monitor-derived geometry, allowing the SMALL window's
10:16 aspect ratio to be preserved instead of stretching it to fill a
monitor.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#635
## Description of change
Adds optional **button modifiers**, allowing a binding to require one or
more "modifier" buttons to be held before it activates.
- New "Modifiers" controller page in the overlay config to bind the
Modifier 1–4 source buttons.
- Each binding gains a 4-bit modifier_mask (Modifier 1-4). It is
persisted as an optional modifiers XML attribute on button nodes and
controller-preset entries. The attribute is optional and defaults to 0,
so existing config files and presets load unchanged and the feature is
off unless the user opts in.
- The button Edit properties popup gains a "Modifiers" dropdown to pick
which modifiers a binding requires. Doesn't apply to MIDI though.
- Input evaluation skips a binding whose required modifiers are not
held, falling through to its alternatives; velocity reporting uses the
same gated path.
- Controller-preset templates gain a "Modifiers" group for importing and
exporting.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Part 1 of many fixes for #814.
## Description of change
For the native touch hook - add code to inject synthetic touches using
Windows API (`InjectTouchInput`).
Note that this is Windows 8+ only, but we can make an assumption that we
are running on Win10+ for these games (TDJ/UFC/High Cheers) since the
cabs assume Win10.
Detect mouse events and allow IIDX poke to call into this to inject
synthetic touches.
Also, update the nativetouchhook to independently calculate window size
and rotation, instead of relying on rawinput layer.
## Testing
Tested to work with native touch option on IIDX, SDVX, POPN, all full
screen / windowed / sub on/off combinations.
Edge cases:
* sdvx main monitor rotated 270 deg
* touch invert option
* windowed mode resize / moved
All seem to work.
## Link to GitHub Issue or related Pull Request, if one exists
Regressed by #790
## Description of change
Avoid enumerating every display mode with `EnumDisplaySettings` during
the first raw touchscreen report, as it can take a couple hundred
milliseconds.
The latency-sensitive path now refreshes only the current display size
using `GetWindowRect(GetDesktopWindow())` and orientation using
`EnumDisplaySettingsEx(..., ENUM_CURRENT_SETTINGS, ..., EDS_RAWMODE)`.
Full `EnumDisplaySettings` enumeration runs only when native resolution
is needed for aspect compensation.
Jubeat and Reflec Beat now enable aspect compensation before
initializing touch input.
## Testing
Sanity checked rb/jb on laptops with non-16:9 ratio
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
In summary: for SDVX VM mode, this PR eliminates the need for `Note FPS
Target 120Hz` / `Game FPS Target 120Hz` patches typically used for AMD
GPU via synthetic responses provided via a fake NVAPI layer.
Before this change, playing on AMD GPU required patches to force the
game to render at 60Hz (See #107 for relevant discussion). Basically, if
NVAPI query fails, the game shows
`I:NvDisplayConfig: GetMainDisplayRefreshRate = 60.000hz (DUMMY)`
the game renders at 120Hz but the notes render at 60Hz, which would look
stuttery.
After this change, even without a real `nvapi64.dll`, spice will provide
a stub implementation, just enough to convince the game that the main
display is 120Hz, which causes notes to render at 120Hz as well.
This can be overridden by `-graphics-force-refresh` option.
Important note: if user has the `Note FPS Target 60Hz` patch but running
the game at 120Hz, before this change the notes would render at 60Hz,
but after this they will be at 120Hz. I don't know why anyone would
intentionally lower the notes framerate, so this is not going to be
fixed. If the user wants to run the game at 60Hz they can do so via
`-graphics-force-refresh`.
Another change - `-nonvapi` will always force down this synthetic nvapi
path, even if the system has the real `nvapi64.dll`. Even on NVDIA GPU
this option can be used to force this.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#245
## Description of change
Introduce patch groups. JSON schema now allows for a `"type": "group"`:
```json
{
"type": "group",
"gameCode": "LDJ",
"id": "timer-freeze",
"name": "Timer Freeze Patches",
"description": "Freezes various timers in the game."
},
{
"name": "Standard/Menu Timer Freeze",
"description": "Freezes all non-premium area timers.",
"caution": "",
"gameCode": "LDJ",
"type": "memory",
"group": "timer-freeze",
"patches": [
{
"offset": 9962743,
"dllName": "bm2dx.dll",
"dataDisabled": "0F84",
"dataEnabled": "90E9"
}
]
},
{
"name": "Premium Free Timer Freeze",
"description": "Freezes all premium area timers.",
"caution": "",
"gameCode": "LDJ",
"type": "memory",
"group": "timer-freeze",
"patches": [
{
"offset": 9111965,
"dllName": "bm2dx.dll",
"dataDisabled": "7E",
"dataEnabled": "EB"
}
]
},
```
In the UI, these will show up as tree nodes. The parent is not actually
treated as a patch; e.g., its state is not saved to the patch manager
config file; only the child patches states are managed, the parent's
state only bubble up only in the UI.
In downlevel versions of spice, group parents will show up as a patch of
invalid type. Child patches will still show up as individual patches.
## Testing
*how was the code tested?*
## Link to GitHub Issue or related Pull Request, if one exists
#345
## Description of change
If IIDX/SDVX/POPN "native touch" option is enabled, show an error
message if user toggles subscreen window.
Those options are meant for users with touch screens, and disables mouse
interactions. Users who like to randomly turn on options often latch on
to this option and get confused when clicks don't register.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Fix a long-standing issue of hotplug not working for keyboards and mice.
The code only registered for HID notifications; we also need to do it
for the keyboard GUID and mouse GUID.
## Testing
Confirmed that keyboards and mice can be hot unplugged and plugged.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#782
## Description of change
This addresses an issue only seen on Linux + WINE.
Defer retaining WASAPI clients until `Initialize` succeeds.
Before this PR, temporary clients created during DirectShow device
capability probing were retained as active audio clients, causing
Wine/Linux crashes in DDR and popn.
Also covers IAudioClient3, dummy, ASIO, WaveOut, and null-device
initialization paths, for consistency.
## Testing
WIP
## Link to GitHub Issue or related Pull Request, if one exists
Regressed by #793
## Description of change
Due to lock inversion, when binding an analog axis as a button, spice
deadlocks. Fix that.
Also create a separate `unordered_map` that keeps track of device
handles so that `WM_INPUT` handle can look up devices without having to
acquire the larger `devices_mutex` which could be held by (potentially)
lengthy operations like hotplug.
Fix more synchronization issues around hotplug. Latent bug exposed by
MIDI 2.0 issues.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Refactor patch manager.
This one file had the UI logic, config save/load, parsing patches JSON,
applying memory patches, everything all in one cpp file. Refactor and
separate out the layers.
## Testing
Sanity checked patch workflows.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
GDI bit blit overlay used exclusively for jubeat & shogikai was running
at 30fps, which caused the Jubeat touch debug UI to not render fast
enough. Run it at 60 fps, and also perform double buffering to avoid
flickering.
This could have been scoped to JB but I made the change for both. XP
builds will keep running at 30fps since those people run on cabs with
ancient hardware.
## Testing
Tested jubeat and shogikai, overlay renders without flickering at 60 fps
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Fixes held touch contacts briefly dropping under rapid multi-touch (e.g.
holding several jubeat buttons and tapping elsewhere many times would
make the holds briefly release and the hold again).
A HID digitizer reports a fixed number of contact slots per report and
cycles the rest through later reports, so the touch layer keeps an
unreported contact alive for a few reports (a per-contact TTL). The TTL
was only set for contacts in the current report and had no slack, so
when the contact count rose (from the rapid taps) the reporting cycle
got longer and stationary holds were expired before the device cycled
back to them.
Now, the cycle length is recomputed every report and every tracked
contact's TTL is extended to it (never shrunk), so a rising contact
count can't starve a currently held contact. The 50 ms last-report
timeout still removes genuinely lifted contacts.
## Testing
Tested on jb, rb.
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Fix a long standing issue with card reader behavior in jubeat.
sciunit emulation has a bug - when on the title screen / demo loop,
inserting a card did not generate an interrupt. Users always had to
press the game start button and card in. Fix this by reversing what the
actual sciunit does and mirroring the state machine behavior.
## Testing
Tested L44 and K44.
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#800
## Description of change
Restores keyboard navigation by default in spicecfg, and add an option
to optionally enable it in the overlay.
## Testing
## 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#603
## Description of change
Scanning for midi devices can take a while on Windows 11 with MIDI 2.0
service. Sometimes it'll take a couple seconds. Sometimes, on a PC with
zero MIDI devices, it takes 10-11 seconds.
This was causing two issues:
1. slow startup time
2. crash on invalid memory access due to a race condition
Address both.
Also fix a bug: when a device change event fires, we do a MIDI scan, and
invalidated all existing MIDI devices in favor of creating new handles.
Stop doing this, and instead check for duplicates by matching the ID and
keep existing device handles alone. Properly clean up devices on unplug.
Also: fix MIDI buttons being stuck on when unplugged while holding a
key.
## Testing
Tested with Nostroller in MIDI mode. rtpMIDI works too.
## 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
#787
## Description of change
Updates usage of `windows_dll_compat_checker`
## Testing
it builds
## Link to GitHub Issue or related Pull Request, if one exists
Fixes#787
## Description of change
Remove the call to `RegGetValueA` as it is Vista and up. Replace with
`RegOpenKeyExA` + `RegQueryValueExA`
## Testing