diff --git a/packages/wolf_3d_dart/lib/src/rendering/ascii_renderer.dart b/packages/wolf_3d_dart/lib/src/rendering/ascii_renderer.dart index ba55b86..5d99c9b 100644 --- a/packages/wolf_3d_dart/lib/src/rendering/ascii_renderer.dart +++ b/packages/wolf_3d_dart/lib/src/rendering/ascii_renderer.dart @@ -861,12 +861,7 @@ class AsciiRenderer extends CliRendererBackend { }) { final List? cachedColumn = _mainMenuBandFirstColumn; if (cachedColumn != null && cachedColumn.isNotEmpty) { - final int bandHeight = cachedColumn.length.clamp(0, 200); - for (int y = 0; y < bandHeight; y++) { - final int paletteIndex = cachedColumn[y]; - final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex; - _fillRect320(0, y, 320, 1, ColorPalette.vga32Bit[fillIndex]); - } + _drawScaledColumnBand(cachedColumn); return; } @@ -888,12 +883,7 @@ class AsciiRenderer extends CliRendererBackend { void _drawMainMenuOptionsSideBars(VgaImage optionsLabel, int optionsX320) { _mainMenuBandFirstColumn = _cacheFirstColumn(optionsLabel); - final List firstColumn = _mainMenuBandFirstColumn!; - for (int y = 0; y < optionsLabel.height; y++) { - final int paletteIndex = firstColumn[y]; - final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex; - _fillRect320(0, y, 320, 1, ColorPalette.vga32Bit[fillIndex]); - } + _drawScaledColumnBand(_mainMenuBandFirstColumn!); } List _cacheFirstColumn(VgaImage image) { @@ -904,6 +894,40 @@ class AsciiRenderer extends CliRendererBackend { return column; } + void _drawScaledColumnBand(List column) { + if (column.isEmpty) { + return; + } + + final int maxDrawHeight = _usesTerminalLayout + ? _terminalPixelHeight + : height; + final double scaleY = maxDrawHeight / 200.0; + final int destHeight = math.max(1, (column.length * scaleY).toInt()); + + for (int dy = 0; dy < destHeight; dy++) { + final int srcY = (dy / scaleY).toInt().clamp(0, column.length - 1); + final int fillColor = ColorPalette.vga32Bit[column[srcY]]; + + if (_usesTerminalLayout) { + if (dy < 0 || dy >= _terminalPixelHeight) { + continue; + } + for (int drawX = 0; drawX < _terminalSceneWidth; drawX++) { + _scenePixels[dy][drawX] = fillColor; + } + } else { + if (dy < 0 || dy >= height) { + continue; + } + final List row = _screen[dy]; + for (int drawX = 0; drawX < width; drawX++) { + row[drawX] = ColoredChar(activeTheme.solid, fillColor); + } + } + } + } + void _applyMenuFade(double alpha, int fadeColor) { if (alpha <= 0.0) { return; diff --git a/packages/wolf_3d_dart/lib/src/rendering/sixel_renderer.dart b/packages/wolf_3d_dart/lib/src/rendering/sixel_renderer.dart index e803102..0e2353d 100644 --- a/packages/wolf_3d_dart/lib/src/rendering/sixel_renderer.dart +++ b/packages/wolf_3d_dart/lib/src/rendering/sixel_renderer.dart @@ -698,39 +698,17 @@ class SixelRenderer extends CliRendererBackend { }) { final List? cachedColumn = _mainMenuBandFirstColumn; if (cachedColumn != null && cachedColumn.isNotEmpty) { - final int bandHeight = cachedColumn.length.clamp(0, 200); - for (int y = 0; y < bandHeight; y++) { - final int paletteIndex = cachedColumn[y]; - final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex; - _fillRect320(0, y, 320, 1, fillIndex); - } + _drawScaledColumnBand(cachedColumn); return; } final int mainBarTop = (headingY200 - 4).clamp(0, 199); - - _fillRect320(0, mainBarTop, 320, 18, barColor); - - int stripeY = mainBarTop + 18; - for (int i = 0; i < 4; i++) { - _fillRect320( - 0, - (stripeY + i).clamp(0, 199), - 320, - 1, - i.isEven ? barColor : backgroundColor, - ); - } + _fillRect320(0, mainBarTop, 320, 22, barColor); } void _drawMainMenuOptionsSideBars(VgaImage optionsLabel, int optionsX320) { _mainMenuBandFirstColumn = _cacheFirstColumn(optionsLabel); - final List firstColumn = _mainMenuBandFirstColumn!; - for (int y = 0; y < optionsLabel.height; y++) { - final int paletteIndex = firstColumn[y]; - final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex; - _fillRect320(0, y, 320, 1, fillIndex); - } + _drawScaledColumnBand(_mainMenuBandFirstColumn!); } List _cacheFirstColumn(VgaImage image) { @@ -741,6 +719,33 @@ class SixelRenderer extends CliRendererBackend { return column; } + void _drawScaledColumnBand(List column) { + if (column.isEmpty) { + return; + } + + final double scaleY = height / 200.0; + final int destHeight = math.max(1, (column.length * scaleY).toInt()); + + for (int dy = 0; dy < destHeight; dy++) { + final int drawY = dy; + if (drawY < 0 || drawY >= height) { + continue; + } + + final int srcY = ((dy / destHeight) * column.length).toInt().clamp( + 0, + column.length - 1, + ); + final int paletteIndex = column[srcY]; + final int fillIndex = paletteIndex == 0 ? 0 : paletteIndex; + final int rowStart = drawY * width; + for (int drawX = 0; drawX < width; drawX++) { + _screen[rowStart + drawX] = fillIndex; + } + } + } + bool get _useCompactMenuLayout => width < _compactMenuMinWidthPx || height < _compactMenuMinHeightPx; @@ -782,9 +787,6 @@ class SixelRenderer extends CliRendererBackend { int colorIndex, { int scale = 1, }) { - final double scaleX = width / 320.0; - final double scaleY = height / 200.0; - int x320 = startX; for (final rune in text.runes) { final char = String.fromCharCode(rune).toUpperCase(); @@ -799,12 +801,7 @@ class SixelRenderer extends CliRendererBackend { for (int sx = 0; sx < scale; sx++) { final int px320 = x320 + (col * scale) + sx; final int py200 = startY + (row * scale) + sy; - - final int drawX = (px320 * scaleX).toInt(); - final int drawY = (py200 * scaleY).toInt(); - if (drawX >= 0 && drawX < width && drawY >= 0 && drawY < height) { - _screen[drawY * width + drawX] = colorIndex; - } + _fillRect320(px320, py200, 1, 1, colorIndex); } } } @@ -1088,15 +1085,13 @@ class SixelRenderer extends CliRendererBackend { final double scaleX = width / 320.0; final double scaleY = height / 200.0; - final int destStartX = (startX * scaleX).toInt(); - final int destStartY = (startY * scaleY).toInt(); - final int destWidth = math.max(1, (w * scaleX).toInt()); - final int destHeight = math.max(1, (h * scaleY).toInt()); + final int destStartX = (startX * scaleX).floor(); + final int destEndX = ((startX + w) * scaleX).ceil(); + final int destStartY = (startY * scaleY).floor(); + final int destEndY = ((startY + h) * scaleY).ceil(); - for (int dy = 0; dy < destHeight; dy++) { - for (int dx = 0; dx < destWidth; dx++) { - final int drawX = destStartX + dx; - final int drawY = destStartY + dy; + for (int drawY = destStartY; drawY < destEndY; drawY++) { + for (int drawX = destStartX; drawX < destEndX; drawX++) { if (drawX >= 0 && drawX < width && drawY >= 0 && drawY < height) { _screen[drawY * width + drawX] = colorIndex; }