Browse code

Starting paint example

neauoire authored on 19/02/2021 02:16:39
Showing 5 changed files
... ...
@@ -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/test.usm bin/boot.rom
23
+./bin/assembler examples/paint.usm bin/boot.rom
24 24
 ./bin/emulator bin/boot.rom
... ...
@@ -20,12 +20,13 @@ WITH REGARD TO THIS SOFTWARE.
20 20
 #define RES (HOR * VER * 16)
21 21
 
22 22
 typedef struct {
23
+	Uint8 reqdraw;
23 24
 	Uint8 bg[RES], fg[RES];
24 25
 } Screen;
25 26
 
26 27
 int WIDTH = 8 * HOR + 8 * PAD * 2;
27 28
 int HEIGHT = 8 * VER + 8 * PAD * 2;
28
-int FPS = 30, GUIDES = 1, REQDRAW = 0, ZOOM = 2;
29
+int FPS = 30, GUIDES = 1, ZOOM = 2;
29 30
 
30 31
 Uint32 theme[] = {
31 32
 	0x000000,
... ...
@@ -58,7 +59,15 @@ SDL_Texture *gTexture;
58 59
 Uint32 *pixels;
59 60
 
60 61
 Screen screen;
61
-Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller, *devfg;
62
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller;
63
+
64
+#pragma mark - Helpers
65
+
66
+int
67
+clamp(int val, int min, int max)
68
+{
69
+	return (val >= min) ? (val <= max) ? val : max : min;
70
+}
62 71
 
63 72
 #pragma mark - Paint
64 73
 
... ...
@@ -85,12 +94,27 @@ paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color)
85 94
 }
86 95
 
87 96
 void
88
-painticn(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg)
97
+paintchr(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite)
98
+{
99
+	Uint16 v, h;
100
+	for(v = 0; v < 8; v++)
101
+		for(h = 0; h < 8; h++) {
102
+			Uint8 ch1 = ((sprite[v] >> h) & 0x1);
103
+			Uint8 ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
104
+			paintpixel(dst, x + h, y + v, ch1 + ch2);
105
+		}
106
+}
107
+
108
+void
109
+painticn(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg, Uint8 alpha)
89 110
 {
90 111
 	Uint16 v, h;
91 112
 	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);
113
+		for(h = 0; h < 8; h++) {
114
+			Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1);
115
+			if(!alpha || (alpha && ch1))
116
+				paintpixel(dst, x + h, y + v, ch1 ? fg : 0);
117
+		}
94 118
 }
95 119
 
96 120
 #pragma mark - Helpers
... ...
@@ -175,7 +199,7 @@ redraw(Uint32 *dst, Uxn *u)
175 199
 	SDL_RenderClear(gRenderer);
176 200
 	SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
177 201
 	SDL_RenderPresent(gRenderer);
178
-	REQDRAW = 0;
202
+	screen.reqdraw = 0;
179 203
 }
180 204
 
181 205
 void
... ...
@@ -216,16 +240,8 @@ init(void)
216 240
 void
217 241
 domouse(SDL_Event *event)
218 242
 {
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;
243
+	int x = clamp((event->motion.x - PAD * 8 * ZOOM) / ZOOM, 0, WIDTH - 1);
244
+	int y = clamp((event->motion.y - PAD * 8 * ZOOM) / ZOOM, 0, HEIGHT - 1);
229 245
 	devmouse->mem[0] = (x >> 8) & 0xff;
230 246
 	devmouse->mem[1] = x & 0xff;
231 247
 	devmouse->mem[2] = (y >> 8) & 0xff;
... ...
@@ -300,7 +316,7 @@ screenw(Device *d, Memory *m, Uint8 b)
300 316
 			(d->mem[0] << 8) + d->mem[1],
301 317
 			d->mem[4]);
302 318
 		if(d->mem[5] == 1)
303
-			REQDRAW = 1;
319
+			screen.reqdraw = 1;
304 320
 		d->ptr = 0;
305 321
 	}
306 322
 	(void)m;
... ...
@@ -309,24 +325,6 @@ screenw(Device *d, Memory *m, Uint8 b)
309 325
 
310 326
 Uint8
311 327
 spritew(Device *d, Memory *m, Uint8 b)
