Only affects the caption bar.
Should work for:
- [x] standalone configurator
- [x] dx9 games, including multi-window games like gitadora
- [x] Unity games
## Link to GitHub Issue or related Pull Request, if one exists
n/a
## Description of change
Fully flush `tmp` file and then use `MoveFileExW` instead of `CopyFileW`
which guarantees atomic operation on NTFS.
## Testing
## Link to GitHub Issue or related Pull Request, if one exists
#73
## Description of change
Generated cards now start with E0040100 to fully match real cards. The
placeholder example `E004010000000000` is replaced with
`E0040100FFFFFFFF`.
The invalid placeholder/fallback PCBID `04040000000000000000` is
replaced with `01201000000000010101`, which contains a valid
header/checksum, making it closer resemble a real PCBID while still
clearly being an example.
## 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
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
#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
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
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.
## Description of change
`std::ostringstream.str()` returns a temporary string so it's invalid to
obtain c_str from it and pass it around.
## Testing
wip
## 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
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.
## 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.
## Link to GitHub Issue or related Pull Request, if one exists
#592
## Description of change
* when custom DLLs are detected (`d3d9.dll`) print out some basic data
from the PE header
* for our own NVIDIA DLL stubs, add manifest files to identify ourselves
* as a bonus, when DLL hooks are loaded from `-k`, print DLL info there
as well
This is mainly to detect when DXVK is in use.
- 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, if one exists
n/a
## Description of change
Adds an option to pick from four algorithms for guitar picking input.
The default behavior is being switched from legacy (rising edge only,
always 1 frame of input) to SOCD "prefer recent" algorithm. This makes
it slightly easier to navigate the menu with the guitar.
## Testing
Validated gw, gwdelta, and sdvx just in case.
## Link to GitHub Issue, if one exists
Fixes#512
## Description of change
Fix digital wailing not being recognized consistently.
Also address the fact that wailing was completely broken when lefty mode
was on. This requires a new option that the user needs to check off in
the configurator since we can't magically guess if the user is holding
the guitar in lefty mode.
- [x] fix downward wail
- [x] digital lefty mode
- [x] implement all of this for arena model i/o
- [x] test dx cab 2p
- [x] lefty toggle in overlay
- [x] fix analog not working for 2p guitar
- [ ] analog lefty mode?
## Testing
Checked GW and GW Delta
## Link to GitHub Issue, if one exists
n/a
## Description of change
Use fmt library for formatting time
Round down sub-second units so that the FPS counter only updates once
per second (instead of Time and Uptime ticking independently)
clean up usage of `localtime` in `logging.cpp`
## Link to GitHub Issue, if one exists
n/a
## Description of change
Apply SOCD cleaner algorithm to deal with the case where both
counter-clockwise and clockwise buttons are pressed at the same time.
In SDVX, default algorithm is to prefer the most recently pressed
direction. This is better for dealing with slams in rapid succession,
for example, as you don't have to completely let go of one direction to
hit the other now.
In IIDX, default algorithm is neutral (same behavior as before). Using
last or first algorithm results in double scratches which means you'll
likely end up with an excessive poor after hitting a scratch, so neutral
is actually beneficial. Besides, if you are serious about playing on the
keyboard, you should be using `TT +/-` and `TT +/- Alternate`.
## Testing
Tested SDVX 3, EG (old cab), EG valk cab modes, IIDX 24, 27, 33
(tdj/ldj)
## Link to GitHub Issue, if one exists
n/a
## Description of change
Make the text color cyan to make the messages stand out.
## Testing
Verified in terminal.
## 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
n/a
## Description of change
For HID device descriptor, use the "W" version of Windows API, and make
sure UTF-8 is being used throughout since that's the only format IMGUI
supports.
Before this change, non-Latin characters would have shown up as `HID ???
?????` for a mouse, for example.
Due to the way ImGui loads fonts, only the following languages are
supported:
* Simplified Chinese
* Cyrillic
* Japanese
* Korean
* Thai
* Vietnamese
## Testing
Tested various combination of Windows UI language and non-Unicode
language.
## Link to GitHub Issue, if one exists
#410
## Description of change
When raising fatal errors via `log_fatal`, also show a modal popup.
Update instances of `log_fatal` where the message was too long to fit.
## Testing
Tested various failure conditions.
## Link to GitHub Issue, if one exists
#410
## Description of change
Forcibly minimize all windows before showing the crash dialog. Without
this, the dialog shows "behind" the game when launching multi-monitor
fullscreen games (TDJ, VM)
## Testing
Tested TDJ and VM in fullscreen.
## Link to GitHub Issue, if one exists
#345
## Description of change
Show a MessageBox when signal detects a crash.
## Testing
Tested full screen and windowed games.
## Description of change
Detect and log troubleshooter messages for:
* (early) hook DLL load failure
* data_mods folder without ifs_hook.dll
* spice version (print out current version and add a link to github
download)
## Testing
## Description of change
Finally figured out where the deadlock was coming from - it's because
the `dump_to_logger` was writing `SuperstepSound: Audio device is not
available` to the logger which calls back into the log hook, and then
emits another deferred message, trying to acquire the lock again on the
same stack.
## Testing
Tested the superstep sound failure case again.
## 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
[#390 ](https://github.com/spice2x/spice2x.github.io/pull/390)
## Description of change
Just like the normal logger, deferred logging can be called from any
component at any time, so accessing the vector needs to be guarded.
## Testing
## 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.