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

@@ -1,16 +1,17 @@
import 'package:flutter/material.dart';
import 'package:wolf_3d_data/wolf_3d_data.dart';
import 'package:wolf_dart/features/difficulty/difficulty.dart';
import 'package:wolf_dart/features/renderer/renderer.dart';
class DifficultyScreen extends StatefulWidget {
const DifficultyScreen({super.key});
class DifficultyScreen extends StatelessWidget {
const DifficultyScreen(
this.data, {
super.key,
});
@override
State<DifficultyScreen> createState() => _DifficultyScreenState();
}
final WolfensteinData data;
class _DifficultyScreenState extends State<DifficultyScreen> {
bool isShareware = true; // Default to Shareware (WL1)
bool get isShareware => data.version == GameVersion.shareware;
@override
Widget build(BuildContext context) {
@@ -22,6 +23,7 @@ class _DifficultyScreenState extends State<DifficultyScreen> {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => WolfRenderer(
data,
difficulty: Difficulty.bringEmOn,
isShareware: isShareware,
showSpriteGallery: true,
@@ -44,27 +46,6 @@ class _DifficultyScreenState extends State<DifficultyScreen> {
fontFamily: 'Courier',
),
),
const SizedBox(height: 20),
// --- Version Toggle ---
Theme(
data: ThemeData(unselectedWidgetColor: Colors.grey),
child: CheckboxListTile(
title: const Text(
"Play Shareware Version (WL1)",
style: TextStyle(color: Colors.white),
),
value: isShareware,
onChanged: (bool? value) {
setState(() {
isShareware = value ?? true;
});
},
controlAffinity: ListTileControlAffinity.leading,
contentPadding: const EdgeInsets.symmetric(horizontal: 100),
),
),
const SizedBox(height: 20),
// --- Difficulty Buttons ---
ListView.builder(
@@ -87,6 +68,7 @@ class _DifficultyScreenState extends State<DifficultyScreen> {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => WolfRenderer(
data,
difficulty: difficulty,
isShareware: isShareware,
),

View File

@@ -2,7 +2,6 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:wolf_3d_data/wolf_3d_data.dart';
import 'package:wolf_dart/classes/coordinate_2d.dart';
import 'package:wolf_dart/features/difficulty/difficulty.dart';
@@ -21,13 +20,15 @@ import 'package:wolf_dart/features/ui/hud.dart';
import 'package:wolf_dart/sprite_gallery.dart';
class WolfRenderer extends StatefulWidget {
const WolfRenderer({
const WolfRenderer(
this.data, {
super.key,
this.difficulty = Difficulty.bringEmOn,
this.showSpriteGallery = false,
this.isShareware = true,
});
final WolfensteinData data;
final Difficulty difficulty;
final bool showSpriteGallery;
final bool isShareware;
@@ -44,7 +45,6 @@ class _WolfRendererState extends State<WolfRenderer>
late Ticker _gameLoop;
final FocusNode _focusNode = FocusNode();
late WolfensteinData gameData;
late Level currentLevel;
late WolfLevel activeLevel;
@@ -61,22 +61,12 @@ class _WolfRendererState extends State<WolfRenderer>
@override
void initState() {
super.initState();
_initGame(widget.isShareware);
_initGame();
}
Future<void> _initGame(bool isShareware) async {
gameData = await WLParser.loadAsync(
(filename) => rootBundle.load(
'assets/${isShareware ? "shareware" : "retail"}/$filename',
),
);
print('Detected Game Version: ${gameData.version.name}');
print('Loaded ${gameData.levels.length} levels!');
print('Loaded ${gameData.vgaImages.length} images!');
Future<void> _initGame() async {
// Get the first level out of the data class
activeLevel = gameData.levels.first;
activeLevel = widget.data.levels.first;
// Set up your grids directly from the active level
currentLevel = activeLevel.wallGrid;
@@ -118,8 +108,8 @@ class _WolfRendererState extends State<WolfRenderer>
x + 0.5,
y + 0.5,
widget.difficulty,
gameData.sprites.length,
isSharewareMode: isShareware,
widget.data.sprites.length,
isSharewareMode: widget.isShareware,
);
if (newEntity != null) {
@@ -364,7 +354,7 @@ class _WolfRendererState extends State<WolfRenderer>
entity.x,
entity.y,
widget.difficulty,
gameData.sprites.length,
widget.data.sprites.length,
);
if (droppedAmmo != null) {
@@ -413,7 +403,7 @@ class _WolfRendererState extends State<WolfRenderer>
}
if (widget.showSpriteGallery) {
return SpriteGallery(sprites: gameData.sprites);
return SpriteGallery(sprites: widget.data.sprites);
}
return Scaffold(
@@ -439,12 +429,12 @@ class _WolfRendererState extends State<WolfRenderer>
),
painter: RaycasterPainter(
map: currentLevel,
textures: gameData.walls,
textures: widget.data.walls,
player: player,
fov: fov,
doorOffsets: doorManager.getOffsetsForRenderer(),
entities: entities,
sprites: gameData.sprites,
sprites: widget.data.sprites,
activePushwall: pushwallManager.activePushwall,
),
),
@@ -461,9 +451,10 @@ class _WolfRendererState extends State<WolfRenderer>
child: CustomPaint(
painter: WeaponPainter(
sprite:
gameData.sprites[player.currentWeapon
widget.data.sprites[player
.currentWeapon
.getCurrentSpriteIndex(
gameData.sprites.length,
widget.data.sprites.length,
)],
),
),