import 'package:dartterm/cp437.dart'; import 'package:dartterm/fonts.dart'; import 'package:dartterm/terminal_painter.dart'; import 'package:flutter/material.dart'; class Terminal { static const int width = 96; static const int height = 54; static const int cellW = 64; static const int cellH = 64; static const int nTiles = width * height; late List tiles; Terminal() { tiles = [for (var i = 0; i < nTiles; i += 1) Tile.empty()]; for (final (x, c) in toCp437String("Hello, world!").indexed) { tiles[x].content = Content(Font.normal.imageName, c % 32, 2 * (c ~/ 32)); tiles[x + Terminal.width].content = Content(Font.normal.imageName, c % 32, 2 * (c ~/ 32) + 1); } for (final (x, c) in toCp437String("BEWARE OF THE BAT!").indexed) { tiles[x + Terminal.width * 2].content = Content(Font.small.imageName, c % 16, c ~/ 16); } for (final (x, c) in toCp437String("BEWARE OF THE BAT!").indexed) { tiles[Terminal.width * (x + 2)].content = Content(Font.small.imageName, c % 16, c ~/ 16); } } CustomPaint toWidget(BuildContext context) { var scalingFactor = MediaQuery.devicePixelRatioOf(context); return CustomPaint(painter: TerminalCustomPainter(this, scalingFactor)); } (int, int)? toXY(int i) { if (i < 0 || i > nTiles) { return null; } return (i % width, i ~/ width); } int? fromXY(int x, int y) { if (x < 0 || x >= width) { return null; } if (y < 0 || y >= height) { return null; } return x + y * width; } } class Tile { Content? content; Color bg; Color fg; Tile(this.content, this.bg, this.fg); static Tile empty() => Tile(null, Colors.black, Colors.white); } class Content { final String sourceImage; final int sourceCx; final int sourceCy; const Content(this.sourceImage, this.sourceCx, this.sourceCy); } // reexports Terminal terminal = Terminal(); const int width = Terminal.width; const int height = Terminal.height; const int cellW = Terminal.cellW; const int cellH = Terminal.cellH; const int nTiles = Terminal.nTiles; Widget toWidget(BuildContext context) { return terminal.toWidget(context); }