| ... | ... |
@@ -20,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr |
| 20 | 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/images.usm bin/boot.rom |
|
| 23 |
+./bin/assembler examples/gui.paint.usm bin/boot.rom |
|
| 24 | 24 |
./bin/emulator bin/boot.rom |
| ... | ... |
@@ -20,9 +20,14 @@ WITH REGARD TO THIS SOFTWARE. |
| 20 | 20 |
#define PAD 2 |
| 21 | 21 |
#define RES (HOR * VER * 16) |
| 22 | 22 |
|
| 23 |
+typedef struct {
|
|
| 24 |
+ Uint16 x1, y1, x2, y2; |
|
| 25 |
+} Rect2d; |
|
| 26 |
+ |
|
| 23 | 27 |
typedef struct {
|
| 24 | 28 |
Uint8 reqdraw; |
| 25 | 29 |
Uint8 bg[RES], fg[RES]; |
| 30 |
+ Rect2d bounds; |
|
| 26 | 31 |
} Screen; |
| 27 | 32 |
|
| 28 | 33 |
int WIDTH = 8 * HOR + 8 * PAD * 2; |
| ... | ... |
@@ -72,26 +77,20 @@ clamp(int val, int min, int max) |
| 72 | 77 |
|
| 73 | 78 |
#pragma mark - Paint |
| 74 | 79 |
|
| 75 |
-Uint16 |
|
| 76 |
-rowchr(Uint16 x, Uint16 y) |
|
| 77 |
-{
|
|
| 78 |
- return (y % 8) + ((x / 8 + y / 8 * HOR) * 16); |
|
| 79 |
-} |
|
| 80 |
- |
|
| 81 | 80 |
void |
| 82 | 81 |
paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color) |
| 83 | 82 |
{
|
| 84 |
- Uint16 row = rowchr(x, y), col = x % 8; |
|
| 83 |
+ Uint16 row = (y % 8) + ((x / 8 + y / 8 * HOR) * 16), col = 7 - (x % 8); |
|
| 85 | 84 |
if(x >= HOR * 8 || y >= VER * 8 || row > RES - 8) |
| 86 | 85 |
return; |
| 87 | 86 |
if(color == 0 || color == 2) |
| 88 |
- dst[row] &= ~(1UL << (7 - col)); |
|
| 87 |
+ dst[row] &= ~(1UL << col); |
|
| 89 | 88 |
else |
| 90 |
- dst[row] |= 1UL << (7 - col); |
|
| 89 |
+ dst[row] |= 1UL << col; |
|
| 91 | 90 |
if(color == 0 || color == 1) |
| 92 |
- dst[row + 8] &= ~(1UL << (7 - col)); |
|
| 91 |
+ dst[row + 8] &= ~(1UL << col); |
|
| 93 | 92 |
else |
| 94 |
- dst[row + 8] |= 1UL << (7 - col); |
|
| 93 |
+ dst[row + 8] |= 1UL << col; |
|
| 95 | 94 |
} |
| 96 | 95 |
|
| 97 | 96 |
void |
| ... | ... |
@@ -131,37 +130,33 @@ clear(Uint32 *dst) |
| 131 | 130 |
} |
| 132 | 131 |
|
| 133 | 132 |
void |
| 134 |
-putpixel(Uint32 *dst, int x, int y, int color) |
|
| 133 |
+drawpixel(Uint32 *dst, Uint16 x, Uint16 y, Uint8 color) |
|
| 135 | 134 |
{
|
| 136 |
- if(y == PAD * 8 || y == HEIGHT - PAD * 8 - 1) {
|
|
| 137 |
- if(x == PAD * 8) return; |
|
| 138 |
- if(x == WIDTH - PAD * 8 - 1) return; |
|
| 139 |
- } |
|
| 140 |
- if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8) |
|
| 135 |
+ if(x >= screen.bounds.x1 && x <= screen.bounds.x2 && y >= screen.bounds.x1 && y <= screen.bounds.y2) |
|
| 141 | 136 |
dst[y * WIDTH + x] = theme[color]; |
| 142 | 137 |
} |
| 143 | 138 |
|
| 144 | 139 |
void |
| 145 |
-drawchr(Uint32 *dst, int x, int y, Uint8 *sprite, Uint8 alpha) |
|
| 140 |
+drawchr(Uint32 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 alpha) |
|
| 146 | 141 |
{
|
| 147 |
- int v, h; |
|
| 142 |
+ Uint8 v, h; |
|
| 148 | 143 |
for(v = 0; v < 8; v++) |
| 149 | 144 |
for(h = 0; h < 8; h++) {
|
| 150 | 145 |
Uint8 ch1 = ((sprite[v] >> h) & 0x1); |
| 151 | 146 |
Uint8 ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); |
| 152 | 147 |
if(!alpha || (alpha && ch1 + ch2 != 0)) |
| 153 |
- putpixel(dst, x + 7 - h, y + v, ch1 + ch2); |
|
| 148 |
+ drawpixel(dst, x + 7 - h, y + v, ch1 + ch2); |
|
| 154 | 149 |
} |
| 155 | 150 |
} |
| 156 | 151 |
|
| 157 | 152 |
void |
| 158 |
-drawicn(Uint32 *dst, int x, int y, Uint8 *sprite, int fg, int bg) |
|
| 153 |
+drawicn(Uint32 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg, Uint8 bg) |
|
| 159 | 154 |
{
|
| 160 |
- int v, h; |
|
| 155 |
+ Uint8 v, h; |
|
| 161 | 156 |
for(v = 0; v < 8; v++) |
| 162 | 157 |
for(h = 0; h < 8; h++) {
|
| 163 |
- int ch1 = (sprite[v] >> (7 - h)) & 0x1; |
|
| 164 |
- putpixel(dst, x + h, y + v, ch1 ? fg : bg); |
|
| 158 |
+ Uint8 ch1 = (sprite[v] >> (7 - h)) & 0x1; |
|
| 159 |
+ drawpixel(dst, x + h, y + v, ch1 ? fg : bg); |
|
| 165 | 160 |
} |
| 166 | 161 |
} |
| 167 | 162 |
|
| ... | ... |
@@ -191,14 +186,11 @@ loadtheme(Uint8 *addr) |
| 191 | 186 |
void |
| 192 | 187 |
drawdebugger(Uint32 *dst, Uxn *u) |
| 193 | 188 |
{
|
| 194 |
- Uint8 i; |
|
| 189 |
+ Uint8 i, x, y, b; |
|
| 195 | 190 |
for(i = 0; i < 0x10; ++i) { /* memory */
|
| 196 |
- Uint8 x = (i % 8) * 3 + 3, y = i / 8 + 3, b = u->ram.dat[i]; |
|
| 197 |
- drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1, 0); |
|
| 198 |
- drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1, 0); |
|
| 199 |
- y = VER - 1 + i / 8, b = u->wst.dat[i]; |
|
| 200 |
- drawicn(dst, x * 8, y * 8, icons[(b >> 4) & 0xf], 1 + (u->wst.ptr == i), 0); |
|
| 201 |
- drawicn(dst, x * 8 + 8, y * 8, icons[b & 0xf], 1 + (u->wst.ptr == i), 0); |
|
| 191 |
+ x = ((i % 8) * 3 + 3) * 8, y = screen.bounds.x1 + 8 + i / 8 * 8, b = u->wst.dat[i]; |
|
| 192 |
+ drawicn(dst, x, y, icons[(b >> 4) & 0xf], 1 + (u->wst.ptr == i), 0); |
|
| 193 |
+ drawicn(dst, x + 8, y, icons[b & 0xf], 1 + (u->wst.ptr == i), 0); |
|
| 202 | 194 |
} |
| 203 | 195 |
} |
| 204 | 196 |
|
| ... | ... |
@@ -253,6 +245,10 @@ init(void) |
| 253 | 245 |
return error("Pixels", "Failed to allocate memory");
|
| 254 | 246 |
clear(pixels); |
| 255 | 247 |
SDL_ShowCursor(SDL_DISABLE); |
| 248 |
+ screen.bounds.x1 = PAD * 8; |
|
| 249 |
+ screen.bounds.x2 = WIDTH - PAD * 8 - 1; |
|
| 250 |
+ screen.bounds.y1 = PAD * 8; |
|
| 251 |
+ screen.bounds.y2 = HEIGHT - PAD * 8 - 1; |
|
| 256 | 252 |
return 1; |
| 257 | 253 |
} |
| 258 | 254 |
|
| ... | ... |
@@ -260,8 +256,8 @@ void |
| 260 | 256 |
domouse(SDL_Event *event) |
| 261 | 257 |
{
|
| 262 | 258 |
Uint8 flag = 0x00; |
| 263 |
- int x = clamp((event->motion.x - PAD * 8 * ZOOM) / ZOOM, 0, WIDTH - 1); |
|
| 264 |
- int y = clamp((event->motion.y - PAD * 8 * ZOOM) / ZOOM, 0, HEIGHT - 1); |
|
| 259 |
+ Uint16 x = clamp(event->motion.x / ZOOM - PAD * 8, 0, HOR * 8 - 1); |
|
| 260 |
+ Uint16 y = clamp(event->motion.y / ZOOM - PAD * 8, 0, VER * 8 - 1); |
|
| 265 | 261 |
devmouse->mem[0] = (x >> 8) & 0xff; |
| 266 | 262 |
devmouse->mem[1] = x & 0xff; |
| 267 | 263 |
devmouse->mem[2] = (y >> 8) & 0xff; |
| ... | ... |
@@ -310,21 +306,19 @@ doctrl(SDL_Event *event, int z) |
| 310 | 306 |
if(SDL_GetModState() & KMOD_LALT || SDL_GetModState() & KMOD_RALT) |
| 311 | 307 |
flag = 0x02; |
| 312 | 308 |
switch(event->key.keysym.sym) {
|
| 313 |
- case SDLK_ESCAPE: flag = 0x04; break; |
|
| 314 |
- case SDLK_RETURN: flag = 0x08; break; |
|
| 309 |
+ case SDLK_BACKSPACE: |
|
| 310 |
+ flag = 0x04; |
|
| 311 |
+ if(z) devkey->mem[0] = 0x08; |
|
| 312 |
+ break; |
|
| 313 |
+ case SDLK_RETURN: |
|
| 314 |
+ flag = 0x08; |
|
| 315 |
+ if(z) devkey->mem[0] = 0x0d; |
|
| 316 |
+ break; |
|
| 315 | 317 |
case SDLK_UP: flag = 0x10; break; |
| 316 | 318 |
case SDLK_DOWN: flag = 0x20; break; |
| 317 | 319 |
case SDLK_LEFT: flag = 0x40; break; |
| 318 | 320 |
case SDLK_RIGHT: flag = 0x80; break; |
| 319 | 321 |
} |
| 320 |
- if(z) {
|
|
| 321 |
- /* special key controls */ |
|
| 322 |
- switch(event->key.keysym.sym) {
|
|
| 323 |
- case SDLK_BACKSPACE: devkey->mem[0] = 0x08; break; |
|
| 324 |
- case SDLK_RETURN: devkey->mem[0] = 0x0d; break; |
|
| 325 |
- } |
|
| 326 |
- } |
|
| 327 |
- |
|
| 328 | 322 |
setflag(&devcontroller->mem[0], flag, z); |
| 329 | 323 |
} |
| 330 | 324 |
|