129 lines
4.1 KiB
Dart
129 lines
4.1 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:wolf_3d_data/wolf_3d_data.dart';
|
|
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
|
|
import 'package:wolf_dart/features/difficulty/difficulty_screen.dart';
|
|
|
|
class GameSelectScreen extends StatelessWidget {
|
|
const GameSelectScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: FutureBuilder(
|
|
future: loadData(),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
return CircularProgressIndicator();
|
|
}
|
|
|
|
if (!snapshot.hasData) {
|
|
return Text("Unable to load data");
|
|
}
|
|
|
|
final List<WolfensteinData> loadedGames = snapshot.data!;
|
|
|
|
if (loadedGames.length == 1) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (context) => DifficultyScreen(loadedGames.first),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
return ListView.builder(
|
|
itemCount: loadedGames.length,
|
|
itemBuilder: (context, i) {
|
|
final WolfensteinData data = loadedGames[i];
|
|
final GameVersion version = data.version;
|
|
|
|
return Card(
|
|
child: ListTile(
|
|
title: Text(version.name),
|
|
onTap: () {
|
|
Navigator.of(context).push(
|
|
MaterialPageRoute(
|
|
builder: (context) => DifficultyScreen(data),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<List<WolfensteinData>> loadData([String? directory]) async {
|
|
final List<WolfensteinData> loadedGames = [];
|
|
|
|
// 1. Always attempt to load bundled assets first (works on ALL platforms)
|
|
final versionsToTry = [
|
|
(version: GameVersion.retail, path: 'retail'),
|
|
(version: GameVersion.shareware, path: 'shareware'),
|
|
];
|
|
|
|
for (final config in versionsToTry) {
|
|
try {
|
|
final data = WolfensteinLoader.loadFromBytes(
|
|
version: config.version,
|
|
vswap: await rootBundle.load(
|
|
'assets/${config.path}/VSWAP.${config.version.fileExtension}',
|
|
),
|
|
mapHead: await rootBundle.load(
|
|
'assets/${config.path}/MAPHEAD.${config.version.fileExtension}',
|
|
),
|
|
gameMaps: await rootBundle.load(
|
|
'assets/${config.path}/GAMEMAPS.${config.version.fileExtension}',
|
|
),
|
|
vgaDict: await rootBundle.load(
|
|
'assets/${config.path}/VGADICT.${config.version.fileExtension}',
|
|
),
|
|
vgaHead: await rootBundle.load(
|
|
'assets/${config.path}/VGAHEAD.${config.version.fileExtension}',
|
|
),
|
|
vgaGraph: await rootBundle.load(
|
|
'assets/${config.path}/VGAGRAPH.${config.version.fileExtension}',
|
|
),
|
|
audioHed: await rootBundle.load(
|
|
'assets/${config.path}/AUDIOHED.${config.version.fileExtension}',
|
|
),
|
|
audioT: await rootBundle.load(
|
|
'assets/${config.path}/AUDIOT.${config.version.fileExtension}',
|
|
),
|
|
);
|
|
loadedGames.add(data);
|
|
} catch (e) {
|
|
debugPrint(
|
|
"Bundled ${config.version.name} not found or failed to load.",
|
|
);
|
|
}
|
|
}
|
|
|
|
// 2. On non-web, also check for external files in a specific "games" folder
|
|
// if you want to support side-loading.
|
|
if (!kIsWeb) {
|
|
try {
|
|
final externalGames = await WolfensteinLoader.discover(
|
|
directoryPath: directory,
|
|
recursive: true,
|
|
);
|
|
for (var entry in externalGames.entries) {
|
|
if (!loadedGames.any((g) => g.version == entry.key)) {
|
|
loadedGames.add(entry.value);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
debugPrint("External discovery failed: $e");
|
|
}
|
|
}
|
|
|
|
return loadedGames;
|
|
}
|
|
}
|