github spacefarergames/AloneInTheDarkReHaunted 1.0.2
1.0.2.2003

latest releases: 2.1.0.2204, 2.0.1.2004_Pre, 2.0.1.1504...
one month ago

Download Link Removed due to this version being out of date. Please download latest release.

Version 1.0.2.2003 — Stability & Audio Fixes

🐛 Critical Crash Fixes

Use-After-Free in Music Playback (ACCESS VIOLATION 0xC0000005)

  • Root cause: osystem_playTrack() freed the audio archive buffer (s_musicArchiveBuf) while SoLoud's audio mixing thread was still streaming from it. WavStream::loadMem() was called with aCopy=false, meaning SoLoud reads directly from the provided buffer pointer — freeing it mid-stream caused an access violation on read.
  • Fix: The old WavStream is now fully destroyed (not just stopped) before freeing the buffer, ensuring SoLoud's audio thread has completely released all references.
  • Previous DiskFile objects from the filesystem fallback path are now also properly deleted, fixing a memory leak on every track change.

Heap Corruption from malloc/delete[] Mismatch

  • Root cause: readAudioEntry() allocated buffers with malloc(), but SoLoud's MemoryFile::~MemoryFile() frees owned memory with delete[]. When osystem_playSampleFromName() passed aTakeOwnership=true, SoLoud would later delete[] a malloc'd buffer — undefined behavior that silently corrupts the heap and causes delayed crashes.
  • Fix: readAudioEntry() now allocates with new unsigned char[], and all error-path deallocations use delete[], matching SoLoud's expected deallocation mechanism.

Null Pointer Dereferences in Rendering Loop

  • Root cause: AllRedraw() in main.cpp accessed pHybrid from HQR_Get(HQ_Hybrides) and bodyPtr from HQR_Get(HQ_Bodys) without null checks. Certain game states returned null pointers, causing immediate crashes.
  • Fix: Added null checks for both pHybrid and bodyPtr with continue to skip invalid entries.

🔊 Audio Fixes

Double Music Playback

  • Root cause: osystem_playTrack() always returned 0, regardless of success. The caller playMusic() checks the return value to decide whether to skip the AdLib/OPL fallback path — returning 0 meant the AdLib music ALSO played on top of the already-playing MP3/OGG stream.
  • Fix: osystem_playTrack() now returns 1 on successful playback (archive or filesystem), 0 on failure. playMusic() correctly skips the AdLib path when streaming audio is active.

Missing Null Guards in Audio System

  • Added gSoloud null checks in osystem_playTrack() and osystemAL_udpate() to prevent crashes if the audio engine hasn't been initialized.
  • Added error handling for the filesystem fallback loadFile() path — previously failed silently without cleanup.

Proper Shutdown Cleanup

  • closeAudioArchive() now stops and destroys the active music stream (pWavStream, pFile, s_musicArchiveBuf) before closing the archive file, preventing use-after-free during exit.

🛠 Diagnostics Improvements

Full Stack Traces in Crash Logs

  • Previously: HandleException called LogExceptionQuiet for all exception types, producing only a one-line crash message with no stack trace — useless for debugging.
  • Now: Access violations and other serious crashes call LogException, which writes a full stack trace with symbol resolution (SymFromAddr, SymGetLineFromAddr64). Heap corruption and CRT breakpoints still use the quiet logger to avoid re-entrancy issues.

Don't miss a new AloneInTheDarkReHaunted release

NewReleases is sending notifications on new releases.