feat: Enhance intro splash screen with retail warning and dynamic slide management
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -420,7 +420,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
final art = WolfClassicMenuArt(engine.data);
|
||||
|
||||
if (engine.menuManager.activeMenu == WolfMenuScreen.introSplash) {
|
||||
_drawIntroSplash(engine, art);
|
||||
_drawIntroSplash(engine, art, menuTypography);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -708,10 +708,16 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
}
|
||||
}
|
||||
|
||||
void _drawIntroSplash(WolfEngine engine, WolfClassicMenuArt art) {
|
||||
final image = engine.menuManager.isIntroPg13Slide
|
||||
? art.mappedPic(WolfMenuPic.pg13)
|
||||
: art.mappedPic(WolfMenuPic.title);
|
||||
void _drawIntroSplash(
|
||||
WolfEngine engine,
|
||||
WolfClassicMenuArt art,
|
||||
_AsciiMenuTypography menuTypography,
|
||||
) {
|
||||
final image = switch (engine.menuManager.currentIntroSlide) {
|
||||
WolfIntroSlide.retailWarning => null,
|
||||
WolfIntroSlide.pg13 => art.mappedPic(WolfMenuPic.pg13),
|
||||
WolfIntroSlide.title => art.mappedPic(WolfMenuPic.title),
|
||||
};
|
||||
|
||||
int splashBg = _rgbToPaletteColor(engine.menuManager.introBackgroundRgb);
|
||||
if (engine.menuManager.isIntroPg13Slide &&
|
||||
@@ -726,6 +732,10 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
_fillRect(0, 0, width, height, activeTheme.solid, splashBg);
|
||||
}
|
||||
|
||||
if (engine.menuManager.isIntroRetailWarningSlide) {
|
||||
_drawRetailWarningIntro(splashBg, menuTypography);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
final int x = engine.menuManager.isIntroPg13Slide
|
||||
? (320 - image.width).clamp(0, 319)
|
||||
@@ -742,6 +752,58 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
);
|
||||
}
|
||||
|
||||
void _drawRetailWarningIntro(
|
||||
int backgroundColor,
|
||||
_AsciiMenuTypography menuTypography,
|
||||
) {
|
||||
final int black = ColorPalette.vga32Bit[0];
|
||||
final int yellow = ColorPalette.vga32Bit[14];
|
||||
final int white = ColorPalette.vga32Bit[15];
|
||||
final int lineColor = ColorPalette.vga32Bit[4];
|
||||
|
||||
_fillRect320(0, 0, 320, 22, black);
|
||||
_drawMenuTextCentered(
|
||||
'Attention',
|
||||
6,
|
||||
yellow,
|
||||
scale: menuTypography.headingScale,
|
||||
);
|
||||
_fillRect320(0, 23, 320, 1, lineColor);
|
||||
|
||||
if (menuTypography.usesCompactRows) {
|
||||
final int textLeft = _menuX320ToColumn(40);
|
||||
final int textRight = _menuX320ToColumn(280);
|
||||
final int textWidth = math.max(1, textRight - textLeft);
|
||||
|
||||
void writeCenteredLine(int y200, String text) {
|
||||
final String clipped = _clipWithEllipsis(text, textWidth);
|
||||
final int centeredLeft =
|
||||
textLeft + math.max(0, ((textWidth - clipped.length) ~/ 2));
|
||||
_writeLeftClipped(
|
||||
_menuY200ToRow(y200),
|
||||
clipped,
|
||||
white,
|
||||
backgroundColor,
|
||||
clipped.length,
|
||||
centeredLeft,
|
||||
);
|
||||
}
|
||||
|
||||
writeCenteredLine(62, 'THIS GAME IS NOT SHAREWARE.');
|
||||
writeCenteredLine(74, 'PLEASE DO NOT DISTRIBUTE IT.');
|
||||
writeCenteredLine(86, 'THANKS.');
|
||||
|
||||
writeCenteredLine(112, 'ID SOFTWARE');
|
||||
} else {
|
||||
_drawMenuText('This game is NOT shareware.', 40, 56, white, scale: 1);
|
||||
_drawMenuText('Please do not distribute it.', 40, 68, white, scale: 1);
|
||||
_drawMenuText('Thanks.', 40, 80, white, scale: 1);
|
||||
_drawMenuTextCentered('Id Software', 106, white, scale: 1);
|
||||
}
|
||||
|
||||
_fillRect320(0, 196, 320, 4, backgroundColor);
|
||||
}
|
||||
|
||||
int _dominantPaletteIndex(VgaImage image) {
|
||||
final List<int> histogram = List<int>.filled(256, 0);
|
||||
for (final int colorIndex in image.pixels) {
|
||||
@@ -767,6 +829,18 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
|
||||
}
|
||||
|
||||
final int threshold = (alpha * 3).round().clamp(1, 3);
|
||||
|
||||
if (_usesTerminalLayout) {
|
||||
for (int y = 0; y < _terminalPixelHeight; y++) {
|
||||
for (int x = 0; x < _terminalSceneWidth; x++) {
|
||||
if (((x + y) % 3) < threshold) {
|
||||
_scenePixels[y][x] = fadeColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int y = 0; y < _screen.length; y++) {
|
||||
final row = _screen[y];
|
||||
for (int x = 0; x < row.length; x++) {
|
||||
|
||||
@@ -561,9 +561,11 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
}
|
||||
|
||||
void _drawIntroSplash(WolfEngine engine, WolfClassicMenuArt art) {
|
||||
final image = engine.menuManager.isIntroPg13Slide
|
||||
? art.mappedPic(WolfMenuPic.pg13)
|
||||
: art.mappedPic(WolfMenuPic.title);
|
||||
final image = switch (engine.menuManager.currentIntroSlide) {
|
||||
WolfIntroSlide.retailWarning => null,
|
||||
WolfIntroSlide.pg13 => art.mappedPic(WolfMenuPic.pg13),
|
||||
WolfIntroSlide.title => art.mappedPic(WolfMenuPic.title),
|
||||
};
|
||||
|
||||
int splashBg = _rgbToPaletteIndex(engine.menuManager.introBackgroundRgb);
|
||||
if (engine.menuManager.isIntroPg13Slide &&
|
||||
@@ -576,6 +578,10 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
_screen[i] = splashBg;
|
||||
}
|
||||
|
||||
if (engine.menuManager.isIntroRetailWarningSlide) {
|
||||
_drawRetailWarningIntro(splashBg);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
final int x = engine.menuManager.isIntroPg13Slide
|
||||
? (320 - image.width).clamp(0, 319)
|
||||
@@ -592,6 +598,24 @@ class SixelRenderer extends CliRendererBackend<String> {
|
||||
);
|
||||
}
|
||||
|
||||
void _drawRetailWarningIntro(int backgroundColor) {
|
||||
const int black = 0;
|
||||
const int yellow = 14;
|
||||
const int white = 15;
|
||||
const int lineColor = 4;
|
||||
|
||||
_fillRect320(0, 0, 320, 22, black);
|
||||
_drawMenuTextCentered('Attention', 6, yellow, scale: 2);
|
||||
_fillRect320(0, 23, 320, 1, lineColor);
|
||||
|
||||
_drawMenuText('This game is NOT shareware.', 40, 56, white, scale: 1);
|
||||
_drawMenuText('Please do not distribute it.', 40, 68, white, scale: 1);
|
||||
_drawMenuText('Thanks.', 40, 80, white, scale: 1);
|
||||
_drawMenuTextCentered('Id Software', 106, white, scale: 1);
|
||||
|
||||
_fillRect320(0, 196, 320, 4, backgroundColor);
|
||||
}
|
||||
|
||||
int _dominantPaletteIndex(VgaImage image) {
|
||||
final List<int> histogram = List<int>.filled(256, 0);
|
||||
for (final int colorIndex in image.pixels) {
|
||||
|
||||
@@ -209,9 +209,11 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
}
|
||||
|
||||
void _drawIntroSplash(WolfEngine engine, WolfClassicMenuArt art) {
|
||||
final image = engine.menuManager.isIntroPg13Slide
|
||||
? art.mappedPic(WolfMenuPic.pg13)
|
||||
: art.mappedPic(WolfMenuPic.title);
|
||||
final image = switch (engine.menuManager.currentIntroSlide) {
|
||||
WolfIntroSlide.retailWarning => null,
|
||||
WolfIntroSlide.pg13 => art.mappedPic(WolfMenuPic.pg13),
|
||||
WolfIntroSlide.title => art.mappedPic(WolfMenuPic.title),
|
||||
};
|
||||
|
||||
int splashBgColor = _rgbToFrameColor(engine.menuManager.introBackgroundRgb);
|
||||
int? matteIndex;
|
||||
@@ -227,6 +229,10 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
_buffer.pixels[i] = splashBgColor;
|
||||
}
|
||||
|
||||
if (engine.menuManager.isIntroRetailWarningSlide) {
|
||||
_drawRetailWarningIntro(splashBgColor);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
final int x = engine.menuManager.isIntroPg13Slide
|
||||
? (320 - image.width).clamp(0, 319)
|
||||
@@ -247,6 +253,36 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
|
||||
);
|
||||
}
|
||||
|
||||
void _drawRetailWarningIntro(int backgroundColor) {
|
||||
final int black = ColorPalette.vga32Bit[0];
|
||||
final int yellow = ColorPalette.vga32Bit[14];
|
||||
final int white = ColorPalette.vga32Bit[15];
|
||||
final int lineColor = ColorPalette.vga32Bit[4];
|
||||
|
||||
_fillCanonicalRect(0, 0, 320, 22, black);
|
||||
_drawCanonicalMenuTextCentered('Attention', 6, yellow, scale: 2);
|
||||
_fillCanonicalRect(0, 23, 320, 1, lineColor);
|
||||
|
||||
_drawCanonicalMenuText(
|
||||
'This game is NOT shareware.',
|
||||
40,
|
||||
56,
|
||||
white,
|
||||
scale: 1,
|
||||
);
|
||||
_drawCanonicalMenuText(
|
||||
'Please do not distribute it.',
|
||||
40,
|
||||
68,
|
||||
white,
|
||||
scale: 1,
|
||||
);
|
||||
_drawCanonicalMenuText('Thanks.', 40, 80, white, scale: 1);
|
||||
_drawCanonicalMenuTextCentered('Id Software', 106, white, scale: 1);
|
||||
|
||||
_fillCanonicalRect(0, 196, 320, 4, backgroundColor);
|
||||
}
|
||||
|
||||
int _dominantPaletteIndex(VgaImage image) {
|
||||
final List<int> histogram = List<int>.filled(256, 0);
|
||||
for (final int colorIndex in image.pixels) {
|
||||
|
||||
Reference in New Issue
Block a user