diff --git a/apps/wolf_3d_cli/bin/main.dart b/apps/wolf_3d_cli/bin/main.dart index 67dc157..b9f568f 100644 --- a/apps/wolf_3d_cli/bin/main.dart +++ b/apps/wolf_3d_cli/bin/main.dart @@ -41,7 +41,10 @@ void main() async { final input = CliInput(); final cliAudio = CliSilentAudio(); - final rasterizer = AsciiRasterizer(); + final rasterizer = AsciiRasterizer( + aspectMultiplier: 1.0, + verticalStretch: 2.0, + ); FrameBuffer buffer = FrameBuffer( stdout.terminalColumns, @@ -107,8 +110,6 @@ void main() async { // Move cursor to top-left (0,0) before drawing the frame stdout.write('\x1b[H'); - input.update(); - engine.tick(elapsed); rasterizer.render(engine, buffer); rasterizer.finalizeFrame(); diff --git a/apps/wolf_3d_gui/lib/screens/game_screen.dart b/apps/wolf_3d_gui/lib/screens/game_screen.dart index 5f7c4a4..2fdf1e8 100644 --- a/apps/wolf_3d_gui/lib/screens/game_screen.dart +++ b/apps/wolf_3d_gui/lib/screens/game_screen.dart @@ -54,6 +54,27 @@ class _GameScreenState extends State { ? WolfAsciiRenderer(engine: _engine) : WolfFlutterRenderer(engine: _engine), + if (!_engine.isInitialized) + Container( + color: Colors.black, + child: const Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(color: Colors.teal), + SizedBox(height: 20), + Text( + "GET PSYCHED!", + style: TextStyle( + color: Colors.teal, + fontFamily: 'monospace', + ), + ), + ], + ), + ), + ), + // TAB listener Focus( autofocus: true, diff --git a/packages/wolf_3d_engine/lib/src/ascii_rasterizer.dart b/packages/wolf_3d_engine/lib/src/ascii_rasterizer.dart index b0e6c2f..a29d6bc 100644 --- a/packages/wolf_3d_engine/lib/src/ascii_rasterizer.dart +++ b/packages/wolf_3d_engine/lib/src/ascii_rasterizer.dart @@ -47,19 +47,21 @@ class ColoredChar { } class AsciiRasterizer extends Rasterizer { - final AsciiTheme activeTheme = AsciiThemes.blocks; + AsciiRasterizer({ + this.activeTheme = AsciiThemes.blocks, + this.aspectMultiplier = 1.0, + this.verticalStretch = 1.0, + }); + + AsciiTheme activeTheme = AsciiThemes.blocks; late List> _screen; late WolfEngine _engine; - // Terminal characters are usually twice as tall as they are wide. - // We override the base multiplier to squish sprites horizontally. @override - double get aspectMultiplier => 1.0; - - // Squish the entire 3D projection vertically by 50% to counteract tall terminal fonts + final double aspectMultiplier; @override - double get verticalStretch => 1.0; + final double verticalStretch; // Intercept the base render call to initialize our text grid @override diff --git a/packages/wolf_3d_renderer/lib/wolf_3d_flutter_renderer.dart b/packages/wolf_3d_renderer/lib/wolf_3d_flutter_renderer.dart index bcbff63..9f38382 100644 --- a/packages/wolf_3d_renderer/lib/wolf_3d_flutter_renderer.dart +++ b/packages/wolf_3d_renderer/lib/wolf_3d_flutter_renderer.dart @@ -26,22 +26,13 @@ class _WolfFlutterRendererState @override Color get scaffoldColor => const Color.fromARGB(255, 4, 64, 64); - @override - void dispose() { - _renderedFrame?.dispose(); - super.dispose(); - } - @override void performRender() { - // Avoid overlapping render calls since decodeImageFromPixels is async if (_isRendering) return; _isRendering = true; - // 1. Rasterize the frame into the pixel buffer _rasterizer.render(widget.engine, _frameBuffer); - // 2. Convert raw pixels to a Flutter ui.Image ui.decodeImageFromPixels( _frameBuffer.pixels.buffer.asUint8List(), _frameBuffer.width, @@ -61,13 +52,16 @@ class _WolfFlutterRendererState @override Widget buildViewport(BuildContext context) { + // If we don't have a frame yet, show the loading state + if (_renderedFrame == null) { + return const CircularProgressIndicator(color: Colors.white24); + } + return Padding( padding: const EdgeInsets.all(16.0), child: AspectRatio( aspectRatio: 4 / 3, - child: CustomPaint( - painter: BufferPainter(_renderedFrame), - ), + child: CustomPaint(painter: BufferPainter(_renderedFrame)), ), ); }