| ... | ... |
@@ -93,11 +93,11 @@ int |
| 93 | 93 |
start(Uxn *u) |
| 94 | 94 |
{
|
| 95 | 95 |
printf("RESET --------\n");
|
| 96 |
- if(!evaluxn(u, PAGE_VECTORS)) |
|
| 96 |
+ if(!evaluxn(u, PAGE_PROGRAM)) |
|
| 97 | 97 |
return error("Reset", "Failed");
|
| 98 | 98 |
printstack(&u->wst); |
| 99 | 99 |
printf("FRAME --------\n");
|
| 100 |
- if(!evaluxn(u, PAGE_VECTORS + 0x08)) |
|
| 100 |
+ if(!evaluxn(u, PAGE_PROGRAM + 0x08)) |
|
| 101 | 101 |
return error("Frame", "Failed");
|
| 102 | 102 |
printstack(&u->wst); |
| 103 | 103 |
return 1; |
| ... | ... |
@@ -22,7 +22,6 @@ SDL_AudioDeviceID audio_id; |
| 22 | 22 |
static SDL_Window *gWindow; |
| 23 | 23 |
static SDL_Renderer *gRenderer; |
| 24 | 24 |
static SDL_Texture *gTexture; |
| 25 |
- |
|
| 26 | 25 |
static Ppu ppu; |
| 27 | 26 |
static Device *devsystem, *devscreen, *devmouse, *devkey, *devctrl; |
| 28 | 27 |
|
| ... | ... |
@@ -45,10 +44,10 @@ error(char *msg, const char *err) |
| 45 | 44 |
void |
| 46 | 45 |
redraw(Uint32 *dst, Uxn *u) |
| 47 | 46 |
{
|
| 48 |
- draw(&ppu); |
|
| 47 |
+ drawppu(&ppu); |
|
| 49 | 48 |
if(ppu.debugger) |
| 50 | 49 |
drawdebugger(&ppu, u->wst.dat, u->wst.ptr); |
| 51 |
- SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32)); |
|
| 50 |
+ SDL_UpdateTexture(gTexture, NULL, dst, ppu.width * sizeof(Uint32)); |
|
| 52 | 51 |
SDL_RenderClear(gRenderer); |
| 53 | 52 |
SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); |
| 54 | 53 |
SDL_RenderPresent(gRenderer); |
| ... | ... |
@@ -66,7 +65,7 @@ void |
| 66 | 65 |
togglezoom(Uxn *u) |
| 67 | 66 |
{
|
| 68 | 67 |
ppu.zoom = ppu.zoom == 3 ? 1 : ppu.zoom + 1; |
| 69 |
- SDL_SetWindowSize(gWindow, WIDTH * ppu.zoom, HEIGHT * ppu.zoom); |
|
| 68 |
+ SDL_SetWindowSize(gWindow, ppu.width * ppu.zoom, ppu.height * ppu.zoom); |
|
| 70 | 69 |
redraw(ppu.output, u); |
| 71 | 70 |
} |
| 72 | 71 |
|
| ... | ... |
@@ -74,6 +73,8 @@ void |
| 74 | 73 |
quit(void) |
| 75 | 74 |
{
|
| 76 | 75 |
free(ppu.output); |
| 76 |
+ free(ppu.fg); |
|
| 77 |
+ free(ppu.bg); |
|
| 77 | 78 |
SDL_DestroyTexture(gTexture); |
| 78 | 79 |
gTexture = NULL; |
| 79 | 80 |
SDL_DestroyRenderer(gRenderer); |
| ... | ... |
@@ -87,21 +88,21 @@ quit(void) |
| 87 | 88 |
int |
| 88 | 89 |
init(void) |
| 89 | 90 |
{
|
| 91 |
+ if(!initppu(&ppu, 48, 32, 16)) |
|
| 92 |
+ return error("PPU", "Init failure");
|
|
| 90 | 93 |
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) |
| 91 | 94 |
return error("Init", SDL_GetError());
|
| 92 |
- gWindow = SDL_CreateWindow("Uxn", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH * ppu.zoom, HEIGHT * ppu.zoom, SDL_WINDOW_SHOWN);
|
|
| 95 |
+ gWindow = SDL_CreateWindow("Uxn", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ppu.width * ppu.zoom, ppu.height * ppu.zoom, SDL_WINDOW_SHOWN);
|
|
| 93 | 96 |
if(gWindow == NULL) |
| 94 | 97 |
return error("Window", SDL_GetError());
|
| 95 | 98 |
gRenderer = SDL_CreateRenderer(gWindow, -1, 0); |
| 96 | 99 |
if(gRenderer == NULL) |
| 97 | 100 |
return error("Renderer", SDL_GetError());
|
| 98 |
- gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT); |
|
| 101 |
+ gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, ppu.width, ppu.height); |
|
| 99 | 102 |
if(gTexture == NULL) |
| 100 | 103 |
return error("Texture", SDL_GetError());
|
| 101 | 104 |
SDL_StartTextInput(); |
| 102 | 105 |
SDL_ShowCursor(SDL_DISABLE); |
| 103 |
- if(!initppu(&ppu)) |
|
| 104 |
- return error("PPU", "Init failure");
|
|
| 105 | 106 |
return 1; |
| 106 | 107 |
} |
| 107 | 108 |
|
| ... | ... |
@@ -110,12 +111,10 @@ domouse(Uxn *u, SDL_Event *event) |
| 110 | 111 |
{
|
| 111 | 112 |
Uint8 flag = 0x00; |
| 112 | 113 |
Uint16 addr = devmouse->addr + 2; |
| 113 |
- Uint16 x = clamp(event->motion.x / ppu.zoom - PAD * 8, 0, HOR * 8 - 1); |
|
| 114 |
- Uint16 y = clamp(event->motion.y / ppu.zoom - PAD * 8, 0, VER * 8 - 1); |
|
| 115 |
- u->ram.dat[addr + 0] = (x >> 8) & 0xff; |
|
| 116 |
- u->ram.dat[addr + 1] = x & 0xff; |
|
| 117 |
- u->ram.dat[addr + 2] = (y >> 8) & 0xff; |
|
| 118 |
- u->ram.dat[addr + 3] = y & 0xff; |
|
| 114 |
+ Uint16 x = clamp(event->motion.x / ppu.zoom - ppu.pad, 0, ppu.hor * 8 - 1); |
|
| 115 |
+ Uint16 y = clamp(event->motion.y / ppu.zoom - ppu.pad, 0, ppu.ver * 8 - 1); |
|
| 116 |
+ mempoke16(u, addr + 0, x); |
|
| 117 |
+ mempoke16(u, addr + 2, y); |
|
| 119 | 118 |
u->ram.dat[addr + 5] = 0x00; |
| 120 | 119 |
switch(event->button.button) {
|
| 121 | 120 |
case SDL_BUTTON_LEFT: flag = 0x01; break; |
| ... | ... |
@@ -193,9 +192,6 @@ console_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
| 193 | 192 |
case 0x0d: printf("%s\n", &m[(m[ptr + 0x0c] << 8) + b1]); break;
|
| 194 | 193 |
} |
| 195 | 194 |
fflush(stdout); |
| 196 |
- (void)m; |
|
| 197 |
- (void)ptr; |
|
| 198 |
- (void)b0; |
|
| 199 | 195 |
return b1; |
| 200 | 196 |
} |
| 201 | 197 |
|
| ... | ... |
@@ -207,7 +203,7 @@ screen_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
| 207 | 203 |
if(b0 == 0x0c) {
|
| 208 | 204 |
Uint16 x = (m[ptr] << 8) + m[ptr + 1]; |
| 209 | 205 |
Uint16 y = (m[ptr + 2] << 8) + m[ptr + 3]; |
| 210 |
- putpixel(b1 >> 4 & 0xf ? ppu.fg : ppu.bg, x, y, b1 & 0xf); |
|
| 206 |
+ putpixel(&ppu, b1 >> 4 & 0xf ? ppu.fg : ppu.bg, x, y, b1 & 0xf); |
|
| 211 | 207 |
ppu.reqdraw = 1; |
| 212 | 208 |
} |
| 213 | 209 |
return b1; |
| ... | ... |
@@ -230,7 +226,7 @@ sprite_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
| 230 | 226 |
Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); |
| 231 | 227 |
if(ch1 == 0 && (blend == 0x05 || blend == 0x0a || blend == 0x0f)) |
| 232 | 228 |
continue; |
| 233 |
- putpixel(layer, x + h, y + v, ch1 ? blend % 4 : blend / 4); |
|
| 229 |
+ putpixel(&ppu, layer, x + h, y + v, ch1 ? blend % 4 : blend / 4); |
|
| 234 | 230 |
} |
| 235 | 231 |
ppu.reqdraw = 1; |
| 236 | 232 |
} |
| ... | ... |
@@ -393,10 +389,8 @@ main(int argc, char **argv) |
| 393 | 389 |
portuxn(&u, 0x0f, "---", ppnil); |
| 394 | 390 |
|
| 395 | 391 |
/* Write screen size to dev/screen */ |
| 396 |
- u.ram.dat[devscreen->addr + 2] = (HOR * 8 >> 8) & 0xff; |
|
| 397 |
- u.ram.dat[devscreen->addr + 3] = HOR * 8 & 0xff; |
|
| 398 |
- u.ram.dat[devscreen->addr + 4] = (VER * 8 >> 8) & 0xff; |
|
| 399 |
- u.ram.dat[devscreen->addr + 5] = VER * 8 & 0xff; |
|
| 392 |
+ mempoke16(&u, devscreen->addr + 2, ppu.hor * 8); |
|
| 393 |
+ mempoke16(&u, devscreen->addr + 4, ppu.ver * 8); |
|
| 400 | 394 |
|
| 401 | 395 |
start(&u); |
| 402 | 396 |
quit(); |
| ... | ... |
@@ -33,16 +33,21 @@ Uint8 font[][8] = {
|
| 33 | 33 |
void |
| 34 | 34 |
clear(Ppu *p) |
| 35 | 35 |
{
|
| 36 |
- int i, sz = HEIGHT * WIDTH; |
|
| 37 |
- for(i = 0; i < sz; ++i) |
|
| 36 |
+ int i, sz = p->height * p->width; |
|
| 37 |
+ for(i = 0; i < sz; ++i) {
|
|
| 38 | 38 |
p->output[i] = p->colors[0]; |
| 39 |
+ p->fg[i] = 0; |
|
| 40 |
+ p->bg[i] = 0; |
|
| 41 |
+ p->fg[sz + i] = 0; |
|
| 42 |
+ p->bg[sz + i] = 0; |
|
| 43 |
+ } |
|
| 39 | 44 |
} |
| 40 | 45 |
|
| 41 | 46 |
void |
| 42 | 47 |
drawpixel(Ppu *p, Uint16 x, Uint16 y, Uint8 color) |
| 43 | 48 |
{
|
| 44 | 49 |
if(x >= p->x1 && x <= p->x2 && y >= p->x1 && y <= p->y2) |
| 45 |
- p->output[y * WIDTH + x] = p->colors[color]; |
|
| 50 |
+ p->output[y * p->width + x] = p->colors[color]; |
|
| 46 | 51 |
} |
| 47 | 52 |
|
| 48 | 53 |
void |
| ... | ... |
@@ -79,20 +84,20 @@ drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr) |
| 79 | 84 |
drawicn(p, x + 8, y, font[b & 0xf], 1 + (ptr == i), 0); |
| 80 | 85 |
} |
| 81 | 86 |
for(x = 0; x < 32; ++x) {
|
| 82 |
- drawpixel(p, x, HEIGHT / 2, 2); |
|
| 83 |
- drawpixel(p, WIDTH - x, HEIGHT / 2, 2); |
|
| 84 |
- drawpixel(p, WIDTH / 2, HEIGHT - x, 2); |
|
| 85 |
- drawpixel(p, WIDTH / 2, x, 2); |
|
| 86 |
- drawpixel(p, WIDTH / 2 - 16 + x, HEIGHT / 2, 2); |
|
| 87 |
- drawpixel(p, WIDTH / 2, HEIGHT / 2 - 16 + x, 2); |
|
| 87 |
+ drawpixel(p, x, p->height / 2, 2); |
|
| 88 |
+ drawpixel(p, p->width - x, p->height / 2, 2); |
|
| 89 |
+ drawpixel(p, p->width / 2, p->height - x, 2); |
|
| 90 |
+ drawpixel(p, p->width / 2, x, 2); |
|
| 91 |
+ drawpixel(p, p->width / 2 - 16 + x, p->height / 2, 2); |
|
| 92 |
+ drawpixel(p, p->width / 2, p->height / 2 - 16 + x, 2); |
|
| 88 | 93 |
} |
| 89 | 94 |
} |
| 90 | 95 |
|
| 91 | 96 |
void |
| 92 |
-putpixel(Uint8 *layer, Uint16 x, Uint16 y, Uint8 color) |
|
| 97 |
+putpixel(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 color) |
|
| 93 | 98 |
{
|
| 94 |
- Uint16 row = (y % 8) + ((x / 8 + y / 8 * HOR) * 16), col = 7 - (x % 8); |
|
| 95 |
- if(x >= HOR * 8 || y >= VER * 8 || row > RES - 8) |
|
| 99 |
+ Uint16 row = (y % 8) + ((x / 8 + y / 8 * p->hor) * 16), col = 7 - (x % 8); |
|
| 100 |
+ if(x >= p->hor * 8 || y >= p->ver * 8 || row > (p->hor * p->ver * 16) - 8) |
|
| 96 | 101 |
return; |
| 97 | 102 |
if(color == 0 || color == 2) |
| 98 | 103 |
layer[row] &= ~(1UL << col); |
| ... | ... |
@@ -119,26 +124,36 @@ loadtheme(Ppu *p, Uint8 *addr) |
| 119 | 124 |
} |
| 120 | 125 |
|
| 121 | 126 |
void |
| 122 |
-draw(Ppu *p) |
|
| 127 |
+drawppu(Ppu *p) |
|
| 123 | 128 |
{
|
| 124 | 129 |
Uint16 x, y; |
| 125 |
- for(y = 0; y < VER; ++y) |
|
| 126 |
- for(x = 0; x < HOR; ++x) {
|
|
| 127 |
- Uint16 key = (y * HOR + x) * 16; |
|
| 128 |
- drawchr(p, (x + PAD) * 8, (y + PAD) * 8, &p->bg[key], 0); |
|
| 129 |
- drawchr(p, (x + PAD) * 8, (y + PAD) * 8, &p->fg[key], 1); |
|
| 130 |
+ for(y = 0; y < p->ver; ++y) |
|
| 131 |
+ for(x = 0; x < p->hor; ++x) {
|
|
| 132 |
+ Uint16 key = (y * p->hor + x) * 16; |
|
| 133 |
+ drawchr(p, x * 8 + p->pad, y * 8 + p->pad, &p->bg[key], 0); |
|
| 134 |
+ drawchr(p, x * 8 + p->pad, y * 8 + p->pad, &p->fg[key], 1); |
|
| 130 | 135 |
} |
| 131 | 136 |
} |
| 132 | 137 |
|
| 133 | 138 |
int |
| 134 |
-initppu(Ppu *p) |
|
| 139 |
+initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) |
|
| 135 | 140 |
{
|
| 136 |
- if(!(p->output = (Uint32 *)malloc(WIDTH * HEIGHT * sizeof(Uint32)))) |
|
| 141 |
+ p->hor = hor; |
|
| 142 |
+ p->ver = ver; |
|
| 143 |
+ p->pad = pad; |
|
| 144 |
+ p->width = (8 * p->hor + p->pad * 2); |
|
| 145 |
+ p->height = (8 * p->ver + p->pad * 2); |
|
| 146 |
+ |
|
| 147 |
+ if(!(p->output = malloc(p->width * p->height * sizeof(Uint32)))) |
|
| 148 |
+ return 0; |
|
| 149 |
+ if(!(p->bg = malloc(p->width * p->height * sizeof(Uint8) * 2))) |
|
| 150 |
+ return 0; |
|
| 151 |
+ if(!(p->fg = malloc(p->width * p->height * sizeof(Uint8) * 2))) |
|
| 137 | 152 |
return 0; |
| 138 | 153 |
clear(p); |
| 139 |
- p->x1 = PAD * 8; |
|
| 140 |
- p->x2 = WIDTH - PAD * 8 - 1; |
|
| 141 |
- p->y1 = PAD * 8; |
|
| 142 |
- p->y2 = HEIGHT - PAD * 8 - 1; |
|
| 154 |
+ p->x1 = p->pad; |
|
| 155 |
+ p->x2 = p->width - p->pad - 1; |
|
| 156 |
+ p->y1 = p->pad; |
|
| 157 |
+ p->y2 = p->height - p->pad - 1; |
|
| 143 | 158 |
return 1; |
| 144 | 159 |
} |
| 145 | 160 |
\ No newline at end of file |
| ... | ... |
@@ -18,21 +18,14 @@ typedef unsigned short Uint16; |
| 18 | 18 |
typedef signed short Sint16; |
| 19 | 19 |
typedef unsigned int Uint32; |
| 20 | 20 |
|
| 21 |
-#define HOR 48 |
|
| 22 |
-#define VER 32 |
|
| 23 |
-#define PAD 2 |
|
| 24 |
-#define RES (HOR * VER * 16) |
|
| 25 |
-#define WIDTH (8 * HOR + 8 * PAD * 2) |
|
| 26 |
-#define HEIGHT (8 * VER + 8 * PAD * 2) |
|
| 27 |
- |
|
| 28 | 21 |
typedef struct Ppu {
|
| 29 |
- Uint8 reqdraw, zoom, debugger, bg[RES], fg[RES]; |
|
| 30 |
- Uint16 x1, y1, x2, y2; |
|
| 22 |
+ Uint8 reqdraw, zoom, debugger, *bg, *fg; |
|
| 23 |
+ Uint16 hor, ver, pad, width, height, x1, y1, x2, y2; |
|
| 31 | 24 |
Uint32 *output, colors[4]; |
| 32 | 25 |
} Ppu; |
| 33 | 26 |
|
| 34 |
-int initppu(Ppu *p); |
|
| 35 |
-void draw(Ppu *p); |
|
| 27 |
+int initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad); |
|
| 28 |
+void drawppu(Ppu *p); |
|
| 36 | 29 |
void drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr); |
| 37 | 30 |
void loadtheme(Ppu *p, Uint8 *addr); |
| 38 |
-void putpixel(Uint8 *layer, Uint16 x, Uint16 y, Uint8 color); |
|
| 39 | 31 |
\ No newline at end of file |
| 32 |
+void putpixel(Ppu *p, Uint8 *layer, Uint16 x, Uint16 y, Uint8 color); |
|
| 40 | 33 |
\ No newline at end of file |
| ... | ... |
@@ -178,7 +178,7 @@ loaduxn(Uxn *u, char *filepath) |
| 178 | 178 |
FILE *f; |
| 179 | 179 |
if(!(f = fopen(filepath, "rb"))) |
| 180 | 180 |
return haltuxn(u, "Missing input rom.", 0); |
| 181 |
- fread(u->ram.dat + PAGE_VECTORS, sizeof(u->ram.dat) - PAGE_VECTORS, 1, f); |
|
| 181 |
+ fread(u->ram.dat + PAGE_PROGRAM, sizeof(u->ram.dat) - PAGE_PROGRAM, 1, f); |
|
| 182 | 182 |
printf("Uxn loaded[%s].\n", filepath);
|
| 183 | 183 |
return 1; |
| 184 | 184 |
} |
| ... | ... |
@@ -17,7 +17,7 @@ typedef unsigned short Uint16; |
| 17 | 17 |
typedef signed short Sint16; |
| 18 | 18 |
|
| 19 | 19 |
#define PAGE_DEVICE 0x0100 |
| 20 |
-#define PAGE_VECTORS 0x0200 |
|
| 20 |
+#define PAGE_PROGRAM 0x0200 |
|
| 21 | 21 |
|
| 22 | 22 |
typedef struct {
|
| 23 | 23 |
Uint8 ptr, error; |
| ... | ... |
@@ -47,3 +47,4 @@ int bootuxn(Uxn *c); |
| 47 | 47 |
int inituxn(Uxn *u, Uint16 vec); |
| 48 | 48 |
int evaluxn(Uxn *u, Uint16 vec); |
| 49 | 49 |
Device *portuxn(Uxn *u, Uint8 id, char *name, Uint8 (*pofn)(Uxn *, Uint16, Uint8, Uint8)); |
| 50 |
+void mempoke16(Uxn *u, Uint16 a, Uint16 b); |
|
| 50 | 51 |
\ No newline at end of file |