68 lines
1.7 KiB
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;
|
|
}
|
|
}
|