WIP fixing ASCII renderer

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-16 15:42:48 +01:00
parent fdfe5d336f
commit dd9bd5897e
7 changed files with 62 additions and 45 deletions

54
.gitignore vendored
View File

@@ -1,22 +1,22 @@
# Miscellaneous # Miscellaneous
*.class **/*.class
*.log **/*.log
*.pyc **/*.pyc
*.swp **/*.swp
.DS_Store **/.DS_Store
.atom/ **/.atom/
.build/ **/.build/
.buildlog/ **/.buildlog/
.history **/.history
.svn/ **/.svn/
.swiftpm/ **/.swiftpm/
migrate_working_dir/ **/migrate_working_dir/
# IntelliJ related # IntelliJ related
*.iml **/*.iml
*.ipr **/*.ipr
*.iws **/*.iws
.idea/ **/.idea/
# The .vscode folder contains launch configuration and tasks you configure in # The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line # VS Code which you may wish to be included in version control, so this line
@@ -26,20 +26,20 @@ migrate_working_dir/
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
**/ios/Flutter/.last_build_id **/ios/Flutter/.last_build_id
.dart_tool/ **/.dart_tool/
.flutter-plugins-dependencies **/.flutter-plugins-dependencies
.pub-cache/ **/.pub-cache/
.pub/ **/.pub/
/build/ **/build/
/coverage/ **/coverage/
# Symbolication related # Symbolication related
app.*.symbols **/app.*.symbols
# Obfuscation related # Obfuscation related
app.*.map.json **/app.*.map.json
# Android Studio will place build artifacts here # Android Studio will place build artifacts here
/android/app/debug **/android/app/debug
/android/app/profile **/android/app/profile
/android/app/release **/android/app/release

18
.vscode/launch.json vendored
View File

