Skip to content

Commit 2415d64

Browse files
committed
Merge branch 'refactor' of https://github.com/Raffaello/sdl2-sonic-drivers into refactor
2 parents 8d7a0ea + e6bb4a9 commit 2415d64

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed

sdl2-hyper-sonic-drivers/examples/adl-play.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,32 @@ using files::westwood::ADLFile;
3030
using drivers::westwood::ADLDriver;
3131

3232

33+
/**
34+
* @brief Play an ADL file using a chosen OPL emulator/type until the user exits.
35+
*
36+
* Plays the given ADL file through an OPL device constructed from the specified
37+
* emulator and OPL type. The function creates an ADLDriver bound to the
38+
* Music channel group and enters an SDL event-driven loop that starts playback
39+
* (initial track index is 5) and responds to key presses to control playback.
40+
*
41+
* Behavior:
42+
* - Selects an OPL device based on `type`:
43+
* - OPL2 -> Adlib + Opl
44+
* - DUAL_OPL2-> SbPro + Opl
45+
* - OPL3 -> SbPro2 + Opl
46+
* - If the provided mixer is not ready, logs an error and returns immediately.
47+
* - Starts playing the current track when not already playing.
48+
* - Key controls (during playback):
49+
* - ESC: stop all channels and return (exit function)
50+
* - RIGHT: stop channels and advance to the next track (wraps to 0)
51+
* - LEFT: stop channels and go to the previous track (wraps to last)
52+
*
53+
* This function blocks until ESC is pressed.
54+
*
55+
* @param emu OPL emulator selection used when constructing the device.
56+
* @param type OPL hardware type used to choose the concrete device implementation.
57+
* @param filename Path to the ADL file to load and play.
58+
*/
3359
void adl_play(const OplEmulator emu, const OplType type, std::shared_ptr<audio::IMixer> mixer, const std::string& filename)
3460
{
3561
using devices::make_device;
@@ -114,6 +140,20 @@ void adl_play(const OplEmulator emu, const OplType type, std::shared_ptr<audio::
114140
} while (true);
115141
}
116142

143+
/**
144+
* @brief Program entry point for the ADL playback demo using SDL2 and OPL emulation.
145+
*
146+
* Initializes SDL video, creates a minimal SDL window, and starts an SDL-based audio mixer.
147+
* Iterates over configured OPL emulator and OPL type combinations, prints a colored header
148+
* for each pair, and invokes adl_play to run the ADL playback demo for "DUNE0.ADL".
149+
* Cleans up SDL resources before exiting.
150+
*
151+
* Return codes:
152+
* - 0 : Normal exit after running demos and cleanup.
153+
* - 1 : Mixer initialization failed.
154+
* - -1 : SDL video initialization failed.
155+
* - -2 : SDL window creation failed.
156+
*/
117157
int main(int argc, char* argv[])
118158
{
119159
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0)

sdl2-hyper-sonic-drivers/sdl2-hyper-sonic-drivers.cpp

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// sdl2-hyper-sonic-drivers.cpp : Defines the entry point for the application.
1+
// sdl2-hyper-sonic-drivers.cpp : Defines the entry point for the application.
22
// TODO: delete this file and its target, this is kind of scratch pad
33

44
#include <iostream>
@@ -338,6 +338,16 @@ void testMT32()
338338
}
339339

340340

341+
/**
342+
* @brief Load a WAV fixture, append it to itself, and play the result to completion.
343+
*
344+
* Initializes an SDL2 mixer, loads "test/fixtures/test_renderer_adlib_mame2.wav" into two sound
345+
* objects, concatenates them into a single PCM sound, and plays that combined sound via a
346+
* PCMDriver. The function blocks, polling until playback finishes.
347+
*
348+
* @note This function is a test utility: it uses a hard-coded test fixture path and performs
349+
* synchronous waiting while playback is active.
350+
*/
341351
void pcm_sound_append()
342352
{
343353
auto mixer = audio::make_mixer<audio::sdl2::Mixer>(8, 44100, 1024);
@@ -358,6 +368,24 @@ void pcm_sound_append()
358368
}
359369
}
360370

