Browse code

(Screen) Cache row during sprite drawing

neauoire authored on 13/11/2023 00:46:44
Showing 1 changed files
... ...
@@ -49,43 +49,50 @@ screen_fill(Uint8 *layer, int color)
49 49
 void
50 50
 screen_rect(Uint8 *layer, Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2, int color)
51 51
 {
52
-	int x, y, width = uxn_screen.width, height = uxn_screen.height;
53
-	for(y = y1; y < y2 && y < height; y++)
54
-		for(x = x1; x < x2 && x < width; x++)
55
-			layer[x + y * width] = color;
52
+	int x, y, w, h;
53
+	if(!x1 && !y1) {
54
+		screen_fill(layer, color);
55
+		return;
56
+	}
57
+	w = uxn_screen.width, h = uxn_screen.height;
58
+	for(y = y1; y < y2 && y < h; y++)
59
+		for(x = x1; x < x2 && x < w; x++)
60
+			layer[x + y * w] = color;
56 61
 }
57 62
 
58 63
 static void
59 64
 screen_2bpp(Uint8 *layer, Uint8 *ram, Uint16 addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
60 65
 {
61
-	int width = uxn_screen.width, height = uxn_screen.height, opaque = (color % 5);
66
+	int w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5);
62 67
 	Uint8 *ch1 = &ram[addr], *ch2 = ch1 + 8;
63 68
 	Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
64 69
 	Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
65 70
 	for(y = y1 + ymod; y != ymax; y += fy) {
66
-		Uint16 c = *ch1++ | (*ch2++ << 8);
67
-		for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
68
-			Uint8 ch = (c & 1) | ((c >> 7) & 2);
69
-			if((opaque || ch) && x < width && y < height)
70
-				layer[x + y * width] = blending[ch][color];
71
-		}
71
+		int row = y * w, c = *ch1++ | (*ch2++ << 8);
72
+		if(y < h)
73
+			for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
74
+				Uint8 ch = (c & 1) | ((c >> 7) & 2);
75
+				if((opaque || ch) && x < w)
76
+					layer[x + row] = blending[ch][color];
77
+			}
72 78
 	}
73 79
 }
74 80
 
75 81
 static void
76 82
 screen_1bpp(Uint8 *layer, Uint8 *ram, Uint16 addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy)
77 83
 {
78
-	int width = uxn_screen.width, height = uxn_screen.height, opaque = (color % 5);
84
+	int w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5);
79 85
 	Uint8 *ch1 = &ram[addr];
80 86
 	Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8;
81 87
 	Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8;
82 88
 	for(y = y1 + ymod; y != ymax; y += fy) {
83
-		Uint16 c = *ch1++;
84
-		for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
85
-			Uint8 ch = c & 1;
86
-			if((opaque || ch) && x < width && y < height)
87
-				layer[x + y * width] = blending[ch][color];
88
-		}
89
+		int row = y * w, c = *ch1++;
90
+		if(y < h)
91
+			for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) {
92
+				Uint8 ch = c & 1;
93
+				if((opaque || ch) && x < w)
94
+					layer[x + row] = blending[ch][color];
95
+			}
89 96
 	}
90 97
 }
91 98
 
... ...
@@ -212,29 +219,27 @@ screen_dei(Uxn *u, Uint8 addr)
212 219
 void
213 220
 screen_deo(Uint8 *ram, Uint8 *d, Uint8 port)
214 221
 {
215
-	Uint8 *port_height, *port_x, *port_y, *port_addr;
222
+	Uint8 *port_x, *port_y, *port_addr;
216 223
 	Uint16 x, y, dx, dy, dxy, dyx, addr, addr_incr;
217 224
 	switch(port) {
218 225
 	case 0x3: {
219 226
 		Uint8 *port_width = d + 0x2;
220 227
 		screen_resize(PEEK2(port_width), uxn_screen.height);
221 228
 	} break;
222
-	case 0x5:
223
-		port_height = d + 0x4;
229
+	case 0x5: {
230
+		Uint8 *port_height = d + 0x4;
224 231
 		screen_resize(uxn_screen.width, PEEK2(port_height));
225
-		break;
232
+	} break;
226 233
 	case 0xe: {
227 234
 		Uint8 ctrl = d[0xe];
228 235
 		Uint8 color = ctrl & 0x3;
229 236
 		Uint8 *layer = (ctrl & 0x40) ? uxn_screen.fg : uxn_screen.bg;
230
-		port_x = d + 0x8;
231
-		port_y = d + 0xa;
237
+		port_x = d + 0x8, port_y = d + 0xa;
232 238
 		x = PEEK2(port_x);
233 239
 		y = PEEK2(port_y);
234 240
 		/* fill mode */
235 241
 		if(ctrl & 0x80) {
236
-			Uint16 x2 = uxn_screen.width;
237
-			Uint16 y2 = uxn_screen.height;
242
+			Uint16 x2 = uxn_screen.width, y2 = uxn_screen.height;
238 243
 			if(ctrl & 0x10) x2 = x, x = 0;
239 244
 			if(ctrl & 0x20) y2 = y, y = 0;
240 245
 			screen_rect(layer, x, y, x2, y2, color);
... ...
@@ -242,10 +247,9 @@ screen_deo(Uint8 *ram, Uint8 *d, Uint8 port)
242 247
 		}
243 248
 		/* pixel mode */
244 249
 		else {
245
-			Uint16 width = uxn_screen.width;
246
-			Uint16 height = uxn_screen.height;
247
-			if(x < width && y < height)
248
-				layer[x + y * width] = color;
250
+			Uint16 w = uxn_screen.width, h = uxn_screen.height;
251
+			if(x < w && y < h)
252
+				layer[x + y * w] = color;
249 253
 			screen_change(x, y, x + 1, y + 1);
250 254
 			if(d[0x6] & 0x1) POKE2(port_x, x + 1);
251 255
 			if(d[0x6] & 0x2) POKE2(port_y, y + 1);
... ...
@@ -262,8 +266,7 @@ screen_deo(Uint8 *ram, Uint8 *d, Uint8 port)
262 266
 		Uint8 color = ctrl & 0xf;
263 267
 		int flipx = (ctrl & 0x10), fx = flipx ? -1 : 1;
264 268
 		int flipy = (ctrl & 0x20), fy = flipy ? -1 : 1;
265
-		port_x = d + 0x8;
266
-		port_y = d + 0xa;
269
+		port_x = d + 0x8, port_y = d + 0xa;
267 270
 		port_addr = d + 0xc;
268 271
 		x = PEEK2(port_x), dx = (move & 0x1) << 3, dxy = dx * fy;
269 272
 		y = PEEK2(port_y), dy = (move & 0x2) << 2, dyx = dy * fx;