joeylib2/src/core/scb.c

68 lines
1.7 KiB
C

// Scanline control byte (SCB) accessors.
//
// Each scanline holds one uint8_t SCB value in range 0..15 selecting
// which of the 16 palettes that scanline uses at display time.
#include <stddef.h>
#include <string.h>
#include "joey/palette.h"
#include "surfaceInternal.h"
// ----- Public API (alphabetical) -----
uint8_t scbGet(const SurfaceT *s, uint16_t line) {
if (s == NULL || line >= SURFACE_HEIGHT) {
return 0;
}
return s->scb[line];
}
void scbSet(SurfaceT *s, uint16_t line, uint8_t paletteIndex) {
if (s == NULL || line >= SURFACE_HEIGHT) {
return;
}
if (paletteIndex >= SURFACE_PALETTE_COUNT) {
return;
}
s->scb[line] = paletteIndex;
if (s == stageGet()) {
gStageScbDirty = true;
}
}
void scbSetRange(SurfaceT *s, uint16_t firstLine, uint16_t lastLine, uint8_t paletteIndex) {
uint16_t line;
uint16_t last;
if (s == NULL) {
return;
}
if (paletteIndex >= SURFACE_PALETTE_COUNT) {
return;
}
if (firstLine >= SURFACE_HEIGHT) {
return;
}
last = lastLine;
if (last >= SURFACE_HEIGHT) {
last = SURFACE_HEIGHT - 1;
}
if (last < firstLine) {
return;
}
// memset is far cheaper than the per-iter loop on ORCA-C with -b
// (scb is uint8_t, sizeof(uint8_t)==1, so the call form below is
// exact). On IIgs ORCA-C lowers small fixed-size memsets to MVP /
// PEI tricks; on Amiga/ST/DOS it uses libc memset which is
// already vectorized. Either way, much tighter than the C loop.
(void)line;
memset(&s->scb[firstLine], paletteIndex, (size_t)(last - firstLine + 1));
if (s == stageGet()) {
gStageScbDirty = true;
}
}