Commit Graph
58 Commits
Author SHA1 Message Date
YourWishesandClaude Sonnet 5 c8a6325615 Collapse dusk.dsk from two zip archives into one, all uncompressed
Bulk assets (mp3, png) are already compressed at the file level, so a
DEFLATE pass on top bought negligible space for real CPU cost. Packs
everything into a single ZIP_STORED archive instead, so every entry
(not just locale/*) gets the reliable repeated seeking/re-opening that
libzip only supports for uncompressed entries. Header shrinks from 32
to 16 bytes; version bumped to 2 so a stale pre-change dusk.dsk is
rejected and rebuilt rather than misread.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-09 10:17:34 -05:00
YourWishes 8139a0ea54 Add versioned save slot/settings schemas with strict version checks
Splits saveslot_t/savesettings_t into a stable, version-independent
in-memory struct (save/slot/, save/settings/) and a separate frozen
per-schema-version struct (saveslotver1_t/savesettingsver1_t) used only
for JSON serialization, converted between manually. Every write now
stamps a "version" field (SAVE_SLOT_CURRENT/SAVE_SETTINGS_CURRENT), and
every read requires it to match exactly, rejecting anything else -
laying the groundwork for a real migration path instead of silently
misreading old/incompatible save data.
2026-09-08 12:49:06 -05:00
YourWishesandClaude Sonnet 5 cebd3d81e7 Wrap long lines to fit within 80 columns across the codebase
Pure whitespace/line-break reformatting (braces, newlines, and line
continuations matching this codebase's existing wrap conventions) - no
logic, string content, or identifiers changed anywhere. Confirmed via
diff against the pre-change tree and by rebuilding + re-running the
affected test suites, which produce identical pass/fail results.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-05 13:13:10 -05:00
YourWishesandClaude Sonnet 5 3c3dc35e1d Default Wii saves to SD card, store saves next to dusk.dsk/EBOOT.PBP
Wii NAND save storage is blocked by Dolphin's IOS ticket-rights check for
homebrew (documented earlier this session as a known, non-code limitation),
so Wii now defaults DUSK_SAVE_WII_METHOD to SD instead of NAND.

Also: asset_t gains ASSET.baseDirectory, populated by each platform's asset
loader with the real directory dusk.dsk was opened from (or, on PSP, the
directory EBOOT.PBP itself lives in, since dusk.dsk is embedded inside it).
Wii SD and PSP now write their single combined save file directly into
that directory instead of a separate hardcoded path, and no longer need to
create it (it's already known to exist). Linux now uses a `saves/`
subdirectory of that same directory instead of ~/.dusk/saves, since it
keeps multiple files (settings + one per slot). Wii NAND and GameCube/Wii
memory-card storage are unaffected - neither has a real filesystem-path
concept this applies to.

Built and verified on Linux, PSP (Docker), GameCube (Docker) and Wii
(Docker) - confirmed via the compiler invocation that Wii now compiles
with DUSK_SAVE_WII_METHOD_SD.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-04 09:43:00 -05:00
YourWishesandClaude Sonnet 5 619ce932f9 Split audio update into early/late phases, add asset<->stream type map, switch volume/pan to float, add stream loop limit
- audioUpdate()/audioMixerUpdate() split into Early (before rendering, per-stream buffering) and Late (end of frame, starts newly-queued mixer sounds) phases, wired into engineUpdate() around displayUpdate(); mixer is now actually initialized/disposed/updated from audio.c.
- New src/dusk/audio/stream/audiostreamtype.{h,c}: asset-loader-type <-> audio-stream-type map (with file extension), plus audioStreamAssetTypeForPath()/audioStreamTypeForAssetType()/audioStreamAssetTypeForStreamType() lookups.
- audiostream_t/audiomixerchanneldata_t volume and directionality/pan switched from integer (0-0xFF / -128..127) to float (0.0-1.0 / -1.0..1.0), removing the manual scaling each platform backend had to do.
- audiostream_t gains loopLimit/loopRestartCount so a stream can be told to stop (fire onEnd) after a fixed number of loop restarts instead of looping forever; wired into the shared restart path (Linux/Dolphin) and PSP's own read-ahead loop decision.

Built and verified on Linux, PSP (Docker) and GameCube (Docker).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-02 14:39:27 -05:00
YourWishesandClaude Sonnet 5 b564d0b1c1 Add Dolphin MP3 decode-thread ring, share it with Linux, dedupe common code
Fixes the main-thread hitch reported on Dolphin (and, less severely,
elsewhere) whenever the MP3 decode buffer needed refilling:
audioStreamMp3Read() -> audioStreamMp3DecoderDecodeFrame() does real work
synchronously (asset I/O + libmad decode), previously called directly from
each platform's once-per-frame Feed(), blocking rendering for a frame on
every refill.

Adds a background decode-ahead ring (src/duskmad/audiostreammp3ring.c):
a one-shot-per-pass thread reads via the existing audioStreamRead() into a
ring buffer ahead of need; Feed() becomes a cheap, lock-protected drain
instead of a decode call. Reuses this project's own thread_t/threadmutex_t
(mutex+condvar) primitives, mirroring PSP's own background-thread-plus-ring
precedent. Fixes a real (if narrow) race in thread.c along the way:
threadHandler() reset thread->threadId outside the mutex it also used to
signal STOPPED, which a stop-then-immediately-restart pattern (needed once
per pass: play/seek/loop-restart) could hit as a stale-threadId assertion.

Initially built Dolphin-only, then generalized: the ring doesn't touch
ASND at all, so it was straightforward to share with Linux too, moving
both it and the libmad decoder into a new top-level src/duskmad/ - a
shared-capability directory in the same vein as src/duskgl or
src/dusknetwork, pulled in by whichever DUSK_TARGET_SYSTEM values need it
(linux/knulli, wii/gamecube) rather than PSP, which keeps its own
hardware sceMp3 decoder and ring untouched.

With both platforms now sharing real code, deduped what was left:
audioStreamComputeEndFrame() (loop-segment math, byte-identical between
Linux/Dolphin) moved to the generic audio/stream/audiostream.c, and
audioStreamMp3Ring*IfNeeded()/audioStreamReadForPlayback() wrappers (in
duskmad) collapse each platform's own `if(stream->type ==
AUDIO_STREAM_TYPE_MP3)` branches at every Init/Dispose/Buffer/Feed call
site into one check each, living in the ring module itself.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-02 14:10:36 -05:00
YourWishesandClaude Sonnet 5 fd5bcfae90 Switch Linux/Dolphin MP3 decode from minimp3 to libmad
minimp3's sliding-window frame confirmation could spuriously discard real
frames near the tail of a not-yet-full window, losing ~5.5% of a real
VBR file's content even at a tuned 256KB window (~0.3% residual) -
audible as the whole track finishing early with stutters at each drop.

libmad's mad_stream/mad_frame/mad_synth API reports "need more data"
(MAD_ERROR_BUFLEN) and "genuinely bad data" separately rather than
overloading one return value, which was the actual ambiguity minimp3
couldn't resolve. Verified against the same real file with a 32KB window
(vs minimp3's 256KB): frame count and duration match the Xing header
exactly. Confirmed building for Linux, GameCube, and Wii (the latter two
via the project's real devkitPPC/libogc Docker toolchain) - libmad ships
inside libogc itself on Dolphin, no separate fetch needed there.

libmad is GPL-licensed, unlike the rest of this MIT project - a
deliberate tradeoff, noted at each site that pulls it in.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-02 09:47:15 -05:00
YourWishesandClaude Sonnet 5 3ee0a53688 Split audio into stream/ and mixer/ subdirs, fix resulting build breaks
Reorganizes src/dusk/audio/: individual stream implementations
(audiostream, audiostreampcm, audiostreammp3, audiostreammp3decodersw)
move into audio/stream/, and a new audio/mixer/ holds a channel-based
playback queue (audiomixer.c/.h) for future use - not yet wired into
the engine.

Fixes needed to keep the tree buildable after the move:
 - A stray duplicate of audiostreammp3decodersw.c/.h was left at the old
   flat path; removed in favor of the canonical copy in stream/.
 - Updated every #include "audio/audiostream*.h" and the two platform
   CMakeLists.txt (dusklinux, duskdolphin) that still pointed at the old
   flat location.
 - audiomixer.c/.h didn't compile: audiomixerqueue_t was referenced but
   never defined (audiomixerchanneldata_t has the matching fields), a
   trailing comma in audioMixerPlayLooped's parameter list is illegal in
   C, and `file` was declared as an array of pointers instead of a char
   buffer.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-02 09:32:41 -05:00
YourWishesandClaude Sonnet 5 62c081ecf2 Fix minimp3 sliding-window decoder silently dropping frames near tail
audioStreamMp3DecoderDecodeFrame was treating minimp3's "can't confirm
a frame here" verdict as genuine garbage even when the window simply
hadn't been topped up yet - discarding real frames whenever one landed
near the tail of a not-yet-full window, since minimp3 needs to also
validate the *next* frame's header to confirm a decode. On a real ~236s
VBR file this silently dropped ~5.5% of frames, heard as the stream
finishing early ("racing") with a stutter at each drop.

Now refills before ever trusting a "not found" verdict as confirmed
garbage, and grows the window from 16KB to 256KB (past the point of
diminishing returns, ~0.3% residual loss). PSP is unaffected - it uses
the hardware sceMp3 decoder, not this file.

Also removes now-unneeded debug instrumentation from the Linux feed
path.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-01 09:43:19 -05:00
YourWishesandClaude Sonnet 5 f8f8a80a21 Add MP3 audio stream support with hardware/software decoder backends
New ASSET_LOADER_TYPE_MP3 (hand-rolled MPEG-1/2/2.5 Layer III header
parser - no third-party dependency needed just for metadata, since PSP's
hardware path doesn't need one at all) plus a shared audiostreammp3.c
stream layer mirroring audiostreampcm.c's shape. Generalized the stream
dispatch (hoisted sampleRate/channels onto audiostream_t, added
audioStreamGetTotalFrames()/Seek()/Read()) so all three platform audio
backends keep working unchanged, just calling the generic names instead
of PCM-specific ones.

Two decoder backends behind one interface: PSP uses the real sceMp3
hardware decoder (firmware-offloaded, lazily initialized on first use);
Linux and Dolphin share one minimp3-based software decoder (public
domain, vendored via CMake FetchContent) - libogc's own MP3Player wraps
libmad (GPL) and drives its own output pipeline, not a fit for the
ansnd-based architecture already in place, so skipped in favor of the
shared minimp3 path.

Fixed three real bugs found via hardware/runtime testing along the way:
- LAME's Xing header counts its own placeholder frame in the declared
  total, which made playback stall permanently one frame short of the
  declared end (looked like "never loops") - fixed by subtracting it.
- sceMp3Decode() can return more PCM than one MPEG frame's worth in a
  single call (PSP's pcmBuf is provisioned for 2x), overflowing the
  shared per-frame decode buffer with no bound check - very intermittent
  corruption/clicking on real hardware. Widened the buffer to the real
  worst case and added an assertion.
- sceMp3ResetPlayPosition()'s exact internal reset semantics aren't
  documented precisely enough to trust for looping - occasionally
  disagreed with the fresh stream position fed right after, clicking at
  the loop boundary about 1 in 3-4 loops. Rewind now fully tears down and
  recreates the decoder instead, the same path already proven correct at
  first Init. Also widened the PSP ring buffer to absorb that now-heavier
  operation, capping each top-up call's own work so the bigger buffer
  doesn't turn into one long blocking decode burst instead.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-01 08:21:30 -05:00
YourWishes d37109f5f7 Fixed PSP trying to load entirely into memory 2026-08-31 19:07:51 -05:00
YourWishes 15bd9fc43c Clean up audio subsystem duplication, implement seeking and loop regions
- Extract audioStreamGetPanFactors() into the shared layer, replacing
  identical pan-to-LR math duplicated in the PSP and Dolphin backends
  (and dropping a dead clamp - directionality's int8_t range already
  guarantees pan stays in [-1, 1]).
- Implement audioStreamSetPosition() for real (was previously a no-op
  that computed a value and threw it away) and add
  audioStreamSetLoopPoints() to actually drive loopStart/loopTo, which
  were previously dead fields with no setter at all. Both are threaded
  through all three platform backends:
  - PSP: the feeder thread now bounds each pass by the loop segment
    and wraps to loopTo instead of always frame 0, while still filling
    hardware chunks gaplessly.
  - Dolphin: loopTo/loopStart map directly onto ansnd's existing
    loop_start_offset/loop_end_offset, and startFrame onto start_offset.
  - Linux: Buffer() now queues only the current segment, clearing the
    SDL queue on an explicit seek but preserving the existing
    overlap-based gapless loop restart otherwise.
- Linux: skip the mix scratch-buffer entirely at full volume, queuing
  stream->data directly instead of allocating/zeroing/copying into one
  every buffer call for no reason.

Verified no regression in the default (no seek, no loop points) case on
Linux/PPSSPP/Dolphin (-a LLE), and verified seek + loop-region behavior
manually via a temporary engine.c smoke-test tweak (reverted) showing
the expected faster loop cadence and seek-then-loop sequencing.
2026-08-31 17:18:49 -05:00
YourWishes e47a2c3e5c Redesign dusk.dsk into a dual-archive DSK2 format
Splits the asset archive into a compressed (DEFLATE) zip and an
uncompressed (STORED) zip back to back behind a small header, instead of
one plain zip. DEFLATE-compressed zip entries aren't reliably seekable in
libzip, which caused locale string lookups (repeated rewind/reopen of the
same entry) to silently skip content on Dolphin specifically. Uncompressed
entries don't have that problem, so locale files now go in the stored
archive without needing to buffer the whole thing in memory.

Adds tools/asset/pack as the new packer (replacing the plain
`tar --format=zip`), a shared assetdsk.h/.c opener used by all platforms,
and a second ASSET.zipStored handle with fallback lookup in assetfile.c.

Confirmed working: Linux, PSP (PPSSPP), and Dolphin-FAT (Wii DOL under
-a LLE) - the original Dolphin locale lookup failure no longer reproduces.
2026-08-31 15:33:45 -05:00
YourWishes 8a77001016 Fix audio loop gaps: same-tick re-buffer + Linux lead-margin refill
Two independent gap sources, both confirmed fixed on Linux:

1. audiostream.c's Update() used if/else-if, so a loop restart
   (clearing BUFFERED) couldn't re-trigger Buffer() until the *next*
   frame's Update() noticed - up to one frame of dead air on every
   loop, on every platform. Restructured to two sequential ifs so a
   loop falls straight through into re-buffering in the same call.

2. audioStreamLinuxIsFinished only reported true once SDL's queue was
   completely empty - meaning silence had already started by the time
   "empty" could be observed, guaranteeing a gap by construction.
   Changed it to report ready-to-refill once the queue drops to a
   4096-frame lead margin (matching the SDL device's own internal
   buffer size) instead of waiting for zero. SDL_QueueAudio only ever
   appends to a FIFO, so refilling that early never causes overlap -
   it just means the device's callback never runs dry.

Confirmed looping gaplessly on Linux.
2026-08-31 12:33:33 -05:00
YourWishes 8ea370a1d1 Add audio subsystem skeleton with a working Linux PCM playback path
Cross-platform audiostream/audio API with per-platform hooks for
PSP/Dolphin/Linux. Linux is fully wired end-to-end through SDL2
(device open, volume-mixed queueing, finish detection via
SDL_GetQueuedAudioSize) and verified playing a generated test tone
in engine.c. PSP and Dolphin hooks are stubbed for now.
2026-08-31 10:24:02 -05:00
YourWishesandClaude Sonnet 5 28f5e66662 Fix PSP memory stick availability check on real hardware
sceIoGetstat on a bare device root ("ms0:/") returns EINVAL on real
PSP hardware even when a memory stick is present - confirmed via a
diagnostic print during hardware testing. Switched to sceIoDopen/
sceIoDclose, the SDK's own documented way to probe a device root,
which real hardware handles correctly.

Also adds a temporary unconditional settings write once a save device
is selected, to confirm the write path itself works on hardware now
that availability detection is fixed.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-20 17:22:24 -05:00
YourWishes 092e259a06 First pass of actual saving 2026-08-17 09:18:44 -05:00
YourWishes 08b4bbfe91 Added savestatus 2026-08-17 00:17:23 -05:00
YourWishes 45331c2a60 First pass of save 2026-08-14 14:19:44 -05:00
YourWishesandClaude Sonnet 5 33f50a2c69 Strip legacy save/settings systems for a unified savemanager rewrite; split uielement list out of uielement.c
Removes the per-platform save/savestream/autosave implementations, the settings UI frames, and the autosave overlay, replacing them with a savemanager.c/h + savefile.h/savedevice.h scaffold to build the new save system on top of. Also separates the concrete UI_ELEMENTS registration into uielementlist.h/.c so uielement.c only holds the generic per-element lifecycle logic.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-14 12:56:02 -05:00
YourWishesandClaude Sonnet 5 fbd3c71ba7 Move network code into its own dusknetwork module, gate behind DUSK_NETWORK
Splits the platform-agnostic network core out of dusk into a top-level
dusknetwork module, mirroring the duskgl/dusksdl2 pattern. Adds a
DUSK_NETWORK cmake option (default ON) so builds can exclude all
networking code, including the per-platform implementations.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-08 16:13:09 -05:00
YourWishesandClaude Sonnet 5 7357b4a5df Localize remaining hardcoded UI strings and persist language preference
Replaces the last hardcoded English strings (initial-scene modals, game
menu save status messages) with locale-loaded text, adds a shared
LOCALE_LIST so the settings dropdown and locale manager stay in sync,
and persists the chosen language into savemeta_t across all platforms.
Also fixes two message buffers that were too small for their longest
translations.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-04 21:39:24 -05:00
YourWishesandClaude Sonnet 5 aa0180571e Unify save system into one save.h/.c; diverge storage format per platform
Renames savefile_t to saveslot_t and folds last session's standalone
settings.h/.c module back in as savemeta_t, so there's one save system
(SAVE.slots[] + SAVE.meta) instead of two parallel ones - while letting
each platform pick its own physical format for the two concepts:

- Linux now writes human-editable JSON (slot0.json, settings.json, ...)
  via yyjson's mutable writer API, so players can hand-fix a bad setting.
- PSP folds meta into the same sceUtilitySavedata binary payload as its
  one save slot (SAVE_SLOT_COUNT_MAX=1 there - a future save picker will
  let players manage multiple named saves via the OS's own browser).
- GameCube consolidates the 3 per-slot memory card files and the separate
  settings file into one combined card file.

Also fixes two bugs surfaced while building this: the CRC finalize step
seeked to a hardcoded offset (only safe for one section per file, breaks
once meta+slots share a buffer), and save.c's async/sync dispatch left an
unconditional fallback call that doesn't exist on PSP-only platforms.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-04 18:35:06 -05:00
YourWishesandClaude Sonnet 5 7f7be39230 Split device settings out of the per-slot save file
Deadzone (and future prefs like locale) now live in their own
settingsfile_t/settings.c, loaded eagerly at boot and saved immediately
on Apply, instead of inside savefile_t - a setting shouldn't reset or
diverge just because the player is on a different save slot, and this
also fixes settings changes not actually reaching disk until the next
full game Save.

PSP settings use a new plain sceIo path rather than sceUtilitySavedata,
since that dialog would flash its native icon on every settings tweak.
GameCube reuses the save system's existing memory card mount rather than
mounting it twice (settingsInit() now runs after saveInit()).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-04 13:54:15 -05:00
YourWishes 4d95415232 Move global item collected-state, deadzone, and story flags into save file
Adds three new pieces of save-file state, all following the same shape:
the save file is the single source of truth, not a separate live runtime
copy that gets synced in/out.

- globalitemstore.h/.c: per-global-entity-ID "collected" flags
  (savefile_t.globalItemCollected), so a global item entity's init
  callback can check whether it was already picked up in a prior session
  without needing to keep the entity itself alive to remember that.

- Gamepad deadzone: removed input_t.deadzone entirely. The setting UI and
  every platform's actual deadzone-applying code (inputGetDeadzoneDolphin/
  SDL2, previously hardcoded per-platform literals that the settings menu
  didn't actually affect) now read savefile_t.deadzone directly via
  saveGet(SAVE_ACTIVE_SLOT). Default lives in savefile.h
  (SAVE_DEADZONE_DEFAULT), stamped onto every slot in saveInit().

- Story flags: STORY_FLAG_VALUES (a live, codegen-initialized array) is
  replaced by savefile_t.storyFlags, read/written via the existing
  storyFlagGet()/storyFlagSet() call sites (now macros/functions over the
  active save file instead of a separate array). tools/story.py now
  generates STORY_FLAG_DEFAULTS (const) instead; storyFlagInitDefaults()
  stamps those onto a save the first time it's used (file->exists false),
  called from rpgInit().

Added SAVE_ACTIVE_SLOT (0) to savefile.h as the one shared "which slot is
actually being played" constant, replacing three different local/implicit
0s (uigamemenu.c, rpg.c, and now the settings/input call sites).

Verified round-trip on Linux (all three together in one save/load cycle);
both Linux and PSP build clean.
2026-08-04 11:10:44 -05:00
YourWishes 8faf881399 Bit if UI cleanup 2026-06-25 14:56:48 -05:00
YourWishes dc41c0e302 Cleanup 2026-06-07 21:16:46 -05:00
YourWishes 6502822583 Update render, spritebatch and input stuffs. 2026-05-21 09:51:56 -05:00
YourWishes a8fd55cb38 Save file update (incomplete) 2026-05-10 11:20:09 -05:00
YourWishes 73e73d8772 Cleanup animation 2026-05-08 15:44:55 -05:00
YourWishes 6edcf75a0c add display state 2026-05-04 22:16:30 -05:00
YourWishes 0e94c1fa6d Fixed a bunch of messy over 80 char lines 2026-05-04 08:29:43 -05:00
YourWishes 4a4adeb3c8 Finally fixed linux asset weirdness 2026-05-02 15:18:49 -05:00
YourWishes a9948142ad Fix linux warning 2026-05-01 14:00:24 -05:00
YourWishes 61f69af35a Refactor pass 1 2026-04-29 14:53:35 -05:00
YourWishes 52ee627079 Merge branch 'jerryscript' into playertest 2026-04-28 14:02:53 -05:00
YourWishes 73e7d6c7f3 Add epoch 2026-04-28 10:33:23 -05:00
YourWishes a41b0e916b prog 2026-04-28 08:04:01 -05:00
YourWishesandClaude Sonnet 4.6 998601f722 Playertest: scene/script system refactor and Wii ABI fix
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-26 23:30:08 -05:00
YourWishes b640295be2 Scene script 2026-04-20 15:34:24 -05:00
YourWishes c78135aa09 Fixed bugs with console 2026-04-20 12:05:35 -05:00
YourWishes acea610773 Disable curl on linux 2026-04-17 22:53:29 -05:00
YourWishes 8f2f1fd496 Added network info 2026-04-17 17:00:03 -05:00
YourWishes ff84ce2b04 Added PSP Accept/Cance 2026-04-17 15:28:03 -05:00
YourWishes 225f405592 PSP Networking refactor 2026-04-17 14:57:10 -05:00
YourWishes e51cdc8992 PSP net code first pass 2026-04-15 15:50:43 -05:00
YourWishes 133685ea37 Linux HTTP implementation 2026-04-15 15:11:44 -05:00
YourWishes 09c35f0aa6 Builds on knulli 2026-03-27 20:48:43 -05:00
YourWishes 7356286fe0 Adjust how deadzones work
Build Dusk / run-tests (push) Failing after 15s
Build Dusk / build-linux (push) Failing after 21s
Build Dusk / build-psp (push) Failing after 17s
Build Dusk / build-gamecube (push) Failing after 17s
Build Dusk / build-wii (push) Failing after 17s
2026-03-11 13:00:11 -05:00
YourWishes d21cd7f78b Update error and debug logging methods
Build Dusk / run-tests (push) Failing after 14s
Build Dusk / build-linux (push) Failing after 15s
Build Dusk / build-psp (push) Failing after 22s
Build Dusk / build-gamecube (push) Failing after 18s
Build Dusk / build-wii (push) Failing after 15s
2026-03-11 10:33:43 -05:00