@@ -5,24 +5,30 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "wolf_dart", "name": "GUI",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"program": "lib/main.dart" "program": "apps/wolf_3d_gui/lib/main.dart"
}, },
{ {
"name": "wolf_dart (profile mode)", "name": "CLI",
"request": "launch",
"type": "dart",
"program": "apps/wolf_3d_cli/bin/main.dart"
},
{
"name": "GUI (profile mode)",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"flutterMode": "profile", "flutterMode": "profile",
"program": "lib/main.dart" "program": "apps/wolf_3d_gui/lib/main.dart"
}, },
{ {
"name": "wolf_dart (release mode)", "name": "GUI (release mode)",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"flutterMode": "release", "flutterMode": "release",
"program": "lib/main.dart" "program": "apps/wolf_3d_gui/lib/main.dart"
} }
] ]
} }

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart'; import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
import 'package:wolf_3d_flutter/wolf_3d.dart'; import 'package:wolf_3d_flutter/wolf_3d.dart';
import 'package:wolf_3d_renderer/wolf_3d_ascii_renderer.dart'; import 'package:wolf_3d_renderer/wolf_3d_flutter_renderer.dart';
class DifficultyScreen extends StatefulWidget { class DifficultyScreen extends StatefulWidget {
const DifficultyScreen({ const DifficultyScreen({
@@ -26,7 +26,7 @@ class _DifficultyScreenState extends State<DifficultyScreen> {
Navigator.of(context).pushReplacement( Navigator.of(context).pushReplacement(
MaterialPageRoute( MaterialPageRoute(
builder: (_) => WolfAsciiRenderer( builder: (_) => WolfFlutterRenderer(
Wolf3d.I.activeGame, Wolf3d.I.activeGame,
difficulty: difficulty, difficulty: difficulty,
startingEpisode: Wolf3d.I.activeEpisode, startingEpisode: Wolf3d.I.activeEpisode,

View File

@@ -55,7 +55,11 @@ class AsciiRasterizer extends Rasterizer {
// Terminal characters are usually twice as tall as they are wide. // Terminal characters are usually twice as tall as they are wide.
// We override the base multiplier to squish sprites horizontally. // We override the base multiplier to squish sprites horizontally.
@override @override
double get aspectMultiplier => 0.6; double get aspectMultiplier => 2.0;
// Squish the entire 3D projection vertically by 50% to counteract tall terminal fonts
@override
double get verticalStretch => 1.8;
// Intercept the base render call to initialize our text grid // Intercept the base render call to initialize our text grid
@override @override

View File

@@ -15,6 +15,10 @@ abstract class Rasterizer {
/// ASCII renderers can override this (e.g., 0.6) to account for tall characters. /// ASCII renderers can override this (e.g., 0.6) to account for tall characters.
double get aspectMultiplier => 1.0; double get aspectMultiplier => 1.0;
/// A multiplier to counteract tall pixel formats (like 1:2 terminal fonts).
/// Defaults to 1.0 (no squish) for standard pixel rendering.
double get verticalStretch => 1.0;
/// The main entry point called by the game loop. /// The main entry point called by the game loop.
/// Orchestrates the mathematical rendering pipeline. /// Orchestrates the mathematical rendering pipeline.
dynamic render(WolfEngine engine, FrameBuffer buffer) { dynamic render(WolfEngine engine, FrameBuffer buffer) {
@@ -279,7 +283,8 @@ abstract class Rasterizer {
if (side == 1 && math.sin(player.angle) < 0) texX = 63 - texX; if (side == 1 && math.sin(player.angle) < 0) texX = 63 - texX;
// Calculate drawing dimensions // Calculate drawing dimensions
int columnHeight = (viewHeight / perpWallDist).toInt(); int columnHeight = ((viewHeight / perpWallDist) * verticalStretch)
.toInt();
int drawStart = (-columnHeight ~/ 2 + viewHeight ~/ 2).clamp( int drawStart = (-columnHeight ~/ 2 + viewHeight ~/ 2).clamp(
0, 0,
viewHeight, viewHeight,
@@ -330,10 +335,12 @@ abstract class Rasterizer {
if (transformY > 0) { if (transformY > 0) {
int spriteScreenX = ((width / 2) * (1 + transformX / transformY)) int spriteScreenX = ((width / 2) * (1 + transformX / transformY))
.toInt(); .toInt();
int spriteHeight = (viewHeight / transformY).abs().toInt(); int spriteHeight = ((viewHeight / transformY).abs() * verticalStretch)
.toInt();
// Scale width based on the aspectMultiplier (useful for ASCII) // Scale width based on the aspectMultiplier (useful for ASCII)
int spriteWidth = (spriteHeight * aspectMultiplier).toInt(); int spriteWidth = (spriteHeight * aspectMultiplier / verticalStretch)
.toInt();
int drawStartY = -spriteHeight ~/ 2 + viewHeight ~/ 2; int drawStartY = -spriteHeight ~/ 2 + viewHeight ~/ 2;
int drawEndY = spriteHeight ~/ 2 + viewHeight ~/ 2; int drawEndY = spriteHeight ~/ 2 + viewHeight ~/ 2;

View File

@@ -185,7 +185,7 @@ class WolfEngine {
} }
if (input.isFiring) { if (input.isFiring) {
player.fire(elapsed.inMilliseconds); player.fire(_timeAliveMs);
} else { } else {
player.releaseTrigger(); player.releaseTrigger();
} }
@@ -271,7 +271,7 @@ class WolfEngine {
for (Entity entity in entities) { for (Entity entity in entities) {
if (entity is Enemy) { if (entity is Enemy) {
final intent = entity.update( final intent = entity.update(
elapsedMs: elapsed.inMilliseconds, elapsedMs: _timeAliveMs,
playerPosition: player.position, playerPosition: player.position,
isWalkable: isWalkable, isWalkable: isWalkable,
tryOpenDoor: doorManager.tryOpenDoor, tryOpenDoor: doorManager.tryOpenDoor,

View File

@@ -7,8 +7,8 @@ import 'package:wolf_3d_engine/wolf_3d_engine.dart';
import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart'; import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart';
import 'package:wolf_3d_input/wolf_3d_input.dart'; import 'package:wolf_3d_input/wolf_3d_input.dart';
class WolfRenderer extends StatefulWidget { class WolfFlutterRenderer extends StatefulWidget {
const WolfRenderer( const WolfFlutterRenderer(
this.data, { this.data, {
required this.difficulty, required this.difficulty,
required this.startingEpisode, required this.startingEpisode,
@@ -22,10 +22,10 @@ class WolfRenderer extends StatefulWidget {
final EngineAudio audio; final EngineAudio audio;
@override @override
State<WolfRenderer> createState() => _WolfRendererState(); State<WolfFlutterRenderer> createState() => _WolfFlutterRendererState();
} }
class _WolfRendererState extends State<WolfRenderer> class _WolfFlutterRendererState extends State<WolfFlutterRenderer>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final Wolf3dInput inputManager = Wolf3dFlutterInput(); final Wolf3dInput inputManager = Wolf3dFlutterInput();
late final WolfEngine engine; late final WolfEngine engine;