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

Implement double-height.

This is so gross... outputting any character depends on every
character above it, so it must be checked every time.  If the state
was ste up differently, this could be avoided, but it's not, so it
can't.

For v2, I'm going to want to store some per-line data in a separate
struct so I can track this.
parent 18a9e5cc
No related branches found
No related tags found
No related merge requests found
Pipeline #7011 passed
......@@ -541,6 +541,9 @@ static int bitmap_draw_one_char(struct vmem_cell *vc, unsigned int xpos, unsigne
WORD sch;
BOOL draw_fg = TRUE;
size_t rsz;
bool double_height = false;
bool bottom = false;
bool top = false;
if(!bitmap_initialized) {
return(-1);
......@@ -596,6 +599,58 @@ static int bitmap_draw_one_char(struct vmem_cell *vc, unsigned int xpos, unsigne
pixeloffset = PIXEL_OFFSET(screena, xoffset, yoffset);
rsz = screena.screenwidth - vstat.charwidth;
// PRESTEL!
if (vstat.mode == PRESTEL_40X24) {
struct vstat_vmem *vmem_ptr = get_vmem(&vstat);
if (ypos > 1) {
for (y = 0; y < ypos; y++) {
if (top) {
bottom = true;
top = false;
}
else {
if (bottom)
bottom = false;
else {
if (y == ypos - 1)
break;
for (x = 0; x < vstat.cols; x++) {
if (vmem_ptr->vmem[y * vstat.cols + x].bg & 0x01000000) {
top = true;
break;
}
}
}
}
}
}
if (bottom) {
if (vmem_ptr->vmem[(ypos - 2) * vstat.cols + (xpos - 1)].bg & 0x01000000) {
double_height = true;
}
fg = vmem_ptr->vmem[(ypos - 2) * vstat.cols + (xpos - 1)].fg;
bg = vmem_ptr->vmem[(ypos - 2) * vstat.cols + (xpos - 1)].bg;
}
else {
if (ypos != vstat.rows) {
if (vmem_ptr->vmem[(ypos - 1) * vstat.cols + (xpos - 1)].bg & 0x01000000) {
top = true;
double_height = true;
}
}
}
// Draw as space if not double-bottom
if (bottom) {
if (double_height) {
pixeloffset -= vstat.charheight * vstat.scrnwidth;
fontoffset=(vmem_ptr->vmem[(ypos - 2) * vstat.cols + (xpos - 1)].ch) * (vstat.charheight * ((fdw + 7) / 8));
}
else
fontoffset=(32) * (vstat.charheight * ((fdw + 7) / 8));
}
release_vmem(vmem_ptr);
}
for (y = 0; y < vstat.charheight; y++) {
for(x = 0; x < vstat.charwidth; x++) {
fdx = x;
......@@ -624,12 +679,24 @@ static int bitmap_draw_one_char(struct vmem_cell *vc, unsigned int xpos, unsigne
screena.update_pixels = 1;
screena.rect->data[pixeloffset] = fg;
}
if (double_height) {
if (screena.rect->data[pixeloffset+screena.screenwidth] != fg) {
screena.update_pixels = 1;
screena.rect->data[pixeloffset+screena.screenwidth] = fg;
}
}
}
else {
if (screena.rect->data[pixeloffset] != bg) {
screena.update_pixels = 1;
screena.rect->data[pixeloffset] = bg;
}
if (double_height) {
if (screena.rect->data[pixeloffset+screena.screenwidth] != bg) {
screena.update_pixels = 1;
screena.rect->data[pixeloffset+screena.screenwidth] = bg;
}
}
}
if(fbb) {
......@@ -637,18 +704,35 @@ static int bitmap_draw_one_char(struct vmem_cell *vc, unsigned int xpos, unsigne
screenb.update_pixels = 1;
screenb.rect->data[pixeloffset] = fg;
}
if (double_height) {
if (screenb.rect->data[pixeloffset+screena.screenwidth] != fg) {
screenb.update_pixels = 1;
screenb.rect->data[pixeloffset+screena.screenwidth] = fg;
}
}
}
else {
if (screenb.rect->data[pixeloffset] != bg) {
screenb.update_pixels = 1;
screenb.rect->data[pixeloffset] = bg;
}
if (double_height) {
if (screenb.rect->data[pixeloffset+screena.screenwidth] != bg) {
screenb.update_pixels = 1;
screenb.rect->data[pixeloffset+screena.screenwidth] = bg;
}
}
}
pixeloffset++;
}
if (x & 0x07)
if (x & 0x07) {
fontoffset++;
if (double_height && ((y & 1) == 0))
fontoffset--;
}
pixeloffset += rsz;
if (double_height)
pixeloffset += screena.screenwidth;
}
pthread_mutex_unlock(&screenlock);
......
......@@ -796,6 +796,10 @@ set_attr(struct cterminal *cterm, unsigned char colour, bool bg)
cterm->attr |= (colour & 0x07);
}
attr2palette(cterm->attr, bg ? NULL : &cterm->fg_color, bg ? &cterm->bg_color : NULL);
if (cterm->emulation == CTERM_EMULATION_PRESTEL) {
if (cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT)
cterm->bg_color |= 0x01000000;
}
if (bg)
FREE_AND_NULL(cterm->bg_tc_str);
else
......@@ -832,9 +836,12 @@ prestel_apply_ctrl_before(struct cterminal *cterm, uint8_t ch)
case 73: // Steady
cterm->attr &= 0x7f;
attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
if (CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT)
cterm->bg_color |= 0x01000000;
break;
case 76: // Normal Height
cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT);
cterm->bg_color &= ~0x01000000;
cterm->prestel_last_mosaic = 32;
break;
case 88: // Conceal Display
......@@ -908,9 +915,12 @@ prestel_apply_ctrl_after(struct cterminal *cterm, uint8_t ch)
case 72: // Flash
cterm->attr |= 0x80;
attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
if (cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT)
cterm->bg_color |= 0x01000000;
break;
case 77: // Double Height
cterm->extattr |= CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT;
cterm->bg_color |= 0x01000000;
cterm->prestel_last_mosaic = 32;
break;
case 80: // Mosaic Black
......@@ -4948,7 +4958,7 @@ void cterm_start(struct cterminal *cterm)
* - Format effector added or removed
* - Hold mosaic character changed
*/
static void prestel_fix_line(struct cterminal *cterm, int x, int y)
static void prestel_fix_line(struct cterminal *cterm, int x, int y, bool restore, bool force)
{
int sy = y;
int sx = 1;
......@@ -4960,6 +4970,7 @@ static void prestel_fix_line(struct cterminal *cterm, int x, int y)
unsigned char attr = cterm->attr;
uint8_t prestel_last_mosaic = cterm->prestel_last_mosaic;
bool fixed = false;
bool fixedheight = false;
coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_SCREEN, &sy, &sx);
ex = sx + TERM_MAXX - 1;
......@@ -4973,6 +4984,18 @@ static void prestel_fix_line(struct cterminal *cterm, int x, int y)
// This is a control character
ch = (line[i].fg & 0x7F000000) >> 24;
prestel_apply_ctrl_before(cterm, ch);
if ((cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT) && ((line[i].bg & 0x01000000) == 0)) {
// Should be double-high
line[i].bg |= 0x01000000;
fixed = true;
fixedheight = true;
}
if (((cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT) == 0) && (line[i].bg & 0x01000000)) {
// Should not be double-high
line[i].bg &= ~0x01000000;
fixed = true;
fixedheight = true;
}
if (line[i].fg != (cterm->fg_color | (ch << 24))
|| line[i].bg != cterm->bg_color
|| line[i].legacy_attr != cterm->attr) {
......@@ -5009,6 +5032,18 @@ static void prestel_fix_line(struct cterminal *cterm, int x, int y)
prestel_last_mosaic = cterm->prestel_last_mosaic;
}
// This is displayable
if ((cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT) && ((line[i].bg & 0x01000000) == 0)) {
// Should be double-high
line[i].bg |= 0x01000000;
fixed = true;
fixedheight = true;
}
if (((cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT) == 0) && (line[i].bg & 0x01000000)) {
// Should not be double-high
line[i].bg &= ~0x01000000;
fixed = true;
fixedheight = true;
}
if (line[i].fg != cterm->fg_color
|| line[i].bg != cterm->bg_color
|| line[i].legacy_attr != cterm->attr) {
......@@ -5052,15 +5087,20 @@ static void prestel_fix_line(struct cterminal *cterm, int x, int y)
}
}
}
if (fixed)
if (force || fixed)
vmem_puttext(sx, sy, ex, sy, line);
free(line);
if (restore) {
cterm->extattr = extattr;
cterm->fg_color = fg_color;
cterm->bg_color = bg_color;
cterm->attr = attr;
cterm->prestel_last_mosaic = prestel_last_mosaic;
}
if (fixedheight) {
prestel_fix_line(cterm, x, y+1, false, true);
}
}
static void
advance_char(struct cterminal *cterm, int *x, int *y, int move)
......@@ -5070,7 +5110,7 @@ advance_char(struct cterminal *cterm, int *x, int *y, int move)
int bm = cterm->bottom_margin;
if (cterm->emulation == CTERM_EMULATION_PRESTEL) {
prestel_fix_line(cterm, *x, *y);
prestel_fix_line(cterm, *x, *y, true, false);
TEXTATTR(cterm->attr);
setcolour(cterm->fg_color, cterm->bg_color);
}
......@@ -5199,6 +5239,8 @@ ctputs(struct cterminal *cterm, char *buf)
}
}
CPUTS(outp);
if (cterm->emulation == CTERM_EMULATION_PRESTEL)
prestel_fix_line(cterm, cx, cy, true, false);
*cterm->_wscroll=oldscroll;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment