Browse code

Faster screen drawing routines

neauoire authored on 18/12/2023 22:44:36
Showing 5 changed files
... ...
@@ -26,7 +26,7 @@
26 26
 	( | clear )
27 27
 	#0000 DUP2 .Screen/x DEO2
28 28
 	.Screen/y DEO2
29
-	#80 .Screen/pixel DEO
29
+	[ LIT2 80 -Screen/pixel ] DEO
30 30
 	( | draw )
31 31
 	.timer LDZk INC SWP STZ
32 32
 	<draw-cube>
... ...
@@ -36,7 +36,7 @@
36 36
 	( | create box )
37 37
 	#0800
38 38
 	&loop ( -- )
39
-		STHk #00 .timer LDZ #00 STHkr INC #07 AND #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #01 SFT #00 .timer LDZ #00 STHkr #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #02 SFT #00 STHkr #62 SFT2 ADD2 .cube/v0 STHr DUP ADD ADD STZ2
39
+		STHk [ LIT2 00 -timer ] LDZ #00 STHkr INC #07 AND #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #01 SFT #00 .timer LDZ #00 STHkr #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #02 SFT #00 STHkr #62 SFT2 ADD2 .cube/v0 STHr DUP ADD ADD STZ2
40 40
 		INC GTHk ?&loop
41 41
 	POP2
42 42
 	( | vertices )
... ...
@@ -65,7 +65,7 @@
65 65
 	#00 SWP #0004 SUB2 .center/y LDZ2 ADD2 .Screen/y DEO2
66 66
 	#00 SWP #0003 SUB2 .center/x LDZ2 ADD2 .Screen/x DEO2
67 67
 	;&icn .Screen/addr DEO2
68
-	#05 .Screen/sprite DEO
68
+	[ LIT2 05 -Screen/sprite ] DEO
69 69
 	JMP2r
70 70
 	&icn [ 0000 387c 7c7c 3800 ]
71 71
 
... ...
@@ -30,12 +30,12 @@
30 30
 	#00 draw-dvd
31 31
 	( | x )
32 32
 	.dvd/x LDZ2
