...
 
......@@ -68,6 +68,7 @@ print 9 "\nsnap snap\nsnup snop\nSnap up"
waitkey noclear=1
tbox.setnumboxes 7
tbox.reset 6
tbox.setloc 5 3200,2500
print 2 "Quotes and escapes"
......
......@@ -259,7 +259,7 @@ begin
if InitEverythingCommon <> '' then exit;
// More basic variable init, specific to the console port.
preference.restTime := 1000 div 16; // consoles don't need too many FPS
preference.restTime := 1000 div 20; // consoles don't need too many FPS
with sysvar do begin
windowSize.w := 80; windowSize.h := 25;
end;
......
......@@ -160,11 +160,21 @@ var i : dword;
if dword(textcolor) = dword(c) then isvisible := FALSE;
dword(textcolor) := dword(c);
if (isvisible) or (force) then begin
textpal := Rendermatic.palette[textcolor.r shr 4][textcolor.g shr 4][textcolor.b shr 4].color1;
if (invertcolors) then
SetColor(backpal + textpal shl 4)
else
SetColor(textpal + backpal shl 4);
if sakuparam.palettemode = PM_TRUECOLOR then begin
if invertcolors then
write(#27'[48;2;', textcolor.r, ';', textcolor.g, ';', textcolor.b,
'm'#27'[38;2;', style.baseColor[0].r, ';', style.baseColor[0].g, ';', style.baseColor[0].b, 'm')
else
write(#27'[38;2;', textcolor.r, ';', textcolor.g, ';', textcolor.b,
'm'#27'[48;2;', style.baseColor[0].r, ';', style.baseColor[0].g, ';', style.baseColor[0].b, 'm');
end
else begin
textpal := Rendermatic.palette[textcolor.r shr 4][textcolor.g shr 4][textcolor.b shr 4].color1;
if invertcolors then
SetColor(backpal + textpal shl 4)
else
SetColor(textpal + backpal shl 4);
end;
end;
end;
......@@ -281,7 +291,7 @@ begin
or (boxclipping.top + boxclipping.bottom >= boxSizeP_r.h) then exit;
// Calculate the drawable location and size of the box, and prepare to draw.
backpal := Rendermatic.palette[style.baseColor[0].r shr 4][style.baseColor[0].g shr 4][style.baseColor[0].b shr 4].color1;
backpal := Rendermatic.palette[style.baseColor[0].r shr 4][style.baseColor[0].g shr 4][style.baseColor[0].b shr 4].flatcolor;
_NewColor(style.textColor, TRUE, TRUE);
inc(distfromedge.left, boxclipping.left);
......@@ -437,7 +447,9 @@ begin
result := FALSE;
for i := high(BoxHub.textbox) downto 0 do if i <> boxIndex then begin
box2 := BoxHub.textbox[i];
if (box2.boxState <> BS_NULL) and (box2.isHidden = FALSE) and (box2.boxNeedsRedraw = FALSE)
// This is called from box destructor to ensure boxes overlapped by boxes being destroyed get redrawn, but when this is
// done as part of setnumboxes, some destroyed boxes may be null already.
if (box2 <> NIL) and (box2.boxState <> BS_NULL) and (box2.isHidden = FALSE) and (box2.boxNeedsRedraw = FALSE)
and (box2.boxLocP_r.x < boxLocP_r.x + boxSizeP_r.w) and (box2.boxLocP_r.x + box2.boxSizeP_r.w >= boxLocP_r.x)
and (box2.boxLocP_r.y < boxLocP_r.y + boxSizeP_r.h) and (box2.boxLocP_r.y + box2.boxSizeP_r.h >= boxLocP_r.y)
then begin
......
......@@ -230,9 +230,7 @@ var sakuparam : record
overrideWindowSize : TSizeP;
frameDelay : dword; // 0 = auto
autotest : boolean;
{$ifdef sakucon} {$note todo: Add 24-bit RGB mixing}
// Also in windows 10 console!
// https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#Output_Sequences
{$ifdef sakucon}
palettemode : EPaletteMode;
{$endif}
end;
......
......@@ -234,6 +234,18 @@ const numcombos = length(asciigradient) * 16;
mycol.g := gg * 17;
mycol.r := rr * 17;
// Find the nearest flat palette index to this color.
bestscore := $FFFFFFFF;
for i := 15 downto 0 do begin
j := crtpalette[i].b + crtpalette[i].g shl 8 + crtpalette[i].r shl 16;
score := DiffRGBX(mycol, RGBAquad(j));
if score < bestscore then begin
nearest := i;
bestscore := score;
end;
end;
palette[rr][gg][bb].flatcolor := nearest;
// Find the nearest palette index + character to this color.
readp1 := @lut_palcharRGB[0];
bestscore := $FFFFFFFF;
......@@ -263,8 +275,16 @@ const numcombos = length(asciigradient) * 16;
end;
j := numcombos - 1 - nearest;
with palette[rr][gg][bb] do begin
color2 := j and $F;
char2 := asciigradient[j shr 4].ch;
// Keep pairs in consistent order to avoid dither banding.
if (color2 < color1) or ((color2 = color1) and (char2 < char1)) then begin
color2 := color1; char2 := char1;
color1 := j and $F;
char1 := asciigradient[j shr 4].ch;
end
else begin
color2 := j and $F;
char2 := asciigradient[j shr 4].ch;
end;
end;
end;
end;
......@@ -330,6 +350,17 @@ const numcombos = length(asciigradient) * 16;
// Convert the 4-bit sRGB lookup index to 8-bit sRGB, then to LXY.
mycol := _RGBtoLXY(bb * 17, gg * 17, rr * 17);
// Find the nearest flat palette index to this color.
bestscore := $FFFFFFFF;
for i := 15 downto 0 do begin
score := _Differ(mycol, _RGBtoLXY(crtpalette[i].b, crtpalette[i].g, crtpalette[i].r));
if score < bestscore then begin
nearest := i;
bestscore := score;
end;
end;
palette[rr][gg][bb].flatcolor := nearest;
// Find the nearest palette index + character to this color.
readp1 := @lut_palcharLXY[0];
bestscore := $FFFFFFFF;
......@@ -359,8 +390,16 @@ const numcombos = length(asciigradient) * 16;
end;
j := numcombos - 1 - nearest;
with palette[rr][gg][bb] do begin
color2 := j and $F;
char2 := asciigradient[j shr 4].ch;
// Keep pairs in consistent order to avoid dither banding.
if (color2 < color1) or ((color2 = color1) and (char2 < char1)) then begin
color2 := color1; char2 := char1;
color1 := j and $F;
char1 := asciigradient[j shr 4].ch;
end
else begin
color2 := j and $F;
char2 := asciigradient[j shr 4].ch;
end;
end;
end;
end;
......@@ -396,7 +435,6 @@ var srcp, writep, endp : pointer;
outbuf : string;
workbuf : string[20];
x, y : longint;
l : dword;
b, g, r, thiscolor : byte;
thischar : char;
......@@ -485,7 +523,7 @@ begin
if sakuparam.palettemode = PM_TRUECOLOR then begin _TrueBlitz; exit; end;
lastcolor := $FF; l := 0;
lastcolor := $FF;
SetColor(0);
endp := @outbuf[240];
for y := y1 to y2 - 1 do begin
......
......@@ -23,6 +23,7 @@ type TRendermatic = object
// Lookup table for converting 24-bit colors into colorful ASCII approximations. CC1 is the single nearest, CC2 is either
// the same or something that gives an even better result at a 50-50 dither.
type TPaletteEntry = packed record
flatcolor : byte;
color1, color2 : byte;
char1, char2 : char;
end;
......