Prevents loaded VS unloaded record data output from falling out of sync.
Specifically resolvesKartKrew/RingRacers#130 by making unloaded skins handled properly
The hypothesis for this patch is that the operating system has not actually
finished writing the file to disk when moving the tmp file into place. The
move operation is atomic, but the write is not, even when flushed or using
unbuffered IO. So we reorder these operations, make the old save .bak
atomically and write the new save in place.
I doubt saving this backup will actually be useful given the frequency of
saves in the game, but at the very least it leaves _some_ backup in place in
the event of failure.
- Most R_SkinAvailable calls should be returning index into demo.skinlist (same numerical value as when demo was recorded), for demo sync
- A handful of general things permit exception for this
- Expose `replaynumskins` (calculated as `(demo.playback ? demo.numskins : numskins)`) to Lua
- There's *always* more that can be done for this, but this is the minimum spec that can at least be somewhat stable
- If emerald not yet collected on that cup, pick the first uncollected emerald, then get the cup's CUPCACHE_SPECIAL with that ID to pick the stage
- Already collected emeralds retain their swappage across gamedata saves
- Returns to normal order if you get all 7 OR Special Mode is unlocked (chao key? debug? password in modded games? sky's the limit)
- Pops up a Message from the Stars telling you the gems have been returned to their natural place
- Add-ons will always use their dedicated sealed star, since it's unordered material
If it weren't so last minute I could have a better solution for GP Backups, but right now what I've gone for is it always trusts whatever G_GPCupIntoRoundQueue does AS LONG AS THE COURSE ISN'T THE ONE YOU'RE RELOADING INTO. If it IS, then it checks to see if it's exactly what's been saved, and complains (with the generic error message, unfortunately) if it isn't.