Used a single array for attributed chars to simplify code as well as condensed bold style for the font, so to have a regular grid.

This commit is contained in:
DarwinNE 2020-01-09 22:39:08 +01:00
parent 4524604aae
commit bcf635d5f9
2 changed files with 43 additions and 88 deletions

View File

@ -80,6 +80,16 @@ inline bool operator!=(const Attributes& lhs, const Attributes& rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
inline bool operator==(const AttributedChar& lhs, const AttributedChar& rhs)
{
return lhs.c==rhs.c && lhs.attrs==rhs.attrs;
}
inline bool operator!=(const AttributedChar& lhs, const AttributedChar& rhs)
{
return !(lhs == rhs);
}
namespace namespace
{ {
class FontSetup class FontSetup
@ -143,8 +153,7 @@ void IConsole::Init(GrafPtr port, Rect r)
rows = (bounds.bottom - bounds.top) / cellSizeY; rows = (bounds.bottom - bounds.top) / cellSizeY;
cols = (bounds.right - bounds.left) / cellSizeX; cols = (bounds.right - bounds.left) / cellSizeX;
chars = std::vector<char>(rows*cols, ' '); chars = std::vector<AttributedChar>(rows*cols, AttributedChar(' ',currentAttr));
attrs = std::vector<Attributes>(rows*cols);
onscreen = chars; onscreen = chars;
@ -154,37 +163,13 @@ void IConsole::Init(GrafPtr port, Rect r)
void IConsole::SetAttributes(Attributes aa) void IConsole::SetAttributes(Attributes aa)
{ {
TextFace(aa.isBold()?bold:0 + aa.isUnderline()?underline:0 + aa.isItalic()?italic:0); TextFace(aa.isBold()?bold+condense:0 + aa.isUnderline()?underline:0 + aa.isItalic()?italic:0);
}
short IConsole::CalcStartX(short x, short y)
{
Attributes a=attrs[y * cols];
SetAttributes(a);
short start=0;
short widthpx=0;
for(int i=0; i<x; ++i)
{
if(a!=attrs[y * cols + i])
{
widthpx+=TextWidth(&chars[y * cols + start], 0, i - start);
a=attrs[y * cols + i];
SetAttributes(a);
start=i;
}
}
widthpx+=TextWidth(&chars[y * cols + start], 0, x - start);
return widthpx;
} }
Rect IConsole::CellRect(short x, short y) Rect IConsole::CellRect(short x, short y)
{ {
short widthpx=CalcStartX(x,y); return { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x * cellSizeX),
FontSetup fontSetup; (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + (x+1) * cellSizeX) };
SetAttributes(attrs[y * cols+x]);
short cellSizeP=CharWidth('M');
return { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + widthpx),
(short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + widthpx+cellSizeP) };
} }
void IConsole::DrawCell(short x, short y, bool erase) void IConsole::DrawCell(short x, short y, bool erase)
{ {
@ -202,43 +187,13 @@ void IConsole::DrawCell(short x, short y, bool erase)
if(erase) if(erase)
EraseRect(&r); EraseRect(&r);
MoveTo(r.left, r.bottom - 2); MoveTo(r.left, r.bottom - 2);
DrawChar(chars[y * cols + x]); DrawChar(chars[y * cols + x].c);
} }
void IConsole::DrawCells(short x1, short x2, short y, bool erase) void IConsole::DrawCells(short x1, short x2, short y, bool erase)
{ {
Attributes a=attrs[y * cols]; Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x1 * cellSizeX),
SetAttributes(a); (short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) };
int start=0;
int xstart=0;
int xend=0;
for(int i=0; i<x1; ++i)
{
if(a!=attrs[y * cols + i])
{
xstart+=TextWidth(&chars[y * cols + start], 0, i - start);
a=attrs[y * cols + i];
SetAttributes(a);
start=i;
}
}
xstart+=TextWidth(&chars[y * cols + start], 0, x1 - start);
xend=xstart;
for(int i=x1; i<x2; ++i)
{
if(a!=attrs[y * cols + i])
{
xend+=TextWidth(&chars[y * cols + start], 0, i - start);
a=attrs[y * cols + i];
SetAttributes(a);
start=i;
}
}
xend+=TextWidth(&chars[y * cols + start], 0, x2 - start);
Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + xstart),
(short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + xend) };
if(cursorDrawn) if(cursorDrawn)
{ {
if(y == cursorY && x1 <= cursorX && x2 > cursorX) if(y == cursorY && x1 <= cursorX && x2 > cursorX)
@ -252,20 +207,16 @@ void IConsole::DrawCells(short x1, short x2, short y, bool erase)
EraseRect(&r); EraseRect(&r);
MoveTo(r.left, r.bottom - 2); MoveTo(r.left, r.bottom - 2);
a=attrs[y * cols + x1]; Attributes a=chars[y * cols + x1].attrs;
SetAttributes(a); SetAttributes(a);
start=x1;
for(int i=x1; i<x2; ++i) for(int i=x1; i<x2; ++i)
{ {
if(a!=attrs[y * cols + i]) if(a!=chars[y * cols + i].attrs) {
{ a=chars[y * cols + i].attrs;
DrawText(&chars[y * cols + start], 0, i - start);
a=attrs[y * cols + i];
SetAttributes(a); SetAttributes(a);
start=i;
} }
DrawChar(chars[y * cols + i].c);
} }
DrawText(&chars[y * cols + start], 0, x2 - start);
} }
void IConsole::Draw(Rect r) void IConsole::Draw(Rect r)
@ -292,7 +243,7 @@ void IConsole::Draw(Rect r)
if(cursorDrawn) if(cursorDrawn)
{ {
Rect cursor = CellRect(cursorX, cursorY); Rect cursor = CellRect(cursorX, cursorY);
//InvertRect(&cursor); InvertRect(&cursor);
} }
onscreen = chars; onscreen = chars;
} }
@ -301,11 +252,9 @@ void IConsole::ScrollUp(short n)
{ {
cursorY--; cursorY--;
std::copy(chars.begin() + cols, chars.end(), chars.begin()); std::copy(chars.begin() + cols, chars.end(), chars.begin());
std::fill(chars.end() - cols, chars.end(), ' '); std::fill(chars.end() - cols, chars.end(), AttributedChar(' ', currentAttr));
std::copy(attrs.begin() + cols, attrs.end(), attrs.begin());
std::fill(attrs.end() - cols, attrs.end(), currentAttr);
std::copy(onscreen.begin() + cols, onscreen.end(), onscreen.begin()); std::copy(onscreen.begin() + cols, onscreen.end(), onscreen.begin());
std::fill(onscreen.end() - cols, onscreen.end(), ' '); std::fill(onscreen.end() - cols, onscreen.end(), AttributedChar(' ', currentAttr));
RgnHandle rgn = NewRgn(); RgnHandle rgn = NewRgn();
ScrollRect(&bounds, 0, -cellSizeY, rgn); ScrollRect(&bounds, 0, -cellSizeY, rgn);
DisposeRgn(rgn); DisposeRgn(rgn);
@ -380,8 +329,8 @@ void IConsole::PutCharNoUpdate(char c)
ScrollUp(); ScrollUp();
break; break;
default: default:
chars[cursorY * cols + cursorX] = c; chars[cursorY * cols + cursorX].c = c;
attrs[cursorY * cols + cursorX] = currentAttr; chars[cursorY * cols + cursorX].attrs = currentAttr;
if(dirtyRect.right == 0) if(dirtyRect.right == 0)
{ {
@ -400,8 +349,7 @@ void IConsole::PutCharNoUpdate(char c)
if(cursorX >= cols) if(cursorX >= cols)
PutCharNoUpdate('\n'); PutCharNoUpdate('\n');
// This is to make sure the cursor width is calculated correctly // This is to make sure the cursor width is calculated correctly
attrs[cursorY * cols + cursorX] = currentAttr; chars[cursorY * cols + cursorX].attrs = currentAttr;
} }
} }
@ -416,12 +364,12 @@ void IConsole::Update()
bool needclear = false; bool needclear = false;
for(short col = dirtyRect.left; col < dirtyRect.right; ++col) for(short col = dirtyRect.left; col < dirtyRect.right; ++col)
{ {
char old = onscreen[row * cols + col]; AttributedChar old = onscreen[row * cols + col];
if(chars[row * cols + col] != old) if(chars[row * cols + col] != old)
{ {
if(start == -1) if(start == -1)
start = col; start = col;
if(old != ' ') if(old.c != ' ')
needclear = true; needclear = true;
onscreen[row * cols + col] = chars[row * cols + col]; onscreen[row * cols + col] = chars[row * cols + col];
} }
@ -443,8 +391,8 @@ void IConsole::Update()
Rect r = CellRect(cursorX, cursorY); Rect r = CellRect(cursorX, cursorY);
if(cursorDrawn) if(cursorDrawn)
DrawCell(cursorX, cursorY, true); DrawCell(cursorX, cursorY, true);
//else else
// InvertRect(&r); InvertRect(&r);
cursorDrawn = !cursorDrawn; cursorDrawn = !cursorDrawn;
} }
@ -555,11 +503,11 @@ void IConsole::Reshape(Rect newBounds)
cursorY = newRows - 1; cursorY = newRows - 1;
} }
std::vector<char> newChars(newRows*newCols, ' '); std::vector<AttributedChar> newChars(newRows*newCols, AttributedChar(' ', currentAttr));
for(short row = 0; row < newRows && row + upshift < rows; row++) for(short row = 0; row < newRows && row + upshift < rows; row++)
{ {
char *src = &chars[(row+upshift) * cols]; AttributedChar *src = &chars[(row+upshift) * cols];
char *dst = &newChars[row * newCols]; AttributedChar *dst = &newChars[row * newCols];
std::copy(src, src + std::min(cols, newCols), dst); std::copy(src, src + std::min(cols, newCols), dst);
} }
chars.swap(newChars); chars.swap(newChars);

View File

@ -46,6 +46,14 @@ namespace retro
bool cUnderline; bool cUnderline;
bool cItalic; bool cItalic;
}; };
class AttributedChar
{
public:
char c;
Attributes attrs;
AttributedChar(char cc, Attributes aa) {c=cc; attrs=aa;}
};
// inline bool operator==(const Attributes& lhs, const Attributes& rhs); // inline bool operator==(const Attributes& lhs, const Attributes& rhs);
// inline bool operator!=(const Attributes& lhs, const Attributes& rhs); // inline bool operator!=(const Attributes& lhs, const Attributes& rhs);
@ -79,8 +87,7 @@ namespace retro
Rect bounds; Rect bounds;
Attributes currentAttr; Attributes currentAttr;
std::vector<char> chars, onscreen; std::vector<AttributedChar> chars, onscreen;
std::vector<Attributes> attrs;
bool isProcessingEscSequence; bool isProcessingEscSequence;
int sequenceStep; int sequenceStep;