1 #include <bz/gfx/gfx_platform.h>
3 #include <bz/gfx/gfx_internal.h>
4 #include <bz/math/math.h>
5 #include <bz/renderer/palette_internal.h>
6 #include <bz/renderer/render_pass_internal.h>
8 static void gfxRender(BZRendererPaletteID palette
, uint32_t *output
, size_t width
, size_t height
, size_t pixelWidth
, size_t pixelHeight
);
10 static BZRenderPass renderPass
= {
11 .softwareHook
= gfxRender
,
13 BZRenderPassID bzGFXRenderPass
= &renderPass
;
15 #define bzGenerateColor(r, g, b) ((r)&0xFF) << 0 | ((g)&0xFF) << 8 | ((b)&0xFF) << 16 | (0xFF) << 24
16 uint32_t paletteColors
[] = {
17 /* 00: */ bzGenerateColor(13, 2, 33), // black
18 /* 01: */ bzGenerateColor(36, 23, 52), // grey
19 /* 02: */ bzGenerateColor(46, 33, 86), // grey
20 /* 03: */ bzGenerateColor(45, 226, 230), // white
21 /* 04: */ bzGenerateColor(253, 55, 119), // red
22 /* 05: */ bzGenerateColor(255, 56, 100), // red
23 /* 06: */ bzGenerateColor(255, 67, 101), // orange
24 /* 07: */ bzGenerateColor(255, 108, 17), // orange
25 /* 08: */ bzGenerateColor(181, 181, 40), // yellow
26 /* 09: */ bzGenerateColor(249, 200, 14), // yellow
27 /* 10: */ bzGenerateColor(31, 105, 75), // green
28 /* 11: */ bzGenerateColor(106, 190, 48), // green
29 /* 12: */ bzGenerateColor(48, 96, 130), // blue
30 /* 13: */ bzGenerateColor(99, 155, 255), // blue
31 /* 14: */ bzGenerateColor(118, 66, 138), // purple
32 /* 15: */ bzGenerateColor(246, 1, 157), // purple
35 /* 00: */ bzGenerateColor(0, 0, 0), // black
36 /* 01: */ bzGenerateColor(92, 92, 92), // grey
37 /* 02: */ bzGenerateColor(150, 150, 150), // grey
38 /* 03: */ bzGenerateColor(255, 255, 255), // white
39 /* 04: */ bzGenerateColor(172, 50, 50), // red
40 /* 05: */ bzGenerateColor(217, 87, 99), // red
41 /* 06: */ bzGenerateColor(143, 78, 30), // orange
42 /* 07: */ bzGenerateColor(223, 113, 38), // orange
43 /* 08: */ bzGenerateColor(181, 181, 40), // yellow
44 /* 09: */ bzGenerateColor(251, 242, 54), // yellow
45 /* 10: */ bzGenerateColor(31, 105, 75), // green
46 /* 11: */ bzGenerateColor(106, 190, 48), // green
47 /* 12: */ bzGenerateColor(48, 96, 130), // blue
48 /* 13: */ bzGenerateColor(99, 155, 255), // blue
49 /* 14: */ bzGenerateColor(118, 66, 138), // purple
50 /* 15: */ bzGenerateColor(215, 123, 186), // purple
54 /* 00: */ bzGenerateColor(0, 0, 0),
55 /* 01: */ bzGenerateColor(29, 43, 83),
56 /* 02: */ bzGenerateColor(126, 37, 83),
57 /* 03: */ bzGenerateColor(0, 135, 81),
58 /* 04: */ bzGenerateColor(171, 82, 54),
59 /* 05: */ bzGenerateColor(95, 87, 79),
60 /* 06: */ bzGenerateColor(194, 195, 199),
61 /* 07: */ bzGenerateColor(255, 241, 232),
62 /* 08: */ bzGenerateColor(255, 0, 77),
63 /* 09: */ bzGenerateColor(255, 163, 0),
64 /* 10: */ bzGenerateColor(255, 236, 39),
65 /* 11: */ bzGenerateColor(0, 228, 54),
66 /* 12: */ bzGenerateColor(41, 173, 255),
67 /* 13: */ bzGenerateColor(131, 118, 156),
68 /* 14: */ bzGenerateColor(255, 119, 168),
69 /* 15: */ bzGenerateColor(255, 204, 170),
71 /* 16: */ bzGenerateColor(41,24,20),
72 /* 17: */ bzGenerateColor(17,29,53),
73 /* 18: */ bzGenerateColor(66,33,54),
74 /* 19: */ bzGenerateColor(18,83,89),
75 /* 20: */ bzGenerateColor(116,47,41),
76 /* 21: */ bzGenerateColor(73,51,59),
77 /* 22: */ bzGenerateColor(162,136,121),
78 /* 23: */ bzGenerateColor(243,239,125),
79 /* 24: */ bzGenerateColor(190,18,80),
80 /* 25: */ bzGenerateColor(255,108,36),
81 /* 26: */ bzGenerateColor(168,231,46),
82 /* 27: */ bzGenerateColor(0,181,67),
83 /* 28: */ bzGenerateColor(6,90,181),
84 /* 29: */ bzGenerateColor(117,70,101),
85 /* 30: */ bzGenerateColor(255,110,89),
86 /* 31: */ bzGenerateColor(255,157,129)
90 static void gfxRender(BZRendererPaletteID palette
, uint32_t *output
, size_t width
, size_t height
, size_t pixelWidth
, size_t pixelHeight
) {
93 bzPerfTimerStart("game.blit.transfer");
95 uint32_t *pixels
= output
;
97 for (size_t y
= 0; y
< height
; ++y
) {
98 uint8_t *bufferLine
= &bzGfxCompositedBuffer
[y
<< bufferStrideShift
]; // FIXME, bitshift
99 for (size_t x
= 0; x
< width
; ++x
) {
100 uint8_t c
= bufferLine
[x
];
101 uint32_t out
= palette
->colors
[c
% palette
->numColors
];
102 uint32_t *pixelsOut
= pixels
;
103 for (size_t py
= 0; py
< pixelHeight
; ++py
) {
104 for (size_t px
= 0; px
< pixelWidth
; ++px
) {
108 pixelsOut
+=width
* pixelWidth
- pixelWidth
;
111 pixels
+= pixelWidth
;
113 pixels
+= (pixelHeight
- 1) * width
* pixelWidth
;
116 bzPerfTimerStop("game.blit.transfer");
128 void bzGfxComposite(uint8_t *outputBuffer
) {
129 bzPerfTimerStart("game.blit.composite");
131 size_t canvasMemorySize
= bufferStride
* height
* sizeof(uint8_t);
133 uint8_t *drawBufferReadHead
= drawBuffer
;
134 uint8_t *paletteBufferReadHead
= paletteBuffer
;
135 uint8_t *maskBufferReadHead
= maskBuffer
;
136 uint8_t *overlayBufferReadHead
= overlayBuffer
;
137 uint8_t *outputBufferWriteHead
= outputBuffer
;
138 for (size_t i
= 0; i
< bufferStride
* height
; ++i
) {
139 *outputBufferWriteHead
= palettes
[*paletteBufferReadHead
+ 1][*drawBufferReadHead
];
141 ++drawBufferReadHead
;
142 ++paletteBufferReadHead
;
143 ++maskBufferReadHead
;
144 ++overlayBufferReadHead
;
145 ++outputBufferWriteHead
;
148 bzPerfTimerStop("game.blit.composite");
178 // The real memory seems stupid slow??
180 //#define kScreenMem 3120
181 //static uint32_t *fakeScreen = NULL;//[3120];
183 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
) {
184 // if (fakeScreen == NULL) {
185 // fakeScreen = malloc(kScreenMem * sizeof(uint32_t));
188 // FIXME, this one is very very slow.
190 bzPerfTimerStart("game.blit.composite");
192 uint8_t *p
= &buffer
[0][0][0];
194 for (size_t y
= 0; y
< canvasHeight
; ++y
) {
195 for (size_t x
= 0; x
< canvasWidth
; ++x
) {
196 // bzAssertMessage(buffer[1][y][x] == 1, "Got: %d", buffer[1][y][x]);
198 p
[7] = palettes
[p
[1] + 1][p
[0]];
199 p
+=8*sizeof(uint8_t);
201 // uint8_t cIdx = palettes[buffer[y][x][1] + 1][buffer[y][x][0]]; ////////// (palettes[buffer[y][x][1] + 1][buffer[y][x][0]] & buffer[y][x][2]); // PALETTE, return this (buffer[1][y][x]) + 1
202 // if (buffer[y][x][2] == 0) cIdx = 0;
203 // if (buffer[y][x][3] != 0) cIdx = buffer[y][x][3];
204 // bzBufferSet(7, x, y, cIdx);
206 // if (buffer[2][y][x] == 0) {
209 // if (buffer[3][y][x] > 0) {
210 // cIdx = buffer[3][y][x];
212 // intermediateBuffer[y][x] = cIdx;
213 //intermediateBuffer[y][x] = paletteColors[cIdx];
217 bzPerfTimerStop("game.blit.composite");
219 bzPerfTimerStart("game.blit.transfer");
221 // uint32_t *pixels = output;
222 uint32_t *pixels
= (uint32_t *)output
;//(uint32_t *)output;
225 for (size_t y
= 0; y
< canvasHeight
* pixelHeight
; ++y
) {
231 for (size_t x
= 0; x
< canvasWidth
* pixelWidth
; ) {
233 int target
= bzMin(canvasWidth
* pixelWidth
- x
, 32);
234 for (int i
= 0; i
< target
; ++i
, ++x
) {
235 uint8_t c
= buffer
[ly
/*/ pixelHeight*/][lx
/*/ pixelWidth*/][7];
236 uint8_t patternIdx
= patternLookup
[c
];
237 //bzAssertMessage(patternIdx <= 7, "Pattern index %d at %d,%d %d,%d", patternIdx, x, y, x / pixelWidth, y / pixelHeight);
238 uint8_t bit
= patterns
[patternIdx
][patY
][x
& 0b11 /*% 4*/];
239 value
= (value
<< 1) | bit
;// | patterns[patternIdx][patY][x % 4]; //(patterns[patternIdx][patY][x % 4] * 0b10000000000000000000000000000000);//x % 4 -> patX FIXME
242 // *pixels = swap(value);
243 __asm
volatile ("rev %0, %1" : "=l" (*pixels
) : "l" (value
));
244 pixels
++;// += 4;//sizeof(uint32_t);
246 //pixels += 2; // stride...
249 bzPerfTimerStop("game.blit.transfer");
251 // memcpy(output, fakeScreen, kScreenMem * sizeof(uint32_t));
259 #include <bz/gfx/gfx_internal.h>
261 #include <bz/gfx/font_internal.h>
262 #include <bz/math/math.h>
263 #include <bz/renderer/render_pass_internal.h>
267 // http://members.chello.at/~easyfilter/Bresenham.pdf
269 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
);
271 static BZRenderPass renderPass
= {
272 .softwareHook
= gfxRender
,
274 BZRenderPassID bzGFXRenderPass
= &renderPass
;
276 #define GFX_WIDTH 200 //256 // 128 //320
277 #define GFX_HEIGHT 120 //128 // 128 //180
279 static int currentBuffer
= 0;
280 static uint8_t buffer
[GFX_HEIGHT
][GFX_WIDTH
][8];
281 static int cameraX
= 0;
282 static int cameraY
= 0;
283 static bool fillPattern
[4][4];
285 #define _bzBufferSet(idx, x, y, value) buffer[(y)][(x)][(idx)] = (value)
286 #define _bzBufferSetSafe(idx, x, y, value) { bzAssert(idx>= 0 && idx<8);bzAssertMessage((x)>= 0 && (x)<GFX_WIDTH, "invalid x: %d %s, %d", x, __FILE__, __LINE__);bzAssertMessage((y)>= 0 && (y)<GFX_HEIGHT, "invalid y: %d %s, %d", y, __FILE__, __LINE__);_bzBufferSet(idx, x, y, value); }
288 #define bzBufferSet _bzBufferSet
290 //uint32_t intermediateBuffer[GFX_HEIGHT][GFX_WIDTH];
293 #define SS_HEIGHT 128
295 static uint8_t spritesheet
[SS_HEIGHT
][SS_WIDTH
];
297 static BZFont
*currentFont
;
299 #define bzGenerateColor(r, g, b) (r&0xFF) << 0 | (g&0xFF) << 8 | (b&0xFF) << 16 | (0xFF) << 24
300 uint32_t paletteColors
[] = {
301 bzGenerateColor(0, 0, 0),
302 bzGenerateColor(29, 43, 83),
303 bzGenerateColor(126, 37, 83),
304 bzGenerateColor(0, 135, 81),
305 bzGenerateColor(171, 82, 54),
306 bzGenerateColor(95, 87, 79),
307 bzGenerateColor(194, 195, 199),
308 bzGenerateColor(255, 241, 232),
309 bzGenerateColor(255, 0, 77),
310 bzGenerateColor(255, 163, 0),
311 bzGenerateColor(255, 236, 39),
312 bzGenerateColor(0, 228, 54),
313 bzGenerateColor(41, 173, 255),
314 bzGenerateColor(131, 118, 156),
315 bzGenerateColor(255, 119, 168),
316 bzGenerateColor(255, 204, 170),
318 bzGenerateColor(41,24,20),
319 bzGenerateColor(17,29,53),
320 bzGenerateColor(66,33,54),
321 bzGenerateColor(18,83,89),
322 bzGenerateColor(116,47,41),
323 bzGenerateColor(73,51,59),
324 bzGenerateColor(162,136,121),
325 bzGenerateColor(243,239,125),
326 bzGenerateColor(190,18,80),
327 bzGenerateColor(255,108,36),
328 bzGenerateColor(168,231,46),
329 bzGenerateColor(0,181,67),
330 bzGenerateColor(6,90,181),
331 bzGenerateColor(117,70,101),
332 bzGenerateColor(255,110,89),
333 bzGenerateColor(255,157,129)
336 uint8_t palettes
[16][16] = {
337 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
338 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
339 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
340 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
341 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
342 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
343 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
344 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
347 //BZRect bzCalculateCullRect() {
348 // return bzRectMake(cameraX, cameraY, GFX_WIDTH, SS_HEIGHT);
351 void bzGfxPrepareSpritesheet(size_t width
, size_t height
, void *data
) {
352 uint8_t *imageData
= (uint8_t *)data
;
353 bzLog("Preparing spritesheet %dx%d", width
, height
);
354 //assert(width == 128 && height == 128);
355 for (size_t y
= 0, i
= 0; y
< SS_HEIGHT
; ++y
) {
356 for (size_t x
= 0; x
< SS_WIDTH
; ++x
, ++i
) {
357 spritesheet
[y
][x
] = imageData
[i
];
362 void bzGfxPrepareFont(void *font
) {
366 static bool prepareFrame(int *minXOut
, int *minYOut
, int *maxXOut
, int *maxYOut
, int x0
, int y0
, int x1
, int y1
, int *clippedLeftX
, int *clippedTopY
, int *clippedRightX
, int *clippedBottomY
) {
367 int xMin
= x0
, xMax
= x1
;
368 int yMin
= y0
, yMax
= y1
;
380 int xMinOut
= xMin
- cameraX
, xMaxOut
= xMax
- cameraX
;
381 int yMinOut
= yMin
- cameraY
, yMaxOut
= yMax
- cameraY
;
383 if (xMaxOut
< 0 || yMaxOut
< 0 || xMinOut
>= GFX_WIDTH
|| yMinOut
>= GFX_HEIGHT
) {
387 int safeXMinOut
= bzMax(0, xMinOut
);
388 int safeXMaxOut
= bzMin(GFX_WIDTH
- 1, xMaxOut
);
389 int safeYMinOut
= bzMax(0, yMinOut
);
390 int safeYMaxOut
= bzMin(GFX_HEIGHT
- 1, yMaxOut
);
392 *minXOut
= safeXMinOut
;
393 *minYOut
= safeYMinOut
;
394 *maxXOut
= safeXMaxOut
;
395 *maxYOut
= safeYMaxOut
;
397 if (clippedLeftX
!= NULL
) {
398 *clippedLeftX
= safeXMinOut
- xMinOut
;
399 *clippedTopY
= safeYMinOut
- yMinOut
;
401 *clippedRightX
= xMaxOut
- safeXMaxOut
;
402 *clippedBottomY
= yMaxOut
- safeYMaxOut
;
408 static bool prepareColor(int *colorOut
, int color
) {
409 int c
= (color
<= 15) ? palettes
[0][color
] : color
;
418 void bzPSet(int x
, int y
, int c
) {
421 int ox
= x
- cameraX
;
422 int oy
= y
- cameraY
;
423 if (ox
>= 0 && ox
< GFX_WIDTH
&& oy
>=0 && oy
< GFX_HEIGHT
) {
424 if(fillPattern
[y
%4][x
%4] == false) bzBufferSet(currentBuffer
, ox
, oy
, (c
<= 15) ? palettes
[0][c
] : c
); // FIXME
428 int bzSGet(int x
, int y
) {
429 if (x
>= 0 && x
< SS_WIDTH
&& y
>=0 && y
< SS_HEIGHT
) {
430 return spritesheet
[y
][x
];
436 //void bzSSet(int x, int y, int c);
438 //bool bzFGet(int n, int f);
439 //void bzFSet(int n, int f, bool v);
441 void bzCls(uint8_t c
) {
443 //memset(&buffer[currentBuffer], c, BUFFER_WIDTH * GFX_HEIGHT);
445 // for (size_t i = 0; i < )
447 for (size_t y
= 0; y
< GFX_HEIGHT
; ++y
) {
448 for (size_t x
= 0; x
< GFX_WIDTH
; ++x
) {
449 bzBufferSet(currentBuffer
, x
, y
, c
);
457 void bzGetCamera(int *x
, int *y
) {
458 if (x
!= NULL
) *x
= cameraX
;
459 if (y
!= NULL
) *y
= cameraY
;
462 void bzCamera(int x
, int y
) {
467 void bzCirc(int xm
, int ym
, int r
, int c
) {
468 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
469 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, xm
- r
, ym
- r
, xm
+ r
, ym
+ r
, NULL
, NULL
, NULL
, NULL
)) {
478 bzPSet(xm
-x
, ym
+y
, cOut
);
479 bzPSet(xm
-y
, ym
-x
, cOut
);
480 bzPSet(xm
+x
, ym
-y
, cOut
);
481 bzPSet(xm
+y
, ym
+x
, cOut
);
485 if (r
<= y
) err
+= (++y
<< 1) + 1;
486 if (r
> x
|| err
> y
) err
+= (++x
<< 1) + 1;
491 void bzCircFill(int xm
, int ym
, int r
, int c
) {
492 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
493 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, xm
- r
, ym
- r
, xm
+ r
, ym
+ r
, NULL
, NULL
, NULL
, NULL
)) {
502 int fy1
= ym
- bzAbs(y
);
503 int fy2
= ym
+ bzAbs(y
);
504 int fx
= bzMax(xm
- bzAbs(x
), 0);
505 int tx
= bzMin(xm
+ bzAbs(x
), GFX_WIDTH
- 1); // FIXME, not as many abs
507 bool validFy1
= fy1
>= 0 && fy1
< GFX_HEIGHT
;
508 bool validFy2
= fy2
>= 0 && fy2
< GFX_HEIGHT
;
510 if (validFy1
&& validFy2
) {
511 for (int ox
= fx
; ox
<= tx
; ++ox
) {
512 bzBufferSet(currentBuffer
, ox
, fy1
, cOut
);
513 bzBufferSet(currentBuffer
, ox
, fy2
, cOut
);
515 } else if (validFy1
) {
516 for (int ox
= fx
; ox
<= tx
; ++ox
) {
517 bzBufferSet(currentBuffer
, ox
, fy1
, cOut
);
519 } else if (validFy2
) {
520 for (int ox
= fx
; ox
<= tx
; ++ox
) {
521 bzBufferSet(currentBuffer
, ox
, fy2
, cOut
);
527 if (r
<= y
) err
+= (++y
<< 1) + 1;
528 if (r
> x
|| err
> y
) err
+= (++x
<< 1) + 1;
533 //void bzOval(int x0, int y0, int x1, int y1, int c);
534 //void bzOvalFill(int x0, int y0, int x1, int y1, int c);
536 void bzLine(int x0
, int y0
, int x1
, int y1
, int c
) {
537 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
538 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
544 int deltaX
= bzAbs(x1
- x0
);
545 int deltaY
= -bzAbs(y1
- y0
);
546 int signX
= bzSgn(x1
- x0
);
547 int signY
= bzSgn(y1
- y0
);
548 int err
= deltaX
+ deltaY
;
554 if (x
>= 0 && x
< GFX_WIDTH
&& y
>=0 && y
< GFX_HEIGHT
) { // FIXME, easier way to offset this...
555 bzBufferSet(currentBuffer
, x
, y
, cOut
);
575 void bzRect(int x0
, int y0
, int x1
, int y1
, int c
) {
576 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
577 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
578 if (clipLeft
== 0 && clipRight
== 0) {
579 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
580 bzBufferSet(currentBuffer
, xMinOut
, oy
, cOut
);
581 bzBufferSet(currentBuffer
, xMaxOut
, oy
, cOut
);
583 } else if (clipLeft
== 0) {
584 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
585 bzBufferSet(currentBuffer
, xMinOut
, oy
, cOut
);
587 } else if (clipRight
== 0) {
588 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
589 bzBufferSet(currentBuffer
, xMaxOut
, oy
, cOut
);
593 if (clipTop
== 0 && clipBottom
== 0) {
594 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
595 bzBufferSet(currentBuffer
, ox
, yMinOut
, cOut
);
596 bzBufferSet(currentBuffer
, ox
, yMaxOut
, cOut
);
598 } else if (clipTop
== 0) {
599 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
600 bzBufferSet(currentBuffer
, ox
, yMinOut
, cOut
);
602 } else if (clipBottom
== 0) {
603 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
604 bzBufferSet(currentBuffer
, ox
, yMaxOut
, cOut
);
610 void bzRectFill(int x0
, int y0
, int x1
, int y1
, int c
) {
611 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
612 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, NULL
, NULL
, NULL
, NULL
)) {
613 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
614 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
615 bzBufferSet(currentBuffer
, ox
, oy
, cOut
);
621 void bzSpr(int n
, int x
, int y
) {
622 bzSprExt(n
, x
, y
, 1, 1, false, false);
625 void bzSprExt(int n
, int x
, int y
, int w
, int h
, bool flipX
, bool flipY
) {
626 int px
= (n
% 16) * 8;
627 int py
= (n
/ 16) * 8;
630 bzSSprExt(px
, py
, pw
, ph
, x
, y
, pw
, ph
, flipX
, flipY
);
633 void bzSSpr(int sx
, int sy
, int sw
, int sh
, int dx
, int dy
) {
634 bzSSprExt(sx
, sy
, sw
, sh
, dx
, dy
, sw
, sh
, false, false);
637 void bzSSprExt(int sx
, int sy
, int sw
, int sh
, int dx
, int dy
, int dw
, int dh
, bool flipX
, bool flipY
) {
638 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
639 if (prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, dx
, dy
, dx
+dw
, dy
+dh
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
641 for (size_t y
= 0; y
< sh
- (clipTop
+ clipBottom
); ++y
) {
642 for (size_t x
= 0; x
< sw
- (clipLeft
+ clipRight
); ++x
) {
643 int color
= spritesheet
[clipTop
+sy
+y
][clipLeft
+sx
+x
];
644 if (color
> 0) bzBufferSet(currentBuffer
, xMinOut
+x
, yMinOut
+y
, color
); // FIXME, scaled up and 0 check removal??
669 for (int rY = fromY, wY = dy; rY != toY; rY += dY, ++wY) {
670 for (int rX = fromX, wX = dx; rX != toX; rX += dX, ++wX) {
671 bzPSet(wX, wY, bzSGet(sx + rX, sy + rY));
676 void bzFillP(int p
) {
678 for (int y
= 3; y
>= 0; --y
) {
679 for (int x
= 3; x
>= 0; --x
, f
<<=1) {
680 fillPattern
[y
][x
] = (p
& f
) > 0;
687 void bzPrint(int x
, int y
, int color
, const char *text
) {
688 int currentX
= x
, currentY
= y
;
689 bzGfxRenderFont(bzPSet
, ¤tX
, ¤tY
, currentFont
, color
, text
);
692 void bzSetPaletteColor(int palette
, int colorIdx
, int color
) {
693 palettes
[palette
][colorIdx
] = color
;
696 #define bzGeneratePattern(p11, p12, p13, p14, p21, p22, p23, p24, p31, p32, p33, p34, p41, p42, p43, p44) { {p11, p12, p13, p14}, {p21, p22, p23, p24}, {p31, p32, p33, p34}, {p41, p42, p43, p44} }
698 //(r&0xFF) << 0 | (g&0xFF) << 8 | (b&0xFF) << 16 | (0xFF) << 24
700 int patterns
[8][4][4] = {
701 bzGeneratePattern(0, 0, 0, 0,
705 bzGeneratePattern(1, 0, 0, 0,
709 bzGeneratePattern(0, 0, 0, 0,
713 bzGeneratePattern(0, 1, 0, 1,
717 bzGeneratePattern(0, 0, 0, 0,
721 bzGeneratePattern(0, 1, 0, 1,
725 bzGeneratePattern(1, 1, 1, 1,
731 uint8_t patternLookup
[] = {
773 // The real memory seems stupid slow??
775 //#define kScreenMem 3120
776 //static uint32_t *fakeScreen = NULL;//[3120];
778 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
) {
779 // if (fakeScreen == NULL) {
780 // fakeScreen = malloc(kScreenMem * sizeof(uint32_t));
783 // FIXME, this one is very very slow.
785 bzPerfTimerStart("game.blit.composite");
787 uint8_t *p
= &buffer
[0][0][0];
789 for (size_t y
= 0; y
< GFX_HEIGHT
; ++y
) {
790 for (size_t x
= 0; x
< GFX_WIDTH
; ++x
) {
791 // bzAssertMessage(buffer[1][y][x] == 1, "Got: %d", buffer[1][y][x]);
793 p
[7] = palettes
[p
[1] + 1][p
[0]];
794 p
+=8*sizeof(uint8_t);
796 // uint8_t cIdx = palettes[buffer[y][x][1] + 1][buffer[y][x][0]]; ////////// (palettes[buffer[y][x][1] + 1][buffer[y][x][0]] & buffer[y][x][2]); // PALETTE, return this (buffer[1][y][x]) + 1
797 // if (buffer[y][x][2] == 0) cIdx = 0;
798 // if (buffer[y][x][3] != 0) cIdx = buffer[y][x][3];
799 // bzBufferSet(7, x, y, cIdx);
801 // if (buffer[2][y][x] == 0) {
804 // if (buffer[3][y][x] > 0) {
805 // cIdx = buffer[3][y][x];
807 // intermediateBuffer[y][x] = cIdx;
808 //intermediateBuffer[y][x] = paletteColors[cIdx];
812 bzPerfTimerStop("game.blit.composite");
814 bzPerfTimerStart("game.blit.transfer");
816 // uint32_t *pixels = output;
817 uint32_t *pixels
= (uint32_t *)output
;//(uint32_t *)output;
820 for (size_t y
= 0; y
< GFX_HEIGHT
* pixelHeight
; ++y
) {
826 for (size_t x
= 0; x
< GFX_WIDTH
* pixelWidth
; ) {
828 int target
= bzMin(GFX_WIDTH
* pixelWidth
- x
, 32);
829 for (int i
= 0; i
< target
; ++i
, ++x
) {
830 uint8_t c
= buffer
[ly
/*/ pixelHeight*/][lx
/*/ pixelWidth*/][7];
831 uint8_t patternIdx
= patternLookup
[c
];
832 //bzAssertMessage(patternIdx <= 7, "Pattern index %d at %d,%d %d,%d", patternIdx, x, y, x / pixelWidth, y / pixelHeight);
833 uint8_t bit
= patterns
[patternIdx
][patY
][x
& 0b11 /*% 4*/];
834 value
= (value
<< 1) | bit
;// | patterns[patternIdx][patY][x % 4]; //(patterns[patternIdx][patY][x % 4] * 0b10000000000000000000000000000000);//x % 4 -> patX FIXME
837 // *pixels = swap(value);
838 __asm
volatile ("rev %0, %1" : "=l" (*pixels
) : "l" (value
));
839 pixels
++;// += 4;//sizeof(uint32_t);
841 //pixels += 2; // stride...
844 bzPerfTimerStop("game.blit.transfer");
846 // memcpy(output, fakeScreen, kScreenMem * sizeof(uint32_t));
849 void bzSetOutputBuffer(int idx
) {