Releases: davidvanderburgh/pinball-asset-decryptor
Release list
v0.226.0 — The boot menu's card counter and countdown word are the card owner's
Highlights
The boot menu on a multi-boot card has carried two lines nobody could change: the < 2 / 5 > counter under the cards, and the word "starting" in front of "starting <title> in 9 s". Both are now the card owner's. Menu settings in the Multi-boot tab has a Count the cards under them tick that takes the counter line off the menu altogether, and the At power-up section has a Countdown says box whose gray example under it is the real line, drawn with the highlighted image's own name in it, so you can see the wording before you build. Leave the box empty and the countdown reads just the title and the seconds.
The countdown line is now sized from the wider of the "press START to boot" form and the countdown at three digits, so a word longer than "starting" is shrunk and cut to fit the glass rather than running off the edge of it.
On the card these are two new images.conf keys, counter=on|off and countdown_word=TEXT. mkmulticard.py and mkjjpmulti.py take them as --counter and --countdown-word on every command that builds, injects or updates a menu, record them in build.json, read them back off a card and name them in the report; the emulator preview shows the card's own lines. A counter word the menu does not recognise is warned about and the counter kept, and a card that sets neither key renders byte-identically to before.
Requires
No new external dependencies.
v0.225.4 — A random set no longer blanks the Multi-boot card size
Adding a random set to the Multi-boot image list made SD card needed go to a dash and stay there: the strip said the images had to be on this machine about a list whose every image was right there, and nothing re-armed the check for the rest of the session.
A random card is ONE row with several member games behind it and no path of its own, and both halves of the size check read one path per row — so the group's empty path read as an image that is not on this machine. The check now counts the GAMES the card will carry, a set's members included, so the size is measured, editing a set's members asks the question again, and an image that really is missing still refuses. Whether a set keeps its members' own cards is part of the question too: a keeping set adds no games to the card and a consuming one adds all of them, which is two different sizes off the same images.
The size strip is also its own refresh button now — click it and the list is measured again. That is the way back from the two states that carry no next question in them: a check that failed, and an image that was not on this machine when the list last moved and is now. No new widget, so the tab's height budget is unchanged.
Requirements: Windows 10/11, macOS 12+, or a Linux desktop. Download the installer for your platform below.
v0.225.3 — An in-app update keeps the session it updated from
Highlights
Using the app's own Update button no longer costs you the work you did in that session. If you added a Multi-boot image, changed the menu, or pointed the app at a different card and then took the update that popped up, the app used to come back holding the state of your last clean quit instead — the rows from the session that pressed Update were simply gone.
The save now happens FIRST. The open project's card and folder, and every global setting including the whole Multi-boot form, are written to disk before the installer is launched on Windows, and before the successor AppImage starts on Linux. Previously that write sat behind stopping the preview and shutting the emulators down, which is a blocking step bounded at 25 seconds for a Stern panel and two minutes for a JJP one — meanwhile the installer was already closing the app, so whichever got there first won, and it was usually not the save.
Quitting normally writes exactly the same things in exactly the same way; it just does them before the shutdown rather than after it, which changes nothing about what gets written.
Requires
No new dependencies.
v0.225.2 — A drained ball ends the game on the virtual playfield
On the virtual playfield, a drained ball now rolls down the trough before it settles. The ball that left play is genuinely out of play, so when the last one drains the game ends instead of sitting there waiting for a ball that is already gone. Watching a battle play out no longer leaves the playfield stuck at the end of it.
Every ball move is now read back after it is written, and a move that did not land is named rather than quietly counted as done. On systems where the live event feed runs through mawk it keeps up in real time again, and the feeder's own log is timestamped, so a line that arrived late can be told apart from one that never arrived.
This re-ships the content of v0.225.2's withdrawn predecessor with the test-side regression that withdrew it fixed: the live-feed scraper the tests share now lives in one place, accepts both spellings of the feed's awk line, and a new test pins that anchor in the script itself.
v0.225.0 — Edit image fits the screen, and draws the card it is editing
Highlights
The multi-boot Edit image… window no longer runs off the bottom of the screen. OK and Cancel are packed against the bottom of the window before anything else asks for room, and a form with no room left scrolls instead - a bar, the wheel, and the Page keys - so the buttons are always reachable. It takes a short desktop (a 768-high laptop) or Windows display scaling for the tallest form of that dialog to hang off the edge at all, which is why it never showed on a tall monitor; now it cannot. Menu settings… and Build / flash card… are built on the same modal and inherit the fix, and a dialog that already fits is drawn exactly as it always was.
Edit image… now also draws the card it is editing, beside the fields. It is the card as the boot menu draws it - the picture, the title under it, the subtitle under that, in the menu's own highlighted colours - and it follows every keystroke, so naming a card or choosing its picture shows you the result there and then instead of sending you back to the main page to look. The preview costs a file read, not a build: it takes the picture file you picked, or the first frame of the clip, or the art the card last rendered, whichever the row actually has.
What the card's picture comes from is now a single drop-down rather than a column of choices. Nine options stacked as radio buttons spent 250 px on a question with one answer, and the preview beside them answers what that column was there to answer. The options themselves, and what each one writes to the row, are unchanged; the two ways a random card picks its game are still a pair of radio buttons.
Requires
No new dependencies.
v0.224.2 — Virtual playfield: watching a battle no longer costs you the ball
Highlights
The virtual playfield's mouse-driven ball feeder used to decide "nobody is playing" one ball at a time, so a quiet moment right after a launch was enough for it to take that ball back to the trough. A battle is the worst place for that, because a battle is exactly when a player stops clicking and watches: the feeder took the ball, the game handed it straight back under the battle's ball save and auto-plunged it, and the player's own Drain then landed on a trough the feeder had already filled, so the game never ended.
Whether anybody is playing is now a question about the room. While anybody has moved anything in the last minute, no launched ball is taken back at all, and the feeder says how long ago somebody was at the controls rather than quietly helping itself. It is a window and not a latch, so a room that really did empty still returns its balls a minute later and a ball search still gets what it is waiting for.
Notable bits
PAD_BALL_HUMAN_MSsets the window, default60000ms;0restores the previous per-ball rule exactly.- Documented next to
PAD_BALL_HOME_MSin the Spike 2 emulator README. - New unit tests and a feeder-test section that clicks BEFORE the launch, which is the only order that shows the fault.
Requires
No new dependencies.
v0.224.1 — A multi-image boot menu takes the keyboard on a first run
Highlights
The boot menu on a multi-image Spike 2 card now takes the keyboard the first time you run a title in the emulator. Before, on a fresh install or a title that had never been run, the arrow keys and Select did nothing: the menu reads its keys through the game's switch list, but the game only builds that list about a minute into its first start, after the menu has already run. The virtual playfield sat on "WAITING for tables" and the countdown booted the default image. The menu's eight buttons (left, right, start, action, select, plus, minus, back) are now also read by name, fed by the keyboard and by the virtual playfield, so they work from the first second on any title.
Notable bits
- The game never reads these buttons, so a key mapped to the menu cannot press a switch on a title that owns that index.
- A card whose switch list has no lockdown (Action) button still has no Action button in the menu.
- Real-hardware input is unchanged; this is the emulator's input path only.
Requires
Nothing new.
v0.224.0 — A random card's "never repeat the last one" is a tick, not a rule
Multi-boot: the random card's box now matches how it really works
There are two ways a random card can draw a game, and "never the one it booted last" was never a third one — it is a rule laid over whichever way you chose. The Edit random card box now says that: two radio buttons, Truly random ("100% random, so it can give you the same one twice") and Shuffle ("cycle through every game before any of them repeats"), with a tick underneath for never the one it booted last. Before, the three sat as exclusive buttons, so asking for no immediate repeat quietly gave up the shuffle.
Under Shuffle the tick shows on and greyed rather than disappearing, because a deck never deals the same card twice running — it is the shuffle's own answer to the question. Come back off shuffle and the tick is the way you left it, so the round trip is a round trip.
Nothing about the cards changed: the pair of controls spells the same single word the card has always stored, so cards already built, the card format and mkmulticard all read exactly as before.
The shuffle now keeps the promise the greyed tick makes
On a card where a game boots from its own image, a shuffle could previously hand that same game straight back as the very next roll — the greyed tick would have been a lie there. A shuffle now leaves the build the machine booted last (and its device) out of the deck on every kind of card, not just the ones that boot from a shared pool.
Requirements: unchanged. Windows installer, macOS DMGs and the Linux AppImage attach to this release as their builds finish.
v0.223.1 — Edit image names the confirm sound it will play
Multi-boot: the Confirm sound box says which sound it will play
Edit image's Confirm sound box now carries a live line under it naming the sound that image will play — "Plays Kaiju Confirm.wav, the menu's own.", "Plays Godzilla Roar.wav, this image's own.", or "Plays nothing: neither this image nor the menu has a confirm sound." — rebuilt as you type. It shows the file's NAME, which is what the images list's Confirm column shows and what the box itself cannot (the box holds the whole path), so the properties page and the list finally say one thing. The old static sentence buried in the paragraph underneath is gone, so the name is not said twice.
A per-image none now reads the same everywhere: the Confirm column, the Play button and the built card all agree that it falls back to the menu's sound, because that is what the card does with it — the format has no per-image silence. The Confirm column also copes with a quoted path.
Re-ships v0.223.0, which was yanked
- One text size for every card in the boot menu. Every card draws its title and subtitle at a single size, measured so the longest name on the card still fits, so one long title no longer shrinks only itself while its neighbours stay large. Same text size on every card in Menu settings is the tick; clearing it puts every card back on a size of its own.
- An elevated run no longer poisons the Linux emulator rig. A run that does have root hands each thing it builds back to the account that owns your emulator folder, and the writes that can still fail name the file, its owner and you before they stop.
The regression test that caused that yank is fixed here: its simulated BSD stat asked the real stat in GNU syntax, so it could only pass on a GNU host.
v0.222.0 — Carry a built card's baked-in mods and the folder's own replacements in one transfer
Highlights
A modding folder that was extracted from a card this app built carries two rounds of work: the mods already baked into that card, and the replacements assigned in the folder since. Transfer Mods to New Version only ever carried the second of those, because the baked ones are the folder's baseline rather than edits, and the only way to reach them was a pristine extract of the old card - which means having that card.
Now the transfer names the situation instead of quietly dropping half of it. A folder off a card this app built says which card, and says that on its own only its own replacements come across. Fill field 3 (the optional clean extract of the OLD version) with a stock extract of that card's code and the transfer offers to carry both in one run: the baked-in mods first, compared against that stock extract, then the folder's own replacements on top, which win on any slot the two share by being the newer round.
Each pass keeps its own confirm dialog, and declining the first - or finding nothing in it - still runs the second; they are separate decisions. A failed apply stops the chain, being an error rather than an answer. A folder extracted from a stock card behaves exactly as it always did.
Notable bits
- The built-card check costs one
statfor the build record beside the recorded source card, so nothing about the normal transfer got slower. - With no stock extract given, the offer would be a lie, so the pending route opens with the limit stated plainly and names the field to fill.
- Two transfers onto one folder already compose, so this is the two existing routes run in order rather than a third route.
Requires
No new external dependencies.