... | ... |
@@ -18,36 +18,20 @@ WITH REGARD TO THIS SOFTWARE. |
18 | 18 |
|
19 | 19 |
int initapu(Uxn *u, Uint8 id); |
20 | 20 |
|
21 |
-static Ppu screen; |
|
22 |
- |
|
21 |
+SDL_AudioDeviceID audio_id; |
|
23 | 22 |
static SDL_Window *gWindow; |
24 | 23 |
static SDL_Renderer *gRenderer; |
25 | 24 |
static SDL_Texture *gTexture; |
26 |
-SDL_AudioDeviceID audio_id; |
|
25 |
+ |
|
26 |
+static Ppu ppu; |
|
27 | 27 |
static Device *devsystem, *devscreen, *devmouse, *devkey, *devctrl; |
28 | 28 |
|
29 | 29 |
#pragma mark - Helpers |
30 | 30 |
|
31 |
-int |
|
32 |
-clamp(int val, int min, int max) |
|
33 |
-{ |
|
34 |
- return (val >= min) ? (val <= max) ? val : max : min; |
|
35 |
-} |
|
36 |
- |
|
37 |
-void |
|
38 |
-setflag(Uint8 *a, char flag, int b) |
|
39 |
-{ |
|
40 |
- if(b) |
|
41 |
- *a |= flag; |
|
42 |
- else |
|
43 |
- *a &= (~flag); |
|
44 |
-} |
|
45 |
- |
|
46 |
-int |
|
47 |
-getflag(Uint8 *a, char flag) |
|
48 |
-{ |
|
49 |
- return *a & flag; |
|
50 |
-} |
|
31 |
+/* clang-format off */ |
|
32 |
+int clamp(int val, int min, int max) { return (val >= min) ? (val <= max) ? val : max : min; } |
|
33 |
+void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); } |
|
34 |
+/* clang-format on */ |
|
51 | 35 |
|
52 | 36 |
#pragma mark - Core |
53 | 37 |
|
... | ... |
@@ -61,41 +45,35 @@ error(char *msg, const char *err) |
61 | 45 |
void |
62 | 46 |
redraw(Uint32 *dst, Uxn *u) |
63 | 47 |
{ |
64 |
- Uint16 x, y; |
|
65 |
- for(y = 0; y < VER; ++y) |
|
66 |
- for(x = 0; x < HOR; ++x) { |
|
67 |
- Uint16 key = (y * HOR + x) * 16; |
|
68 |
- drawchr(&screen, (x + PAD) * 8, (y + PAD) * 8, &screen.bg[key], 0); |
|
69 |
- drawchr(&screen, (x + PAD) * 8, (y + PAD) * 8, &screen.fg[key], 1); |
|
70 |
- } |
|
71 |
- if(screen.debugger) |
|
72 |
- drawdebugger(&screen, u->wst.dat, u->wst.ptr); |
|
48 |
+ draw(&ppu); |
|
49 |
+ if(ppu.debugger) |
|
50 |
+ drawdebugger(&ppu, u->wst.dat, u->wst.ptr); |
|
73 | 51 |
SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32)); |
74 | 52 |
SDL_RenderClear(gRenderer); |
75 | 53 |
SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); |
76 | 54 |
SDL_RenderPresent(gRenderer); |
77 |
- screen.reqdraw = 0; |
|
55 |
+ ppu.reqdraw = 0; |
|
78 | 56 |
} |
79 | 57 |
|
80 | 58 |
void |
81 | 59 |
toggledebug(Uxn *u) |
82 | 60 |
{ |
83 |
- screen.debugger = !screen.debugger; |
|
84 |
- redraw(screen.output, u); |
|
61 |
+ ppu.debugger = !ppu.debugger; |
|
62 |
+ redraw(ppu.output, u); |
|
85 | 63 |
} |
86 | 64 |
|
87 | 65 |
void |
88 | 66 |
togglezoom(Uxn *u) |
89 | 67 |
{ |
90 |
- screen.zoom = screen.zoom == 3 ? 1 : screen.zoom + 1; |
|
91 |
- SDL_SetWindowSize(gWindow, WIDTH * screen.zoom, HEIGHT * screen.zoom); |
|
92 |
- redraw(screen.output, u); |
|
68 |
+ ppu.zoom = ppu.zoom == 3 ? 1 : ppu.zoom + 1; |
|
69 |
+ SDL_SetWindowSize(gWindow, WIDTH * ppu.zoom, HEIGHT * ppu.zoom); |
|
70 |
+ redraw(ppu.output, u); |
|
93 | 71 |
} |
94 | 72 |
|
95 | 73 |
void |
96 | 74 |
quit(void) |
97 | 75 |
{ |
98 |
- free(screen.output); |
|
76 |
+ free(ppu.output); |
|
99 | 77 |
SDL_DestroyTexture(gTexture); |
100 | 78 |
gTexture = NULL; |
101 | 79 |
SDL_DestroyRenderer(gRenderer); |
... | ... |
@@ -111,7 +89,7 @@ init(void) |
111 | 89 |
{ |
112 | 90 |
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) |
113 | 91 |
return error("Init", SDL_GetError()); |
114 |
- gWindow = SDL_CreateWindow("Uxn", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH * screen.zoom, HEIGHT * screen.zoom, SDL_WINDOW_SHOWN); |
|
92 |
+ gWindow = SDL_CreateWindow("Uxn", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH * ppu.zoom, HEIGHT * ppu.zoom, SDL_WINDOW_SHOWN); |
|
115 | 93 |
if(gWindow == NULL) |
116 | 94 |
return error("Window", SDL_GetError()); |
117 | 95 |
gRenderer = SDL_CreateRenderer(gWindow, -1, 0); |
... | ... |
@@ -122,7 +100,7 @@ init(void) |
122 | 100 |
return error("Texture", SDL_GetError()); |
123 | 101 |
SDL_StartTextInput(); |
124 | 102 |
SDL_ShowCursor(SDL_DISABLE); |
125 |
- if(!initppu(&screen)) |
|
103 |
+ if(!initppu(&ppu)) |
|
126 | 104 |
return error("PPU", "Init failure"); |
127 | 105 |
return 1; |
128 | 106 |
} |
... | ... |
@@ -132,8 +110,8 @@ domouse(Uxn *u, SDL_Event *event) |
132 | 110 |
{ |
133 | 111 |
Uint8 flag = 0x00; |
134 | 112 |
Uint16 addr = devmouse->addr + 2; |
135 |
- Uint16 x = clamp(event->motion.x / screen.zoom - PAD * 8, 0, HOR * 8 - 1); |
|
136 |
- Uint16 y = clamp(event->motion.y / screen.zoom - PAD * 8, 0, VER * 8 - 1); |
|
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); |
|
137 | 115 |
u->ram.dat[addr + 0] = (x >> 8) & 0xff; |
138 | 116 |
u->ram.dat[addr + 1] = x & 0xff; |
139 | 117 |
u->ram.dat[addr + 2] = (y >> 8) & 0xff; |
... | ... |
@@ -149,9 +127,9 @@ domouse(Uxn *u, SDL_Event *event) |
149 | 127 |
break; |
150 | 128 |
case SDL_MOUSEBUTTONDOWN: |
151 | 129 |
setflag(&u->ram.dat[addr + 4], flag, 1); |
152 |
- if(flag == 0x10 && getflag(&u->ram.dat[addr + 4], 0x01)) |
|
130 |
+ if(flag == 0x10 && (u->ram.dat[addr + 4] & 0x01)) |
|
153 | 131 |
u->ram.dat[addr + 5] = 0x01; |
154 |
- if(flag == 0x01 && getflag(&u->ram.dat[addr + 4], 0x10)) |
|
132 |
+ if(flag == 0x01 && (u->ram.dat[addr + 4] & 0x10)) |
|
155 | 133 |
u->ram.dat[addr + 5] = 0x10; |
156 | 134 |
break; |
157 | 135 |
} |
... | ... |
@@ -229,8 +207,8 @@ screen_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
229 | 207 |
if(b0 == 0x0c) { |
230 | 208 |
Uint16 x = (m[ptr] << 8) + m[ptr + 1]; |
231 | 209 |
Uint16 y = (m[ptr + 2] << 8) + m[ptr + 3]; |
232 |
- paintpixel(b1 >> 4 & 0xf ? screen.fg : screen.bg, x, y, b1 & 0xf); |
|
233 |
- screen.reqdraw = 1; |
|
210 |
+ putpixel(b1 >> 4 & 0xf ? ppu.fg : ppu.bg, x, y, b1 & 0xf); |
|
211 |
+ ppu.reqdraw = 1; |
|
234 | 212 |
} |
235 | 213 |
return b1; |
236 | 214 |
} |
... | ... |
@@ -245,16 +223,16 @@ sprite_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
245 | 223 |
Uint16 x = (m[ptr] << 8) + m[ptr + 1]; |
246 | 224 |
Uint16 y = (m[ptr + 2] << 8) + m[ptr + 3]; |
247 | 225 |
Uint8 blend = b1 & 0xf; |
248 |
- Uint8 *layer = ((b1 >> 4) & 0xf) % 2 ? screen.fg : screen.bg; |
|
226 |
+ Uint8 *layer = ((b1 >> 4) & 0xf) % 2 ? ppu.fg : ppu.bg; |
|
249 | 227 |
Uint8 *sprite = &m[(m[ptr + 4] << 8) + m[ptr + 5]]; |
250 | 228 |
for(v = 0; v < 8; v++) |
251 | 229 |
for(h = 0; h < 8; h++) { |
252 | 230 |
Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); |
253 | 231 |
if(ch1 == 0 && (blend == 0x05 || blend == 0x0a || blend == 0x0f)) |
254 | 232 |
continue; |
255 |
- paintpixel(layer, x + h, y + v, ch1 ? blend % 4 : blend / 4); |
|
233 |
+ putpixel(layer, x + h, y + v, ch1 ? blend % 4 : blend / 4); |
|
256 | 234 |
} |
257 |
- screen.reqdraw = 1; |
|
235 |
+ ppu.reqdraw = 1; |
|
258 | 236 |
} |
259 | 237 |
return b1; |
260 | 238 |
} |
... | ... |
@@ -319,7 +297,7 @@ system_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) |
319 | 297 |
{ |
320 | 298 |
Uint8 *m = u->ram.dat; |
321 | 299 |
m[PAGE_DEVICE + b0] = b1; |
322 |
- loadtheme(&screen, &m[PAGE_DEVICE + 0x0008]); |
|
300 |
+ loadtheme(&ppu, &m[PAGE_DEVICE + 0x0008]); |
|
323 | 301 |
(void)ptr; |
324 | 302 |
return b1; |
325 | 303 |
} |
... | ... |
@@ -339,7 +317,7 @@ int |
339 | 317 |
start(Uxn *u) |
340 | 318 |
{ |
341 | 319 |
inituxn(u, 0x0200); |
342 |
- redraw(screen.output, u); |
|
320 |
+ redraw(ppu.output, u); |
|
343 | 321 |
while(1) { |
344 | 322 |
SDL_Event event; |
345 | 323 |
double elapsed, start = SDL_GetPerformanceCounter(); |
... | ... |
@@ -367,14 +345,14 @@ start(Uxn *u) |
367 | 345 |
break; |
368 | 346 |
case SDL_WINDOWEVENT: |
369 | 347 |
if(event.window.event == SDL_WINDOWEVENT_EXPOSED) |
370 |
- redraw(screen.output, u); |
|
348 |
+ redraw(ppu.output, u); |
|
371 | 349 |
break; |
372 | 350 |
} |
373 | 351 |
} |
374 | 352 |
evaluxn(u, devscreen->vector); |
375 | 353 |
SDL_UnlockAudioDevice(audio_id); |
376 |
- if(screen.reqdraw) |
|
377 |
- redraw(screen.output, u); |
|
354 |
+ if(ppu.reqdraw) |
|
355 |
+ redraw(ppu.output, u); |
|
378 | 356 |
elapsed = (SDL_GetPerformanceCounter() - start) / (double)SDL_GetPerformanceFrequency() * 1000.0f; |
379 | 357 |
SDL_Delay(clamp(16.666f - elapsed, 0, 1000)); |
380 | 358 |
} |
... | ... |
@@ -385,7 +363,7 @@ int |
385 | 363 |
main(int argc, char **argv) |
386 | 364 |
{ |
387 | 365 |
Uxn u; |
388 |
- screen.zoom = 2; |
|
366 |
+ ppu.zoom = 2; |
|
389 | 367 |
|
390 | 368 |
if(argc < 2) |
391 | 369 |
return error("Input", "Missing"); |
... | ... |
@@ -33,10 +33,9 @@ Uint8 font[][8] = { |
33 | 33 |
void |
34 | 34 |
clear(Ppu *p) |
35 | 35 |
{ |
36 |
- int v, h; |
|
37 |
- for(v = 0; v < HEIGHT; v++) |
|
38 |
- for(h = 0; h < WIDTH; h++) |
|
39 |
- p->output[v * WIDTH + h] = p->colors[0]; |
|
36 |
+ int i, sz = HEIGHT * WIDTH; |
|
37 |
+ for(i = 0; i < sz; ++i) |
|
38 |
+ p->output[i] = p->colors[0]; |
|
40 | 39 |
} |
41 | 40 |
|
42 | 41 |
void |
... | ... |
@@ -90,19 +89,19 @@ drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr) |
90 | 89 |
} |
91 | 90 |
|
92 | 91 |
void |
93 |
-paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color) |
|
92 |
+putpixel(Uint8 *layer, Uint16 x, Uint16 y, Uint8 color) |
|
94 | 93 |
{ |
95 | 94 |
Uint16 row = (y % 8) + ((x / 8 + y / 8 * HOR) * 16), col = 7 - (x % 8); |
96 | 95 |
if(x >= HOR * 8 || y >= VER * 8 || row > RES - 8) |
97 | 96 |
return; |
98 | 97 |
if(color == 0 || color == 2) |
99 |
- dst[row] &= ~(1UL << col); |
|
98 |
+ layer[row] &= ~(1UL << col); |
|
100 | 99 |
else |
101 |
- dst[row] |= 1UL << col; |
|
100 |
+ layer[row] |= 1UL << col; |
|
102 | 101 |
if(color == 0 || color == 1) |
103 |
- dst[row + 8] &= ~(1UL << col); |
|
102 |
+ layer[row + 8] &= ~(1UL << col); |
|
104 | 103 |
else |
105 |
- dst[row + 8] |= 1UL << col; |
|
104 |
+ layer[row + 8] |= 1UL << col; |
|
106 | 105 |
} |
107 | 106 |
|
108 | 107 |
void |
... | ... |
@@ -119,6 +118,18 @@ loadtheme(Ppu *p, Uint8 *addr) |
119 | 118 |
p->reqdraw = 1; |
120 | 119 |
} |
121 | 120 |
|
121 |
+void |
|
122 |
+draw(Ppu *p) |
|
123 |
+{ |
|
124 |
+ 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 |
+ } |
|
131 |
+} |
|
132 |
+ |
|
122 | 133 |
int |
123 | 134 |
initppu(Ppu *p) |
124 | 135 |
{ |
... | ... |
@@ -32,11 +32,8 @@ typedef struct Ppu { |
32 | 32 |
Uint32 *output, colors[4]; |
33 | 33 |
} Ppu; |
34 | 34 |
|
35 |
-void clear(Ppu *p); |
|
36 |
-void drawpixel(Ppu *p, Uint16 x, Uint16 y, Uint8 color); |
|
37 |
-void drawchr(Ppu *p, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 alpha); |
|
38 |
-void drawicn(Ppu *p, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg, Uint8 bg); |
|
35 |
+int initppu(Ppu *p); |
|
36 |
+void draw(Ppu *p); |
|
39 | 37 |
void drawdebugger(Ppu *p, Uint8 *stack, Uint8 ptr); |
40 |
-void paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color); |
|
41 | 38 |
void loadtheme(Ppu *p, Uint8 *addr); |
42 |
-int initppu(Ppu *p); |
|
43 | 39 |
\ No newline at end of file |
40 |
+void putpixel(Uint8 *layer, Uint16 x, Uint16 y, Uint8 color); |
|
44 | 41 |
\ No newline at end of file |