312
-{
313
-	d->mem[d->ptr++] = b;
314
-	if(d->ptr == 6) {
315
-		int i;
316
-		Uint16 x = (d->mem[2] << 8) + d->mem[3];
317
-		Uint16 y = (d->mem[0] << 8) + d->mem[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 328
 {
331 329
 	d->mem[d->ptr++] = b;
332 330
 	if(d->ptr == 7) {
... ...
@@ -335,8 +333,11 @@ fgw(Device *d, Memory *m, Uint8 b)
335 333
 		Uint16 a = (d->mem[4] << 8) + d->mem[5];
336 334
 		Uint8 clr = d->mem[6] & 0xf;
337 335
 		Uint8 layer = d->mem[6] >> 4 & 0xf;
338
-		painticn(layer ? screen.fg : screen.bg, x, y, &m->dat[a], clr);
339
-		REQDRAW = 1;
336
+		if(clr > 7)
337
+			paintchr(layer ? screen.fg : screen.bg, x, y, &m->dat[a]);
338
+		else
339
+			painticn(layer ? screen.fg : screen.bg, x, y, &m->dat[a], clr % 4, clr > 3);
340
+		screen.reqdraw = 1;
340 341
 		d->ptr = 0;
341 342
 	}
342 343
 	return 0;
... ...
@@ -349,7 +350,7 @@ start(Uxn *u)
349 350
 {
350 351
 	int ticknext = 0;
351 352
 	evaluxn(u, u->vreset);
352
-	if(REQDRAW)
353
+	if(screen.reqdraw)
353 354
 		redraw(pixels, u);
354 355
 	while(1) {
355 356
 		int tick = SDL_GetTicks();
... ...
@@ -372,7 +373,7 @@ start(Uxn *u)
372 373
 			}
373 374
 		}
374 375
 		evaluxn(u, u->vframe);
375
-		if(REQDRAW)
376
+		if(screen.reqdraw)
376 377
 			redraw(pixels, u);
377 378
 	}
378 379
 }
... ...
@@ -397,7 +398,6 @@ main(int argc, char **argv)
397 398
 	devcontroller = portuxn(&u, "controller", defaultrw, defaultrw);
398 399
 	devkey = portuxn(&u, "key", defaultrw, consolew);
399 400
 	devmouse = portuxn(&u, "mouse", defaultrw, defaultrw);
400
-	devfg = portuxn(&u, "fg", defaultrw, fgw);
401 401
 
402 402
 	start(&u);
403 403
 	quit();
404 404
new file mode 100644
... ...
@@ -0,0 +1,58 @@
1
+( sprite )
2
+
3
+:dev/r fff8 ( std read port )
4
+:dev/w fff9 ( std write port )
5
+
6
+;mousex 2 ;mousey 2 ;lastx 2 ;lasty 2 ;color 1
7
+
8
+|0100 @RESET 
9
+
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
14
+
15
+BRK
16
+
17
+|c000 @FRAME
18
+	
19
+	#02 =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
+
30
+	( check paint )
31
+	#04 IOR #00 EQU ,skip ROT JMP? POP2
32
+	#05 ,brush_large ~mousex #0004 SUB2 ~mousey #0004 SUB2 ,drawsprite JSR
33
+	@skip
34
+
35
+	~mousex =lastx ~mousey =lasty
36
+
37
+BRK
38
+
39
+@drawsprite
40
+	IOW2 ( y byte )
41
+	IOW2 ( x byte )
42
+	IOW2 ( sprite address )
43
+	IOW ( layer-color )
44
+	RTS
45
+
46
+|0200 @SPRITESHEET
47
+
48
+@rounds_chr [ 3844 92aa 9244 3800 0038 7c7c 7c38 0000 ]
49
+@cursor_icn [ 80c0 e0f0 f8e0 1000 ]
50
+@clear_icn [ 0000 0000 0000 0000 ]
51
+@brush_large [ 387c fefe fe7c 3800 ]
52
+@brush_small [ 0038 7c7c 7c38 0000 ]
53
+
54
+BRK
55
+
56
+|d000 @ERROR BRK 
57
+
58
+|FFFA .RESET .FRAME .ERROR
... ...
@@ -16,7 +16,7 @@ BRK
16 16
 
17 17
 |c000 @FRAME
18 18
 	
19
-	#06 =dev/w ( set dev/write to sprite ) 
19
+	#02 =dev/w ( set dev/write to sprite ) 
20 20
 
21 21
 	( clear last cursor )
22 22
 	#10 ,clear_icn ~lastx ~lasty ,drawsprite JSR
... ...
@@ -26,6 +26,12 @@ BRK
26 26
 	#04 IOR #11 ADD =color
27 27
 
28 28
 	~color ,cursor_icn ~mousex ~mousey ,drawsprite JSR
29
+
30
+	( check paint )
31
+	#04 IOR #00 EQU ,skip ROT JMP? POP2
32
+	#05 ,brush_large ~mousex #0004 SUB2 ~mousey #0004 SUB2 ,drawsprite JSR
33
+	@skip
34
+
29 35
 	~mousex =lastx ~mousey =lasty
30 36
 
31 37
 BRK
... ...
@@ -42,6 +48,8 @@ BRK
42 48
 @rounds_chr [ 3844 92aa 9244 3800 0038 7c7c 7c38 0000 ]
43 49
 @cursor_icn [ 80c0 e0f0 f8e0 1000 ]
44 50
 @clear_icn [ 0000 0000 0000 0000 ]
51
+@brush_large [ 387c fefe fe7c 3800 ]
52
+@brush_small [ 0038 7c7c 7c38 0000 ]
45 53
 
46 54
 BRK
47 55
 
48 56
deleted file mode 100644
49 57
Binary files a/untitled.chr and /dev/null differ