Fixed sprite lookups

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-13 18:56:43 +01:00
parent bf8d9d7eb1
commit 827d858f0f
10 changed files with 51 additions and 35 deletions

BIN
assets/GAMEMAPS.WL6 Normal file

Binary file not shown.

BIN
assets/MAPHEAD.WL6 Normal file

Binary file not shown.

BIN
assets/VSWAP.WL6 Normal file

Binary file not shown.

View File

@@ -43,7 +43,7 @@ class VswapParser {
/// Extracts the compiled scaled sprites from VSWAP.WL1 /// Extracts the compiled scaled sprites from VSWAP.WL1
static List<Matrix<int>> parseSprites(ByteData vswap) { static List<Matrix<int>> parseSprites(ByteData vswap) {
int chunks = vswap.getUint16(0, Endian.little); int chunks = vswap.getUint16(0, Endian.little);
int spriteStart = vswap.getUint16(2, Endian.little); // 64 int spriteStart = vswap.getUint16(2, Endian.little);
int soundStart = vswap.getUint16(4, Endian.little); int soundStart = vswap.getUint16(4, Endian.little);
List<int> offsets = []; List<int> offsets = [];

View File

@@ -18,7 +18,7 @@ class WolfMap {
); );
/// Asynchronously loads the map files and parses them into a new WolfMap instance. /// Asynchronously loads the map files and parses them into a new WolfMap instance.
static Future<WolfMap> load() async { static Future<WolfMap> loadDemo() async {
// 1. Load the binary data // 1. Load the binary data
final mapHead = await rootBundle.load("assets/MAPHEAD.WL1"); final mapHead = await rootBundle.load("assets/MAPHEAD.WL1");
final gameMaps = await rootBundle.load("assets/GAMEMAPS.WL1"); final gameMaps = await rootBundle.load("assets/GAMEMAPS.WL1");
@@ -36,4 +36,24 @@ class WolfMap {
parsedSprites, parsedSprites,
); );
} }
/// Asynchronously loads the map files and parses them into a new WolfMap instance.
static Future<WolfMap> load() async {
// 1. Load the binary data
final mapHead = await rootBundle.load("assets/MAPHEAD.WL6");
final gameMaps = await rootBundle.load("assets/GAMEMAPS.WL6");
final vswap = await rootBundle.load("assets/VSWAP.WL6");
// 2. Parse the data using the parser we just built
final parsedLevels = WolfMapParser.parseMaps(mapHead, gameMaps);
final parsedTextures = VswapParser.parseWalls(vswap);
final parsedSprites = VswapParser.parseSprites(vswap);
// 3. Return the populated instance!
return WolfMap._(
parsedLevels,
parsedTextures,
parsedSprites,
);
}
} }

View File

