... | ... |
@@ -16,9 +16,9 @@ clang-format -i uxn.c |
16 | 16 |
# Emulator |
17 | 17 |
clang-format -i emulator.c |
18 | 18 |
rm -f ./bin/emulator |
19 |
-# cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator |
|
20 |
-cc uxn.c emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/emulator |
|
19 |
+cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator |
|
20 |
+# cc uxn.c emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/emulator |
|
21 | 21 |
|
22 | 22 |
# run |
23 |
-./bin/assembler examples/drag.usm bin/boot.rom |
|
23 |
+./bin/assembler examples/test.usm bin/boot.rom |
|
24 | 24 |
./bin/emulator bin/boot.rom |
... | ... |
@@ -15,14 +15,16 @@ WITH REGARD TO THIS SOFTWARE. |
15 | 15 |
#include "uxn.h" |
16 | 16 |
|
17 | 17 |
#define HOR 32 |
18 |
-#define VER 16 |
|
18 |
+#define VER 18 |
|
19 | 19 |
#define PAD 2 |
20 |
-#define SZ (HOR * VER * 16) |
|
20 |
+#define RES (HOR * VER * 16) |
|
21 | 21 |
|
22 |
-typedef unsigned char Uint8; |
|
22 |
+typedef struct { |
|
23 |
+ Uint8 bg[RES], fg[RES]; |
|
24 |
+} Screen; |
|
23 | 25 |
|
24 | 26 |
int WIDTH = 8 * HOR + 8 * PAD * 2; |
25 |
-int HEIGHT = 8 * (VER + 2) + 8 * PAD * 2; |
|
27 |
+int HEIGHT = 8 * VER + 8 * PAD * 2; |
|
26 | 28 |
int FPS = 30, GUIDES = 1, REQDRAW = 0, ZOOM = 2; |
27 | 29 |
|
28 | 30 |
Uint32 theme[] = { |
... | ... |
@@ -55,7 +57,41 @@ SDL_Renderer *gRenderer; |
55 | 57 |
SDL_Texture *gTexture; |
56 | 58 |
Uint32 *pixels; |
57 | 59 |
|
58 |
-Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller; |
|
60 |
+Screen screen; |
|
61 |
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller, *devfg; |
|
62 |
+ |
|
63 |
+#pragma mark - Paint |
|
64 |
+ |
|
65 |
+Uint16 |
|
66 |
+rowchr(Uint16 x, Uint16 y) |
|
67 |
+{ |
|
68 |
+ return (y % 8) + ((x / 8 + y / 8 * HOR) * 16); |
|
69 |
+} |
|
70 |
+ |
|
71 |
+void |
|
72 |
+paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color) |
|
73 |
+{ |
|
74 |
+ Uint16 row = rowchr(x, y), col = x % 8; |
|
75 |
+ if(x >= HOR * 8 || y >= VER * 8 || row > RES - 8) |
|
76 |
+ return; |
|
77 |
+ if(color == 0 || color == 2) |
|
78 |
+ dst[row] &= ~(1UL << (7 - col)); |
|
79 |
+ else |
|
80 |
+ dst[row] |= 1UL << (7 - col); |
|
81 |
+ if(color == 0 || color == 1) |
|
82 |
+ dst[row + 8] &= ~(1UL << (7 - col)); |
|
83 |
+ else |
|
84 |
+ dst[row + 8] |= 1UL << (7 - col); |
|
85 |
+} |
|
86 |
+ |
|
87 |
+void |
|
88 |
+painticn(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg) |
|
89 |
+{ |
|
90 |
+ Uint16 v, h; |
|
91 |
+ for(v = 0; v < 8; v++) |
|
92 |
+ for(h = 0; h < 8; h++) |
|
93 |
+ paintpixel(dst, x + h, y + v, ((sprite[v] >> (7 - h)) & 0x1) ? fg : 0); |
|
94 |
+} |
|
59 | 95 |
|
60 | 96 |
#pragma mark - Helpers |
61 | 97 |
|
... | ... |
@@ -76,14 +112,15 @@ putpixel(Uint32 *dst, int x, int y, int color) |
76 | 112 |
} |
77 | 113 |
|
78 | 114 |
void |
79 |
-drawchr(Uint32 *dst, int x, int y, Uint8 *sprite) |
|
115 |
+drawchr(Uint32 *dst, int x, int y, Uint8 *sprite, Uint8 alpha) |
|
80 | 116 |
{ |
81 | 117 |
int v, h; |
82 | 118 |
for(v = 0; v < 8; v++) |
83 | 119 |
for(h = 0; h < 8; h++) { |
84 |
- int ch1 = ((sprite[v] >> h) & 0x1); |
|
85 |
- int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); |
|
86 |
- putpixel(dst, x + 7 - h, y + v, ch1 + ch2); |
|
120 |
+ Uint8 ch1 = ((sprite[v] >> h) & 0x1); |
|
121 |
+ Uint8 ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); |
|
122 |
+ if(!alpha || (alpha && ch1 + ch2 != 0)) |
|
123 |
+ putpixel(dst, x + 7 - h, y + v, ch1 + ch2); |
|
87 | 124 |
} |
88 | 125 |
} |
89 | 126 |
|
... | ... |
@@ -111,25 +148,27 @@ void |
111 | 148 |
drawdebugger(Uint32 *dst, Uxn *u) |
112 | 149 |
{ |
113 | 150 |
Uint8 i; |
114 |
- for(i = 0; i < 0x20; ++i) { /* memory */ |
|
115 |
- Uint8 x = (i % 8) * 3 + 1, y = i / 8 + 1, b = u->ram.dat[i]; |
|
151 |
+ for(i = 0; i < 0x10; ++i) { /* memory */ |
|
152 |
+ Uint8 x = (i % 8) * 3 + 3, y = i / 8 + 3, b = u->ram.dat[i]; |
|
116 | 153 |
drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1, 0); |
117 | 154 |
drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1, 0); |
118 |
- } |
|
119 |
- for(i = 0; i < 0x10; ++i) { /* memory */ |
|
120 |
- Uint8 x = (i % 8) * 3 + 1, y = i / 8 + 0x13, b = u->wst.dat[i]; |
|
155 |
+ y = i / 8 + 0x11, b = u->wst.dat[i]; |
|
121 | 156 |
drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1 + (u->wst.ptr == i), 0); |
122 | 157 |
drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1 + (u->wst.ptr == i), 0); |
123 | 158 |
} |
124 |
- drawicn(dst, 25 * 8, 8, icons[getflag(&u->status, FLAG_HALT) != 0], 2, 0); |
|
125 |
- drawicn(dst, 26 * 8, 8, icons[getflag(&u->status, FLAG_SHORT) != 0], 2, 0); |
|
126 |
- drawicn(dst, 27 * 8, 8, icons[getflag(&u->status, FLAG_SIGN) != 0], 2, 0); |
|
127 |
- drawicn(dst, 28 * 8, 8, icons[getflag(&u->status, FLAG_COND) != 0], 2, 0); |
|
128 | 159 |
} |
129 | 160 |
|
130 | 161 |
void |
131 | 162 |
redraw(Uint32 *dst, Uxn *u) |
132 | 163 |
{ |
164 |
+ int x, y; |
|
165 |
+ /* merge layers */ |
|
166 |
+ for(y = 0; y < VER; ++y) |
|
167 |
+ for(x = 0; x < HOR; ++x) { |
|
168 |
+ int key = (y * HOR + x) * 16; |
|
169 |
+ drawchr(dst, (x + PAD) * 8, (y + PAD) * 8, &screen.bg[key], 0); |
|
170 |
+ drawchr(dst, (x + PAD) * 8, (y + PAD) * 8, &screen.fg[key], 1); |
|
171 |
+ } |
|
133 | 172 |
if(GUIDES) |
134 | 173 |
drawdebugger(dst, u); |
135 | 174 |
SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32)); |
... | ... |
@@ -170,14 +209,23 @@ init(void) |
170 | 209 |
if(!(pixels = (Uint32 *)malloc(WIDTH * HEIGHT * sizeof(Uint32)))) |
171 | 210 |
return error("Pixels", "Failed to allocate memory"); |
172 | 211 |
clear(pixels); |
212 |
+ SDL_ShowCursor(SDL_DISABLE); |
|
173 | 213 |
return 1; |
174 | 214 |
} |
175 | 215 |
|
176 | 216 |
void |
177 | 217 |
domouse(SDL_Event *event) |
178 | 218 |
{ |
179 |
- int x = event->motion.x / ZOOM; |
|
180 |
- int y = event->motion.y / ZOOM; |
|
219 |
+ int x = (event->motion.x - PAD * 8 * ZOOM) / ZOOM; |
|
220 |
+ int y = (event->motion.y - PAD * 8 * ZOOM) / ZOOM; |
|
221 |
+ if(x < 0) |
|
222 |
+ x = 0; |
|
223 |
+ else if(x > WIDTH) |
|
224 |
+ x = WIDTH - 1; |
|
225 |
+ if(y < 0) |
|
226 |
+ y = 0; |
|
227 |
+ else if(y > HEIGHT) |
|
228 |
+ y = HEIGHT - 1; |
|
181 | 229 |
devmouse->mem[0] = (x >> 8) & 0xff; |
182 | 230 |
devmouse->mem[1] = x & 0xff; |
183 | 231 |
devmouse->mem[2] = (y >> 8) & 0xff; |
... | ... |
@@ -263,16 +311,32 @@ Uint8 |
263 | 311 |
spritew(Device *d, Memory *m, Uint8 b) |
264 | 312 |
{ |
265 | 313 |
d->mem[d->ptr++] = b; |
266 |
- if(d->ptr > 7) { |
|
314 |
+ if(d->ptr == 6) { |
|
315 |
+ int i; |
|
267 | 316 |
Uint16 x = (d->mem[2] << 8) + d->mem[3]; |
268 | 317 |
Uint16 y = (d->mem[0] << 8) + d->mem[1]; |
269 |
- Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]]; |
|
270 |
- if(!d->mem[6]) |
|
271 |
- drawchr(pixels, x, y, chr); |
|
272 |
- else |
|
273 |
- drawicn(pixels, x, y, chr, d->mem[6] & 0xf, (d->mem[6] >> 4) & 0xf); |
|
274 |
- if(d->mem[7]) |
|
275 |
- REQDRAW = 1; |
|
318 |
+ Uint16 a = (d->mem[4] << 8) + d->mem[5]; |
|
319 |
+ Uint16 key = (x + y * HOR) * 16; |
|
320 |
+ for(i = 0; i < 16; ++i) |
|
321 |
+ screen.bg[key + i] = m->dat[a + i]; |
|
322 |
+ REQDRAW = 1; |
|
323 |
+ d->ptr = 0; |
|
324 |
+ } |
|
325 |
+ return 0; |
|
326 |
+} |
|
327 |
+ |
|
328 |
+Uint8 /* TODO: merge this device into screen/sprite */ |
|
329 |
+fgw(Device *d, Memory *m, Uint8 b) |
|
330 |
+{ |
|
331 |
+ d->mem[d->ptr++] = b; |
|
332 |
+ if(d->ptr == 7) { |
|
333 |
+ Uint16 x = (d->mem[2] << 8) + d->mem[3]; |
|
334 |
+ Uint16 y = (d->mem[0] << 8) + d->mem[1]; |
|
335 |
+ Uint16 a = (d->mem[4] << 8) + d->mem[5]; |
|
336 |
+ Uint8 clr = d->mem[6] & 0xf; |
|
337 |
+ Uint8 layer = d->mem[6] >> 4 & 0xf; |
|
338 |
+ painticn(layer ? screen.fg : screen.bg, x, y, &m->dat[a], clr); |
|
339 |
+ REQDRAW = 1; |
|
276 | 340 |
d->ptr = 0; |
277 | 341 |
} |
278 | 342 |
return 0; |
... | ... |
@@ -333,6 +397,7 @@ main(int argc, char **argv) |
333 | 397 |
devcontroller = portuxn(&u, "controller", defaultrw, defaultrw); |
334 | 398 |
devkey = portuxn(&u, "key", defaultrw, consolew); |
335 | 399 |
devmouse = portuxn(&u, "mouse", defaultrw, defaultrw); |
400 |
+ devfg = portuxn(&u, "fg", defaultrw, fgw); |
|
336 | 401 |
|
337 | 402 |
start(&u); |
338 | 403 |
quit(); |
... | ... |
@@ -7,16 +7,16 @@ |
7 | 7 |
#01 =dev/w ( set dev/write to screen ) |
8 | 8 |
#02 =dev/w ( set dev/write to sprite ) |
9 | 9 |
|
10 |
- #0110 ,cursor_icn #0020 #0038 ,drawsprite JSR |
|
11 |
- #0010 ,rounds_chr #0028 #0038 ,drawsprite JSR |
|
12 |
- #3210 ,cursor_icn #0020 #0040 ,drawsprite JSR |
|
13 |
- #0010 ,rounds_chr #0028 #0040 ,drawsprite JSR |
|
10 |
+ #0110 ,cursor_icn #20 #38 ,drawsprite JSR |
|
11 |
+ #0010 ,rounds_chr #28 #38 ,drawsprite JSR |
|
12 |
+ #3210 ,cursor_icn #20 #40 ,drawsprite JSR |
|
13 |
+ #0010 ,rounds_chr #28 #40 ,drawsprite JSR |
|
14 | 14 |
|
15 | 15 |
BRK |
16 | 16 |
|
17 | 17 |
@drawsprite |
18 |
- IOW2 ( y short ) |
|
19 |
- IOW2 ( x short ) |
|
18 |
+ IOW ( y byte ) |
|
19 |
+ IOW ( x byte ) |
|
20 | 20 |
IOW2 ( sprite address ) |
21 | 21 |
IOW2 ( redraw byte ) |
22 | 22 |
RTS |
... | ... |
@@ -1,21 +1,50 @@ |
1 |
-( blank ) |
|
1 |
+( sprite ) |
|
2 | 2 |
|
3 | 3 |
:dev/r fff8 ( std read port ) |
4 | 4 |
:dev/w fff9 ( std write port ) |
5 | 5 |
|
6 |
-;x 1 ;y 2 |
|
6 |
+;mousex 2 ;mousey 2 ;lastx 2 ;lasty 2 ;color 1 |
|
7 | 7 |
|
8 |
-|0100 @RESET |
|
8 |
+|0100 @RESET |
|
9 | 9 |
|
10 |
- #12 #34 WSR2 |
|
11 |
- ,test JSR |
|
10 |
+ #05 =dev/r ( set dev/read mouse ) |
|
11 |
+ #02 =dev/w ( set dev/write to sprite ) |
|
12 |
+ |
|
13 |
+ #00 ,rounds_chr #0004 #0004 ,drawsprite JSR |
|
12 | 14 |
|
13 | 15 |
BRK |
14 | 16 |
|
15 |
-@test |
|
17 |
+|c000 @FRAME |
|
18 |
+ |
|
19 |
+ #06 =dev/w ( set dev/write to sprite ) |
|
20 |
+ |
|
21 |
+ ( clear last cursor ) |
|
22 |
+ #10 ,clear_icn ~lastx ~lasty ,drawsprite JSR |
|
23 |
+ |
|
24 |
+ ( record mouse values ) |
|
25 |
+ #00 IOR2 =mousex #02 IOR2 =mousey |
|
26 |
+ #04 IOR #11 ADD =color |
|
27 |
+ |
|
28 |
+ ~color ,cursor_icn ~mousex ~mousey ,drawsprite JSR |
|
29 |
+ ~mousex =lastx ~mousey =lasty |
|
30 |
+ |
|
31 |
+BRK |
|
32 |
+ |
|
33 |
+@drawsprite |
|
34 |
+ IOW2 ( y byte ) |
|
35 |
+ IOW2 ( x byte ) |
|
36 |
+ IOW2 ( sprite address ) |
|
37 |
+ IOW ( layer-color ) |
|
16 | 38 |
RTS |
17 | 39 |
|
18 |
-|c000 @FRAME BRK |
|
40 |
+|0200 @SPRITESHEET |
|
41 |
+ |
|
42 |
+@rounds_chr [ 3844 92aa 9244 3800 0038 7c7c 7c38 0000 ] |
|
43 |
+@cursor_icn [ 80c0 e0f0 f8e0 1000 ] |
|
44 |
+@clear_icn [ 0000 0000 0000 0000 ] |
|
45 |
+ |
|
46 |
+BRK |
|
47 |
+ |
|
19 | 48 |
|d000 @ERROR BRK |
20 | 49 |
|
21 | 50 |
|FFFA .RESET .FRAME .ERROR |