Refactor audio module to use built-in music and sound effect identifiers

- Introduced BuiltInMusicModule and BuiltInSfxModule to replace RetailMusicModule and RetailSfxModule.
- Updated RetailAssetRegistry and SharewareAssetRegistry to utilize the new built-in modules.
- Removed deprecated MusicKey and SfxKey classes, replacing them with Music and SoundEffect enums for better clarity and maintainability.
- Adjusted music and sound effect resolution methods to align with the new structure.
- Updated audio playback methods in WolfAudio and FlutterAudioAdapter to accept the new Music and SoundEffect types.
- Refactored tests to accommodate changes in audio event handling and ensure compatibility with the new identifiers.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-20 17:07:25 +01:00
parent 8cca66e966
commit 10417d26ba
42 changed files with 499 additions and 622 deletions
@@ -13,20 +13,6 @@ import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
abstract class WLParser {
static const int _areaTileBase = 107;
// --- Original Song Lookup Tables ---
static const List<int> _sharewareMusicMap = [
2, 3, 4, 5, 2, 3, 4, 5, 6, 7, // Episode 1
];
static const List<int> _retailMusicMap = [
2, 3, 4, 5, 2, 3, 4, 5, 6, 7, // Ep 1
8, 9, 10, 11, 8, 9, 11, 10, 6, 12, // Ep 2
13, 14, 15, 16, 13, 14, 15, 16, 17, 18, // Ep 3
2, 3, 4, 5, 2, 3, 4, 5, 6, 7, // Ep 4
8, 9, 10, 11, 8, 9, 11, 10, 6, 12, // Ep 5
13, 14, 15, 16, 13, 14, 15, 16, 17, 19, // Ep 6
];
/// Asynchronously discovers the game version and loads all necessary files.
///
/// Provide a [fileFetcher] callback (e.g., Flutter's `rootBundle.load` or
@@ -182,8 +168,6 @@ abstract class WLParser {
required DataVersion dataIdentity,
AssetRegistry? registryOverride,
}) {
final isShareware = version == GameVersion.shareware;
final audio = parseAudio(audioHed, audioT, version);
final vgaImages = parseVgaImages(vgaDict, vgaHead, vgaGraph);
@@ -204,7 +188,7 @@ abstract class WLParser {
walls: parseWalls(vswap),
sprites: parseSprites(vswap),
sounds: parseSounds(vswap).map((bytes) => PcmSound(bytes)).toList(),
episodes: parseEpisodes(mapHead, gameMaps, isShareware: isShareware),
episodes: parseEpisodes(mapHead, gameMaps, version: version),
vgaImages: vgaImages,
adLibSounds: audio.adLib,
music: audio.music,
@@ -438,13 +422,12 @@ abstract class WLParser {
static List<Episode> parseEpisodes(
ByteData mapHead,
ByteData gameMaps, {
bool isShareware = true,
required GameVersion version,
}) {
List<WolfLevel> allLevels = [];
int rlewTag = mapHead.getUint16(0, Endian.little);
// Select the correct music map based on the version
final activeMusicMap = isShareware ? _sharewareMusicMap : _retailMusicMap;
final isShareware = version == GameVersion.shareware;
final episodeNames = isShareware
? _sharewareEpisodeNames
: _retailEpisodeNames;
@@ -510,9 +493,9 @@ abstract class WLParser {
}
// --- ASSIGN MUSIC ---
int trackIndex = (i < activeMusicMap.length)
? activeMusicMap[i]
: activeMusicMap[i % activeMusicMap.length];
final episodeIndex = i ~/ 10;
final levelIndex = i % 10;
final levelMusic = Music.levelFor(version, episodeIndex, levelIndex);
allLevels.add(
WolfLevel(
@@ -520,7 +503,7 @@ abstract class WLParser {
wallGrid: wallGrid,
objectGrid: objectGrid,
areaGrid: areaGrid,
musicIndex: trackIndex,
music: levelMusic,
),
);
}