mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-28 21:49:33 +00:00
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:
parent
4524604aae
commit
bcf635d5f9
@ -80,6 +80,16 @@ inline bool operator!=(const Attributes& lhs, const Attributes& 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
|
||||
{
|
||||
class FontSetup
|
||||
@ -143,8 +153,7 @@ void IConsole::Init(GrafPtr port, Rect r)
|
||||
rows = (bounds.bottom - bounds.top) / cellSizeY;
|
||||
cols = (bounds.right - bounds.left) / cellSizeX;
|
||||
|
||||
chars = std::vector<char>(rows*cols, ' ');
|
||||
attrs = std::vector<Attributes>(rows*cols);
|
||||
chars = std::vector<AttributedChar>(rows*cols, AttributedChar(' ',currentAttr));
|
||||
|
||||
onscreen = chars;
|
||||
|
||||
@ -154,37 +163,13 @@ void IConsole::Init(GrafPtr port, Rect r)
|
||||
|
||||
void IConsole::SetAttributes(Attributes aa)
|
||||
{
|
||||
TextFace(aa.isBold()?bold: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;
|
||||
TextFace(aa.isBold()?bold+condense:0 + aa.isUnderline()?underline:0 + aa.isItalic()?italic:0);
|
||||
}
|
||||
|
||||
Rect IConsole::CellRect(short x, short y)
|
||||
{
|
||||
short widthpx=CalcStartX(x,y);
|
||||
FontSetup fontSetup;
|
||||
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) };
|
||||
return { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x * cellSizeX),
|
||||
(short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + (x+1) * cellSizeX) };
|
||||
}
|
||||
void IConsole::DrawCell(short x, short y, bool erase)
|
||||
{
|
||||
@ -202,43 +187,13 @@ void IConsole::DrawCell(short x, short y, bool erase)
|
||||
if(erase)
|
||||
EraseRect(&r);
|
||||
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)
|
||||
{
|
||||
Attributes a=attrs[y * cols];
|
||||
SetAttributes(a);
|
||||
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) };
|
||||
|
||||
Rect r = { (short) (bounds.top + y * cellSizeY), (short) (bounds.left + x1 * cellSizeX),
|
||||
(short) (bounds.top + (y+1) * cellSizeY), (short) (bounds.left + x2 * cellSizeX) };
|
||||
if(cursorDrawn)
|
||||
{
|
||||
if(y == cursorY && x1 <= cursorX && x2 > cursorX)
|
||||
@ -252,20 +207,16 @@ void IConsole::DrawCells(short x1, short x2, short y, bool erase)
|
||||
EraseRect(&r);
|
||||
MoveTo(r.left, r.bottom - 2);
|
||||
|
||||
a=attrs[y * cols + x1];
|
||||
Attributes a=chars[y * cols + x1].attrs;
|
||||
SetAttributes(a);
|
||||
start=x1;
|
||||
for(int i=x1; i<x2; ++i)
|
||||
{
|
||||
if(a!=attrs[y * cols + i])
|
||||
{
|
||||
DrawText(&chars[y * cols + start], 0, i - start);
|
||||
a=attrs[y * cols + i];
|
||||
if(a!=chars[y * cols + i].attrs) {
|
||||
a=chars[y * cols + i].attrs;
|
||||
SetAttributes(a);
|
||||
start=i;
|
||||
}
|
||||
DrawChar(chars[y * cols + i].c);
|
||||
}
|
||||
DrawText(&chars[y * cols + start], 0, x2 - start);
|
||||
}
|
||||
|
||||
void IConsole::Draw(Rect r)
|
||||
@ -292,7 +243,7 @@ void IConsole::Draw(Rect r)
|
||||
if(cursorDrawn)
|
||||
{
|
||||
Rect cursor = CellRect(cursorX, cursorY);
|
||||
//InvertRect(&cursor);
|
||||
InvertRect(&cursor);
|
||||
}
|
||||
onscreen = chars;
|
||||
}
|
||||
@ -301,11 +252,9 @@ void IConsole::ScrollUp(short n)
|
||||
{
|
||||
cursorY--;
|
||||
std::copy(chars.begin() + cols, chars.end(), chars.begin());
|
||||
std::fill(chars.end() - cols, chars.end(), ' ');
|
||||
std::copy(attrs.begin() + cols, attrs.end(), attrs.begin());
|
||||
std::fill(attrs.end() - cols, attrs.end(), currentAttr);
|
||||
std::fill(chars.end() - cols, chars.end(), AttributedChar(' ', currentAttr));
|
||||
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();
|
||||
ScrollRect(&bounds, 0, -cellSizeY, rgn);
|
||||
DisposeRgn(rgn);
|
||||
@ -380,8 +329,8 @@ void IConsole::PutCharNoUpdate(char c)
|
||||
ScrollUp();
|
||||
break;
|
||||
default:
|
||||
chars[cursorY * cols + cursorX] = c;
|
||||
attrs[cursorY * cols + cursorX] = currentAttr;
|
||||
chars[cursorY * cols + cursorX].c = c;
|
||||
chars[cursorY * cols + cursorX].attrs = currentAttr;
|
||||
|
||||
if(dirtyRect.right == 0)
|
||||
{
|
||||
@ -400,8 +349,7 @@ void IConsole::PutCharNoUpdate(char c)
|
||||
if(cursorX >= cols)
|
||||
PutCharNoUpdate('\n');
|
||||
// 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;
|
||||
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(start == -1)
|
||||
start = col;
|
||||
if(old != ' ')
|
||||
if(old.c != ' ')
|
||||
needclear = true;
|
||||
onscreen[row * cols + col] = chars[row * cols + col];
|
||||
}
|
||||
@ -443,8 +391,8 @@ void IConsole::Update()
|
||||
Rect r = CellRect(cursorX, cursorY);
|
||||
if(cursorDrawn)
|
||||
DrawCell(cursorX, cursorY, true);
|
||||
//else
|
||||
// InvertRect(&r);
|
||||
else
|
||||
InvertRect(&r);
|
||||
cursorDrawn = !cursorDrawn;
|
||||
}
|
||||
|
||||
@ -555,11 +503,11 @@ void IConsole::Reshape(Rect newBounds)
|
||||
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++)
|
||||
{
|
||||
char *src = &chars[(row+upshift) * cols];
|
||||
char *dst = &newChars[row * newCols];
|
||||
AttributedChar *src = &chars[(row+upshift) * cols];
|
||||
AttributedChar *dst = &newChars[row * newCols];
|
||||
std::copy(src, src + std::min(cols, newCols), dst);
|
||||
}
|
||||
chars.swap(newChars);
|
||||
|
@ -46,6 +46,14 @@ namespace retro
|
||||
bool cUnderline;
|
||||
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);
|
||||
@ -79,8 +87,7 @@ namespace retro
|
||||
Rect bounds;
|
||||
Attributes currentAttr;
|
||||
|
||||
std::vector<char> chars, onscreen;
|
||||
std::vector<Attributes> attrs;
|
||||
std::vector<AttributedChar> chars, onscreen;
|
||||
bool isProcessingEscSequence;
|
||||
int sequenceStep;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user