33
-	( left ) DUP2 #0000 NEQ2 ?{ #0001 ,&x STR2 }
33
+	( left ) ORAk ?{ #0001 ,&x STR2 }
34 34
 	( right ) DUP2 [ LIT2 &hit-hor $2 ] NEQ2 ?{ #ffff ,&x STR2 }
35 35
 	[ LIT2 &x 0001 ] ADD2 .dvd/x STZ2
36 36
 	( | y )
37 37
 	.dvd/y LDZ2
38
-	( top ) DUP2 #0000 NEQ2 ?{ #0001 ,&y STR2 }
38
+	( top ) ORAk ?{ #0001 ,&y STR2 }
39 39
 	( bottom ) DUP2 [ LIT2 &hit-ver $2 ] NEQ2 ?{ #ffff ,&y STR2 }
40 40
 	[ LIT2 &y 0001 ] ADD2 .dvd/y STZ2
41 41
 	#01 draw-dvd BRK
... ...
@@ -44,8 +44,7 @@
44 44
 	;dvd-icn .Screen/addr DEO2
45 45
 	.dvd/x LDZ2 .Screen/x DEO2
46 46
 	.dvd/y LDZ2 .Screen/y DEO2
47
-	.Screen/sprite DEOk
48
-	DEO
47
+	.Screen/sprite DEOk DEO
49 48
 	JMP2r
50 49
 
51 50
 @dvd-icn ( 4 x 2 )
... ...
@@ -1,10 +1,6 @@
1 1
 |00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1
2 2
 |20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1
3 3
 
4
-|00
5
-
6
-	@line &x2 $2 &y2 $2
7
-
8 4
 |0100
9 5
 
10 6
 	#6f0b .System/r DEO2
... ...
@@ -22,7 +18,7 @@ BRK
22 18
 @on-frame ( -> )
23 19
 
24 20
 	[ LIT2 &f $2 ] INC2k ,&f STR2
25
-		INC2k d2xy ROT2 d2xy #01 draw-line
21
+		INC2k d2xy ROT2 d2xy #01 <draw-line>
26 22
 
27 23
 BRK
28 24
 
... ...
@@ -65,43 +61,39 @@ JMP2r
65 61
 
66 62
 JMP2r
67 63
 
68
-@draw-line ( x1* y1* x2* y2* color -- )
69
-
70
-	( load )
64
+@<draw-line> ( x1* y1* x2* y2* color -- )
71 65
 	,&color STR
72 66
 	,&y STR2
73 67
 	,&x STR2
74
-	.line/y2 STZ2
75
-	.line/x2 STZ2
76
-
77
-	,&x LDR2 .line/x2 LDZ2 SUB2 abs2 ,&dx STR2
78
-	#0000 ,&y LDR2 .line/y2 LDZ2 SUB2 abs2 SUB2 ,&dy STR2
79
-
80
-	#ffff #00 .line/x2 LDZ2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
81
-	#ffff #00 .line/y2 LDZ2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
82
-
83
-	[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 ,&e1 STR2
84
-
85
-	&loop
86
-		.line/x2 LDZ2 DUP2 .Screen/x DEO2 [ LIT2 &x $2 ] EQU2
87
-		.line/y2 LDZ2 DUP2 .Screen/y DEO2 [ LIT2 &y $2 ] EQU2
88
-			[ LIT2 &color $1 -Screen/pixel ] DEO
89
-			AND ?&end
90
-		[ LIT2 &e1 $2 ] DUP2 ADD2 DUP2
91
-		,&dy LDR2 lts2 ?&skipy
92
-			,&e1 LDR2 ,&dy LDR2 ADD2 ,&e1 STR2
93
-			.line/x2 LDZ2 [ LIT2 &sx $2 ] ADD2 .line/x2 STZ2
94
-		&skipy
95
-		,&dx LDR2 gts2 ?&skipx
96
-			,&e1 LDR2 ,&dx LDR2 ADD2 ,&e1 STR2
97
-			.line/y2 LDZ2 [ LIT2 &sy $2 ] ADD2 .line/y2 STZ2
98
-		&skipx
99
-		!&loop
100
-	&end
101
-
102
-JMP2r
103
-
104
-@abs2 DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 SUB2 JMP2r
105
-@lts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
106
-@gts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
68
+	,&y2 STR2
69
+	,&x2 STR2
70
+	,&x LDR2 ,&x2 LDR2 SUB2 abs2 ,&dx STR2
71
+	#0000 ,&y LDR2 ,&y2 LDR2 SUB2 abs2 SUB2 ,&dy STR2
72
+	#ffff [ LIT2 00 _&x2 ] LDR2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2
73
+	#ffff [ LIT2 00 _&y2 ] LDR2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2
74
+	[ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 STH2
75
+	&while ( -- )
76
+		[ LIT2 &x2 $2 ] DUP2 .Screen/x DEO2
77
+		[ LIT2 &x $2 ] EQU2 [ LIT2 &y2 $2 ] DUP2 .Screen/y DEO2
78
+		[ LIT2 &y $2 ] EQU2 [ LIT2 &color $1 -Screen/pixel ] DEO
79
+		AND ?&end
80
+		STH2kr DUP2 ADD2 DUP2 ,&dy LDR2 lts2 ?&skipy
81
+		STH2r ,&dy LDR2 ADD2 STH2
82
+		,&x2 LDR2 [ LIT2 &sx $2 ] ADD2 ,&x2 STR2
83
+	&skipy ( -- )
84
+		,&dx LDR2 gts2 ?&while
85
+	STH2r ,&dx LDR2 ADD2 STH2
86
+	,&y2 LDR2 [ LIT2 &sy $2 ] ADD2 ,&y2 STR2
87
+	!&while
88
+	&end POP2r JMP2r
89
+
90
+@abs2 ( a* -- f )
91
+	DUP2 #0f SFT2 EQU ?{ #0000 SWP2 SUB2 }
92
+	JMP2r
93
+
94
+@lts2 ( a* b* -- f )
95
+	#8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r
96
+
97
+@gts2 ( a* b* -- f )
98
+	#8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r
107 99
 
... ...
@@ -19,11 +19,12 @@ UxnScreen uxn_screen;
19 19
 
20 20
 /* c = !ch ? (color % 5 ? color >> 2 : 0) : color % 4 + ch == 1 ? 0 : (ch - 2 + (color & 3)) % 3 + 1; */
21 21
 
22
-static Uint8 blending[4][16] = {
22
+static Uint8 blending[][16] = {
23 23
 	{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
24 24
 	{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
25 25
 	{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
26
-	{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}};
26
+	{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
27
+	{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
27 28
 
28 29
 void
29 30
 screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2)
... ...
@@ -58,15 +59,15 @@ screen_rect(Uint8 *layer, Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2, int color)
58 59
 static void
59 60
 screen_2bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
60 61
 {
61
-	int row, w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5);
62
+	int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color];
62 63
 	Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
63 64
 	Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
64 65
 	for(y = y1 + ymod; y != ymax; y += fy) {
65
-		int c = *addr++ | (*(addr + 7) << 8);
66
+		int c = *addr++ | (*(addr + 7) << 8), row = y * w;
66 67
 		if(y < h)
67
-			for(x = x1 + xmod, row = y * w; x != xmax; x -= fx, c >>= 1) {
68
+			for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
68 69
 				Uint8 ch = (c & 1) | ((c >> 7) & 2);
69
-				if((opaque || ch) && x < w)
70
+				if(x < w && (opaque || ch))
70 71
 					layer[x + row] = blending[ch][color];
71 72
 			}
72 73
 	}
... ...
@@ -75,15 +76,15 @@ screen_2bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int f
75 76
 static void
76 77
 screen_1bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
77 78
 {
78
-	int row, w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5);
79
+	int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color];
79 80
 	Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
80 81
 	Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
81 82
 	for(y = y1 + ymod; y != ymax; y += fy) {
82
-		int c = *addr++;
83
+		int c = *addr++, row = y * w;
83 84
 		if(y < h)
84
-			for(x = x1 + xmod, row = y * w; x != xmax; x -= fx, c >>= 1) {
85
+			for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
85 86
 				Uint8 ch = c & 1;
86
-				if((opaque || ch) && x < w)
87
+				if(x < w && (opaque || ch))
87 88
 					layer[x + row] = blending[ch][color];
88 89
 			}
89 90
 	}
... ...
@@ -495,7 +495,7 @@ main(int argc, char **argv)
495 495
 	/* Read flag. Right now, there can be only one. */
496 496
 	if(argv[i][0] == '-') {
497 497
 		if(argv[i][1] == 'v')
498
-			return system_version("Uxnemu - Graphical Varvara Emulator", "18 Nov 2023");
498
+			return system_version("Uxnemu - Graphical Varvara Emulator", "18 Dec 2023");
499 499
 		if(argv[i][1] == '-')
500 500
 			i++;
501 501
 		if(strcmp(argv[i], "-2x") == 0 || strcmp(argv[i], "-3x") == 0)