Optimize negative bounds checking in rendering loops

This commit is contained in:
pixel-jupiter
2025-10-24 01:12:26 +03:00
parent f58164db1b
commit 258c89151c

View File

@@ -396,37 +396,51 @@ vid_render(tandy_t *dev, int line, int hos_offs)
uint16_t dat;
int col;
int cols[4];
uint32_t border_val;
int out_x;
int c_start;
cols[0] = (vid->array[2] & 0xf) + 16;
if (line >= 0) {
if (line < 0) {
if (dev->is_sl2 && (vid->array[5] & 1)) {
vid->memaddr += vid->crtc[1] * 2;
} else {
vid->memaddr += vid->crtc[1];
}
return;
}
if (vid->array[3] & 4) {
border_val = cols[0];
} else if ((vid->mode & 0x12) == 0x12) {
border_val = 0;
} else {
border_val = (vid->col & 15) + 16;
}
if (vid->array[3] & 4) {
for (c = 0; c < hos_offs; c++) {
if (vid->array[3] & 4) {
buffer32->line[line][c] = cols[0];
} else if ((vid->mode & 0x12) == 0x12) {
buffer32->line[line][c] = 0;
} else {
buffer32->line[line][c] = buffer32->line[(line) + 1][c] = (vid->col & 15) + 16;
}
buffer32->line[line][c] = border_val;
}
for (c = 0; c < 8 - vid->hsync_offset; c++) {
if (vid->mode & 1)
out_x = c + (vid->crtc[1] << 3) + hos_offs;
else
out_x = c + (vid->crtc[1] << 4) + hos_offs;
if (out_x >= 0) {
if (vid->array[3] & 4) {
buffer32->line[line][out_x] = cols[0];
} else if ((vid->mode & 0x12) == 0x12) {
buffer32->line[line][out_x] = 0;
} else {
buffer32->line[line][out_x] = (vid->col & 15) + 16;
}
}
} else if ((vid->mode & 0x12) == 0x12) {
for (c = 0; c < hos_offs; c++) {
buffer32->line[line][c] = border_val;
}
} else {
for (c = 0; c < hos_offs; c++) {
buffer32->line[line][c] = buffer32->line[(line) + 1][c] = border_val;
}
}
if (vid->mode & 1) {
out_x = (vid->crtc[1] << 3) + hos_offs;
} else {
out_x = (vid->crtc[1] << 4) + hos_offs;
}
c_start = out_x < 0 ? -out_x : 0;
for (c = c_start; c < 8 - vid->hsync_offset; c++) {
buffer32->line[line][out_x + c] = border_val;
}
if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/
@@ -434,11 +448,16 @@ vid_render(tandy_t *dev, int line, int hos_offs)
dat = (vid->vram[(vid->memaddr << 1) & 0xffff] << 8) | vid->vram[((vid->memaddr << 1) + 1) & 0xffff];
vid->memaddr++;
out_x = (x << 2) + hos_offs;
if (line >= 0) {
if (out_x >= 0) buffer32->line[line][out_x] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
if (out_x + 1 >= 0) buffer32->line[line][out_x + 1] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
if (out_x + 2 >= 0) buffer32->line[line][out_x + 2] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
if (out_x + 3 >= 0) buffer32->line[line][out_x + 3] = vid->array[(dat & 0xf) + 16] + 16;
if (out_x >= 0) {
buffer32->line[line][out_x] = vid->array[((dat >> 12) & 0xf) + 16] + 16;
buffer32->line[line][out_x + 1] = vid->array[((dat >> 8) & 0xf) + 16] + 16;
buffer32->line[line][out_x + 2] = vid->array[((dat >> 4) & 0xf) + 16] + 16;
buffer32->line[line][out_x + 3] = vid->array[(dat & 0xf) + 16] + 16;
} else if (out_x > -4) {
for (c = -out_x; c < 4; c++) {
buffer32->line[line][out_x + c] =
vid->array[((dat >> (12 - c * 4)) & 0xf) + 16] + 16;
}
}
}
} else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/
@@ -447,15 +466,20 @@ vid_render(tandy_t *dev, int line, int hos_offs)
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1];
vid->memaddr++;
out_x = (x << 3) + hos_offs;
if (line >= 0) {
if (out_x >= 0) buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] =
if (out_x >= 0) {
buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] =
vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 2 >= 0) buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] =
buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] =
vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 4 >= 0) buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] =
buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] =
vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 6 >= 0) buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] =
buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] =
vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
} else if (out_x > -8) {
for (c = -out_x; c < 8; c++) {
buffer32->line[line][out_x + c] =
vid->array[((dat >> 12 - (c >> 1) * 4) & vid->array[1] & 0x0f) + 16] + 16;
}
}
}
} else if (vid->array[3] & 0x10) { /*160x200x16*/
@@ -468,19 +492,24 @@ vid_render(tandy_t *dev, int line, int hos_offs)
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1];
vid->memaddr++;
out_x = (x << 4) + hos_offs;
if (line >= 0) {
if (out_x >= 0) buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] =
buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] =
if (out_x >= 0) {
buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] =
buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] =
vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 4 >= 0) buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] =
buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] =
buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] =
buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] =
vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 8 >= 0) buffer32->line[line][out_x + 8] = buffer32->line[line][out_x + 9] =
buffer32->line[line][out_x + 8] = buffer32->line[line][out_x + 9] =
buffer32->line[line][out_x + 10] = buffer32->line[line][out_x + 11] =
vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16;
if (out_x + 12 >= 0) buffer32->line[line][out_x + 12] = buffer32->line[line][out_x + 13] =
buffer32->line[line][out_x + 12] = buffer32->line[line][out_x + 13] =
buffer32->line[line][out_x + 14] = buffer32->line[line][out_x + 15] =
vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16;
} else if (out_x > -16) {
for (c = -out_x; c < 16; c++) {
buffer32->line[line][out_x + c] =
vid->array[((dat >> 12 - (c >> 2) * 4) & vid->array[1] & 0x0f) + 16] + 16;
}
}
}
} else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/
@@ -488,14 +517,17 @@ vid_render(tandy_t *dev, int line, int hos_offs)
dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) |
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1];
vid->memaddr++;
for (c = 0; c < 8; c++) {
chr = (dat >> 6) & 2;
chr |= ((dat >> 15) & 1);
out_x = (x << 3) + hos_offs + c;
if (out_x >= 0 && line >= 0)
buffer32->line[line][out_x] =
out_x = (x << 3) + hos_offs;
if (out_x > -8) {
c_start = out_x < 0 ? -out_x : 0;
dat <<= c_start;
for (c = c_start; c < 8; c++) {
chr = (dat >> 6) & 2;
chr |= ((dat >> 15) & 1);
buffer32->line[line][out_x + c] =
vid->array[(chr & vid->array[1]) + 16] + 16;
dat <<= 1;
dat <<= 1;
}
}
}
} else if (vid->mode & 1) {
@@ -512,25 +544,20 @@ vid_render(tandy_t *dev, int line, int hos_offs)
cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16;
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
}
if (line >= 0) {
if (vid->scanline & 8) for (c = 0; c < 8; c++) {
out_x = (x << 3) + c + hos_offs;
if (out_x >= 0)
buffer32->line[line][out_x] =
((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0];
} else for (c = 0; c < 8; c++) {
out_x = (x << 3) + c + hos_offs;
if (out_x >= 0) {
if (vid->scanline == 8)
buffer32->line[line][out_x] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
else
buffer32->line[line][out_x] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
out_x = (x << 3) + hos_offs;
if (out_x > -8) {
c_start = out_x < 0 ? -out_x : 0;
if (vid->scanline & 8) for (c = c_start; c < 8; c++) {
buffer32->line[line][out_x + c] =
((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0];
} else for (c = c_start; c < 8; c++) {
if (vid->scanline == 8)
buffer32->line[line][out_x + c] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
else
buffer32->line[line][out_x + c] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
if (drawcursor) for (c = 0; c < 8; c++) {
out_x = (x << 3) + c + hos_offs;
if (out_x >= 0)
buffer32->line[line][out_x] ^= 15;
if (drawcursor) for (c = c_start; c < 8; c++) {
buffer32->line[line][out_x + c] ^= 15;
}
}
vid->memaddr++;
@@ -550,28 +577,29 @@ vid_render(tandy_t *dev, int line, int hos_offs)
cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16;
}
vid->memaddr++;
if (line >= 0) {
if (vid->scanline & 8) for (c = 0; c < 8; c++) {
out_x = (x << 4) + (c << 1) + hos_offs;
if (out_x >= 0) buffer32->line[line][out_x] =
buffer32->line[line][out_x + 1] =
out_x = (x << 4) + hos_offs;
if (out_x > -16) {
c_start = out_x < 0 ? -out_x >> 1 : 0;
if (vid->scanline & 8) for (c = c_start; c < 8; c++) {
buffer32->line[line][out_x + (c << 1)] =
buffer32->line[line][out_x + 1 + (c << 1)] =
((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0];
} else for (c = 0; c < 8; c++) {
out_x = (x << 4) + (c << 1) + hos_offs;
} else for (c = c_start; c < 8; c++) {
if (vid->scanline == 8) {
if (out_x >= 0) buffer32->line[line][out_x] =
buffer32->line[line][out_x + 1] =
buffer32->line[line][out_x + (c << 1)] =
buffer32->line[line][out_x + 1 + (c << 1)] =
cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0];
} else {
if (out_x >= 0) buffer32->line[line][out_x] =
buffer32->line[line][out_x + 1] =
buffer32->line[line][out_x + (c << 1)] =
buffer32->line[line][out_x + 1 + (c << 1)] =
cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
if (drawcursor) for (c = 0; c < 16; c++) {
out_x = (x << 4) + c + hos_offs;
if (out_x >= 0)
buffer32->line[line][out_x] ^= 15;
if (drawcursor) {
c_start = out_x < 0 ? -out_x : 0;
for (c = c_start; c < 16; c++) {
buffer32->line[line][out_x + c] ^= 15;
}
}
}
}
@@ -599,11 +627,15 @@ vid_render(tandy_t *dev, int line, int hos_offs)
dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) |
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
vid->memaddr++;
for (c = 0; c < 8; c++) {
out_x = (x << 4) + (c << 1) + hos_offs;
if (out_x >= 0 && line >= 0) buffer32->line[line][out_x] =
buffer32->line[line][out_x + 1] = cols[dat >> 14];
dat <<= 2;
out_x = (x << 4) + hos_offs;
if (out_x > -16) {
c_start = out_x < 0 ? -out_x >> 1 : 0;
dat <<= (c_start > 0 ? c_start << 1 : 0);
for (c = c_start; c < 8; c++) {
buffer32->line[line][out_x + (c << 1)] =
buffer32->line[line][out_x + 1 + (c << 1)] = cols[dat >> 14];
dat <<= 2;
}
}
}
} else {
@@ -613,11 +645,14 @@ vid_render(tandy_t *dev, int line, int hos_offs)
dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) |
vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1];
vid->memaddr++;
for (c = 0; c < 16; c++) {
out_x = (x << 4) + c + hos_offs;
if (out_x >= 0 && line >= 0)
buffer32->line[line][out_x] = buffer32->line[(line) + 1][out_x] = cols[dat >> 15];
dat <<= 1;
out_x = (x << 4) + hos_offs;
if (out_x > -16) {
c_start = out_x < 0 ? -out_x : 0;
dat <<= (c_start > 0 ? c_start : 0);
for (c = c_start; c < 16; c++) {
buffer32->line[line][out_x + c] = buffer32->line[(line) + 1][out_x + c] = cols[dat >> 15];
dat <<= 1;
}
}
}
}
@@ -628,20 +663,21 @@ vid_render_blank(tandy_t *dev, int line)
{
t1kvid_t *vid = dev->vid;
if (line >= 0) {
if (vid->array[3] & 4) {
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
} else {
int cols = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16;
if (line < 0)
return;
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, cols);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, cols);
}
if (vid->array[3] & 4) {
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16);
} else {
int cols = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16;
if (vid->mode & 1)
hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, cols);
else
hline(buffer32, 0, line, (vid->crtc[1] << 4) + 16, cols);
}
}
@@ -651,17 +687,18 @@ vid_render_process(tandy_t *dev, int line)
t1kvid_t *vid = dev->vid;
int x;
if (line < 0)
return;
if (vid->mode & 1)
x = (vid->crtc[1] << 3) + 16;
else
x = (vid->crtc[1] << 4) + 16;
if (line >= 0) {
if (!dev->is_sl2 && vid->composite)
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[line]);
else
video_process_8(x, line);
}
if (!dev->is_sl2 && vid->composite)
Composite_Process(vid->mode, 0, x >> 2, buffer32->line[line]);
else
video_process_8(x, line);
}
static void