Added dynamic discovery of available game data

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-15 11:23:41 +01:00
parent 34b167e03f
commit 2db9dad00d
9 changed files with 288 additions and 54 deletions

View File

@@ -0,0 +1,79 @@
import 'dart:io';
import 'dart:typed_data';
import '../classes/game_file.dart';
import '../classes/game_version.dart';
import '../classes/wolfenstein_data.dart';
import '../wl_parser.dart';
/// dart:io implementation for directory discovery.
Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
String? directoryPath,
bool recursive = false,
}) async {
final dir = Directory(directoryPath ?? Directory.current.path);
if (!await dir.exists()) {
print('Warning: Directory does not exist -> ${dir.path}');
return {};
}
final allFiles = await dir
.list(recursive: recursive)
.where((entity) => entity is File)
.cast<File>()
.toList();
final Map<GameVersion, WolfensteinData> loadedVersions = {};
for (final version in GameVersion.values) {
final ext = version.fileExtension.toUpperCase();
final Map<GameFile, File> foundFiles = {};
for (final requiredFile in GameFile.values) {
final expectedName = '${requiredFile.baseName}.$ext';
final match = allFiles.where((file) {
final fileName = file.uri.pathSegments.last.toUpperCase();
return fileName == expectedName;
}).firstOrNull;
if (match != null) {
foundFiles[requiredFile] = match;
}
}
if (foundFiles.isEmpty) continue;
if (foundFiles.length < GameFile.values.length) {
final missingFiles = GameFile.values
.where((f) => !foundFiles.containsKey(f))
.map((f) => '${f.baseName}.$ext')
.join(', ');
print('Found partial data for ${version.name}. Missing: $missingFiles');
continue;
}
try {
final data = WLParser.load(
version: version,
vswap: await _readFile(foundFiles[GameFile.vswap]!),
mapHead: await _readFile(foundFiles[GameFile.mapHead]!),
gameMaps: await _readFile(foundFiles[GameFile.gameMaps]!),
vgaDict: await _readFile(foundFiles[GameFile.vgaDict]!),
vgaHead: await _readFile(foundFiles[GameFile.vgaHead]!),
vgaGraph: await _readFile(foundFiles[GameFile.vgaGraph]!),
);
loadedVersions[version] = data;
} catch (e) {
print('Error parsing data for ${version.name}: $e');
}
}
return loadedVersions;
}
Future<ByteData> _readFile(File file) async {
final bytes = await file.readAsBytes();
return bytes.buffer.asByteData();
}

View File

@@ -0,0 +1,13 @@
import '../classes/game_version.dart';
import '../classes/wolfenstein_data.dart';
/// Web-safe stub for directory discovery.
Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
String? directoryPath,
bool recursive = false,
}) async {
throw UnsupportedError(
'Directory scanning is not supported on Web. '
'Please load the files manually using WolfensteinLoader.loadFromBytes().',
);
}