110 lines
4 KiB
C
110 lines
4 KiB
C
// stsim -- host-side driver for the Space Taxi simulation core.
|
|
//
|
|
// Loads an STL4 level, attaches a recorded demo input stream and runs
|
|
// the game tick, printing one line of state per tick in the same shape
|
|
// the VICE tracer records (see stuff/spacetaxi and the compare script),
|
|
// so the port's engine can be diffed against the real machine.
|
|
//
|
|
// stsim <level.dat> <H|W|T|X> <ticks>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "../../examples/spacetaxi/stSim.h"
|
|
#include "../../examples/spacetaxi/stDemoStreams.h"
|
|
|
|
|
|
static StLevelT gLevel;
|
|
static StSimT gSim;
|
|
|
|
|
|
void stAudioSfx(const uint8_t *program9) { (void)program9; }
|
|
void stAudioNoise(bool on) { (void)on; }
|
|
void stAudioThrustSweep(uint8_t value) { (void)value; }
|
|
void stAudioSpeech(uint8_t ch) { (void)ch; }
|
|
void stAudioSilence(void) { }
|
|
void stAudioVoice2(uint8_t freqLo, uint8_t freqHi, uint8_t ctrl) { (void)freqLo; (void)freqHi; (void)ctrl; }
|
|
void stAudioVoice1Freq(uint8_t value) { (void)value; }
|
|
|
|
|
|
static void printState(const StSimT *sim, uint32_t tick) {
|
|
uint8_t k;
|
|
|
|
printf("{\"tick\":%u,\"x\":\"%02X%02X.%02X\",\"y\":\"%02X.%02X\",\"vx\":\"%04X\",\"vy\":\"%04X\","
|
|
"\"pad\":%u,\"st\":%u,\"ph\":%u,\"in\":\"%02X\",\"dir\":\"%02X\",\"ptr0\":\"%02X\",\"ptr1\":\"%02X\","
|
|
"\"s1\":\"%02X%02X.%02X\",\"en\":\"%02X\",\"t4740\":\"%02X\",\"off\":%u,\"rng\":\"%02X%02X\","
|
|
"\"fuel\":%u,\"slots\":%u,\"asi\":%u,\"score\":\"",
|
|
tick, sim->posXmsb, sim->posXcol, sim->posXlo, sim->posYrow, sim->posYlo,
|
|
(uint16_t)sim->velX, (uint16_t)sim->velY, sim->activePad, sim->stage, sim->collisionPhase,
|
|
sim->inputMask, sim->dirMask, sim->spr[0].ptr, sim->spr[1].ptr,
|
|
sim->spr[1].msb, sim->spr[1].col, sim->spr[1].row, sim->frame.enableMask,
|
|
sim->demoTimer, sim->demoOff, sim->rngT1, sim->rngT2, sim->fuelCells, sim->fareSlotCount, sim->activeSpriteIdx);
|
|
for (k = 0u; k < ST_NUMBER_CHARS; k++) {
|
|
printf("%02X", sim->screen[ST_CELL_SCORE + k]);
|
|
}
|
|
printf("\",\"fare\":\"");
|
|
for (k = 0u; k < ST_NUMBER_CHARS; k++) {
|
|
printf("%02X", sim->screen[ST_CELL_FARE + k]);
|
|
}
|
|
printf("\",\"fuelc\":\"");
|
|
for (k = 0u; k < ST_FUEL_CELLS; k++) {
|
|
printf("%02X", sim->screen[ST_CELL_FUEL + k]);
|
|
}
|
|
printf("\",\"sprx\":\"");
|
|
for (k = 0u; k < ST_HW_SPRITES; k++) {
|
|
printf("%03X%02X", sim->frame.x[k], sim->frame.y[k]);
|
|
}
|
|
printf("\"}\n");
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
FILE *fp;
|
|
const uint8_t *stream = kDemoStreamH;
|
|
uint16_t len = (uint16_t)sizeof(kDemoStreamH);
|
|
uint32_t ticks;
|
|
uint32_t t;
|
|
|
|
if (argc < 4) {
|
|
fprintf(stderr, "usage: stsim <level.dat> <H|W|T|X> <ticks>\n");
|
|
return 2;
|
|
}
|
|
fp = fopen(argv[1], "rb");
|
|
if (fp == NULL || !stLevelParse(&gLevel, fp)) {
|
|
fprintf(stderr, "stsim: cannot load %s\n", argv[1]);
|
|
return 1;
|
|
}
|
|
fclose(fp);
|
|
switch (argv[2][0]) {
|
|
case 'W': stream = kDemoStreamW; len = (uint16_t)sizeof(kDemoStreamW); break;
|
|
case 'T': stream = kDemoStreamT; len = (uint16_t)sizeof(kDemoStreamT); break;
|
|
case 'X': stream = kDemoStreamX; len = (uint16_t)sizeof(kDemoStreamX); break;
|
|
default: break;
|
|
}
|
|
ticks = (uint32_t)strtoul(argv[3], NULL, 0);
|
|
stSimNewGame(&gSim, 1u, true);
|
|
stSimSeedDemoBuffer(&gSim, kDemoBufferInit, ST_DEMO_BUFFER_BYTES);
|
|
if (argc > 4) {
|
|
// carried-over state: flame parity, wave index, walk parity
|
|
gSim.flameParity = (uint8_t)strtoul(argv[4], NULL, 16);
|
|
}
|
|
if (argc > 5) {
|
|
gSim.waveIdx = (uint8_t)strtoul(argv[5], NULL, 16);
|
|
}
|
|
if (argc > 6) {
|
|
gSim.walkParity = (uint8_t)strtoul(argv[6], NULL, 16);
|
|
}
|
|
stSimEnterLevel(&gSim, &gLevel);
|
|
stSimSetDemoStream(&gSim, stream, len);
|
|
for (t = 0u; t < ticks; t++) {
|
|
StTickResultE r;
|
|
printState(&gSim, t);
|
|
r = stSimTick(&gSim);
|
|
if (r != ST_TICK_CONTINUE) {
|
|
printf("{\"tick\":%u,\"end\":%d}\n", t, (int)r);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|