371+
/**
372+
* @brief Test harness that plays Westwood ADL music tracks through an Adlib/OPL driver using SDL2.
373+
*
374+
* This routine initializes an SDL2-backed audio mixer and an Adlib/OPL device, loads a Westwood
375+
* ADL file (fixed to "adl/KYRA1A.ADL"), and uses drivers::westwood::ADLDriver to play each
376+
* track (tracks are iterated from index 1 to getNumTracks()-1). Each track is played up to three
377+
* times. The function creates a small SDL window and pumps SDL events while waiting for playback
378+
* to finish; pressing Escape or receiving SDL_QUIT will abort the test, and pressing Return stops
379+
* the current track. After completing playback or aborting, the SDL window is destroyed.
380+
*
381+
* Side effects:
382+
* - Initializes SDL event and video subsystems and creates an SDL window.
383+
* - Initializes audio mixer and constructs Adlib/OPL device and ADL driver.
384+
* - Blocks while tracks are playing (polls events and sleeps).
385+
*
386+
* Notes:
387+
* - File name and iteration counts are hard-coded for this test harness.
388+
*/
361389
void adldune2filestest()
362390
{
363391
auto mixer = audio::make_mixer<audio::sdl2::Mixer>(8, 44100, 1024);
@@ -418,6 +446,18 @@ void adldune2filestest()
418446
SDL_QuitSubSystem(SDL_INIT_EVENTS);
419447
}
420448

449+
/**
450+
* @brief Plays VOC files through an Adlib/OPL-backed PCM driver using SDL for event handling.
451+
*
452+
* Initializes an SDL-backed audio mixer and Adlib/OPL device, scans the local "voc/" directory,
453+
* and plays each VOC file's PCM sound multiple times. While a sound is playing the function
454+
* processes SDL events so the user can quit (window close or Escape) or stop the current playback
455+
* early (Enter). A small SDL window is created for event delivery and destroyed on exit.
456+
*
457+
* This is a test/harness routine with side effects: it initializes SDL subsystems, creates an
458+
* audio mixer and device, opens a window, iterates the filesystem, and drives playback via a
459+
* PCMDriver. It does not return any value.
460+
*/
421461
void vocdune2filestest()
422462
{
423463
auto mixer = audio::make_mixer<audio::sdl2::Mixer>(8, 44100, 1024);
@@ -470,6 +510,19 @@ void vocdune2filestest()
470510
SDL_DestroyWindow(window);
471511
}
472512

513+
/**
514+
* @brief Program entry point that runs selected test routines.
515+
*
516+
* The main function serves as the test harness entry. It dispatches to various
517+
* SDL2/HyperSonicDrivers test routines; currently it invokes adldune2filestest()
518+
* and then returns immediately. The function performs global initialization
519+
* and teardown only for the test routines it calls (handled by those routines).
520+
*
521+
* Note: many test calls are present but commented out; uncommenting changes the
522+
* executed test sequence.
523+
*
524+
* @return int Process exit code (0 on normal completion).
525+
*/
473526
int main(int argc, char* argv[])
474527
{
475528
//newMixerTest();

sdl2-hyper-sonic-drivers/src/HyperSonicDrivers/files/westwood/ADLFile.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,27 @@ namespace HyperSonicDrivers::files::westwood
9191
V3_DATA_HEADER_SIZE
9292
};
9393

