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 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> loadData([String? directory]) async { final List 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; } }