More file handling cleanups

FossilOrigin-Name: c09457f7ad6613411be70250bdc33917e92298e80706560a9a205c997b679297
This commit is contained in:
Jonathan Schleifer 2025-03-05 22:42:56 +00:00
parent a6a0247bb2
commit 3661ce9a40
3 changed files with 110 additions and 79 deletions

View file

@ -69,6 +69,18 @@ VARP(minmillis, 0, 5, 1000);
if (passwd == nil) if (passwd == nil)
passwd = @""; passwd = @"";
_gameDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
_userDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
[OFFileManager.defaultManager
createDirectoryAtIRI:[_userDataIRI
IRIByAppendingPathComponent:@"demos"]
createParents:true];
[OFFileManager.defaultManager
createDirectoryAtIRI:[_userDataIRI
IRIByAppendingPathComponent:@"savegames"]
createParents:true];
if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | par) < 0) if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | par) < 0)
fatal(@"Unable to initialize SDL"); fatal(@"Unable to initialize SDL");
@ -118,8 +130,6 @@ VARP(minmillis, 0, 5, 1000);
gl_init(_width, _height); gl_init(_width, _height);
log(@"basetex"); log(@"basetex");
_gameDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
_userDataIRI = [OFFileManager.defaultManager currentDirectoryIRI];
int xs, ys; int xs, ys;
if (!installtex(2, if (!installtex(2,
[_userDataIRI IRIByAppendingPathComponent:@"data/newchars.png"], [_userDataIRI IRIByAppendingPathComponent:@"data/newchars.png"],

View file

@ -88,21 +88,22 @@ stopifrecording()
} }
void void
savestate(char *fn) savestate(OFIRI *IRI)
{ {
@autoreleasepool {
stop(); stop();
f = gzopen(fn, "wb9"); f = gzopen([IRI.fileSystemRepresentation
cStringWithEncoding:OFLocale.encoding],
"wb9");
if (!f) { if (!f) {
conoutf(@"could not write %s", fn); conoutf(@"could not write %@", IRI.string);
return; return;
} }
gzwrite(f, (void *)"CUBESAVE", 8); gzwrite(f, (void *)"CUBESAVE", 8);
gzputc(f, islittleendian); gzputc(f, islittleendian);
gzputi(SAVEGAMEVERSION); gzputi(SAVEGAMEVERSION);
gzputi(sizeof(dynent)); gzputi(sizeof(dynent));
@autoreleasepool {
gzwrite(f, getclientmap().UTF8String, _MAXDEFSTR); gzwrite(f, getclientmap().UTF8String, _MAXDEFSTR);
}
gzputi(gamemode); gzputi(gamemode);
gzputi(ents.length()); gzputi(ents.length());
loopv(ents) gzputc(f, ents[i].spawned); loopv(ents) gzputc(f, ents[i].spawned);
@ -116,33 +117,41 @@ savestate(char *fn)
gzput(players[i] == NULL); gzput(players[i] == NULL);
gzwrite(f, players[i], sizeof(dynent)); gzwrite(f, players[i], sizeof(dynent));
} }
}
} }
void void
savegame(OFString *name) savegame(OFString *name)
{ {
@autoreleasepool {
if (!m_classicsp) { if (!m_classicsp) {
conoutf(@"can only save classic sp games"); conoutf(@"can only save classic sp games");
return; return;
} }
sprintf_sd(fn)("savegames/%s.csgz", name.UTF8String);
savestate(fn); @autoreleasepool {
OFString *path =
[OFString stringWithFormat:@"savegames/%@.csgz", name];
OFIRI *IRI = [Cube.sharedInstance.userDataIRI
IRIByAppendingPathComponent:path];
savestate(IRI);
stop(); stop();
conoutf(@"wrote %s", fn); conoutf(@"wrote %@", IRI.string);
} }
} }
COMMAND(savegame, ARG_1STR) COMMAND(savegame, ARG_1STR)
void void
loadstate(char *fn) loadstate(OFIRI *IRI)
{ {
@autoreleasepool {
stop(); stop();
if (multiplayer()) if (multiplayer())
return; return;
f = gzopen(fn, "rb9"); f = gzopen([IRI.fileSystemRepresentation
cStringWithEncoding:OFLocale.encoding],
"rb9");
if (!f) { if (!f) {
conoutf(@"could not open %s", fn); conoutf(@"could not open %@", IRI.string);
return; return;
} }
@ -151,31 +160,36 @@ loadstate(char *fn)
if (strncmp(buf, "CUBESAVE", 8)) if (strncmp(buf, "CUBESAVE", 8))
goto out; goto out;
if (gzgetc(f) != islittleendian) if (gzgetc(f) != islittleendian)
goto out; // not supporting save->load accross incompatible goto out; // not supporting save->load accross
// architectures simpifies things a LOT // incompatible architectures simpifies things
// a LOT
if (gzgeti() != SAVEGAMEVERSION || gzgeti() != sizeof(dynent)) if (gzgeti() != SAVEGAMEVERSION || gzgeti() != sizeof(dynent))
goto out; goto out;
string mapname; string mapname;
gzread(f, mapname, _MAXDEFSTR); gzread(f, mapname, _MAXDEFSTR);
nextmode = gzgeti(); nextmode = gzgeti();
@autoreleasepool { @autoreleasepool {
// continue below once map has been loaded and client & server // continue below once map has been loaded and client &
// have updated // server have updated
changemap(@(mapname)); changemap(@(mapname));
} }
return; return;
out: out:
conoutf(@"aborting: savegame/demo from a different version of cube or " conoutf(@"aborting: savegame/demo from a different version of "
@"cpu architecture"); @"cube or cpu architecture");
stop(); stop();
}
} }
void void
loadgame(OFString *name) loadgame(OFString *name)
{ {
@autoreleasepool { @autoreleasepool {
sprintf_sd(fn)("savegames/%s.csgz", name.UTF8String); OFString *path =
loadstate(fn); [OFString stringWithFormat:@"savegames/%@.csgz", name];
OFIRI *IRI = [Cube.sharedInstance.userDataIRI
IRIByAppendingPathComponent:path];
loadstate(IRI);
} }
} }
COMMAND(loadgame, ARG_1STR) COMMAND(loadgame, ARG_1STR)
@ -249,18 +263,23 @@ OFVector3D dorig;
void void
record(OFString *name) record(OFString *name)
{ {
@autoreleasepool {
if (m_sp) { if (m_sp) {
conoutf(@"cannot record singleplayer games"); conoutf(@"cannot record singleplayer games");
return; return;
} }
int cn = getclientnum(); int cn = getclientnum();
if (cn < 0) if (cn < 0)
return; return;
sprintf_sd(fn)("demos/%s.cdgz", name.UTF8String);
savestate(fn); @autoreleasepool {
OFString *path =
[OFString stringWithFormat:@"demos/%@.cdgz", name];
OFIRI *IRI = [Cube.sharedInstance.userDataIRI
IRIByAppendingPathComponent:path];
savestate(IRI);
gzputi(cn); gzputi(cn);
conoutf(@"started recording demo to %s", fn); conoutf(@"started recording demo to %@", IRI.string);
demorecording = true; demorecording = true;
starttime = lastmillis; starttime = lastmillis;
ddamage = bdamage = 0; ddamage = bdamage = 0;
@ -315,8 +334,11 @@ void
demo(OFString *name) demo(OFString *name)
{ {
@autoreleasepool { @autoreleasepool {
sprintf_sd(fn)("demos/%s.cdgz", name.UTF8String); OFString *path =
loadstate(fn); [OFString stringWithFormat:@"demos/%@.cdgz", name];
OFIRI *IRI = [Cube.sharedInstance.userDataIRI
IRIByAppendingPathComponent:path];
loadstate(IRI);
demoloading = true; demoloading = true;
} }
} }

View file

@ -254,8 +254,7 @@ playsound(int n, OFVector3D *loc)
#endif #endif
if (!samples[n]) { if (!samples[n]) {
conoutf(@"failed to load sample: %s", conoutf(@"failed to load sample: %@", IRI.string);
IRI.string.UTF8String);
return; return;
} }
} }