Standardized screen device to the SDL version
This commit is contained in:
parent
adc0ccdad4
commit
ed588f9190
|
@ -4,7 +4,7 @@
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
|
Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -16,12 +16,11 @@ WITH REGARD TO THIS SOFTWARE.
|
||||||
|
|
||||||
UxnScreen uxn_screen;
|
UxnScreen uxn_screen;
|
||||||
|
|
||||||
static Uint8 blending[5][16] = {
|
static Uint8 blending[4][16] = {
|
||||||
{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
|
{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
|
||||||
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
|
{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
|
||||||
{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
|
{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
|
||||||
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
|
{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}};
|
||||||
{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_write(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color)
|
screen_write(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color)
|
||||||
|
@ -35,12 +34,21 @@ screen_write(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
screen_wipe(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y)
|
||||||
|
{
|
||||||
|
int v, h;
|
||||||
|
for(v = 0; v < 8; v++)
|
||||||
|
for(h = 0; h < 8; h++)
|
||||||
|
screen_write(p, layer, x + h, y + v, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screen_blit(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy, Uint8 twobpp)
|
screen_blit(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy, Uint8 twobpp)
|
||||||
{
|
{
|
||||||
int v, h, opaque = blending[4][color];
|
int v, h, opaque = (color % 5) || !color;
|
||||||
for(v = 0; v < 8; v++) {
|
for(v = 0; v < 8; v++) {
|
||||||
Uint16 c = sprite[v] | (twobpp ? sprite[v + 8] : 0) << 8;
|
Uint16 c = sprite[v] | (twobpp ? (sprite[v + 8] << 8) : 0);
|
||||||
for(h = 7; h >= 0; --h, c >>= 1) {
|
for(h = 7; h >= 0; --h, c >>= 1) {
|
||||||
Uint8 ch = (c & 1) | ((c >> 7) & 2);
|
Uint8 ch = (c & 1) | ((c >> 7) & 2);
|
||||||
if(opaque || ch)
|
if(opaque || ch)
|
||||||
|
@ -53,24 +61,6 @@ screen_blit(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
screen_wipe(UxnScreen *p, Layer *layer, Uint16 x, Uint16 y)
|
|
||||||
{
|
|
||||||
int v, h;
|
|
||||||
for(v = 0; v < 8; v++)
|
|
||||||
for(h = 0; h < 8; h++)
|
|
||||||
screen_write(p, layer, x + h, y + v, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
layer_clear(UxnScreen *p, Layer *layer)
|
|
||||||
{
|
|
||||||
Uint32 i, size = p->width * p->height;
|
|
||||||
for(i = 0; i < size; i++)
|
|
||||||
layer->pixels[i] = 0x00;
|
|
||||||
layer->changed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_palette(UxnScreen *p, Uint8 *addr)
|
screen_palette(UxnScreen *p, Uint8 *addr)
|
||||||
{
|
{
|
||||||
|
@ -100,15 +90,18 @@ screen_resize(UxnScreen *p, Uint16 width, Uint16 height)
|
||||||
if(bg && fg && pixels) {
|
if(bg && fg && pixels) {
|
||||||
p->width = width;
|
p->width = width;
|
||||||
p->height = height;
|
p->height = height;
|
||||||
screen_clear(p);
|
screen_clear(p, &p->bg);
|
||||||
|
screen_clear(p, &p->fg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_clear(UxnScreen *p)
|
screen_clear(UxnScreen *p, Layer *layer)
|
||||||
{
|
{
|
||||||
layer_clear(p, &p->bg);
|
Uint32 i, size = p->width * p->height;
|
||||||
layer_clear(p, &p->fg);
|
for(i = 0; i < size; i++)
|
||||||
|
layer->pixels[i] = 0x00;
|
||||||
|
layer->changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern UxnScreen uxn_screen;
|
||||||
|
|
||||||
void screen_palette(UxnScreen *p, Uint8 *addr);
|
void screen_palette(UxnScreen *p, Uint8 *addr);
|
||||||
void screen_resize(UxnScreen *p, Uint16 width, Uint16 height);
|
void screen_resize(UxnScreen *p, Uint16 width, Uint16 height);
|
||||||
void screen_clear(UxnScreen *p);
|
void screen_clear(UxnScreen *p, Layer *layer);
|
||||||
void screen_redraw(UxnScreen *p, Uint32 *pixels);
|
void screen_redraw(UxnScreen *p, Uint32 *pixels);
|
||||||
|
|
||||||
Uint8 screen_dei(Uxn *u, Uint8 addr);
|
Uint8 screen_dei(Uxn *u, Uint8 addr);
|
||||||
|
|
18
src/uxn11.c
18
src/uxn11.c
|
@ -46,7 +46,7 @@ Uint16 dei_mask[] = {0x0000, 0x0000, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0
|
||||||
static int
|
static int
|
||||||
emu_error(char *msg, const char *err)
|
emu_error(char *msg, const char *err)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error %s: %s\n", msg, err);
|
fprintf(stderr, "%s: %s\n", msg, err);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +91,8 @@ emu_start(Uxn *u, char *rom)
|
||||||
return 0;
|
return 0;
|
||||||
if(!uxn_screen.width || !uxn_screen.height)
|
if(!uxn_screen.width || !uxn_screen.height)
|
||||||
screen_resize(&uxn_screen, WIDTH, HEIGHT);
|
screen_resize(&uxn_screen, WIDTH, HEIGHT);
|
||||||
screen_clear(&uxn_screen);
|
|
||||||
if(!uxn_eval(u, PAGE_PROGRAM))
|
if(!uxn_eval(u, PAGE_PROGRAM))
|
||||||
return emu_error("Boot", "Failed to start rom.");
|
return emu_error("boot", "Failed to start rom.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +188,7 @@ display_start(char *title)
|
||||||
visual = DefaultVisual(display, 0);
|
visual = DefaultVisual(display, 0);
|
||||||
window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0, uxn_screen.width + PAD * 2, uxn_screen.height + PAD * 2, 1, 0, 0);
|
window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0, uxn_screen.width + PAD * 2, uxn_screen.height + PAD * 2, 1, 0, 0);
|
||||||
if(visual->class != TrueColor)
|
if(visual->class != TrueColor)
|
||||||
return emu_error("Init", "True-color visual failed");
|
return emu_error("init", "True-color visual failed");
|
||||||
XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | KeyPressMask | KeyReleaseMask);
|
XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | KeyPressMask | KeyReleaseMask);
|
||||||
wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
|
wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
|
||||||
XSetWMProtocols(display, window, &wmDelete, 1);
|
XSetWMProtocols(display, window, &wmDelete, 1);
|
||||||
|
@ -210,15 +209,15 @@ main(int argc, char **argv)
|
||||||
struct pollfd fds[3];
|
struct pollfd fds[3];
|
||||||
static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}};
|
static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}};
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
return emu_error("Usage", "uxn11 game.rom args");
|
return emu_error("usage", "uxn11 game.rom args");
|
||||||
rom_path = argv[1];
|
rom_path = argv[1];
|
||||||
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
|
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
|
||||||
return emu_error("Boot", "Failed");
|
return emu_error("boot", "Failed");
|
||||||
/* start sequence */
|
/* start sequence */
|
||||||
if(!emu_start(&u, rom_path))
|
if(!emu_start(&u, rom_path))
|
||||||
return emu_error("Start", rom_path);
|
return emu_error("start", rom_path);
|
||||||
if(!display_start(rom_path))
|
if(!display_start(rom_path))
|
||||||
return emu_error("Display", "Failed");
|
return emu_error("display", "Failed");
|
||||||
/* console vector */
|
/* console vector */
|
||||||
for(i = 2; i < argc; i++) {
|
for(i = 2; i < argc; i++) {
|
||||||
char *p = argv[i];
|
char *p = argv[i];
|
||||||
|
@ -244,9 +243,8 @@ main(int argc, char **argv)
|
||||||
if((fds[2].revents & POLLIN) != 0) {
|
if((fds[2].revents & POLLIN) != 0) {
|
||||||
n = read(fds[2].fd, coninp, CONINBUFSIZE - 1);
|
n = read(fds[2].fd, coninp, CONINBUFSIZE - 1);
|
||||||
coninp[n] = 0;
|
coninp[n] = 0;
|
||||||
for(i = 0; i < n; i++) {
|
for(i = 0; i < n; i++)
|
||||||
console_input(&u, coninp[i]);
|
console_input(&u, coninp[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(uxn_screen.fg.changed || uxn_screen.bg.changed)
|
if(uxn_screen.fg.changed || uxn_screen.bg.changed)
|
||||||
emu_draw();
|
emu_draw();
|
||||||
|
|
Loading…
Reference in New Issue