Cube  Diff

Differences From Artifact [d379fda5be]:

To Artifact [f35a650122]:


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	unsigned char type; // type is one of the above
	unsigned char attr2, attr3, attr4;
};

void
backup(OFString *name, OFString *backupname)
{
	[OFFileManager.defaultManager removeItemAtPath:backupname];
	[OFFileManager.defaultManager moveItemAtPath:name toPath:backupname];
}

static OFString *cgzname, *bakname, *pcfname, *mcfname;

static void
setnames(OFString *name)
{
	OFCharacterSet *cs =
	    [OFCharacterSet characterSetWithCharactersInString:@"/\\"];
	OFRange range = [name rangeOfCharacterFromSet:cs];
	OFString *pakname, *mapname;

	if (range.location != OFNotFound) {
		pakname = [name substringToIndex:range.location];
		mapname = [name substringFromIndex:range.location + 1];
	} else {
		pakname = @"base";
		mapname = name;
	}

	cgzname = [[OFString alloc]
	    initWithFormat:@"packages/%@/%@.cgz", pakname, mapname];
	bakname = [[OFString alloc] initWithFormat:@"packages/%@/%@_%d.BAK",
	    pakname, mapname, lastmillis];
	pcfname = [[OFString alloc]
	    initWithFormat:@"packages/%@/package.cfg", pakname];
	mcfname = [[OFString alloc]
	    initWithFormat:@"packages/%@/%@.cfg", pakname, mapname];
}

// the optimize routines below are here to reduce the detrimental effects of
// messy mapping by setting certain properties (vdeltas and textures) to
// neighbouring values wherever there is no visible difference. This allows the
// mipmapper to generate more efficient mips. the reason it is done on save is
// to reduce the amount spend in the mipmapper (as that is done in realtime).







|
|








|
|



|
|





|
|
|
|
|
|
|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
	unsigned char type; // type is one of the above
	unsigned char attr2, attr3, attr4;
};

void
backup(OFString *name, OFString *backupname)
{
	[OFFileManager.defaultManager removeItemAtPath: backupname];
	[OFFileManager.defaultManager moveItemAtPath: name toPath: backupname];
}

static OFString *cgzname, *bakname, *pcfname, *mcfname;

static void
setnames(OFString *name)
{
	OFCharacterSet *cs =
	    [OFCharacterSet characterSetWithCharactersInString: @"/\\"];
	OFRange range = [name rangeOfCharacterFromSet: cs];
	OFString *pakname, *mapname;

	if (range.location != OFNotFound) {
		pakname = [name substringToIndex: range.location];
		mapname = [name substringFromIndex: range.location + 1];
	} else {
		pakname = @"base";
		mapname = name;
	}

	cgzname = [[OFString alloc] initWithFormat:
	    @"packages/%@/%@.cgz", pakname, mapname];
	bakname = [[OFString alloc] initWithFormat:
	    @"packages/%@/%@_%d.BAK", pakname, mapname, lastmillis];
	pcfname = [[OFString alloc] initWithFormat:
	    @"packages/%@/package.cfg", pakname];
	mcfname = [[OFString alloc] initWithFormat:
	    @"packages/%@/%@.cfg", pakname, mapname];
}

// the optimize routines below are here to reduce the detrimental effects of
// messy mapping by setting certain properties (vdeltas and textures) to
// neighbouring values wherever there is no visible difference. This allows the
// mipmapper to generate more efficient mips. the reason it is done on save is
// to reduce the amount spend in the mipmapper (as that is done in realtime).
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

void
writemap(OFString *mname, int msize, unsigned char *mdata)
{
	setnames(mname);
	backup(cgzname, bakname);

	FILE *f = fopen([cgzname cStringWithEncoding:OFLocale.encoding], "wb");
	if (!f) {
		conoutf(@"could not write map to %@", cgzname);
		return;
	}
	fwrite(mdata, 1, msize, f);
	fclose(f);
	conoutf(@"wrote map %@ as file %@", mname, cgzname);
}

OFData *
readmap(OFString *mname)
{
	setnames(mname);
	return [OFData dataWithContentsOfFile:mname];
}

// save map as .cgz file. uses 2 layers of compression: first does simple
// run-length encoding and leaves out data for certain kinds of cubes, then zlib
// removes the last bits of redundancy. Both passes contribute greatly to the
// miniscule map sizes.

void
save_world(OFString *mname)
{
	resettagareas(); // wouldn't be able to reproduce tagged areas
	                 // otherwise
	voptimize();
	toptimize();
	if (mname.length == 0)
		mname = getclientmap();
	setnames(mname);
	backup(cgzname, bakname);
	gzFile f =
	    gzopen([cgzname cStringWithEncoding:OFLocale.encoding], "wb9");
	if (!f) {
		conoutf(@"could not write map to %@", cgzname);
		return;
	}
	hdr.version = MAPVERSION;
	hdr.numents = 0;
	for (Entity *e in ents)







|













|


















|
|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

void
writemap(OFString *mname, int msize, unsigned char *mdata)
{
	setnames(mname);
	backup(cgzname, bakname);

	FILE *f = fopen([cgzname cStringWithEncoding: OFLocale.encoding], "wb");
	if (!f) {
		conoutf(@"could not write map to %@", cgzname);
		return;
	}
	fwrite(mdata, 1, msize, f);
	fclose(f);
	conoutf(@"wrote map %@ as file %@", mname, cgzname);
}

OFData *
readmap(OFString *mname)
{
	setnames(mname);
	return [OFData dataWithContentsOfFile: mname];
}

// save map as .cgz file. uses 2 layers of compression: first does simple
// run-length encoding and leaves out data for certain kinds of cubes, then zlib
// removes the last bits of redundancy. Both passes contribute greatly to the
// miniscule map sizes.

void
save_world(OFString *mname)
{
	resettagareas(); // wouldn't be able to reproduce tagged areas
	                 // otherwise
	voptimize();
	toptimize();
	if (mname.length == 0)
		mname = getclientmap();
	setnames(mname);
	backup(cgzname, bakname);
	gzFile f = gzopen([cgzname cStringWithEncoding: OFLocale.encoding],
	    "wb9");
	if (!f) {
		conoutf(@"could not write map to %@", cgzname);
		return;
	}
	hdr.version = MAPVERSION;
	hdr.numents = 0;
	for (Entity *e in ents)
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	}
	spurge;
	gzclose(f);
	conoutf(@"wrote map file %@", cgzname);
	settagareas();
}

