feat: Add GLSL renderer and implement FPS overlay across rendering backends
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -74,6 +74,12 @@ class WolfEngine {
|
||||
/// Elapsed engine lifetime in milliseconds.
|
||||
int get timeAliveMs => _timeAliveMs;
|
||||
|
||||
/// Exponential moving average of rendered frames per second.
|
||||
double _smoothedFps = 0.0;
|
||||
|
||||
/// Current smoothed FPS, suitable for lightweight on-screen diagnostics.
|
||||
double get fps => _smoothedFps;
|
||||
|
||||
/// The episode index where the game session begins.
|
||||
final int? startingEpisode;
|
||||
|
||||
@@ -203,6 +209,14 @@ class WolfEngine {
|
||||
|
||||
// Trust the incoming delta time natively
|
||||
_timeAliveMs += delta.inMilliseconds;
|
||||
if (delta.inMicroseconds > 0) {
|
||||
final double instantaneousFps = 1000000.0 / delta.inMicroseconds;
|
||||
if (_smoothedFps <= 0.0) {
|
||||
_smoothedFps = instantaneousFps;
|
||||
} else {
|
||||
_smoothedFps = (_smoothedFps * 0.88) + (instantaneousFps * 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Process User Input
|
||||
input.update();
|
||||
|
||||
@@ -351,6 +351,13 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void drawFpsOverlay(WolfEngine engine) {
|
||||
const int textColor = 0xFFFFFFFF;
|
||||
const int bgColor = 0xFF000000;
|
||||
_writeString(1, 0, ' ${fpsLabel(engine)} ', textColor, bgColor);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawMenu(WolfEngine engine) {
|
||||
final int bgColor = _rgbToPaletteColor(engine.menuBackgroundRgb);
|
||||
|
||||
@@ -79,6 +79,7 @@ abstract class RendererBackend<T>
|
||||
|
||||
if (engine.difficulty == null) {
|
||||
drawMenu(engine);
|
||||
drawFpsOverlay(engine);
|
||||
return finalizeFrame();
|
||||
}
|
||||
|
||||
@@ -88,6 +89,7 @@ abstract class RendererBackend<T>
|
||||
// 3. Draw 2D overlays.
|
||||
drawWeapon(engine);
|
||||
drawHud(engine);
|
||||
drawFpsOverlay(engine);
|
||||
|
||||
// 4. Finalize and return the frame data (Buffer or String/List).
|
||||
return finalizeFrame();
|
||||
@@ -139,6 +141,14 @@ abstract class RendererBackend<T>
|
||||
/// Default implementation is a no-op for backends that don't support menus.
|
||||
void drawMenu(WolfEngine engine) {}
|
||||
|
||||
/// Draws a small FPS diagnostic in the top-left corner.
|
||||
///
|
||||
/// Backends can override this to render text in their native format.
|
||||
void drawFpsOverlay(WolfEngine engine) {}
|
||||
|
||||
/// Returns a compact FPS label used by renderer-specific overlays.
|
||||
String fpsLabel(WolfEngine engine) => 'FPS ${engine.fps.round()}';
|
||||
|
||||
/// Plots a VGA image into this backend's HUD coordinate space.
|
||||
///
|
||||
/// Coordinates are in the original 320x200 HUD space. Backends that support
|
||||
|
||||
@@ -333,6 +333,18 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
drawStandardVgaHud(engine);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawFpsOverlay(WolfEngine engine) {
|
||||
const int panelColor = 0;
|
||||
const int textColor = 15;
|
||||
final String label = fpsLabel(engine);
|
||||
final int textWidth = WolfMenuFont.measureTextWidth(label, 1);
|
||||
final int panelWidth = (textWidth + 8).clamp(16, 96);
|
||||
|
||||
_fillRect320(2, 2, panelWidth, 10, panelColor);
|
||||
_drawMenuText(label, 4, 3, textColor, scale: 1);
|
||||
}
|
||||
|
||||
@override
|
||||
/// Blits a VGA image into the Sixel index buffer HUD space (320x200).
|
||||
void blitHudVgaImage(VgaImage image, int startX320, int startY200) {
|
||||
|
||||
@@ -121,6 +121,19 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
drawStandardVgaHud(engine);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawFpsOverlay(WolfEngine engine) {
|
||||
const int panelX = 2;
|
||||
const int panelY = 2;
|
||||
const int panelW = 72;
|
||||
const int panelH = 10;
|
||||
final int panelColor = ColorPalette.vga32Bit[0];
|
||||
final int textColor = ColorPalette.vga32Bit[15];
|
||||
|
||||
_fillMenuPanel(panelX, panelY, panelW, panelH, panelColor);
|
||||
_drawMenuText(fpsLabel(engine), panelX + 3, panelY + 1, textColor);
|
||||
}
|
||||
|
||||
@override
|
||||
/// Blits a VGA image into the software framebuffer HUD space (320x200).
|
||||
void blitHudVgaImage(VgaImage image, int startX320, int startY200) {
|
||||
|
||||
Reference in New Issue
Block a user