From 7729d276a6d2658df0c59b6995e112962440d017 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Mon, 1 May 2023 23:26:48 +0200 Subject: [PATCH] Allow `const` source buffers when drawing This is one step towards allowing `constexpr buffer_t`s, saving some RAM and probably compiling a little more optimally. --- libraries/blend.cpp | 20 ++++++++++---------- libraries/picosystem.cpp | 10 +++++----- libraries/picosystem.hpp | 41 ++++++++++++++++++++++------------------ libraries/primitives.cpp | 8 ++++---- libraries/state.cpp | 2 +- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/libraries/blend.cpp b/libraries/blend.cpp index e8040e3..df97179 100644 --- a/libraries/blend.cpp +++ b/libraries/blend.cpp @@ -50,7 +50,7 @@ namespace picosystem { // blend mode functions // blends the source and destination - void ALPHA(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void ALPHA(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { uint32_t s = _unpack_channels(*(ps + (so >> 16))); uint8_t alpha = _extract_alpha(s); @@ -69,7 +69,7 @@ namespace picosystem { } // copy the source over the destination, ignoring alpha channel - void COPY(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void COPY(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { if(!ss) { // optimised for no source step if(uintptr_t(pd) & 0b11 && c) { *pd++ = *ps; c--; } // align to 32bits @@ -87,7 +87,7 @@ namespace picosystem { // copy the source over the destination if source alpha is != 0 // allows for faster blitting of sprites that only need 1-bit alpha - void MASK(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void MASK(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); @@ -101,7 +101,7 @@ namespace picosystem { // uses ALPHA blend but forces pen (even if we're doing a blit) which can // be useful for masking sprites etc - void PEN(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void PEN(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { color_t p = _pen; uint8_t pa = (p & 0x00f0) >> 4; @@ -127,7 +127,7 @@ namespace picosystem { // compares source and destination RGB channels and picks the darker of the // two. if there is global alpha the result is then blended with the // destination. - void DARKEN(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void DARKEN(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); color_t d = *pd; @@ -147,7 +147,7 @@ namespace picosystem { // compares source and destination RGB channels and picks the lighter of the // two. if there is global alpha the result is then blended with the // destination. - void LIGHTEN(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void LIGHTEN(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); color_t d = *pd; @@ -167,7 +167,7 @@ namespace picosystem { // compares source and destination RGB channels and picks the lighter of the // two. if there is global alpha the result is then blended with the // destination. - void ADD(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void ADD(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); color_t d = *pd; @@ -196,7 +196,7 @@ namespace picosystem { // compares source and destination RGB channels and picks the lighter of the // two. if there is global alpha the result is then blended with the // destination. - void SUBTRACT(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void SUBTRACT(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); color_t d = *pd; @@ -220,7 +220,7 @@ namespace picosystem { // compares source and destination RGB channels and picks the lighter of the // two. if there is global alpha the result is then blended with the // destination. - void MULTIPLY(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void MULTIPLY(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); color_t d = *pd; @@ -250,7 +250,7 @@ namespace picosystem { } // performs a "fizzlefade" style effect by only copying the source pixel if // the destination pointer address hashes to a value < source alpha - void DISSOLVE(color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { + void DISSOLVE(const color_t *ps, int32_t so, int32_t ss, color_t *pd, uint32_t c) { while(c--) { color_t s = *(ps + (so >> 16)); diff --git a/libraries/picosystem.cpp b/libraries/picosystem.cpp index 1558bde..1aa8f9b 100644 --- a/libraries/picosystem.cpp +++ b/libraries/picosystem.cpp @@ -39,16 +39,16 @@ namespace picosystem { buffer_t *_dt = SCREEN; #ifdef NO_SPRITESHEET - buffer_t *_ss = nullptr; + const buffer_t *_ss = nullptr; #else - buffer_t *SPRITESHEET = buffer(128, 128, (void *)_default_sprite_sheet); - buffer_t *_ss = SPRITESHEET; + const buffer_t *SPRITESHEET = buffer(128, 128, (void *)_default_sprite_sheet); + const buffer_t *_ss = SPRITESHEET; #endif #ifdef NO_FONT - uint8_t *_font = nullptr; + const uint8_t *_font = nullptr; #else - uint8_t *_font = (uint8_t *)&_default_font[0][0]; + const uint8_t *_font = (uint8_t *)&_default_font[0][0]; #endif } diff --git a/libraries/picosystem.hpp b/libraries/picosystem.hpp index c0cbf05..be82f72 100644 --- a/libraries/picosystem.hpp +++ b/libraries/picosystem.hpp @@ -40,6 +40,10 @@ namespace picosystem { return data + (x + y * w); } + const color_t *p(int32_t x, int32_t y) const { + return data + (x + y * w); + } + ~buffer_t() { if (alloc) delete data; } @@ -57,8 +61,8 @@ namespace picosystem { constexpr uint32_t VFLIP = 0x02; using blend_func_t = - void(*)(color_t* source, int32_t so, int32_t ss, - color_t* dest, uint32_t count); + void(*)(const color_t* source, int32_t so, int32_t ss, + color_t* dest, uint32_t count); // drawing state extern color_t _pen; // pen @@ -72,9 +76,10 @@ namespace picosystem { extern blend_func_t _bf; // blend function extern buffer_t * SCREEN; // framebuffer extern buffer_t *_dt; // drawing target - extern buffer_t * SPRITESHEET; // inbuilt spritesheet - extern buffer_t *_ss; // sprite sheet - extern uint8_t *_font; // font data + + extern const buffer_t * SPRITESHEET; // inbuilt spritesheet + extern const buffer_t *_ss; // sprite sheet + extern const uint8_t *_font; // font data // audio state extern voice_t _v; // current voice @@ -99,7 +104,7 @@ namespace picosystem { void camera(); void camera(int32_t x, int32_t y); void spritesheet(); - void spritesheet(buffer_t *ss); + void spritesheet(const buffer_t *ss); void cursor(); void cursor(int32_t x, int32_t y); void font( @@ -123,12 +128,12 @@ namespace picosystem { void fellipse(int32_t x, int32_t y, int32_t rx, int32_t ry); void line(int32_t x1, int32_t y1, int32_t x2, int32_t y2); void blit( - buffer_t *source, + const buffer_t *source, int32_t x, int32_t y, int32_t w, int32_t h, int32_t dx, int32_t dy, uint32_t flags = 0); void blit( - buffer_t *source, + const buffer_t *source, int32_t sx, int32_t sy, int32_t sw, int32_t sh, int32_t dx, int32_t dy, int32_t dw, int32_t dh, uint32_t flags = 0); @@ -153,25 +158,25 @@ namespace picosystem { // blend functions void COPY( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void ALPHA( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void MASK( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void PEN( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void DARKEN( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void LIGHTEN( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void ADD( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void SUBTRACT( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void MULTIPLY( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); void DISSOLVE( - color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); + const color_t* ps, int32_t so, int32_t ss, color_t* pd, uint32_t c); // audio voice_t voice( diff --git a/libraries/primitives.cpp b/libraries/primitives.cpp index c1f8051..39480ae 100644 --- a/libraries/primitives.cpp +++ b/libraries/primitives.cpp @@ -290,7 +290,7 @@ namespace picosystem { poly(pts.begin(), pts.size() / 2); } - void blit(buffer_t *src, int32_t sx, int32_t sy, int32_t w, int32_t h, int32_t dx, int32_t dy, uint32_t flags) { + void blit(const buffer_t *src, int32_t sx, int32_t sy, int32_t w, int32_t h, int32_t dx, int32_t dy, uint32_t flags) { _camera_offset(dx, dy); if(!intersects(dx, dy, w, h, _cx, _cy, _cw, _ch)) { @@ -313,7 +313,7 @@ namespace picosystem { return; } - color_t *ps = src->data + (sx + sy * src->w); + const color_t *ps = src->data + (sx + sy * src->w); color_t *pd = _dt->data + (dx + dy * _dt->w); int32_t so = 0; @@ -338,7 +338,7 @@ namespace picosystem { } } - void blit(buffer_t *src, int32_t sx, int32_t sy, int32_t sw, int32_t sh, int32_t dx, int32_t dy, int32_t dw, int32_t dh, uint32_t flags) { + void blit(const buffer_t *src, int32_t sx, int32_t sy, int32_t sw, int32_t sh, int32_t dx, int32_t dy, int32_t dw, int32_t dh, uint32_t flags) { _camera_offset(dx, dy); if(!intersects(dx, dy, dw, dh, _cx, _cy, _cw, _ch)) { @@ -350,7 +350,7 @@ namespace picosystem { int32_t ssx = 0, ssxs = (sw << 16) / dw; color_t *pd = _dt->p(dx, dy); - color_t *ps = src->p(sx, sy); + const color_t *ps = src->p(sx, sy); // if we need to offset our start to the clip area then we need to jump // ahead in the source diff --git a/libraries/state.cpp b/libraries/state.cpp index aa4b64e..185b368 100644 --- a/libraries/state.cpp +++ b/libraries/state.cpp @@ -84,7 +84,7 @@ namespace picosystem { _ss = SPRITESHEET; } - void spritesheet(buffer_t *ss) { + void spritesheet(const buffer_t *ss) { _ss = ss; }