Fixed ASCII and cli rendering

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-16 15:26:10 +01:00
parent 9410916b57
commit fdfe5d336f
4 changed files with 109 additions and 13 deletions

View File

@@ -127,9 +127,7 @@ class AsciiRasterizer extends Rasterizer {
int texX,
double transformY,
) {
// Ask the base class for the depth brightness
double brightness = calculateDepthBrightness(transformY);
String spriteChar = activeTheme.getByBrightness(brightness);
for (
int y = math.max(0, drawStartY);
@@ -141,10 +139,21 @@ class AsciiRasterizer extends Rasterizer {
int colorByte = texture.pixels[texX * 64 + texY];
if (colorByte != 255) {
_screen[y][stripeX] = ColoredChar(
spriteChar,
ColorPalette.vga32Bit[colorByte],
);
int rawColor = ColorPalette.vga32Bit[colorByte];
// Shade the sprite's actual RGB color based on distance
int r = (rawColor & 0xFF);
int g = ((rawColor >> 8) & 0xFF);
int b = ((rawColor >> 16) & 0xFF);
r = (r * brightness).toInt();
g = (g * brightness).toInt();
b = (b * brightness).toInt();
int shadedColor = (0xFF000000) | (b << 16) | (g << 8) | r;
// Force sprites to be SOLID so they don't vanish into the terminal background
_screen[y][stripeX] = ColoredChar(activeTheme.solid, shadedColor);
}
}
}
@@ -183,8 +192,80 @@ class AsciiRasterizer extends Rasterizer {
}
}
// --- PRIVATE HUD DRAWING HELPER ---
/// Injects a pure text string directly into the rasterizer grid
void _writeString(int startX, int y, String text, int color) {
for (int i = 0; i < text.length; i++) {
int x = startX + i;
if (x >= 0 && x < width && y >= 0 && y < height) {
_screen[y][x] = ColoredChar(text[i], color);
}
}
}
@override
void drawHud(WolfEngine engine) {
// If the terminal is at least 160 columns wide and 50 rows tall,
// there are enough "pixels" to downscale the VGA image clearly.
if (width >= 160 && height >= 50) {
_drawFullVgaHud(engine);
} else {
_drawSimpleHud(engine);
}
}
void _drawSimpleHud(WolfEngine engine) {
// 1. Clear the HUD area so stray wall characters don't bleed in
for (int y = viewHeight; y < height; y++) {
for (int x = 0; x < width; x++) {
_screen[y][x] = ColoredChar(' ', 0xFF000000);
}
}
// 2. Draw a decorative border to separate the 3D view from the HUD
int borderColor = 0xFF555555; // Dark Gray
for (int x = 0; x < width; x++) {
_screen[viewHeight][x] = ColoredChar('=', borderColor);
}
// 3. Define some clean terminal colors
int white = 0xFFFFFFFF;
int yellow = 0xFFFFFF55;
int red = 0xFFFF5555;
// Turn health text red if dying
int healthColor = engine.player.health > 25 ? white : red;
// Format the strings nicely
String score = "SCORE: ${engine.player.score.toString().padLeft(6, '0')}";
String health = "HEALTH: ${engine.player.health}%";
String ammo = "AMMO: ${engine.player.ammo}";
int textY = viewHeight + 4; // Center it vertically in the HUD area
// 4. Print the stats evenly spaced across the bottom
_writeString(6, textY, "FLOOR 1", white);
_writeString(22, textY, score, white);
_writeString(44, textY, "LIVES: 3", white);
// 5. Reactive ASCII Face
String face = " :-) ";
if (engine.player.health <= 0) {
face = " X-x ";
} else if (engine.player.health <= 25) {
face = " :-( ";
} else if (engine.player.health <= 60) {
face = " :-| ";
}
_writeString(62, textY, "[$face]", yellow);
_writeString(78, textY, health, healthColor);
_writeString(100, textY, ammo, white);
}
void _drawFullVgaHud(WolfEngine engine) {
int statusBarIndex = engine.data.vgaImages.indexWhere(
(img) => img.width == 320 && img.height == 40,
);

View File

@@ -15,6 +15,8 @@ class WolfEngine {
onPlaySound: (sfxId) => audio.playSoundEffect(sfxId),
);
int _timeAliveMs = 0;
final WolfensteinData data;
final Difficulty difficulty;
final int startingEpisode;
@@ -52,6 +54,8 @@ class WolfEngine {
void tick(Duration elapsed, EngineInput input) {
if (!isInitialized) return;
_timeAliveMs += elapsed.inMilliseconds;
final inputResult = _processInputs(elapsed, input);
doorManager.update(elapsed);
@@ -74,7 +78,7 @@ class WolfEngine {
_updateEntities(elapsed);
player.updateWeapon(
currentTime: elapsed.inMilliseconds,
currentTime: _timeAliveMs,
entities: entities,
isWalkable: isWalkable,
);

View File

@@ -20,8 +20,9 @@ class CliInput extends Wolf3dInput {
if (char == 'a') _pLeft = true;
if (char == 'd') _pRight = true;
if (char == 'f' || char == ' ') _pFire = true;
if (char == 'e') _pInteract = true;
// --- NEW MAPPINGS ---
if (char == 'j') _pFire = true;
if (char == ' ') _pInteract = true;
if (char == '1') _pWeapon = WeaponType.knife;
if (char == '2') _pWeapon = WeaponType.pistol;