joeylib2/tools/staxibake/staxibake.c
2026-09-07 15:46:23 -05:00

71 lines
2.6 KiB
C

// staxibake -- generate the Space Taxi cel bank (.spr) for offline
// sprite pre-compilation. Runs on the host: it links the game's shared
// cel table (stCels.c) and the C64 sprite bitmaps (stC64Data.c) and
// writes the cross-platform JSP1 sprite bank in kStCels order. The
// per-target spritebake then compiles it to a .spc the game loads at
// boot with jlSpriteBankLoadPrecompiled, so no cel is JIT-compiled on
// the 65816 (which costs ~0.4 s each).
//
// Usage: staxibake OUTPUT.spr
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "stCels.h"
#include "stC64Data.h"
// JSP1 header (mirrors tools/spritebake + jlSpriteBankLoad): magic,
// target byte (0 = cross-platform chunky), has-palette, w/h tiles,
// cell count LE16, then a 32-byte palette block, all in 44 bytes.
#define SPR_HEADER_BYTES 44u
#define SPR_OFF_TARGET 4u
#define SPR_OFF_HAS_PAL 5u
#define SPR_OFF_WIDTH 6u
#define SPR_OFF_HEIGHT 7u
#define SPR_OFF_CELLS 8u
int main(int argc, char **argv) {
uint8_t header[SPR_HEADER_BYTES];
FILE *out;
uint16_t i;
if (argc < 2) {
fprintf(stderr, "usage: staxibake OUTPUT.spr\n");
return 2;
}
out = fopen(argv[1], "wb");
if (out == NULL) {
fprintf(stderr, "staxibake: cannot write %s\n", argv[1]);
return 1;
}
memset(header, 0, sizeof(header));
memcpy(header, "JSP1", 4);
header[SPR_OFF_TARGET] = 0u; // cross-platform chunky
header[SPR_OFF_HAS_PAL] = 0u; // the game owns its palette
header[SPR_OFF_WIDTH] = (uint8_t)ST_CEL_TILES;
header[SPR_OFF_HEIGHT] = (uint8_t)ST_CEL_TILES;
header[SPR_OFF_CELLS] = (uint8_t)(kStCelCount & 0xFFu);
header[SPR_OFF_CELLS + 1u] = (uint8_t)(kStCelCount >> 8);
if (fwrite(header, 1, SPR_HEADER_BYTES, out) != SPR_HEADER_BYTES) {
fprintf(stderr, "staxibake: header write failed\n");
fclose(out);
return 1;
}
for (i = 0u; i < kStCelCount; i++) {
uint8_t blob[ST_CEL_BYTES];
const uint8_t *bm = stC64SpriteBitmap((uint8_t)(kStCels[i].ptr - ST_SPRITE_PTR_FIRST));
stCelBlob(bm, kStCels[i].multi, kStCels[i].color, kStCels[i].mc0, kStCels[i].mc1, blob);
if (fwrite(blob, 1, ST_CEL_BYTES, out) != ST_CEL_BYTES) {
fprintf(stderr, "staxibake: cel %u write failed\n", (unsigned)i);
fclose(out);
return 1;
}
}
fclose(out);
fprintf(stderr, "staxibake: wrote %u cels (%ux%u tiles) -> %s\n", (unsigned)kStCelCount, (unsigned)ST_CEL_TILES, (unsigned)ST_CEL_TILES, argv[1]);
return 0;
}