fs2port/port/tools/extractCityPolygons.c
2026-05-13 21:32:05 -05:00

68 lines
2.4 KiB
C

// Build a port-compatible RAM dump that has the FS2.1 polygon
// region (file offset $D000+) placed at the dispatcher-expected dest
// address ($BD28 in chicago city RAM).
//
// Usage: extractCityPolygons <city ram dump> <FS2.1 file> <out ram dump>
//
// The chunk5 standard scenery loader (FetchSectorFromDisk →
// ReadBlocks) can't reach FS2.1 blocks past index ~$5F, so the
// polygon region at file offset $D000+ never makes it into RAM via
// fs2trace's normal boot. We manually copy that region into the dump
// at $BD28 (overlaying the database-only section that chunk5 loaded).
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
if (argc != 4) {
fprintf(stderr, "usage: %s <city ram dump> <FS2.1 file> <out ram dump>\n", argv[0]);
return 1;
}
FILE *fr = fopen(argv[1], "rb");
if (fr == NULL) { perror(argv[1]); return 1; }
uint8_t ram[65536];
if (fread(ram, 1, 65536, fr) != 65536) {
fprintf(stderr, "%s: not 64K\n", argv[1]);
fclose(fr);
return 1;
}
fclose(fr);
FILE *fp = fopen(argv[2], "rb");
if (fp == NULL) { perror(argv[2]); return 1; }
fseek(fp, 0, SEEK_END);
long pSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
uint8_t *poly = malloc(pSize);
fread(poly, 1, pSize, fp);
fclose(fp);
// Polygon region in FS2.1: file offset $D000 onwards (~block
// 104+). Copy it on top of the city dump's $BD28 so the
// dispatcher's HEADER target now points to actual polygons
// instead of the COM/NAV database.
uint16_t dest = 0xBD28;
long polyOff = 0xD000;
long maxLen = 0xC000 - dest; // don't cross into $C000 I/O region
long avail = pSize - polyOff;
long copyLen = (avail < maxLen) ? avail : maxLen;
if (copyLen <= 0) {
fprintf(stderr, "polygon region empty\n");
free(poly);
return 1;
}
memcpy(&ram[dest], &poly[polyOff], copyLen);
FILE *fo = fopen(argv[3], "wb");
if (fo == NULL) { perror(argv[3]); free(poly); return 1; }
fwrite(ram, 1, 65536, fo);
fclose(fo);
free(poly);
fprintf(stderr, "Copied %ld bytes from %s @ $%lX to %s @ $%04X\n",
copyLen, argv[2], polyOff, argv[3], dest);
return 0;
}