1 #include <bz/gfx/gfx_platform.h>
3 #include <bz/gfx/gfx_internal.h>
4 #include <bz/math/math.h>
5 #include <bz/renderer/render_pass_internal.h>
7 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
);
9 static BZRenderPass renderPass
= {
10 .softwareHook
= gfxRender
,
12 BZRenderPassID bzGFXRenderPass
= &renderPass
;
19 #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} }
21 //(r&0xFF) << 0 | (g&0xFF) << 8 | (b&0xFF) << 16 | (0xFF) << 24
23 #define pattern0 0b0000000000000000
24 #define pattern1 0b1000000101000010
25 #define pattern2 0b0000000000000000
26 #define pattern3 0b0101111101011111
27 #define pattern4 0b0000110000000000
28 #define pattern5 0b0101101001011010
29 #define pattern6 0b1111111111111111
30 #define pattern7 0b0000000000000000
32 uint16_t patterns
[] = {
74 #define GFX_HEIGHT 120
76 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
) {
79 //extern uint8_t *bzGfxCompositedBuffer;
82 bzPerfTimerStart("game.blit.transfer");
84 uint32_t *pixels
= output
;
89 for (size_t y
= 0; y
< GFX_HEIGHT
* pixelHeight
; ++y
) {
92 size_t patYShift
= 12-patY
*4;
96 uint8_t *bufferLine
= &bzGfxCompositedBuffer
[(y
>> 1) << bufferStrideShift
]; // FIXME, bitshift
97 for (size_t x
= 0; x
< GFX_WIDTH
<< 1; ) {
99 //int target = bzMin(GFX_WIDTH * pixelWidth - x, 32); // FIXME, slow
100 for (int i
= 0; i
< 32; ++i
, ++x
) {
101 uint8_t c
= bufferLine
[lx
];
102 //uint8_t patternIdx = patternLookup[c];
103 //bzAssertMessage(patternIdx <= 7, "Pattern index %d at %d,%d %d,%d", patternIdx, x, y, x / pixelWidth, y / pixelHeight);
104 uint8_t bit
= (patterns
[c
] >> patYShift
>> (3-(x
& 0b11)))&1;
106 //[patternIdx][patY][x & 0b11 /*% 4*/];
107 value
= (value
<< 1) | bit
;// | patterns[patternIdx][patY][x % 4]; //(patterns[patternIdx][patY][x % 4] * 0b10000000000000000000000000000000);//x % 4 -> patX FIXME
110 __asm
volatile ("rev %0, %1" : "=l" (*pixels
) : "l" (value
));
115 bzPerfTimerStop("game.blit.transfer");
127 void bzGfxComposite(uint8_t *outputBuffer
) {
128 bzPerfTimerStart("game.blit.composite");
130 size_t canvasMemorySize
= bufferStride
* height
* sizeof(uint8_t);
132 uint8_t *drawBufferReadHead
= drawBuffer
;
133 uint8_t *paletteBufferReadHead
= paletteBuffer
;
134 uint8_t *maskBufferReadHead
= maskBuffer
;
135 uint8_t *overlayBufferReadHead
= overlayBuffer
;
136 uint8_t *outputBufferWriteHead
= outputBuffer
;
137 for (size_t i
= 0; i
< bufferStride
* height
; ++i
) {
138 *outputBufferWriteHead
= palettes
[*paletteBufferReadHead
+ 1][*drawBufferReadHead
];
140 ++drawBufferReadHead
;
141 ++paletteBufferReadHead
;
142 ++maskBufferReadHead
;
143 ++overlayBufferReadHead
;
144 ++outputBufferWriteHead
;
147 bzPerfTimerStop("game.blit.composite");
177 // The real memory seems stupid slow??
179 //#define kScreenMem 3120
180 //static uint32_t *fakeScreen = NULL;//[3120];
182 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
) {
183 // if (fakeScreen == NULL) {
184 // fakeScreen = malloc(kScreenMem * sizeof(uint32_t));
187 // FIXME, this one is very very slow.
189 bzPerfTimerStart("game.blit.composite");
191 uint8_t *p
= &buffer
[0][0][0];
193 for (size_t y
= 0; y
< canvasHeight
; ++y
) {
194 for (size_t x
= 0; x
< canvasWidth
; ++x
) {
195 // bzAssertMessage(buffer[1][y][x] == 1, "Got: %d", buffer[1][y][x]);
197 p
[7] = palettes
[p
[1] + 1][p
[0]];
198 p
+=8*sizeof(uint8_t);
200 // 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
201 // if (buffer[y][x][2] == 0) cIdx = 0;
202 // if (buffer[y][x][3] != 0) cIdx = buffer[y][x][3];
203 // bzBufferSet(7, x, y, cIdx);
205 // if (buffer[2][y][x] == 0) {
208 // if (buffer[3][y][x] > 0) {
209 // cIdx = buffer[3][y][x];
211 // intermediateBuffer[y][x] = cIdx;
212 //intermediateBuffer[y][x] = paletteColors[cIdx];
216 bzPerfTimerStop("game.blit.composite");
218 bzPerfTimerStart("game.blit.transfer");
220 // uint32_t *pixels = output;
221 uint32_t *pixels
= (uint32_t *)output
;//(uint32_t *)output;
224 for (size_t y
= 0; y
< canvasHeight
* pixelHeight
; ++y
) {
230 for (size_t x
= 0; x
< canvasWidth
* pixelWidth
; ) {
232 int target
= bzMin(canvasWidth
* pixelWidth
- x
, 32);
233 for (int i
= 0; i
< target
; ++i
, ++x
) {
234 uint8_t c
= buffer
[ly
/*/ pixelHeight*/][lx
/*/ pixelWidth*/][7];
235 uint8_t patternIdx
= patternLookup
[c
];
236 //bzAssertMessage(patternIdx <= 7, "Pattern index %d at %d,%d %d,%d", patternIdx, x, y, x / pixelWidth, y / pixelHeight);
237 uint8_t bit
= patterns
[patternIdx
][patY
][x
& 0b11 /*% 4*/];
238 value
= (value
<< 1) | bit
;// | patterns[patternIdx][patY][x % 4]; //(patterns[patternIdx][patY][x % 4] * 0b10000000000000000000000000000000);//x % 4 -> patX FIXME
241 // *pixels = swap(value);
242 __asm
volatile ("rev %0, %1" : "=l" (*pixels
) : "l" (value
));
243 pixels
++;// += 4;//sizeof(uint32_t);
245 //pixels += 2; // stride...
248 bzPerfTimerStop("game.blit.transfer");
250 // memcpy(output, fakeScreen, kScreenMem * sizeof(uint32_t));
258 #include <bz/gfx/gfx_internal.h>
260 #include <bz/gfx/font_internal.h>
261 #include <bz/math/math.h>
262 #include <bz/renderer/render_pass_internal.h>
266 // http://members.chello.at/~easyfilter/Bresenham.pdf
268 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
);
270 static BZRenderPass renderPass
= {
271 .softwareHook
= gfxRender
,
273 BZRenderPassID bzGFXRenderPass
= &renderPass
;
275 #define GFX_WIDTH 200 //256 // 128 //320
276 #define GFX_HEIGHT 120 //128 // 128 //180
278 static int currentBuffer
= 0;
279 static uint8_t buffer
[GFX_HEIGHT
][GFX_WIDTH
][8];
280 static int cameraX
= 0;
281 static int cameraY
= 0;
282 static bool fillPattern
[4][4];
284 #define _bzBufferSet(idx, x, y, value) buffer[(y)][(x)][(idx)] = (value)
285 #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); }
287 #define bzBufferSet _bzBufferSet
289 //uint32_t intermediateBuffer[GFX_HEIGHT][GFX_WIDTH];
292 #define SS_HEIGHT 128
294 static uint8_t spritesheet
[SS_HEIGHT
][SS_WIDTH
];
296 static BZFont
*currentFont
;
298 #define bzGenerateColor(r, g, b) (r&0xFF) << 0 | (g&0xFF) << 8 | (b&0xFF) << 16 | (0xFF) << 24
299 uint32_t paletteColors
[] = {
300 bzGenerateColor(0, 0, 0),
301 bzGenerateColor(29, 43, 83),
302 bzGenerateColor(126, 37, 83),
303 bzGenerateColor(0, 135, 81),
304 bzGenerateColor(171, 82, 54),
305 bzGenerateColor(95, 87, 79),
306 bzGenerateColor(194, 195, 199),
307 bzGenerateColor(255, 241, 232),
308 bzGenerateColor(255, 0, 77),
309 bzGenerateColor(255, 163, 0),
310 bzGenerateColor(255, 236, 39),
311 bzGenerateColor(0, 228, 54),
312 bzGenerateColor(41, 173, 255),
313 bzGenerateColor(131, 118, 156),
314 bzGenerateColor(255, 119, 168),
315 bzGenerateColor(255, 204, 170),
317 bzGenerateColor(41,24,20),
318 bzGenerateColor(17,29,53),
319 bzGenerateColor(66,33,54),
320 bzGenerateColor(18,83,89),
321 bzGenerateColor(116,47,41),
322 bzGenerateColor(73,51,59),
323 bzGenerateColor(162,136,121),
324 bzGenerateColor(243,239,125),
325 bzGenerateColor(190,18,80),
326 bzGenerateColor(255,108,36),
327 bzGenerateColor(168,231,46),
328 bzGenerateColor(0,181,67),
329 bzGenerateColor(6,90,181),
330 bzGenerateColor(117,70,101),
331 bzGenerateColor(255,110,89),
332 bzGenerateColor(255,157,129)
335 uint8_t palettes
[16][16] = {
336 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
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},
346 //BZRect bzCalculateCullRect() {
347 // return bzRectMake(cameraX, cameraY, GFX_WIDTH, SS_HEIGHT);
350 void bzGfxPrepareSpritesheet(size_t width
, size_t height
, void *data
) {
351 uint8_t *imageData
= (uint8_t *)data
;
352 bzLog("Preparing spritesheet %dx%d", width
, height
);
353 //assert(width == 128 && height == 128);
354 for (size_t y
= 0, i
= 0; y
< SS_HEIGHT
; ++y
) {
355 for (size_t x
= 0; x
< SS_WIDTH
; ++x
, ++i
) {
356 spritesheet
[y
][x
] = imageData
[i
];
361 void bzGfxPrepareFont(void *font
) {
365 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
) {
366 int xMin
= x0
, xMax
= x1
;
367 int yMin
= y0
, yMax
= y1
;
379 int xMinOut
= xMin
- cameraX
, xMaxOut
= xMax
- cameraX
;
380 int yMinOut
= yMin
- cameraY
, yMaxOut
= yMax
- cameraY
;
382 if (xMaxOut
< 0 || yMaxOut
< 0 || xMinOut
>= GFX_WIDTH
|| yMinOut
>= GFX_HEIGHT
) {
386 int safeXMinOut
= bzMax(0, xMinOut
);
387 int safeXMaxOut
= bzMin(GFX_WIDTH
- 1, xMaxOut
);
388 int safeYMinOut
= bzMax(0, yMinOut
);
389 int safeYMaxOut
= bzMin(GFX_HEIGHT
- 1, yMaxOut
);
391 *minXOut
= safeXMinOut
;
392 *minYOut
= safeYMinOut
;
393 *maxXOut
= safeXMaxOut
;
394 *maxYOut
= safeYMaxOut
;
396 if (clippedLeftX
!= NULL
) {
397 *clippedLeftX
= safeXMinOut
- xMinOut
;
398 *clippedTopY
= safeYMinOut
- yMinOut
;
400 *clippedRightX
= xMaxOut
- safeXMaxOut
;
401 *clippedBottomY
= yMaxOut
- safeYMaxOut
;
407 static bool prepareColor(int *colorOut
, int color
) {
408 int c
= (color
<= 15) ? palettes
[0][color
] : color
;
417 void bzPSet(int x
, int y
, int c
) {
420 int ox
= x
- cameraX
;
421 int oy
= y
- cameraY
;
422 if (ox
>= 0 && ox
< GFX_WIDTH
&& oy
>=0 && oy
< GFX_HEIGHT
) {
423 if(fillPattern
[y
%4][x
%4] == false) bzBufferSet(currentBuffer
, ox
, oy
, (c
<= 15) ? palettes
[0][c
] : c
); // FIXME
427 int bzSGet(int x
, int y
) {
428 if (x
>= 0 && x
< SS_WIDTH
&& y
>=0 && y
< SS_HEIGHT
) {
429 return spritesheet
[y
][x
];
435 //void bzSSet(int x, int y, int c);
437 //bool bzFGet(int n, int f);
438 //void bzFSet(int n, int f, bool v);
440 void bzCls(uint8_t c
) {
442 //memset(&buffer[currentBuffer], c, BUFFER_WIDTH * GFX_HEIGHT);
444 // for (size_t i = 0; i < )
446 for (size_t y
= 0; y
< GFX_HEIGHT
; ++y
) {
447 for (size_t x
= 0; x
< GFX_WIDTH
; ++x
) {
448 bzBufferSet(currentBuffer
, x
, y
, c
);
456 void bzGetCamera(int *x
, int *y
) {
457 if (x
!= NULL
) *x
= cameraX
;
458 if (y
!= NULL
) *y
= cameraY
;
461 void bzCamera(int x
, int y
) {
466 void bzCirc(int xm
, int ym
, int r
, int c
) {
467 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
468 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, xm
- r
, ym
- r
, xm
+ r
, ym
+ r
, NULL
, NULL
, NULL
, NULL
)) {
477 bzPSet(xm
-x
, ym
+y
, cOut
);
478 bzPSet(xm
-y
, ym
-x
, cOut
);
479 bzPSet(xm
+x
, ym
-y
, cOut
);
480 bzPSet(xm
+y
, ym
+x
, cOut
);
484 if (r
<= y
) err
+= (++y
<< 1) + 1;
485 if (r
> x
|| err
> y
) err
+= (++x
<< 1) + 1;
490 void bzCircFill(int xm
, int ym
, int r
, int c
) {
491 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
492 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, xm
- r
, ym
- r
, xm
+ r
, ym
+ r
, NULL
, NULL
, NULL
, NULL
)) {
501 int fy1
= ym
- bzAbs(y
);
502 int fy2
= ym
+ bzAbs(y
);
503 int fx
= bzMax(xm
- bzAbs(x
), 0);
504 int tx
= bzMin(xm
+ bzAbs(x
), GFX_WIDTH
- 1); // FIXME, not as many abs
506 bool validFy1
= fy1
>= 0 && fy1
< GFX_HEIGHT
;
507 bool validFy2
= fy2
>= 0 && fy2
< GFX_HEIGHT
;
509 if (validFy1
&& validFy2
) {
510 for (int ox
= fx
; ox
<= tx
; ++ox
) {
511 bzBufferSet(currentBuffer
, ox
, fy1
, cOut
);
512 bzBufferSet(currentBuffer
, ox
, fy2
, cOut
);
514 } else if (validFy1
) {
515 for (int ox
= fx
; ox
<= tx
; ++ox
) {
516 bzBufferSet(currentBuffer
, ox
, fy1
, cOut
);
518 } else if (validFy2
) {
519 for (int ox
= fx
; ox
<= tx
; ++ox
) {
520 bzBufferSet(currentBuffer
, ox
, fy2
, cOut
);
526 if (r
<= y
) err
+= (++y
<< 1) + 1;
527 if (r
> x
|| err
> y
) err
+= (++x
<< 1) + 1;
532 //void bzOval(int x0, int y0, int x1, int y1, int c);
533 //void bzOvalFill(int x0, int y0, int x1, int y1, int c);
535 void bzLine(int x0
, int y0
, int x1
, int y1
, int c
) {
536 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
537 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
543 int deltaX
= bzAbs(x1
- x0
);
544 int deltaY
= -bzAbs(y1
- y0
);
545 int signX
= bzSgn(x1
- x0
);
546 int signY
= bzSgn(y1
- y0
);
547 int err
= deltaX
+ deltaY
;
553 if (x
>= 0 && x
< GFX_WIDTH
&& y
>=0 && y
< GFX_HEIGHT
) { // FIXME, easier way to offset this...
554 bzBufferSet(currentBuffer
, x
, y
, cOut
);
574 void bzRect(int x0
, int y0
, int x1
, int y1
, int c
) {
575 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
576 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
577 if (clipLeft
== 0 && clipRight
== 0) {
578 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
579 bzBufferSet(currentBuffer
, xMinOut
, oy
, cOut
);
580 bzBufferSet(currentBuffer
, xMaxOut
, oy
, cOut
);
582 } else if (clipLeft
== 0) {
583 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
584 bzBufferSet(currentBuffer
, xMinOut
, oy
, cOut
);
586 } else if (clipRight
== 0) {
587 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
588 bzBufferSet(currentBuffer
, xMaxOut
, oy
, cOut
);
592 if (clipTop
== 0 && clipBottom
== 0) {
593 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
594 bzBufferSet(currentBuffer
, ox
, yMinOut
, cOut
);
595 bzBufferSet(currentBuffer
, ox
, yMaxOut
, cOut
);
597 } else if (clipTop
== 0) {
598 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
599 bzBufferSet(currentBuffer
, ox
, yMinOut
, cOut
);
601 } else if (clipBottom
== 0) {
602 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
603 bzBufferSet(currentBuffer
, ox
, yMaxOut
, cOut
);
609 void bzRectFill(int x0
, int y0
, int x1
, int y1
, int c
) {
610 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, cOut
;
611 if (prepareColor(&cOut
, c
) && prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, x0
, y0
, x1
, y1
, NULL
, NULL
, NULL
, NULL
)) {
612 for (int oy
= yMinOut
; oy
<= yMaxOut
; ++oy
) {
613 for (int ox
= xMinOut
; ox
<= xMaxOut
; ++ox
) {
614 bzBufferSet(currentBuffer
, ox
, oy
, cOut
);
620 void bzSpr(int n
, int x
, int y
) {
621 bzSprExt(n
, x
, y
, 1, 1, false, false);
624 void bzSprExt(int n
, int x
, int y
, int w
, int h
, bool flipX
, bool flipY
) {
625 int px
= (n
% 16) * 8;
626 int py
= (n
/ 16) * 8;
629 bzSSprExt(px
, py
, pw
, ph
, x
, y
, pw
, ph
, flipX
, flipY
);
632 void bzSSpr(int sx
, int sy
, int sw
, int sh
, int dx
, int dy
) {
633 bzSSprExt(sx
, sy
, sw
, sh
, dx
, dy
, sw
, sh
, false, false);
636 void bzSSprExt(int sx
, int sy
, int sw
, int sh
, int dx
, int dy
, int dw
, int dh
, bool flipX
, bool flipY
) {
637 int xMinOut
, yMinOut
, xMaxOut
, yMaxOut
, clipLeft
, clipTop
, clipRight
, clipBottom
;
638 if (prepareFrame(&xMinOut
, &yMinOut
, &xMaxOut
, &yMaxOut
, dx
, dy
, dx
+dw
, dy
+dh
, &clipLeft
, &clipTop
, &clipRight
, &clipBottom
)) {
640 for (size_t y
= 0; y
< sh
- (clipTop
+ clipBottom
); ++y
) {
641 for (size_t x
= 0; x
< sw
- (clipLeft
+ clipRight
); ++x
) {
642 int color
= spritesheet
[clipTop
+sy
+y
][clipLeft
+sx
+x
];
643 if (color
> 0) bzBufferSet(currentBuffer
, xMinOut
+x
, yMinOut
+y
, color
); // FIXME, scaled up and 0 check removal??
668 for (int rY = fromY, wY = dy; rY != toY; rY += dY, ++wY) {
669 for (int rX = fromX, wX = dx; rX != toX; rX += dX, ++wX) {
670 bzPSet(wX, wY, bzSGet(sx + rX, sy + rY));
675 void bzFillP(int p
) {
677 for (int y
= 3; y
>= 0; --y
) {
678 for (int x
= 3; x
>= 0; --x
, f
<<=1) {
679 fillPattern
[y
][x
] = (p
& f
) > 0;
686 void bzPrint(int x
, int y
, int color
, const char *text
) {
687 int currentX
= x
, currentY
= y
;
688 bzGfxRenderFont(bzPSet
, ¤tX
, ¤tY
, currentFont
, color
, text
);
691 void bzSetPaletteColor(int palette
, int colorIdx
, int color
) {
692 palettes
[palette
][colorIdx
] = color
;
695 #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} }
697 //(r&0xFF) << 0 | (g&0xFF) << 8 | (b&0xFF) << 16 | (0xFF) << 24
699 int patterns
[8][4][4] = {
700 bzGeneratePattern(0, 0, 0, 0,
704 bzGeneratePattern(1, 0, 0, 0,
708 bzGeneratePattern(0, 0, 0, 0,
712 bzGeneratePattern(0, 1, 0, 1,
716 bzGeneratePattern(0, 0, 0, 0,
720 bzGeneratePattern(0, 1, 0, 1,
724 bzGeneratePattern(1, 1, 1, 1,
730 uint8_t patternLookup
[] = {
772 // The real memory seems stupid slow??
774 //#define kScreenMem 3120
775 //static uint32_t *fakeScreen = NULL;//[3120];
777 static void gfxRender(uint32_t *output
, size_t pixelWidth
, size_t pixelHeight
) {
778 // if (fakeScreen == NULL) {
779 // fakeScreen = malloc(kScreenMem * sizeof(uint32_t));
782 // FIXME, this one is very very slow.
784 bzPerfTimerStart("game.blit.composite");
786 uint8_t *p
= &buffer
[0][0][0];
788 for (size_t y
= 0; y
< GFX_HEIGHT
; ++y
) {
789 for (size_t x
= 0; x
< GFX_WIDTH
; ++x
) {
790 // bzAssertMessage(buffer[1][y][x] == 1, "Got: %d", buffer[1][y][x]);
792 p
[7] = palettes
[p
[1] + 1][p
[0]];
793 p
+=8*sizeof(uint8_t);
795 // 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
796 // if (buffer[y][x][2] == 0) cIdx = 0;
797 // if (buffer[y][x][3] != 0) cIdx = buffer[y][x][3];
798 // bzBufferSet(7, x, y, cIdx);
800 // if (buffer[2][y][x] == 0) {
803 // if (buffer[3][y][x] > 0) {
804 // cIdx = buffer[3][y][x];
806 // intermediateBuffer[y][x] = cIdx;
807 //intermediateBuffer[y][x] = paletteColors[cIdx];
811 bzPerfTimerStop("game.blit.composite");
813 bzPerfTimerStart("game.blit.transfer");
815 // uint32_t *pixels = output;
816 uint32_t *pixels
= (uint32_t *)output
;//(uint32_t *)output;
819 for (size_t y
= 0; y
< GFX_HEIGHT
* pixelHeight
; ++y
) {
825 for (size_t x
= 0; x
< GFX_WIDTH
* pixelWidth
; ) {
827 int target
= bzMin(GFX_WIDTH
* pixelWidth
- x
, 32);
828 for (int i
= 0; i
< target
; ++i
, ++x
) {
829 uint8_t c
= buffer
[ly
/*/ pixelHeight*/][lx
/*/ pixelWidth*/][7];
830 uint8_t patternIdx
= patternLookup
[c
];
831 //bzAssertMessage(patternIdx <= 7, "Pattern index %d at %d,%d %d,%d", patternIdx, x, y, x / pixelWidth, y / pixelHeight);
832 uint8_t bit
= patterns
[patternIdx
][patY
][x
& 0b11 /*% 4*/];
833 value
= (value
<< 1) | bit
;// | patterns[patternIdx][patY][x % 4]; //(patterns[patternIdx][patY][x % 4] * 0b10000000000000000000000000000000);//x % 4 -> patX FIXME
836 // *pixels = swap(value);
837 __asm
volatile ("rev %0, %1" : "=l" (*pixels
) : "l" (value
));
838 pixels
++;// += 4;//sizeof(uint32_t);
840 //pixels += 2; // stride...
843 bzPerfTimerStop("game.blit.transfer");
845 // memcpy(output, fakeScreen, kScreenMem * sizeof(uint32_t));
848 void bzSetOutputBuffer(int idx
) {