COMMAND(savemap, ARG_1STR, ^(OFString *mname) {
	save_world(mname);
})

void
load_world(OFString *mname) // still supports all map formats that have existed
                            // since the earliest cube betas!
{
	stopifrecording();
	cleardlights();
	pruneundos(0);
	setnames(mname);
	gzFile f =
	    gzopen([cgzname cStringWithEncoding:OFLocale.encoding], "rb9");
	if (!f) {
		conoutf(@"could not read map %@", cgzname);
		return;
	}
	gzread(f, &hdr, sizeof(struct header) - sizeof(int) * 16);
	endianswap(&hdr.version, sizeof(int), 4);
	if (strncmp(hdr.head, "CUBE", 4) != 0)







|











|
|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	}
	spurge;
	gzclose(f);
	conoutf(@"wrote map file %@", cgzname);
	settagareas();
}

COMMAND(savemap, ARG_1STR, ^ (OFString *mname) {
	save_world(mname);
})

void
load_world(OFString *mname) // still supports all map formats that have existed
                            // since the earliest cube betas!
{
	stopifrecording();
	cleardlights();
	pruneundos(0);
	setnames(mname);
	gzFile f = gzopen([cgzname cStringWithEncoding: OFLocale.encoding],
	    "rb9");
	if (!f) {
		conoutf(@"could not read map %@", cgzname);
		return;
	}
	gzread(f, &hdr, sizeof(struct header) - sizeof(int) * 16);
	endianswap(&hdr.version, sizeof(int), 4);
	if (strncmp(hdr.head, "CUBE", 4) != 0)
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		e.y = tmp.y;
		e.z = tmp.z;
		e.attr1 = tmp.attr1;
		e.type = tmp.type;
		e.attr2 = tmp.attr2;
		e.attr3 = tmp.attr3;
		e.attr4 = tmp.attr4;
		[ents addObject:e];

		if (e.type == LIGHT) {
			if (!e.attr2)
				e.attr2 = 255; // needed for MAPVERSION<=2
			if (e.attr1 > 32)
				e.attr1 = 32; // 12_03 and below
		}







|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		e.y = tmp.y;
		e.z = tmp.z;
		e.attr1 = tmp.attr1;
		e.type = tmp.type;
		e.attr2 = tmp.attr2;
		e.attr3 = tmp.attr3;
		e.attr4 = tmp.attr4;
		[ents addObject: e];

		if (e.type == LIGHT) {
			if (!e.attr2)
				e.attr2 = 255; // needed for MAPVERSION<=2
			if (e.attr1 > 32)
				e.attr1 = 32; // 12_03 and below
		}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
			lookuptexture(i, &xs, &ys);
	conoutf(@"read map %@ (%d milliseconds)", cgzname,
	    SDL_GetTicks() - lastmillis);
	conoutf(@"%s", hdr.maptitle);
	startmap(mname);
	for (int l = 0; l < 256; l++) {
		// can this be done smarter?
		OFString *aliasname =
		    [OFString stringWithFormat:@"level_trigger_%d", l];
		if (identexists(aliasname))
			alias(aliasname, @"");
	}
	OFIRI *gameDataIRI = Cube.sharedInstance.gameDataIRI;
	execfile([gameDataIRI
	    IRIByAppendingPathComponent:@"data/default_map_settings.cfg"]);
	execfile([gameDataIRI IRIByAppendingPathComponent:pcfname]);
	execfile([gameDataIRI IRIByAppendingPathComponent:mcfname]);
}







|
|





|
|
|

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
			lookuptexture(i, &xs, &ys);
	conoutf(@"read map %@ (%d milliseconds)", cgzname,
	    SDL_GetTicks() - lastmillis);
	conoutf(@"%s", hdr.maptitle);
	startmap(mname);
	for (int l = 0; l < 256; l++) {
		// can this be done smarter?
		OFString *aliasname = [OFString stringWithFormat:
		    @"level_trigger_%d", l];
		if (identexists(aliasname))
			alias(aliasname, @"");
	}
	OFIRI *gameDataIRI = Cube.sharedInstance.gameDataIRI;
	execfile([gameDataIRI
	    IRIByAppendingPathComponent: @"data/default_map_settings.cfg"]);
	execfile([gameDataIRI IRIByAppendingPathComponent: pcfname]);
	execfile([gameDataIRI IRIByAppendingPathComponent: mcfname]);
}