![]() |
CHGame 0.3.0
Libraries for the CHGame handheld
|
Full-colour procedural frames computed straight into the DMA's buffers, with no framebuffer and no palette. More...
Typedefs | |
| typedef void(* | gfx_streamFn) (uint8_t *dst, int y0, int rows, void *user) |
A direct-streaming callback: fills rows rows starting at row y0 into dst, in the panel's native format. | |
Functions | |
| void | gfx_stream (gfx_streamFn fn, void *user) |
Draws one full-screen frame by calling fn for every chunk of rows and sending the result straight to the panel. | |
| uint8_t | gfx_bytesPerPixel (void) |
| Bytes per pixel a stream callback writes in the current mode. | |
| static uint8_t * | gfx_px565 (uint8_t *p, uint16_t rgb565) |
| Writes one 16 bpp pixel for a stream callback. | |
| static uint8_t * | gfx_px666 (uint8_t *p, uint8_t r6, uint8_t g6, uint8_t b6) |
| Writes one 18 bpp pixel for a stream callback. | |
Full-colour procedural frames computed straight into the DMA's buffers, with no framebuffer and no palette.
The 4 bpp framebuffer exists because 128*128 RGB565 will not fit in 20 KB. But a procedural effect - plasma, tunnel, rotozoomer, fire - does not need a framebuffer at all: it can compute pixels straight into the buffer the DMA is about to send. That gets you the panel's FULL colour depth, 65536 or 262144 colours, with no framebuffer and no palette.
The callback (a gfx_streamFn) is called once per chunk while the previous chunk is still on the wire, so the transfer never stalls as long as you stay inside budget.
The budget, and it is the whole game: 32 CPU cycles per pixel at 16 bpp, 48 at 18 bpp. Stay under it and you render at full wire speed. Go over and the frame rate degrades in proportion - nothing breaks, it just slows. Put your inner loop in SRAM; flash costs 3 wait states here and measured 2.2x slower on exactly this kind of loop.
| typedef void(* gfx_streamFn) (uint8_t *dst, int y0, int rows, void *user) |
A direct-streaming callback: fills rows rows starting at row y0 into dst, in the panel's native format.
dst takes rows * GFX_W * gfx_bytesPerPixel() bytes: GFX_16BPP is 2 bytes/px, RGB565 little-endian (write uint16_t, or gfx_px565()); GFX_18BPP is 3 bytes/px, each component in bits 7:2 (gfx_px666()). user is the pointer given to gfx_stream().
| void gfx_stream | ( | gfx_streamFn | fn, |
| void * | user | ||
| ) |
Draws one full-screen frame by calling fn for every chunk of rows and sending the result straight to the panel.
Blocking: waits for any flush in flight, then returns when the frame has gone out. Requires GFX_16BPP or GFX_18BPP. In 12 bpp the packing is 1.5 bytes per pixel with pixels straddling bytes, which is no use to a per-pixel generator, so gfx_stream() switches to 16 bpp for you (and the mode stays 16 bpp afterwards).
| fn | The callback that fills each chunk. |
| user | Passed to every call of fn (may be nullptr). |
| uint8_t gfx_bytesPerPixel | ( | void | ) |
Bytes per pixel a stream callback writes in the current mode.
|
inlinestatic |
Writes one 16 bpp pixel for a stream callback.
| p | Where to write it. |
| rgb565 | The colour, in RGB565. |
p advanced past the pixel (2 bytes).
|
inlinestatic |
Writes one 18 bpp pixel for a stream callback.
| p | Where to write it. |
| r6 | Red, 0..63. |
| g6 | Green, 0..63. |
| b6 | Blue, 0..63. |
p advanced past the pixel (3 bytes).