Load menu and level audio dynamically
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -69,11 +69,15 @@ class _WolfRendererState extends State<WolfRenderer>
|
||||
// Grab the specific level from the singleton
|
||||
_currentLevel = Wolf3d.I.levels[mapIndex];
|
||||
|
||||
// Play the exact track id Software intended for this level!
|
||||
Wolf3d.I.audio.playLevelMusic(_currentLevel);
|
||||
|
||||
// TODO: Initialize player position, spawn enemies based on difficulty, etc.
|
||||
debugPrint("Loaded Level: ${_currentLevel.name}");
|
||||
}
|
||||
|
||||
void _onLevelCompleted() {
|
||||
Wolf3d.I.audio.stopMusic();
|
||||
// When the player hits the elevator switch, advance the map
|
||||
setState(() {
|
||||
_currentMapIndex++;
|
||||
|
||||
@@ -22,16 +22,13 @@ class _EpisodeScreenState extends State<EpisodeScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (Wolf3d.I.music.isNotEmpty) {
|
||||
Wolf3d.I.audio.playMusic(Wolf3d.I.music.first);
|
||||
}
|
||||
Wolf3d.I.audio.playMenuMusic();
|
||||
}
|
||||
|
||||
void _selectEpisode(int index) {
|
||||
Wolf3d.I.setActiveEpisode(index);
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
// We pass the audio handles so the next screen can stop them when the game starts
|
||||
builder: (context) => DifficultyScreen(),
|
||||
),
|
||||
);
|
||||
@@ -39,7 +36,6 @@ class _EpisodeScreenState extends State<EpisodeScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Determine how many episodes are available (10 levels per episode)
|
||||
final int numberOfEpisodes = (Wolf3d.I.levels.length / 10).floor().clamp(
|
||||
1,
|
||||
6,
|
||||
|
||||
@@ -45,6 +45,7 @@ class Wolf3d {
|
||||
// --- Actions ---
|
||||
void setActiveGame(WolfensteinData game) {
|
||||
_activeGame = game;
|
||||
audio.activeGame = game;
|
||||
}
|
||||
|
||||
/// Initializes the engine by loading available game data.
|
||||
|
||||
@@ -4,6 +4,20 @@ import 'dart:typed_data';
|
||||
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
||||
|
||||
abstract class WLParser {
|
||||
// --- 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) that
|
||||
/// takes a filename and returns its ByteData.
|
||||
@@ -229,6 +243,10 @@ abstract class WLParser {
|
||||
bool isShareware = true,
|
||||
}) {
|
||||
List<WolfLevel> levels = [];
|
||||
|
||||
// 1. Select the correct map based on the version
|
||||
final activeMusicMap = isShareware ? _sharewareMusicMap : _retailMusicMap;
|
||||
|
||||
int rlewTag = mapHead.getUint16(0, Endian.little);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
@@ -279,11 +297,20 @@ abstract class WLParser {
|
||||
objectGrid.add(objectRow);
|
||||
}
|
||||
|
||||
// Determine music track index.
|
||||
// We use 'i' because it represents the absolute map slot (e.g. Map 12).
|
||||
// If a map exists past the bounds of our lookup table (custom maps),
|
||||
// we wrap around safely.
|
||||
int trackIndex = (i < activeMusicMap.length)
|
||||
? activeMusicMap[i]
|
||||
: activeMusicMap[i % activeMusicMap.length];
|
||||
|
||||
levels.add(
|
||||
WolfLevel(
|
||||
name: name,
|
||||
wallGrid: wallGrid,
|
||||
objectGrid: objectGrid,
|
||||
musicIndex: trackIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,3 +49,5 @@ class ImfMusic {
|
||||
return ImfMusic(instructions);
|
||||
}
|
||||
}
|
||||
|
||||
typedef WolfMusicMap = List<int>;
|
||||
|
||||
@@ -4,10 +4,12 @@ class WolfLevel {
|
||||
final String name;
|
||||
final Sprite wallGrid;
|
||||
final Sprite objectGrid;
|
||||
final int musicIndex;
|
||||
|
||||
const WolfLevel({
|
||||
required this.name,
|
||||
required this.wallGrid,
|
||||
required this.objectGrid,
|
||||
required this.musicIndex,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ library;
|
||||
export 'src/game_file.dart' show GameFile;
|
||||
export 'src/game_version.dart' show GameVersion;
|
||||
export 'src/image.dart' show VgaImage;
|
||||
export 'src/sound.dart' show PcmSound, AdLibSound, ImfMusic, ImfInstruction;
|
||||
export 'src/sound.dart'
|
||||
show PcmSound, AdLibSound, ImfMusic, ImfInstruction, WolfMusicMap;
|
||||
export 'src/sprite.dart' hide Matrix;
|
||||
export 'src/wolf_level.dart' show WolfLevel;
|
||||
export 'src/wolfenstein_data.dart' show WolfensteinData;
|
||||
|
||||
@@ -9,6 +9,8 @@ class WolfAudio {
|
||||
AudioSource? _currentMusicSource;
|
||||
SoundHandle? _currentMusicHandle;
|
||||
|
||||
WolfensteinData? activeGame;
|
||||
|
||||
/// Initializes the SoLoud audio engine.
|
||||
Future<void> init() async {
|
||||
if (_isInitialized) return;
|
||||
@@ -89,4 +91,30 @@ class WolfAudio {
|
||||
SoLoud.instance.setPause(_currentMusicHandle!, false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> playMenuMusic() async {
|
||||
final data = activeGame;
|
||||
// We can't play if data isn't set or doesn't have enough tracks
|
||||
if (data == null || data.music.length <= 1) return;
|
||||
|
||||
// Track 1 is the menu theme in both Shareware and Retail
|
||||
await playMusic(data.music[1]);
|
||||
}
|
||||
|
||||
/// Plays the specific track assigned to a WolfLevel.
|
||||
Future<void> playLevelMusic(WolfLevel level) async {
|
||||
final data = activeGame;
|
||||
if (data == null || data.music.isEmpty) return;
|
||||
|
||||
final index = level.musicIndex;
|
||||
|
||||
if (index < data.music.length) {
|
||||
// 3. FIXED THIS: Call your playMusic method
|
||||
await playMusic(data.music[index]);
|
||||
} else {
|
||||
print(
|
||||
"WolfAudio: Warning - Track index $index out of bounds for level ${level.name}.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user