| ... | ... |
@@ -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 |