Refactor and enhance documentation across the Wolf3D project

- Updated library imports to use the correct package paths for consistency.
- Added detailed documentation comments to various classes and methods, improving code readability and maintainability.
- Refined the GameSelectScreen, SpriteGallery, and VgaGallery classes with clearer descriptions of their functionality.
- Enhanced the CliInput class to better explain the input handling process and its interaction with the engine.
- Improved the SixelRasterizer and Opl2Emulator classes with comprehensive comments on their operations and state management.
- Removed the deprecated wolf_3d.dart file and consolidated its functionality into wolf_3d_flutter.dart for a cleaner architecture.
- Updated the Wolf3dFlutterInput class to clarify its role in merging keyboard and pointer events.
- Enhanced the rendering classes to provide better context on their purpose and usage within the Flutter framework.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-18 10:01:12 +01:00
parent 28938f7301
commit 3c6a4672f7
23 changed files with 404 additions and 183 deletions

View File

@@ -1,5 +1,157 @@
/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
/// High-level Flutter facade for discovering game data and sharing runtime services.
library;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:wolf_3d_dart/wolf_3d_data.dart';
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
import 'package:wolf_3d_dart/wolf_3d_synth.dart';
import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart';
/// Coordinates asset discovery, audio initialization, and input reuse for apps.
class Wolf3d {
/// Creates an empty facade that must be initialized with [init].
Wolf3d();
/// All successfully discovered or bundled game data sets.
final List<WolfensteinData> availableGames = [];
WolfensteinData? _activeGame;
/// Shared engine audio backend used by menus and gameplay sessions.
final EngineAudio audio = WolfAudio();
/// Shared Flutter input adapter reused by gameplay screens.
final Wolf3dFlutterInput input = Wolf3dFlutterInput();
/// The currently selected game data set.
///
/// Throws a [StateError] until [setActiveGame] has been called.
WolfensteinData get activeGame {
if (_activeGame == null) {
throw StateError("No active game selected. Call setActiveGame() first.");
}
return _activeGame!;
}
// Episode selection lives on the facade so menus can configure gameplay
// before constructing a new engine instance.
int _activeEpisode = 0;
/// Index of the episode currently selected in the UI flow.
int get activeEpisode => _activeEpisode;
/// Sets the active episode for the current [activeGame].
void setActiveEpisode(int episodeIndex) {
if (_activeGame == null) {
throw StateError("No active game selected. Call setActiveGame() first.");
}
if (episodeIndex < 0 || episodeIndex >= _activeGame!.episodes.length) {
throw RangeError("Episode index out of range for the active game.");
}
_activeEpisode = episodeIndex;
}
/// Convenience access to the active episode's level list.
List<WolfLevel> get levels => activeGame.episodes[activeEpisode].levels;
/// Convenience access to the active game's wall textures.
List<Sprite> get walls => activeGame.walls;
/// Convenience access to the active game's sprite set.
List<Sprite> get sprites => activeGame.sprites;
/// Convenience access to digitized PCM effects.
List<PcmSound> get sounds => activeGame.sounds;
/// Convenience access to AdLib/OPL effect assets.
List<PcmSound> get adLibSounds => activeGame.adLibSounds;
/// Convenience access to level music tracks.
List<ImfMusic> get music => activeGame.music;
/// Convenience access to VGA UI and splash images.
List<VgaImage> get vgaImages => activeGame.vgaImages;
/// Makes [game] the active data set and points shared services at it.
void setActiveGame(WolfensteinData game) {
if (!availableGames.contains(game)) {
throw ArgumentError(
"The provided game data is not in the list of available games.",
);
}
if (_activeGame == game) {
return; // No change needed
}
_activeGame = game;
audio.activeGame = game;
}
/// Initializes the engine by loading available game data.
Future<Wolf3d> init({String? directory}) async {
await audio.init();
availableGames.clear();
// Bundled assets let the GUI work out of the box on supported platforms.
final versionsToTry = [
(version: GameVersion.retail, path: 'retail'),
(version: GameVersion.shareware, path: 'shareware'),
];
for (final version in versionsToTry) {
try {
final ext = version.version.fileExtension;
final folder = 'packages/wolf_3d_assets/assets/${version.path}';
final data = WolfensteinLoader.loadFromBytes(
version: version.version,
vswap: await _tryLoad('$folder/VSWAP.$ext'),
mapHead: await _tryLoad('$folder/MAPHEAD.$ext'),
gameMaps: await _tryLoad('$folder/GAMEMAPS.$ext'),
vgaDict: await _tryLoad('$folder/VGADICT.$ext'),
vgaHead: await _tryLoad('$folder/VGAHEAD.$ext'),
vgaGraph: await _tryLoad('$folder/VGAGRAPH.$ext'),
audioHed: await _tryLoad('$folder/AUDIOHED.$ext'),
audioT: await _tryLoad('$folder/AUDIOT.$ext'),
);
availableGames.add(data);
} catch (e) {
debugPrint(e.toString());
}
}
// On non-web platforms, also scan the local filesystem for user-supplied
// data folders so the host can pick up extra versions automatically.
if (!kIsWeb) {
try {
final externalGames = await WolfensteinLoader.discover(
directoryPath: directory,
recursive: true,
);
for (var entry in externalGames.entries) {
if (!availableGames.any((g) => g.version == entry.key)) {
availableGames.add(entry.value);
}
}
} catch (e) {
debugPrint("External discovery failed: $e");
}
}
return this;
}
/// Loads an asset from the Flutter bundle, returning `null` when absent.
Future<ByteData?> _tryLoad(String path) async {
try {
return await rootBundle.load(path);
} catch (e) {
debugPrint("Asset not found: $path");
return null;
}
}
}