28PICO9918_PALETTE_LUT_T __aligned(4) pico9918_palette_lut[256];
30#if !PICO9918_SINGLE_INSTANCE
31const pico9918_t* pico9918_palette_owner = 0;
37typedef uint32_t PICO9918_MAY_ALIAS pico9918_aliasing_u32_t;
38_Static_assert(_Alignof(pico9918_t) >= 4,
"palette LUT build requires word alignment");
39_Static_assert(offsetof(pico9918_t, vram.map.pram) % 4 == 0,
"palette LUT build must be word aligned");
50static uint32_t paletteShadow[32];
51static uint8_t paletteShadowLayout;
55static inline uint32_t cachePixelPair(PICO9918_PALETTE_LUT_T* dest,
const uint16_t* source)
57 const pico9918_aliasing_u32_t* alignedSource =
58 (
const pico9918_aliasing_u32_t*)PICO9918_ASSUME_ALIGNED(source, 4);
59 const uint32_t packed = PICO9918_PIXEL_FROM_RGB12_PAIR(*alignedSource);
60 dest[0] = PICO9918_PIXEL_PAIR(PICO9918_LOW16(packed));
61 dest[1] = PICO9918_PIXEL_PAIR(packed >> 16);
69 const uint16_t* source = tms9918->vram.map.pram;
70 const pico9918_aliasing_u32_t* words =
71 (
const pico9918_aliasing_u32_t*)PICO9918_ASSUME_ALIGNED(source, 4);
77 if (!tms9918->palDirty && paletteShadowLayout == (uint8_t)(pixelsDoubled + 1)
78#
if !PICO9918_SINGLE_INSTANCE
79 && pico9918_palette_owner == tms9918
84 for (
int i = 0; i < 32; ++i) diff |= words[i] ^ paletteShadow[i];
85 if (diff == 0)
return;
91 tms9918->palDirty = 0;
92#if !PICO9918_SINGLE_INSTANCE
93 pico9918_palette_owner = tms9918;
96 for (
int i = 0; i < 32; ++i) paletteShadow[i] = words[i];
97 paletteShadowLayout = (uint8_t)(pixelsDoubled + 1);
101 for (
int i = 0; i < 64; i += 8)
103 cachePixelPair(pico9918_palette_lut + i + 0, source + i + 0);
104 cachePixelPair(pico9918_palette_lut + i + 2, source + i + 2);
105 cachePixelPair(pico9918_palette_lut + i + 4, source + i + 4);
106 cachePixelPair(pico9918_palette_lut + i + 6, source + i + 6);
111 uint16_t __aligned(4) tmpPal[16];
112 for (
int i = 0; i < 16; i += 2)
114 const uint32_t packed = cachePixelPair(pico9918_palette_lut + i, source + i);
115 pico9918_aliasing_u32_t* dest = (pico9918_aliasing_u32_t*)PICO9918_ASSUME_ALIGNED(tmpPal + i, 4);
118 for (
int high = 1; high < 16; ++high)
120 const uint32_t highPixel = tmpPal[high];
121 PICO9918_PALETTE_LUT_T* dest = pico9918_palette_lut + (high << 4);
125 for (
int low = 0; low < 16; low += 2)
127 const pico9918_aliasing_u32_t* pairSource =
128 (
const pico9918_aliasing_u32_t*)PICO9918_ASSUME_ALIGNED(tmpPal + low, 4);
129 uint32_t pair = *pairSource;
130 dest[low] = (pair << 16) | highPixel;
131 dest[low + 1] = (pair & 0xFFFF0000) | highPixel;
pico9918_mode_t pico9918_display_mode(pico9918_t *tms9918)
current display mode
uint32_t pico9918_line_bytes(pico9918_t *tms9918)
how many bytes of pixels[] this mode fills.
#define PICO9918_INST_ONLY
pass the instance as the only argument
#define PICO9918_INST_ONLY_ARG
declare the instance as the only parameter
#define TMS9918_PIXELS_X
active display width, every mode
pico9918-core - the private instance layout