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
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];
	[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];
	    [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];
		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];
	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
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");
	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];
	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");
	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
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) {
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");
	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
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];
		[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
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];
		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]);
	    IRIByAppendingPathComponent: @"data/default_map_settings.cfg"]);
	execfile([gameDataIRI IRIByAppendingPathComponent: pcfname]);
	execfile([gameDataIRI IRIByAppendingPathComponent: mcfname]);
}