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