joeylib2/examples/pattern/pattern.c

135 lines
3.4 KiB
C

// M1 deliverable: visible test pattern exercising surfaces, palettes,
// SCBs, fillRect, and present.
//
// Screen is divided into 8 horizontal bands, each assigned its own
// palette. The pattern draws 16 vertical color-index stripes across
// the entire height; as a result each band displays its palette's
// gradient. Color index 0 in every palette is forced to black by the
// library contract, so the leftmost stripe is black in every band.
#include <stdio.h>
#include <joey/joey.h>
#define BAND_COUNT 8
#define BAND_HEIGHT (SURFACE_HEIGHT / BAND_COUNT)
#define STRIPE_COUNT 16
#define STRIPE_WIDTH (SURFACE_WIDTH / STRIPE_COUNT)
static void buildPalettes(SurfaceT *screen);
static void buildScbs(SurfaceT *screen);
static void drawStripes(SurfaceT *screen);
static void makeGradient(uint16_t *out16, int redOn, int greenOn, int blueOn);
static void buildPalettes(SurfaceT *screen) {
uint16_t colors[SURFACE_COLORS_PER_PALETTE];
// Palette 0: grayscale
makeGradient(colors, 1, 1, 1);
paletteSet(screen, 0, colors);
// Palette 1: red
makeGradient(colors, 1, 0, 0);
paletteSet(screen, 1, colors);
// Palette 2: yellow
makeGradient(colors, 1, 1, 0);
paletteSet(screen, 2, colors);
// Palette 3: green
makeGradient(colors, 0, 1, 0);
paletteSet(screen, 3, colors);
// Palette 4: cyan
makeGradient(colors, 0, 1, 1);
paletteSet(screen, 4, colors);
// Palette 5: blue
makeGradient(colors, 0, 0, 1);
paletteSet(screen, 5, colors);
// Palette 6: magenta
makeGradient(colors, 1, 0, 1);
paletteSet(screen, 6, colors);
// Palette 7: white-only (same as grayscale but serves as sanity check)
makeGradient(colors, 1, 1, 1);
paletteSet(screen, 7, colors);
}
static void buildScbs(SurfaceT *screen) {
uint16_t band;
uint16_t first;
uint16_t last;
for (band = 0; band < BAND_COUNT; band++) {
first = (uint16_t)(band * BAND_HEIGHT);
last = (uint16_t)(first + BAND_HEIGHT - 1);
scbSetRange(screen, first, last, (uint8_t)band);
}
}
static void drawStripes(SurfaceT *screen) {
uint8_t colorIndex;
int16_t x;
surfaceClear(screen, 0);
for (colorIndex = 0; colorIndex < STRIPE_COUNT; colorIndex++) {
x = (int16_t)(colorIndex * STRIPE_WIDTH);
fillRect(screen, x, 0, STRIPE_WIDTH, SURFACE_HEIGHT, colorIndex);
}
}
static void makeGradient(uint16_t *out16, int redOn, int greenOn, int blueOn) {
uint8_t i;
uint8_t r;
uint8_t g;
uint8_t b;
for (i = 0; i < SURFACE_COLORS_PER_PALETTE; i++) {
r = (uint8_t)(redOn ? i : 0);
g = (uint8_t)(greenOn ? i : 0);
b = (uint8_t)(blueOn ? i : 0);
out16[i] = (uint16_t)((r << 8) | (g << 4) | b);
}
}
int main(void) {
JoeyConfigT config;
SurfaceT *screen;
config.hostMode = HOST_MODE_TAKEOVER;
config.codegenBytes = 8 * 1024;
config.maxSurfaces = 4;
config.audioBytes = 64UL * 1024;
config.assetBytes = 128UL * 1024;
if (!joeyInit(&config)) {
fprintf(stderr, "joeyInit failed: %s\n", joeyLastError());
return 1;
}
screen = stageGet();
if (screen == NULL) {
fprintf(stderr, "stageGet returned NULL\n");
joeyShutdown();
return 1;
}
buildPalettes(screen);
buildScbs(screen);
drawStripes(screen);
stagePresent();
joeyWaitForAnyKey();
joeyShutdown();
return 0;
}