Skip to content
Snippets Groups Projects
Commit 17f6a666 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Fix Prestel regression on double-height text.

Visible in the double height graphics and engineering test pages.
parent 3a727c6b
Branches
Tags
No related merge requests found
Pipeline #7879 passed
...@@ -624,33 +624,47 @@ calc_charstate(struct blockstate *bs, struct vmem_cell *vc, struct charstate *cs ...@@ -624,33 +624,47 @@ calc_charstate(struct blockstate *bs, struct vmem_cell *vc, struct charstate *cs
cs->extra_rows = 0; cs->extra_rows = 0;
if (vstat.mode == PRESTEL_40X24 && (vc->bg & 0x02000000)) { if (vstat.mode == PRESTEL_40X24 && (vc->bg & 0x02000000)) {
unsigned char lattr = vc->legacy_attr; unsigned char lattr;
int x, y;
bool top = false; bool top = false;
bool bottom = false; bool bottom = false;
// Start at the first cell...
struct vmem_cell *pvc = vmem_cell_ptr(vstat.vmem, 0, 0); struct vmem_cell *pvc = vmem_cell_ptr(vstat.vmem, 0, 0);
for (y = 0; y < ypos; y++) { // And check all the rows including this one.
for (int y = 0; y < ypos; y++) {
// If the previous line was a top line, this one is a bottom.
if (top) { if (top) {
bottom = true; bottom = true;
top = false; top = false;
} }
else { else {
// If the previous line was a bottom, this is not a bottom
if (bottom) if (bottom)
bottom = false; bottom = false;
for (x = 0; x < vstat.cols; x++) { // Check for any of these being tops...
pvc = vmem_cell_ptr(vstat.vmem, 0, y);
for (int x = 0; x < vstat.cols; x++) {
// If there's at least one top, this is a top row
if (pvc->bg & 0x01000000) { if (pvc->bg & 0x01000000) {
top = true; top = true;
pvc = vmem_cell_ptr(vstat.vmem, 0, y + 1);
break; break;
} }
pvc = vmem_next_ptr(vstat.vmem, pvc); pvc = vmem_next_ptr(vstat.vmem, pvc);
} }
} }
} }
// If this is the last row, it can't be a top...
if (ypos == vstat.rows)
top = false;
// If this is a bottom row...
if (bottom) { if (bottom) {
pvc = vmem_cell_ptr(vstat.vmem, xpos - 1, ypos - 2); assert(!top);
// Find the cell above this one...
pvc = vmem_prev_row_ptr(vstat.vmem, vc);
if (pvc->bg & 0x01000000) { if (pvc->bg & 0x01000000) {
// If it's double-height, draw the cell above
cs->double_height = true; cs->double_height = true;
cs->extra_rows = -(vstat.charheight); cs->extra_rows = -(vstat.charheight);
cs->fontoffset = (pvc->ch) * (vstat.charheight * ((bs->font_data_width + 7) / 8)); cs->fontoffset = (pvc->ch) * (vstat.charheight * ((bs->font_data_width + 7) / 8));
...@@ -664,14 +678,18 @@ calc_charstate(struct blockstate *bs, struct vmem_cell *vc, struct charstate *cs ...@@ -664,14 +678,18 @@ calc_charstate(struct blockstate *bs, struct vmem_cell *vc, struct charstate *cs
cs->bg = pvc->bg; cs->bg = pvc->bg;
lattr = pvc->legacy_attr; lattr = pvc->legacy_attr;
} }
// If not a bottom (either a top or no doubles)
else { else {
pvc = vmem_cell_ptr(vstat.vmem, xpos - 1, ypos - 1); // And it's a top row...
if (ypos != vstat.rows) { if (top) {
if (pvc->bg & 0x01000000) { // And it's double-height
top = true; if (vc->bg & 0x01000000) {
//assert(top);
// Draw it as is where is
cs->double_height = true; cs->double_height = true;
} }
} }
lattr = vc->legacy_attr;
} }
if (lattr & 0x08) { if (lattr & 0x08) {
if (!(cio_api.options & CONIO_OPT_PRESTEL_REVEAL)) { if (!(cio_api.options & CONIO_OPT_PRESTEL_REVEAL)) {
...@@ -737,7 +755,7 @@ draw_char_row_double(struct blockstate *bs, struct charstate *cs, uint32_t y) ...@@ -737,7 +755,7 @@ draw_char_row_double(struct blockstate *bs, struct charstate *cs, uint32_t y)
{ {
bool fbb; bool fbb;
ssize_t pixeloffset = bs->pixeloffset + (cs->extra_rows * screena.screenwidth); ssize_t pixeloffset = bs->pixeloffset + cs->extra_rows * screena.screenwidth;
if (pixeloffset >= bs->maxpix) if (pixeloffset >= bs->maxpix)
pixeloffset -= bs->maxpix; pixeloffset -= bs->maxpix;
if (pixeloffset < 0) if (pixeloffset < 0)
...@@ -828,16 +846,21 @@ bitmap_draw_vmem_locked(int sx, int sy, int ex, int ey, struct vmem_cell *fill) ...@@ -828,16 +846,21 @@ bitmap_draw_vmem_locked(int sx, int sy, int ex, int ey, struct vmem_cell *fill)
size_t rsz = screena.screenwidth - vstat.charwidth * vwidth; size_t rsz = screena.screenwidth - vstat.charwidth * vwidth;
// Fill in charstate for this pass // Fill in charstate for this pass
bool cheat = true; // If the whole thing is spaces in compiled in fonts, we can just fill. bool cheat = true;
for (size_t vy = 0; vy < vheight; vy++) { if (vstat.mode == PRESTEL_40X24) {
for (size_t vx = 0; vx < vwidth; vx++) { cheat = false;
if (!can_cheat(&bs, &fill[vy * vwidth + vx])) { }
cheat = false; else {
break; for (size_t vy = 0; vy < vheight; vy++) {
for (size_t vx = 0; vx < vwidth; vx++) {
if (!can_cheat(&bs, &fill[vy * vwidth + vx])) {
cheat = false;
break;
}
} }
if (!cheat)
break;
} }
if (!cheat)
break;
} }
if (cheat) { if (cheat) {
size_t ylim = vheight * vstat.charheight; size_t ylim = vheight * vstat.charheight;
...@@ -1057,11 +1080,13 @@ same_cell(struct vmem_cell *bitmap_cell, struct vmem_cell *c2) ...@@ -1057,11 +1080,13 @@ same_cell(struct vmem_cell *bitmap_cell, struct vmem_cell *c2)
return false; return false;
if (bitmap_cell->bg != c2->bg) if (bitmap_cell->bg != c2->bg)
return false; return false;
if (vstat.mode == PRESTEL_40X24 && (c2->bg & 0x02000000) && (c2->legacy_attr & 0x08)) { if (vstat.mode == PRESTEL_40X24 && (c2->bg & 0x02000000)) {
if (cio_api.options & CONIO_OPT_PRESTEL_REVEAL) if (c2->legacy_attr & 0x08) {
c2->fg |= 0x01000000; if (cio_api.options & CONIO_OPT_PRESTEL_REVEAL)
else c2->fg |= 0x01000000;
c2->fg &= ~0x01000000; else
c2->fg &= ~0x01000000;
}
} }
if (bitmap_cell->fg != c2->fg) if (bitmap_cell->fg != c2->fg)
return false; return false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment