Browse Source

Fixed issue with screen device

main
Devine Lu Linvega 1 year ago
parent
commit
c0d5f6820c
  1. 77
      src/devices/screen.c
  2. 6
      src/devices/screen.h
  3. 12
      src/uxnemu.c

77
src/devices/screen.c

@ -119,23 +119,22 @@ screen_resize(Uint16 width, Uint16 height, int scale)
void void
screen_redraw(void) screen_redraw(void)
{ {
int i, x, y, k, l, s = uxn_screen.scale; int i, x, y, k, l;
Uint8 *fg = uxn_screen.fg, *bg = uxn_screen.bg; int x1 = uxn_screen.x1 < 0 ? 0 : uxn_screen.x1, y1 = uxn_screen.y1 < 0 ? 0 : uxn_screen.y1;
Uint16 w = uxn_screen.width, h = uxn_screen.height; int x2 = uxn_screen.x2 > uxn_screen.width ? uxn_screen.width : uxn_screen.x2;
Uint16 x1 = uxn_screen.x1, y1 = uxn_screen.y1; int y2 = uxn_screen.y2 > uxn_screen.height ? uxn_screen.height : uxn_screen.y2;
Uint16 x2 = uxn_screen.x2 > w ? w : uxn_screen.x2, y2 = uxn_screen.y2 > h ? h : uxn_screen.y2;
Uint32 palette[16], *pixels = uxn_screen.pixels; Uint32 palette[16], *pixels = uxn_screen.pixels;
uxn_screen.x1 = uxn_screen.y1 = 9000; uxn_screen.x1 = uxn_screen.y1 = 9000;
uxn_screen.x2 = uxn_screen.y2 = 0; uxn_screen.x2 = uxn_screen.y2 = 0;
for(i = 0; i < 16; i++) for(i = 0; i < 16; i++)
palette[i] = uxn_screen.palette[(i >> 2) ? (i >> 2) : (i & 3)]; palette[i] = uxn_screen.palette[(i >> 2) ? (i >> 2) : (i & 3)];
for(y = y1; y < y2; y++) { for(y = y1; y < y2; y++) {
int ys = y * s; int ys = y * uxn_screen.scale;
for(x = x1, i = MAR(x) + MAR(y) * MAR2(w); x < x2; x++, i++) { for(x = x1, i = MAR(x) + MAR(y) * MAR2(uxn_screen.width); x < x2; x++, i++) {
int c = palette[fg[i] << 2 | bg[i]]; int c = palette[uxn_screen.fg[i] << 2 | uxn_screen.bg[i]];
for(k = 0; k < s; k++) { for(k = 0; k < uxn_screen.scale; k++) {
int oo = ((ys + k) * w + x) * s; int oo = ((ys + k) * uxn_screen.width + x) * uxn_screen.scale;
for(l = 0; l < s; l++) for(l = 0; l < uxn_screen.scale; l++)
pixels[oo + l] = c; pixels[oo + l] = c;
} }
} }
@ -147,7 +146,7 @@ screen_redraw(void)
static int rX, rY, rA, rMX, rMY, rMA, rML, rDX, rDY; static int rX, rY, rA, rMX, rMY, rMA, rML, rDX, rDY;
Uint8 Uint8
screen_dei(Uxn *u, Uint8 addr) screen_dei(Uint8 addr)
{ {
switch(addr) { switch(addr) {
case 0x22: return uxn_screen.width >> 8; case 0x22: return uxn_screen.width >> 8;
@ -160,25 +159,25 @@ screen_dei(Uxn *u, Uint8 addr)
case 0x2b: return rY; case 0x2b: return rY;
case 0x2c: return rA >> 8; case 0x2c: return rA >> 8;
case 0x2d: return rA; case 0x2d: return rA;
default: return u->dev[addr]; default: return uxn.dev[addr];
} }
} }
void void
screen_deo(Uxn *u, Uint8 addr) screen_deo(Uint8 addr)
{ {
switch(addr) { switch(addr) {
case 0x23: screen_resize(PEEK2(&uxn.dev[0x22]), uxn_screen.height, uxn_screen.scale); return; case 0x23: screen_resize(PEEK2(&uxn.dev[0x22]), uxn_screen.height, uxn_screen.scale); return;
case 0x25: screen_resize(uxn_screen.width, PEEK2(&uxn.dev[0x24]), uxn_screen.scale); return; case 0x25: screen_resize(uxn_screen.width, PEEK2(&uxn.dev[0x24]), uxn_screen.scale); return;
case 0x26: rMX = u->dev[0x26] & 0x1, rMY = u->dev[0x26] & 0x2, rMA = u->dev[0x26] & 0x4, rML = u->dev[0x26] >> 4, rDX = rMX << 3, rDY = rMY << 2; return; case 0x26: rMX = uxn.dev[0x26] & 0x1, rMY = uxn.dev[0x26] & 0x2, rMA = uxn.dev[0x26] & 0x4, rML = uxn.dev[0x26] >> 4, rDX = rMX << 3, rDY = rMY << 2; return;
case 0x28: case 0x28:
case 0x29: rX = (u->dev[0x28] << 8) | u->dev[0x29], rX = twos(rX); return; case 0x29: rX = (uxn.dev[0x28] << 8) | uxn.dev[0x29], rX = twos(rX); return;
case 0x2a: case 0x2a:
case 0x2b: rY = (u->dev[0x2a] << 8) | u->dev[0x2b], rY = twos(rY); return; case 0x2b: rY = (uxn.dev[0x2a] << 8) | uxn.dev[0x2b], rY = twos(rY); return;
case 0x2c: case 0x2c:
case 0x2d: rA = (u->dev[0x2c] << 8) | u->dev[0x2d]; return; case 0x2d: rA = (uxn.dev[0x2c] << 8) | uxn.dev[0x2d]; return;
case 0x2e: { case 0x2e: {
int ctrl = u->dev[0x2e]; int ctrl = uxn.dev[0x2e];
int color = ctrl & 0x3; int color = ctrl & 0x3;
int len = MAR2(uxn_screen.width); int len = MAR2(uxn_screen.width);
Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg; Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
@ -210,24 +209,25 @@ screen_deo(Uxn *u, Uint8 addr)
return; return;
} }
case 0x2f: { case 0x2f: {
int i; int ctrl = uxn.dev[0x2f];
int ctrl = u->dev[0x2f];
int twobpp = !!(ctrl & 0x80); int twobpp = !!(ctrl & 0x80);
int blend = ctrl & 0xf; int blend = ctrl & 0xf;
int fx = ctrl & 0x10 ? -1 : 1, fy = ctrl & 0x20 ? -1 : 1; int fx = ctrl & 0x10 ? -1 : 1, fy = ctrl & 0x20 ? -1 : 1;
int x1, x2, y1, y2, ax, ay, qx, qy, x = rX, y = rY; int i, x1, x2, y1, y2, ax, ay, qx, qy, x = rX, y = rY;
int dxy = rDX * fy, dyx = rDY * fx, addr_incr = rMA << (1 + twobpp); int dxy = rDX * fy, dyx = rDY * fx, addr_incr = rMA << (1 + twobpp);
int len = MAR2(uxn_screen.width); int wmar = MAR(uxn_screen.width), wmar2 = MAR2(uxn_screen.width);
int hmar2 = MAR2(uxn_screen.height);
Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg; Uint8 *layer = ctrl & 0x40 ? uxn_screen.fg : uxn_screen.bg;
if(twobpp) if(twobpp)
for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) { for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
Uint16 xx = MAR(x), yy = MAR(y); Uint16 xmar = MAR(x), ymar = MAR(y);
if(xx < MAR(uxn_screen.width) && MAR(yy) < MAR2(uxn_screen.height)) { Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
Uint8 *sprite = &u->ram[rA]; if(xmar < wmar && ymar2 < hmar2) {
int opaque = blend % 5, by = (yy + 8) * len; Uint8 *sprite = &uxn.ram[rA];
for(ay = yy * len, qy = fy < 0 ? 7 : 0; ay < by; ay += len, qy += fy) { int opaque = blend % 5, by = ymar2 * wmar2;
int ch1 = sprite[qy], ch2 = sprite[qy + 8] << 1, bx = xx + 8 + ay; for(ay = ymar * wmar2, qy = fy < 0 ? 7 : 0; ay < by; ay += wmar2, qy += fy) {
for(ax = xx + ay, qx = fx > 0 ? 7 : 0; ax < bx; ax++, qx -= fx) { int ch1 = sprite[qy], ch2 = sprite[qy + 8] << 1, bx = xmar2 + ay;
for(ax = xmar + ay, qx = fx > 0 ? 7 : 0; ax < bx; ax++, qx -= fx) {
int color = ((ch1 >> qx) & 1) | ((ch2 >> qx) & 2); int color = ((ch1 >> qx) & 1) | ((ch2 >> qx) & 2);
if(opaque || color) layer[ax] = blending[color][blend]; if(opaque || color) layer[ax] = blending[color][blend];
} }
@ -236,13 +236,14 @@ screen_deo(Uxn *u, Uint8 addr)
} }
else else
for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) { for(i = 0; i <= rML; i++, x += dyx, y += dxy, rA += addr_incr) {
Uint16 xx = MAR(x), yy = MAR(y); Uint16 xmar = MAR(x), ymar = MAR(y);
if(xx < MAR(uxn_screen.width) && MAR(yy) < MAR2(uxn_screen.height)) { Uint16 xmar2 = MAR2(x), ymar2 = MAR2(y);
Uint8 *sprite = &u->ram[rA]; if(xmar < wmar && ymar2 < hmar2) {
int opaque = blend % 5, by = (yy + 8) * len; Uint8 *sprite = &uxn.ram[rA];
for(ay = yy * len, qy = fy < 0 ? 7 : 0; ay < by; ay += len, qy += fy) { int opaque = blend % 5, by = ymar2 * wmar2;
int ch1 = sprite[qy], bx = xx + 8 + ay; for(ay = ymar * wmar2, qy = fy < 0 ? 7 : 0; ay < by; ay += wmar2, qy += fy) {
for(ax = xx + ay, qx = fx > 0 ? 7 : 0; ax < bx; ax++, qx -= fx) { int ch1 = sprite[qy], bx = xmar2 + ay;
for(ax = xmar + ay, qx = fx > 0 ? 7 : 0; ax < bx; ax++, qx -= fx) {
int color = (ch1 >> qx) & 1; int color = (ch1 >> qx) & 1;
if(opaque || color) layer[ax] = blending[color][blend]; if(opaque || color) layer[ax] = blending[color][blend];
} }
@ -257,7 +258,7 @@ screen_deo(Uxn *u, Uint8 addr)
y1 = y, y2 = rY; y1 = y, y2 = rY;
else else
y1 = rY, y2 = y; y1 = rY, y2 = y;
screen_change(x1, y1, x2 + 8, y2 + 8); screen_change(x1 - 8, y1 - 8, x2 + 8, y2 + 8);
if(rMX) rX += rDX * fx; if(rMX) rX += rDX * fx;
if(rMY) rY += rDY * fy; if(rMY) rY += rDY * fy;
return; return;

6
src/devices/screen.h

@ -22,9 +22,9 @@ void screen_change(int x1, int y1, int x2, int y2);
void screen_fill(Uint8 *layer, int color); void screen_fill(Uint8 *layer, int color);
void screen_palette(void); void screen_palette(void);
void screen_resize(Uint16 width, Uint16 height, int scale); void screen_resize(Uint16 width, Uint16 height, int scale);
void screen_redraw(void); void screen_redraw();
Uint8 screen_dei(Uxn *u, Uint8 addr); Uint8 screen_dei(Uint8 addr);
void screen_deo(Uxn *u, Uint8 addr); void screen_deo(Uint8 addr);
#define twos(v) (v & 0x8000 ? (int)v - 0x10000 : (int)v) #define twos(v) (v & 0x8000 ? (int)v - 0x10000 : (int)v)

12
src/uxnemu.c

@ -85,7 +85,7 @@ emu_dei(Uxn *u, Uint8 addr)
Uint8 p = addr & 0x0f, d = addr & 0xf0; Uint8 p = addr & 0x0f, d = addr & 0xf0;
switch(d) { switch(d) {
case 0x00: return system_dei(u, addr); case 0x00: return system_dei(u, addr);
case 0x20: return screen_dei(u, addr); case 0x20: return screen_dei(addr);
case 0x30: return audio_dei(0, &uxn.dev[d], p); case 0x30: return audio_dei(0, &uxn.dev[d], p);
case 0x40: return audio_dei(1, &uxn.dev[d], p); case 0x40: return audio_dei(1, &uxn.dev[d], p);
case 0x50: return audio_dei(2, &uxn.dev[d], p); case 0x50: return audio_dei(2, &uxn.dev[d], p);
@ -106,7 +106,7 @@ emu_deo(Uxn *u, Uint8 addr, Uint8 value)
if(p > 0x7 && p < 0xe) screen_palette(); if(p > 0x7 && p < 0xe) screen_palette();
break; break;
case 0x10: console_deo(u, addr); break; case 0x10: console_deo(u, addr); break;
case 0x20: screen_deo(u, addr); break; case 0x20: screen_deo(addr); break;
case 0x30: audio_deo(0, &uxn.dev[d], p); break; case 0x30: audio_deo(0, &uxn.dev[d], p); break;
case 0x40: audio_deo(1, &uxn.dev[d], p); break; case 0x40: audio_deo(1, &uxn.dev[d], p); break;
case 0x50: audio_deo(2, &uxn.dev[d], p); break; case 0x50: audio_deo(2, &uxn.dev[d], p); break;
@ -153,7 +153,6 @@ set_window_size(SDL_Window *window, int w, int h)
if(w == win_old.x && h == win_old.y) return; if(w == win_old.x && h == win_old.y) return;
SDL_RenderClear(emu_renderer); SDL_RenderClear(emu_renderer);
SDL_SetWindowSize(window, w, h); SDL_SetWindowSize(window, w, h);
screen_change(0, 0, uxn_screen.width, uxn_screen.height);
screen_resize(uxn_screen.width, uxn_screen.height, 1); screen_resize(uxn_screen.width, uxn_screen.height, 1);
} }
@ -255,15 +254,15 @@ emu_init(void)
ms_interval = SDL_GetPerformanceFrequency() / 1000; ms_interval = SDL_GetPerformanceFrequency() / 1000;
deadline_interval = ms_interval * TIMEOUT_MS; deadline_interval = ms_interval * TIMEOUT_MS;
exec_deadline = SDL_GetPerformanceCounter() + deadline_interval; exec_deadline = SDL_GetPerformanceCounter() + deadline_interval;
screen_change(0, 0, WIDTH, HEIGHT), screen_resize(WIDTH, HEIGHT, 1);
SDL_PauseAudioDevice(audio_id, 1); SDL_PauseAudioDevice(audio_id, 1);
screen_resize(WIDTH, HEIGHT, 1);
return 1; return 1;
} }
static void static void
emu_restart(char *drop, int soft) emu_restart(char *drop, int soft)
{ {
screen_change(0, 0, WIDTH, HEIGHT), screen_resize(WIDTH, HEIGHT, 1); screen_resize(WIDTH, HEIGHT, uxn_screen.scale);
screen_fill(uxn_screen.bg, 0); screen_fill(uxn_screen.bg, 0);
screen_fill(uxn_screen.fg, 0); screen_fill(uxn_screen.fg, 0);
system_reboot(soft); system_reboot(soft);
@ -473,7 +472,7 @@ main(int argc, char **argv)
/* flags */ /* flags */
if(argc > 1 && argv[i][0] == '-') { if(argc > 1 && argv[i][0] == '-') {
if(!strcmp(argv[i], "-v")) if(!strcmp(argv[i], "-v"))
return system_error("Uxn(gui) - Varvara Emulator", "27 Nov 2024."); return system_error("Uxn(gui) - Varvara Emulator", "23 Dec 2024.");
else if(!strcmp(argv[i], "-2x")) else if(!strcmp(argv[i], "-2x"))
set_zoom(2, 0); set_zoom(2, 0);
else if(!strcmp(argv[i], "-3x")) else if(!strcmp(argv[i], "-3x"))
@ -491,7 +490,6 @@ main(int argc, char **argv)
/* loop */ /* loop */
uxn.dev[0x17] = argc - i; uxn.dev[0x17] = argc - i;
if(uxn_eval(&uxn, PAGE_PROGRAM)) { if(uxn_eval(&uxn, PAGE_PROGRAM)) {
/* uxn_eval(&bios, PAGE_PROGRAM); */
console_listen(i, argc, argv); console_listen(i, argc, argv);
emu_run(rom); emu_run(rom);
} }

Loading…
Cancel
Save