@@ -1,10 +1,10 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wolf_dart/classes/color_palette.dart';
import 'package:wolf_dart/classes/linear_coordinates.dart'; import 'package:wolf_dart/classes/linear_coordinates.dart';
import 'package:wolf_dart/classes/matrix.dart'; import 'package:wolf_dart/classes/matrix.dart';
import 'package:wolf_dart/classes/sprite.dart'; import 'package:wolf_dart/classes/sprite.dart';
import 'package:wolf_dart/features/renderer/color_palette.dart';
class RaycasterPainter extends CustomPainter { class RaycasterPainter extends CustomPainter {
final Matrix<int> map; final Matrix<int> map;
@@ -209,10 +209,8 @@ class RaycasterPainter extends CustomPainter {
// THE Z-BUFFER CHECK! // THE Z-BUFFER CHECK!
// Only draw if the sprite is closer to the camera than the wall at this pixel column // Only draw if the sprite is closer to the camera than the wall at this pixel column
if (transformY < zBuffer[stripe]) { if (transformY < zBuffer[stripe]) {
int texX = ((stripe - drawStartX) * 64 / spriteWidth).toInt().clamp( double texXDouble = (stripe - drawStartX) * 64 / spriteWidth;
0, int texX = texXDouble.toInt().clamp(0, 63);
63,
);
double startY = (size.height / 2) - (spriteHeight / 2); double startY = (size.height / 2) - (spriteHeight / 2);
double stepY = spriteHeight / 64.0; double stepY = spriteHeight / 64.0;

View File

@@ -49,34 +49,18 @@ class _WolfRendererState extends State<WolfRenderer>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_initGame(); _initGame(demo: widget.isDemo);
} }
Future<void> _initGame() async { Future<void> _initGame({bool demo = true}) async {
// 1. Load the entire WAD/WL1 data // 1. Load the entire WL1 (demo)/WL6 (retail) data
gameMap = await WolfMap.load(); gameMap = demo ? await WolfMap.loadDemo() : await WolfMap.load();
// 2. Extract Level 1 (E1M1) // 2. Extract Level 1 (E1M1)
currentLevel = gameMap.levels[0].wallGrid; currentLevel = gameMap.levels[0].wallGrid;
final Matrix<int> objectLevel = gameMap.levels[0].objectGrid; final Matrix<int> objectLevel = gameMap.levels[0].objectGrid;
// Adjusted mapping for WL1 Shareware
// These numbers represent the delta from the FIRST sprite chunk in VSWAP
Map<int, int> staticObjects = {
23: widget.isDemo ? 0 : 23, // Water Puddle
24: widget.isDemo ? 1 : 24, // Green Barrel
25: widget.isDemo ? 2 : 25, // Chairs
26: widget.isDemo ? 3 : 26, // Green Plant
27: widget.isDemo ? 4 : 27, // Skeleton / Bones
28: widget.isDemo ? 5 : 28, // Blue Lamp
29: widget.isDemo ? 6 : 29, // Chandelier
30: widget.isDemo ? 7 : 30, // Dog food
31: widget.isDemo ? 8 : 31, // White pillar
32: widget.isDemo ? 9 : 32, // Hanged man
50: widget.isDemo ? 42 : 95, // Standing Guard (Front-facing frame)
};
// 1. SCAN FOR PLAYER SPAWN & ENTITIES // 1. SCAN FOR PLAYER SPAWN & ENTITIES
for (int y = 0; y < 64; y++) { for (int y = 0; y < 64; y++) {
for (int x = 0; x < 64; x++) { for (int x = 0; x < 64; x++) {
@@ -97,12 +81,26 @@ class _WolfRendererState extends State<WolfRenderer>
} }
} }
// NEW: Populate the Entities! // NEW: Populate the Entities!
else if (staticObjects.containsKey(objId)) { else if (objId >= 23 && objId <= 70) {
entities.add(( int calculatedSpriteIndex = objId - 21;
x: x + 0.5,
y: y + 0.5, // Safety bounds check to prevent crashes on custom/corrupt maps
spriteIndex: staticObjects[objId]!, if (calculatedSpriteIndex >= 0 &&
)); calculatedSpriteIndex < gameMap.sprites.length) {
entities.add((
x: x + 0.5,
y: y + 0.5,
spriteIndex: calculatedSpriteIndex,
));
}
} else if (objId == 124) {
if (95 < gameMap.sprites.length) {
entities.add((
x: x + 0.5,
y: y + 0.5,
spriteIndex: 95,
));
}
} }
} }
} }

View File

@@ -6,7 +6,7 @@ void main() {
const MaterialApp( const MaterialApp(
home: WolfRenderer( home: WolfRenderer(
showSpriteGallery: false, showSpriteGallery: false,
isDemo: true, isDemo: false,
), ),
), ),
); );

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wolf_dart/classes/color_palette.dart';
import 'package:wolf_dart/classes/matrix.dart'; import 'package:wolf_dart/classes/matrix.dart';
import 'package:wolf_dart/features/renderer/color_palette.dart';
class SpriteGallery extends StatelessWidget { class SpriteGallery extends StatelessWidget {
final List<Matrix<int>> sprites; final List<Matrix<int>> sprites;