94+
/**
95+
* @brief Construct an ADLFile by loading and parsing a Westwood ADL file from disk.
96+
*
97+
* Reads the file header, track offsets, instrument offsets and raw data payload
98+
* according to the detected ADL version (V1/V2/V3), validates sizes, computes
99+
* counts for tracks/offsets, then closes the file and converts absolute offsets
100+
* into data-relative offsets (using 0xFFFF as the sentinel for invalid entries).
101+
*
102+
* The constructor:
103+
* - validates the file meets the minimum size for an ADL file,
104+
* - determines the on-disk ADL version and associated metadata,
105+
* - reads version-appropriate header entries,
106+
* - reads track and instrument offset tables,
107+
* - reads the raw data payload and stores its size/header size,
108+
* - sets m_num_tracks from the version metadata and computes the number of
109+
* valid track/instrument offsets,
110+
* - closes the underlying file handle,
111+
* - adjusts offsets to be relative to the in-memory data payload (and maps 0 -> 0xFFFF).
112+
*
113+
* @param filename Path to the ADL file to open and parse.
114+
*/
94115
ADLFile::ADLFile(const std::string& filename) : File(filename)
95116
{
96117
assertValid_(size() >= FILE_SIZE_MIN);
@@ -128,11 +149,31 @@ namespace HyperSonicDrivers::files::westwood
128149
return m_version;
129150
}
130151

152+
/**
153+
* @brief Return the number of tracks (subsongs) in the ADL file.
154+
*
155+
* The value is the internally stored track count determined at file load
156+
* from the version-specific metadata. For some V3 files the in-memory
157+
* header is known to be incorrect, so this returned count reflects the
158+
* metadata-derived value rather than any inferred count from the header.
159+
*
160+
* @return int Number of tracks (subsongs).
161+
*/
131162
int ADLFile::getNumTracks() const noexcept
132163
{
133164
return m_num_tracks;
134165
}
135166

167+
/**
168+
* @brief Return the number of program (track) offsets present in the ADL file.
169+
*
170+
* This value is determined during construction from the file's version-specific
171+
* metadata and offset tables. It represents how many valid track/program
172+
* offset entries are available (sentinel/invalid entries are counted according
173+
* to the parsed offset table).
174+
*
175+
* @return int Number of track/program offsets.
176+
*/
136177
int ADLFile::getNumTrackOffsets() const noexcept
137178
{
138179
return m_num_track_offsets;
@@ -259,6 +300,19 @@ namespace HyperSonicDrivers::files::westwood
259300
}
260301
}
261302

303+
/**
304+
* @brief Read and populate the in-memory header table from the open file.
305+
*
306+
* Resizes ADLFile::m_header to header_size and fills it by invoking the supplied
307+
* read callback header_size times. The read callback is expected to return the
308+
* next header entry (as a 16-bit value) each time it is called. After reading,
309+
* the method validates that the header vector length matches header_size.
310+
*
311+
* @param header_size Number of header entries to read and store into m_header.
312+
* @param read A zero-argument callable that returns the next header entry as uint16_t.
313+
* The caller is responsible for using the correct byte-width and endianness
314+
* for the target ADL version.
315+
*/
262316
void ADLFile::readHeaderFromFile_(const int header_size, std::function<uint16_t()> read)
263317
{
264318
m_header.resize(header_size);

sdl2-hyper-sonic-drivers/test/HyperSonicDrivers/files/westwood/TestADLFile.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ namespace HyperSonicDrivers::files::westwood
7474
EXPECT_EQ(chan, 9);
7575
}
7676

77+
/**
78+
* @brief Tests ADLFile parsing for a version 3 ADL fixture (LOREINTR.ADL).
79+
*
80+
* Verifies that the file is recognized as version 3, reports the expected
81+
* counts (tracks, track offsets, instrument offsets) and data size, and that
82+
* program offsets for a track resolve to the corresponding track and
83+
* instrument offsets. Also checks that the first track's data byte equals 9.
84+
*/
7785
TEST(ADLFile, ADLv3)
7886
{
7987
ADLFile f("../fixtures/LOREINTR.ADL");

0 commit comments

Comments
 (0)