Refactor some file operations

FossilOrigin-Name: 44343f0ed94e4b574fb7d8841f6f73d4927e26ff8ae6b3f508a87905044b4ce0
This commit is contained in:
Jonathan Schleifer 2025-04-18 22:33:51 +00:00
parent e11cbf6b41
commit adac444372

View file

@ -19,6 +19,7 @@ backup(OFString *name, OFString *backupname)
[OFFileManager.defaultManager moveItemAtPath: name toPath: backupname]; [OFFileManager.defaultManager moveItemAtPath: name toPath: backupname];
} }
// FIXME: Should be OFIRI
static OFString *cgzname, *bakname, *pcfname, *mcfname; static OFString *cgzname, *bakname, *pcfname, *mcfname;
static void static void
@ -145,13 +146,17 @@ writemap(OFString *mname, int msize, unsigned char *mdata)
setnames(mname); setnames(mname);
backup(cgzname, bakname); backup(cgzname, bakname);
FILE *f = fopen([cgzname cStringWithEncoding: OFLocale.encoding], "wb"); @try {
if (!f) { OFIRI *IRI = [Cube.sharedInstance.gameDataIRI
IRIByAppendingPathComponent: cgzname];
OFStream *stream = [OFIRIHandler openItemAtIRI: IRI mode: @"w"];
[stream writeBuffer: mdata length: msize];
[stream close];
} @catch (id e) {
conoutf(@"could not write map to %@", cgzname); conoutf(@"could not write map to %@", cgzname);
return; return;
} }
fwrite(mdata, 1, msize, f);
fclose(f);
conoutf(@"wrote map %@ as file %@", mname, cgzname); conoutf(@"wrote map %@ as file %@", mname, cgzname);
} }
@ -267,17 +272,28 @@ COMMAND(savemap, ARG_1STR, ^ (OFString *mname) {
void void
load_world(OFString *mname) load_world(OFString *mname)
{ {
OFGZIPStream *stream;
stopifrecording(); stopifrecording();
cleardlights(); cleardlights();
pruneundos(0); pruneundos(0);
setnames(mname); setnames(mname);
gzFile f = gzopen([cgzname cStringWithEncoding: OFLocale.encoding],
"rb9"); @try {
if (!f) { OFIRI *IRI = [Cube.sharedInstance.gameDataIRI
IRIByAppendingPathComponent: cgzname];
OFStream *compressedStream = [OFIRIHandler openItemAtIRI: IRI
mode: @"r"];
stream = [OFGZIPStream streamWithStream: compressedStream
mode: @"r"];
[stream readIntoBuffer: &hdr
exactLength: sizeof(struct header) -
sizeof(int) * 16];
} @catch (id e) {
conoutf(@"could not read map %@", cgzname); conoutf(@"could not read map %@", cgzname);
return; return;
} }
gzread(f, &hdr, sizeof(struct header) - sizeof(int) * 16);
endianswap(&hdr.version, sizeof(int), 4); endianswap(&hdr.version, sizeof(int), 4);
if (strncmp(hdr.head, "CUBE", 4) != 0) if (strncmp(hdr.head, "CUBE", 4) != 0)
fatal(@"while reading map: header malformatted"); fatal(@"while reading map: header malformatted");
@ -286,7 +302,8 @@ load_world(OFString *mname)
if (sfactor < SMALLEST_FACTOR || sfactor > LARGEST_FACTOR) if (sfactor < SMALLEST_FACTOR || sfactor > LARGEST_FACTOR)
fatal(@"illegal map size"); fatal(@"illegal map size");
if (hdr.version >= 4) { if (hdr.version >= 4) {
gzread(f, &hdr.waterlevel, sizeof(int) * 16); [stream readIntoBuffer: &hdr.waterlevel
exactLength: sizeof(int) * 16];
endianswap(&hdr.waterlevel, sizeof(int), 16); endianswap(&hdr.waterlevel, sizeof(int), 16);
} else { } else {
hdr.waterlevel = -100000; hdr.waterlevel = -100000;
@ -294,7 +311,8 @@ load_world(OFString *mname)
[ents removeAllObjects]; [ents removeAllObjects];
for (int i = 0; i < hdr.numents; i++) { for (int i = 0; i < hdr.numents; i++) {
struct persistent_entity tmp; struct persistent_entity tmp;
gzread(f, &tmp, sizeof(struct persistent_entity)); [stream readIntoBuffer: &tmp
exactLength: sizeof(struct persistent_entity)];
endianswap(&tmp, sizeof(short), 4); endianswap(&tmp, sizeof(short), 4);
Entity *e = [Entity entity]; Entity *e = [Entity entity];
@ -323,10 +341,10 @@ load_world(OFString *mname)
struct sqr *t = NULL; struct sqr *t = NULL;
for (int k = 0; k < cubicsize; k++) { for (int k = 0; k < cubicsize; k++) {
struct sqr *s = &world[k]; struct sqr *s = &world[k];
int type = gzgetc(f); int type = [stream readInt8];
switch (type) { switch (type) {
case 255: { case 255: {
int n = gzgetc(f); int n = [stream readInt8];
for (int i = 0; i < n; i++, k++) for (int i = 0; i < n; i++, k++)
memcpy(&world[k], t, sizeof(struct sqr)); memcpy(&world[k], t, sizeof(struct sqr));
k--; k--;
@ -335,17 +353,17 @@ load_world(OFString *mname)
case 254: // only in MAPVERSION<=2 case 254: // only in MAPVERSION<=2
{ {
memcpy(s, t, sizeof(struct sqr)); memcpy(s, t, sizeof(struct sqr));
s->r = s->g = s->b = gzgetc(f); s->r = s->g = s->b = [stream readInt8];
gzgetc(f); [stream readInt8];
break; break;
} }
case SOLID: { case SOLID: {
s->type = SOLID; s->type = SOLID;
s->wtex = gzgetc(f); s->wtex = [stream readInt8];
s->vdelta = gzgetc(f); s->vdelta = [stream readInt8];
if (hdr.version <= 2) { if (hdr.version <= 2) {
gzgetc(f); [stream readInt8];
gzgetc(f); [stream readInt8];
} }
s->ftex = DEFAULT_FLOOR; s->ftex = DEFAULT_FLOOR;
s->ctex = DEFAULT_CEIL; s->ctex = DEFAULT_CEIL;
@ -361,20 +379,21 @@ load_world(OFString *mname)
@"%d @ %d", @"%d @ %d",
type, k); type, k);
s->type = type; s->type = type;
s->floor = gzgetc(f); s->floor = [stream readInt8];
s->ceil = gzgetc(f); s->ceil = [stream readInt8];
if (s->floor >= s->ceil) if (s->floor >= s->ceil)
s->floor = s->ceil - 1; // for pre 12_13 s->floor = s->ceil - 1; // for pre 12_13
s->wtex = gzgetc(f); s->wtex = [stream readInt8];
s->ftex = gzgetc(f); s->ftex = [stream readInt8];
s->ctex = gzgetc(f); s->ctex = [stream readInt8];
if (hdr.version <= 2) { if (hdr.version <= 2) {
gzgetc(f); [stream readInt8];
gzgetc(f); [stream readInt8];
} }
s->vdelta = gzgetc(f); s->vdelta = [stream readInt8];
s->utex = (hdr.version >= 2) ? gzgetc(f) : s->wtex; s->utex = (hdr.version >= 2
s->tag = (hdr.version >= 5) ? gzgetc(f) : 0; ? [stream readInt8] : s->wtex);
s->tag = (hdr.version >= 5 ? [stream readInt8] : 0);
s->type = type; s->type = type;
} }
} }
@ -384,7 +403,7 @@ load_world(OFString *mname)
if (!SOLID(s)) if (!SOLID(s))
texuse[s->utex] = texuse[s->ftex] = texuse[s->ctex] = 1; texuse[s->utex] = texuse[s->ftex] = texuse[s->ctex] = 1;
} }
gzclose(f); [stream close];
calclight(); calclight();
settagareas(); settagareas();
int xs, ys; int xs, ys;