Cube  Check-in [b5bfe2af86]

Overview
Comment:Remove u{char,short,int}
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b5bfe2af86efc76d1ac600bf7cda4a1709aaa95ae2392ee9e3f98ce6d4b14bcf
User & Date: js on 2025-03-23 02:59:37
Other Links: manifest | tags
Context
2025-03-23
14:17
Adjust to ObjFW changes check-in: 85566b261d user: js tags: trunk
02:59
Remove u{char,short,int} check-in: b5bfe2af86 user: js tags: trunk
02:47
Remove loop[ijkl] check-in: 6b85eefc85 user: js tags: trunk
Changes

Modified src/MD2.m from [1b5856edcb] to [a74f6892f8].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	int numSkins, numVertices, numTexcoords;
	int numTriangles, numGlCommands, numFrames;
	int offsetSkins, offsetTexcoords, offsetTriangles;
	int offsetFrames, offsetGlCommands, offsetEnd;
};

struct md2_vertex {
	uchar vertex[3], lightNormalIndex;
};

struct md2_frame {
	float scale[3];
	float translate[3];
	char name[16];
	struct md2_vertex vertices[1];







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	int numSkins, numVertices, numTexcoords;
	int numTriangles, numGlCommands, numFrames;
	int offsetSkins, offsetTexcoords, offsetTriangles;
	int offsetFrames, offsetGlCommands, offsetEnd;
};

struct md2_vertex {
	unsigned char vertex[3], lightNormalIndex;
};

struct md2_frame {
	float scale[3];
	float translate[3];
	char name[16];
	struct md2_vertex vertices[1];
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	OFAssert(_mverts[frame] == NULL);

	_mverts[frame] = OFAllocMemory(_numVerts, sizeof(OFVector3D));
	struct md2_frame *cf =
	    (struct md2_frame *)((char *)_frames + _frameSize * frame);
	float sc = 16.0f / scale;
	for (int vi = 0; vi < _numVerts; vi++) {
		uchar *cv = (uchar *)&cf->vertices[vi].vertex;
		OFVector3D *v = &(_mverts[frame])[vi];
		v->x = (snap(sn, cv[0] * cf->scale[0]) + cf->translate[0]) / sc;
		v->y =
		    -(snap(sn, cv[1] * cf->scale[1]) + cf->translate[1]) / sc;
		v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc;
	}
}







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	OFAssert(_mverts[frame] == NULL);

	_mverts[frame] = OFAllocMemory(_numVerts, sizeof(OFVector3D));
	struct md2_frame *cf =
	    (struct md2_frame *)((char *)_frames + _frameSize * frame);
	float sc = 16.0f / scale;
	for (int vi = 0; vi < _numVerts; vi++) {
		unsigned char *cv = (unsigned char *)&cf->vertices[vi].vertex;
		OFVector3D *v = &(_mverts[frame])[vi];
		v->x = (snap(sn, cv[0] * cf->scale[0]) + cf->translate[0]) / sc;
		v->y =
		    -(snap(sn, cv[1] * cf->scale[1]) + cf->translate[1]) / sc;
		v->z = (snap(sn, cv[2] * cf->scale[2]) + cf->translate[2]) / sc;
	}
}

Modified src/clientextras.m from [40507de7a2] to [1114a27a28].

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	changemap(mapname);
	mapname = getclientmap();
	OFData *mapdata = readmap(mapname);
	if (mapdata == nil)
		return;
	ENetPacket *packet = enet_packet_create(
	    NULL, MAXTRANS + mapdata.count, ENET_PACKET_FLAG_RELIABLE);
	uchar *start = packet->data;
	uchar *p = start + 2;
	putint(&p, SV_SENDMAP);
	sendstring(mapname, &p);
	putint(&p, mapdata.count);
	if (65535 - (p - start) < mapdata.count) {
		conoutf(@"map %@ is too large to send", mapname);
		enet_packet_destroy(packet);
		return;
	}
	memcpy(p, mapdata.items, mapdata.count);
	p += mapdata.count;
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	sendpackettoserv(packet);
	conoutf(@"sending map %@ to server...", mapname);
	OFString *msg =
	    [OFString stringWithFormat:@"[map %@ uploaded to server, "
	                               @"\"getmap\" to receive it]",
	              mapname];
	toserver(msg);
}

void
getmap()
{
	ENetPacket *packet =
	    enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
	uchar *start = packet->data;
	uchar *p = start + 2;
	putint(&p, SV_RECVMAP);
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	sendpackettoserv(packet);
	conoutf(@"requesting map from server...");
}

COMMAND(sendmap, ARG_1STR)
COMMAND(getmap, ARG_NONE)







|
|










|















|
|

|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
	changemap(mapname);
	mapname = getclientmap();
	OFData *mapdata = readmap(mapname);
	if (mapdata == nil)
		return;
	ENetPacket *packet = enet_packet_create(
	    NULL, MAXTRANS + mapdata.count, ENET_PACKET_FLAG_RELIABLE);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	putint(&p, SV_SENDMAP);
	sendstring(mapname, &p);
	putint(&p, mapdata.count);
	if (65535 - (p - start) < mapdata.count) {
		conoutf(@"map %@ is too large to send", mapname);
		enet_packet_destroy(packet);
		return;
	}
	memcpy(p, mapdata.items, mapdata.count);
	p += mapdata.count;
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	sendpackettoserv(packet);
	conoutf(@"sending map %@ to server...", mapname);
	OFString *msg =
	    [OFString stringWithFormat:@"[map %@ uploaded to server, "
	                               @"\"getmap\" to receive it]",
	              mapname];
	toserver(msg);
}

void
getmap()
{
	ENetPacket *packet =
	    enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	putint(&p, SV_RECVMAP);
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	sendpackettoserv(packet);
	conoutf(@"requesting map from server...");
}

COMMAND(sendmap, ARG_1STR)
COMMAND(getmap, ARG_NONE)

Modified src/clients.m from [e57ccf0fe6] to [6542299bf2].

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
c2sinfo(DynamicEntity *d)
{
	if (clientnum < 0)
		return; // we haven't had a welcome message from the server yet
	if (lastmillis - lastupdate < 40)
		return; // don't update faster than 25fps
	ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, 0);
	uchar *start = packet->data;
	uchar *p = start + 2;
	bool serveriteminitdone = false;
	// suggest server to change map
	if (toservermap.length > 0) {
		// do this exclusively as map change may invalidate rest of
		// update
		packet->flags = ENET_PACKET_FLAG_RELIABLE;
		putint(&p, SV_MAPCHANGE);







|
|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
c2sinfo(DynamicEntity *d)
{
	if (clientnum < 0)
		return; // we haven't had a welcome message from the server yet
	if (lastmillis - lastupdate < 40)
		return; // don't update faster than 25fps
	ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, 0);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	bool serveriteminitdone = false;
	// suggest server to change map
	if (toservermap.length > 0) {
		// do this exclusively as map change may invalidate rest of
		// update
		packet->flags = ENET_PACKET_FLAG_RELIABLE;
		putint(&p, SV_MAPCHANGE);
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
		[messages removeAllObjects];
		if (lastmillis - lastping > 250) {
			putint(&p, SV_PING);
			putint(&p, lastmillis);
			lastping = lastmillis;
		}
	}
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	incomingdemodata(start, p - start, true);
	if (clienthost) {
		enet_host_broadcast(clienthost, 0, packet);
		enet_host_flush(clienthost);
	} else
		localclienttoserver(packet);







|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
		[messages removeAllObjects];
		if (lastmillis - lastping > 250) {
			putint(&p, SV_PING);
			putint(&p, lastmillis);
			lastping = lastmillis;
		}
	}
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	incomingdemodata(start, p - start, true);
	if (clienthost) {
		enet_host_broadcast(clienthost, 0, packet);
		enet_host_flush(clienthost);
	} else
		localclienttoserver(packet);

Modified src/clients2c.m from [8bc911d5e6] to [69be55db81].

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
		d.lag = (d.lag * 5 + lagtime) / 6;
		d.lastUpdate = lastmillis;
	}
}

// processes any updates from the server
void
localservertoclient(uchar *buf, int len)
{
	if (ENET_NET_TO_HOST_16(*(ushort *)buf) != len)
		neterr(@"packet length");
	incomingdemodata(buf, len, false);

	uchar *end = buf + len;
	uchar *p = buf + 2;
	char text[MAXTRANS];
	int cn = -1, type;
	DynamicEntity *d = nil;
	bool mapchanged = false;

	while (p < end)
		switch (type = getint(&p)) {







|

|



|
|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
		d.lag = (d.lag * 5 + lagtime) / 6;
		d.lastUpdate = lastmillis;
	}
}

// processes any updates from the server
void
localservertoclient(unsigned char *buf, int len)
{
	if (ENET_NET_TO_HOST_16(*(unsigned short *)buf) != len)
		neterr(@"packet length");
	incomingdemodata(buf, len, false);

	unsigned char *end = buf + len;
	unsigned char *p = buf + 2;
	char text[MAXTRANS];
	int cn = -1, type;
	DynamicEntity *d = nil;
	bool mapchanged = false;

	while (p < end)
		switch (type = getint(&p)) {
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

		case SV_ITEMPICKUP:
			setspawn(getint(&p), false);
			getint(&p);
			break;

		case SV_ITEMSPAWN: {
			uint i = getint(&p);
			setspawn(i, true);
			if (i >= (uint)ents.count)
				break;
			OFVector3D v =
			    OFMakeVector3D(ents[i].x, ents[i].y, ents[i].z);
			playsound(S_ITEMSPAWN, &v);
			break;
		}
		// server acknowledges that I picked up this item







|

|







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

		case SV_ITEMPICKUP:
			setspawn(getint(&p), false);
			getint(&p);
			break;

		case SV_ITEMSPAWN: {
			unsigned int i = getint(&p);
			setspawn(i, true);
			if (i >= ents.count)
				break;
			OFVector3D v =
			    OFMakeVector3D(ents[i].x, ents[i].y, ents[i].z);
			playsound(S_ITEMSPAWN, &v);
			break;
		}
		// server acknowledges that I picked up this item
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
				break;
			}
			break;
		}

		case SV_EDITENT: // coop edit of ent
		{
			uint i = getint(&p);

			while ((uint)ents.count <= i) {
				Entity *e = [Entity entity];
				e.type = NOTUSED;
				[ents addObject:e];
			}

			int to = ents[i].type;
			ents[i].type = getint(&p);







|

|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
				break;
			}
			break;
		}

		case SV_EDITENT: // coop edit of ent
		{
			unsigned int i = getint(&p);

			while (ents.count <= i) {
				Entity *e = [Entity entity];
				e.type = NOTUSED;
				[ents addObject:e];
			}

			int to = ents[i].type;
			ents[i].type = getint(&p);

Modified src/cube.h from [0e2553a48d] to [06881e859d].

29
30
31
32
33
34
35
36


37
38

39

40

41

42
43
44

45

46
47
48
49
50
51
52
	CHF,       // idem ceiling
	SPACE,     // entirely empty cube
	SEMISOLID, // generated by mipmapping
	MAXTYPE
};

struct sqr {
	uchar type;             // one of the above


	char floor, ceil;       // height, in cubes
	uchar wtex, ftex, ctex; // wall/floor/ceil texture ids

	uchar r, g, b;          // light value at upper left vertex

	uchar vdelta;           // vertex delta, used for heightfield cubes

	char defer; // used in mipmapping, when true this cube is not a perfect

	            // mip
	char occluded; // true when occluded
	uchar utex;    // upper wall tex id

	uchar tag;     // used by triggers

};

// hardcoded texture numbers
enum {
	DEFAULT_SKY = 0,
	DEFAULT_LIQUID,
	DEFAULT_WALL,







|
>
>
|
|
>
|
>
|
>
|
>
|
|
|
>
|
>







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
55
56
57
58
59
60
	CHF,       // idem ceiling
	SPACE,     // entirely empty cube
	SEMISOLID, // generated by mipmapping
	MAXTYPE
};

struct sqr {
	// one of the above
	unsigned char type;
	// height, in cubes
	char floor, ceil;
	// wall/floor/ceil texture ids
	unsigned char wtex, ftex, ctex;
	// light value at upper left vertex
	unsigned char r, g, b;
	// vertex delta, used for heightfield cubes
	unsigned char vdelta;
	// used in mipmapping, when true this cube is not a perfect mip
	char defer;
	// true when occluded
	char occluded;
	// upper wall tex id
	unsigned char utex;
	// used by triggers
	unsigned char tag;
};

// hardcoded texture numbers
enum {
	DEFAULT_SKY = 0,
	DEFAULT_LIQUID,
	DEFAULT_WALL,
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
struct header {
	char head[4];   // "CUBE"
	int version;    // any >8bit quantity is a little indian
	int headersize; // sizeof(header)
	int sfactor;    // in bits
	int numents;
	char maptitle[128];
	uchar texlists[3][256];
	int waterlevel;
	int reserved[15];
};

#define SWS(w, x, y, s) (&(w)[(y) * (s) + (x)])
#define SW(w, x, y) SWS(w, x, y, ssize)
#define S(x, y) SW(world, x, y) // convenient lookup of a lowest mip cube







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
struct header {
	char head[4];   // "CUBE"
	int version;    // any >8bit quantity is a little indian
	int headersize; // sizeof(header)
	int sfactor;    // in bits
	int numents;
	char maptitle[128];
	unsigned char texlists[3][256];
	int waterlevel;
	int reserved[15];
};

#define SWS(w, x, y, s) (&(w)[(y) * (s) + (x)])
#define SW(w, x, y) SWS(w, x, y, ssize)
#define S(x, y) SW(world, x, y) // convenient lookup of a lowest mip cube
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
	S_JUMPPAD,
};

// vertex array format

struct vertex {
	float u, v, x, y, z;
	uchar r, g, b, a;
};

// globals ooh naughty

#ifdef __cplusplus
extern "C" {
#endif







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
	S_JUMPPAD,
};

// vertex array format

struct vertex {
	float u, v, x, y, z;
	unsigned char r, g, b, a;
};

// globals ooh naughty

#ifdef __cplusplus
extern "C" {
#endif

Modified src/editing.m from [f776852317] to [6ba0a980d9].

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
void
tofronttex() // maintain most recently used of the texture lists when applying
             // texture
{
	for (int i = 0; i < 3; i++) {
		int c = curedittex[i];
		if (c >= 0) {
			uchar *p = hdr.texlists[i];
			int t = p[c];
			for (int a = c - 1; a >= 0; a--)
				p[a + 1] = p[a];
			p[0] = t;
			curedittex[i] = -1;
		}
	}







|







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
void
tofronttex() // maintain most recently used of the texture lists when applying
             // texture
{
	for (int i = 0; i < 3; i++) {
		int c = curedittex[i];
		if (c >= 0) {
			unsigned char *p = hdr.texlists[i];
			int t = p[c];
			for (int a = c - 1; a >= 0; a--)
				p[a + 1] = p[a];
			p[0] = t;
			curedittex[i] = -1;
		}
	}

Modified src/entities.m from [a819c302d8] to [aa08365e90].

334
335
336
337
338
339
340

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
	if (player1.quadMillis && (player1.quadMillis -= time) < 0) {
		player1.quadMillis = 0;
		playsoundc(S_PUPOUT);
		conoutf(@"quad damage is over");
	}
}


void
putitems(uchar **p) // puts items in network stream and also spawns them locally
{
	[ents enumerateObjectsUsingBlock:^(Entity *e, size_t i, bool *stop) {
		if ((e.type >= I_SHELLS && e.type <= I_QUAD) ||
		    e.type == CARROT) {
			putint(p, i);
			e.spawned = true;
		}
	}];
}

void
resetspawns()
{
	for (Entity *e in ents)
		e.spawned = false;
}
void
setspawn(uint i, bool on)
{
	if (i < (uint)ents.count)
		ents[i].spawned = on;
}







>

|

















|

|


334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
	if (player1.quadMillis && (player1.quadMillis -= time) < 0) {
		player1.quadMillis = 0;
		playsoundc(S_PUPOUT);
		conoutf(@"quad damage is over");
	}
}

// puts items in network stream and also spawns them locally
void
putitems(unsigned char **p)
{
	[ents enumerateObjectsUsingBlock:^(Entity *e, size_t i, bool *stop) {
		if ((e.type >= I_SHELLS && e.type <= I_QUAD) ||
		    e.type == CARROT) {
			putint(p, i);
			e.spawned = true;
		}
	}];
}

void
resetspawns()
{
	for (Entity *e in ents)
		e.spawned = false;
}
void
setspawn(size_t i, bool on)
{
	if (i < ents.count)
		ents[i].spawned = on;
}

Modified src/protos.h from [7c4924e6fb] to [5294dddff8].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    struct sqr *h2, struct sqr *s, struct sqr *t, struct sqr *u, struct sqr *v);
extern void addwaterquad(int x, int y, int size);
extern int renderwater(float hf);
extern void finishstrips();
extern void setarraypointers();

// client
extern void localservertoclient(uchar *buf, int len);
extern void connects(OFString *servername);
extern void disconnect(bool onlyclean, bool async);
extern void toserver(OFString *text);
extern void addmsg(int rel, int num, int type, ...);
extern bool multiplayer();
extern bool allowedittoggle();
extern void sendpackettoserv(void *packet);







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
    struct sqr *h2, struct sqr *s, struct sqr *t, struct sqr *u, struct sqr *v);
extern void addwaterquad(int x, int y, int size);
extern int renderwater(float hf);
extern void finishstrips();
extern void setarraypointers();

// client
extern void localservertoclient(unsigned char *buf, int len);
extern void connects(OFString *servername);
extern void disconnect(bool onlyclean, bool async);
extern void toserver(OFString *text);
extern void addmsg(int rel, int num, int type, ...);
extern bool multiplayer();
extern bool allowedittoggle();
extern void sendpackettoserv(void *packet);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
extern void particle_trail(
    int type, int fade, const OFVector3D *from, const OFVector3D *to);
extern void render_particles(int time);

// worldio
extern void save_world(OFString *fname);
extern void load_world(OFString *mname);
extern void writemap(OFString *mname, int msize, uchar *mdata);
extern OFData *readmap(OFString *mname);
extern void loadgamerest();
extern void incomingdemodata(uchar *buf, int len, bool extras);
extern void demoplaybackstep();
extern void stop();
extern void stopifrecording();
extern void demodamage(int damage, const OFVector3D *o);
extern void demoblend(int damage);

// physics







|


|







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
extern void particle_trail(
    int type, int fade, const OFVector3D *from, const OFVector3D *to);
extern void render_particles(int time);

// worldio
extern void save_world(OFString *fname);
extern void load_world(OFString *mname);
extern void writemap(OFString *mname, int msize, unsigned char *mdata);
extern OFData *readmap(OFString *mname);
extern void loadgamerest();
extern void incomingdemodata(unsigned char *buf, int len, bool extras);
extern void demoplaybackstep();
extern void stop();
extern void stopifrecording();
extern void demodamage(int damage, const OFVector3D *o);
extern void demoblend(int damage);

// physics
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
extern void initserver(bool dedicated, int uprate, OFString *sdesc,
    OFString *ip, OFString *master, OFString *passwd, int maxcl);
extern void cleanupserver();
extern void localconnect();
extern void localdisconnect();
extern void localclienttoserver(struct _ENetPacket *);
extern void serverslice(int seconds, unsigned int timeout);
extern void putint(uchar **p, int n);
extern int getint(uchar **p);
extern void sendstring(OFString *t, uchar **p);
extern void startintermission();
extern void restoreserverstate(OFArray<Entity *> *ents);
extern uchar *retrieveservers(uchar *buf, int buflen);
extern char msgsizelookup(int msg);
extern void serverms(int mode, int numplayers, int minremain,
    OFString *smapname, int seconds, bool isfull);
extern void servermsinit(OFString *master, OFString *sdesc, bool listen);
extern void sendmaps(int n, OFString *mapname, int mapsize, uchar *mapdata);

extern ENetPacket *recvmap(int n);

// weapon
extern void selectgun(int a, int b, int c);
extern void shoot(DynamicEntity *d, const OFVector3D *to);
extern void shootv(int gun, const OFVector3D *from, const OFVector3D *to,
    DynamicEntity *d, bool local);
extern void createrays(const OFVector3D *from, const OFVector3D *to);
extern void moveprojectiles(float time);
extern void projreset();
extern OFString *playerincrosshair();
extern int reloadtime(int gun);

// entities
extern void initEntities();
extern void renderents();
extern void putitems(uchar **p);
extern void checkquad(int time);
extern void checkitems();
extern void realpickup(int n, DynamicEntity *d);
extern void renderentities();
extern void resetspawns();
extern void setspawn(uint i, bool on);
extern void teleport(int n, DynamicEntity *d);
extern void baseammo(int gun);

// rndmap
extern void perlinarea(const struct block *b, int scale, int seed, int psize);

#ifdef __cplusplus
}
#endif







|
|
|


|




|
>
















|





|









222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
extern void initserver(bool dedicated, int uprate, OFString *sdesc,
    OFString *ip, OFString *master, OFString *passwd, int maxcl);
extern void cleanupserver();
extern void localconnect();
extern void localdisconnect();
extern void localclienttoserver(struct _ENetPacket *);
extern void serverslice(int seconds, unsigned int timeout);
extern void putint(unsigned char **p, int n);
extern int getint(unsigned char **p);
extern void sendstring(OFString *t, unsigned char **p);
extern void startintermission();
extern void restoreserverstate(OFArray<Entity *> *ents);
extern unsigned char *retrieveservers(unsigned char *buf, int buflen);
extern char msgsizelookup(int msg);
extern void serverms(int mode, int numplayers, int minremain,
    OFString *smapname, int seconds, bool isfull);
extern void servermsinit(OFString *master, OFString *sdesc, bool listen);
extern void sendmaps(
    int n, OFString *mapname, int mapsize, unsigned char *mapdata);
extern ENetPacket *recvmap(int n);

// weapon
extern void selectgun(int a, int b, int c);
extern void shoot(DynamicEntity *d, const OFVector3D *to);
extern void shootv(int gun, const OFVector3D *from, const OFVector3D *to,
    DynamicEntity *d, bool local);
extern void createrays(const OFVector3D *from, const OFVector3D *to);
extern void moveprojectiles(float time);
extern void projreset();
extern OFString *playerincrosshair();
extern int reloadtime(int gun);

// entities
extern void initEntities();
extern void renderents();
extern void putitems(unsigned char **p);
extern void checkquad(int time);
extern void checkitems();
extern void realpickup(int n, DynamicEntity *d);
extern void renderentities();
extern void resetspawns();
extern void setspawn(size_t i, bool on);
extern void teleport(int n, DynamicEntity *d);
extern void baseammo(int gun);

// rndmap
extern void perlinarea(const struct block *b, int scale, int seed, int psize);

#ifdef __cplusplus
}
#endif

Modified src/rendercubes.m from [9b7cf3b555] to [3c13e91f26].

145
146
147
148
149
150
151

152
153
154
155

156
157
158
159
160
161
162
163
		        abs(ol4g - l4->g) < lighterr &&
		        abs(ol3b - l3->b) < lighterr &&
		        abs(ol4b - l4->b) < lighterr) ||
		    !wtex) {
			curvert -= 2;
			nquads--;
		} else {

			uchar *p3 = (uchar *)(&verts[curvert - 1].r);
			ol3r = p3[0];
			ol3g = p3[1];
			ol3b = p3[2];

			uchar *p4 = (uchar *)(&verts[curvert - 2].r);
			ol4r = p4[0];
			ol4g = p4[1];
			ol4b = p4[2];
		}
	}

	if (isceil) {







>
|



>
|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
		        abs(ol4g - l4->g) < lighterr &&
		        abs(ol3b - l3->b) < lighterr &&
		        abs(ol4b - l4->b) < lighterr) ||
		    !wtex) {
			curvert -= 2;
			nquads--;
		} else {
			unsigned char *p3 =
			    (unsigned char *)(&verts[curvert - 1].r);
			ol3r = p3[0];
			ol3g = p3[1];
			ol3b = p3[2];
			unsigned char *p4 =
			    (unsigned char *)(&verts[curvert - 2].r);
			ol4r = p4[0];
			ol4g = p4[1];
			ol4b = p4[2];
		}
	}

	if (isceil) {

Modified src/rendergl.m from [34f844358a] to [d9ebc3b45e].

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
		} @finally {
			SDL_FreeFormat(format);
		}
	}

#if 0
	for (int i = 0; i < s->w * s->h * 3; i++) {
		uchar *p = (uchar *)s->pixels + i;
		*p = 255 - *p;
	}
#endif
	glBindTexture(GL_TEXTURE_2D, tnum);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
	    clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);







|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
		} @finally {
			SDL_FreeFormat(format);
		}
	}

#if 0
	for (int i = 0; i < s->w * s->h * 3; i++) {
		unsigned char *p = (unsigned char *)s->pixels + i;
		*p = 255 - *p;
	}
#endif
	glBindTexture(GL_TEXTURE_2D, tnum);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
	    clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);

Modified src/savegamedemo.m from [c92a453804] to [d2d1d77a28].

302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
void
demoblend(int damage)
{
	bdamage = damage;
}

void
incomingdemodata(uchar *buf, int len, bool extras)
{
	if (!demorecording)
		return;
	gzputi(lastmillis - starttime);
	gzputi(len);
	gzwrite(f, buf, len);
	gzput(extras);







|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
void
demoblend(int damage)
{
	bdamage = damage;
}

void
incomingdemodata(unsigned char *buf, int len, bool extras)
{
	if (!demorecording)
		return;
	gzputi(lastmillis - starttime);
	gzputi(len);
	gzwrite(f, buf, len);
	gzput(extras);
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
		int len = gzgeti();
		if (len < 1 || len > MAXTRANS) {
			conoutf(
			    @"error: huge packet during demo play (%d)", len);
			stopreset();
			return;
		}
		uchar buf[MAXTRANS];
		gzread(f, buf, len);
		localservertoclient(buf, len); // update game state

		DynamicEntity *target = players[democlientnum];
		assert(target);

		int extras;







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
		int len = gzgeti();
		if (len < 1 || len > MAXTRANS) {
			conoutf(
			    @"error: huge packet during demo play (%d)", len);
			stopreset();
			return;
		}
		unsigned char buf[MAXTRANS];
		gzread(f, buf, len);
		localservertoclient(buf, len); // update game state

		DynamicEntity *target = players[democlientnum];
		assert(target);

		int extras;

Modified src/server.m from [98a7979cee] to [d5e909dacd].

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
}

void
send2(bool rel, int cn, int a, int b)
{
	ENetPacket *packet =
	    enet_packet_create(NULL, 32, rel ? ENET_PACKET_FLAG_RELIABLE : 0);
	uchar *start = packet->data;
	uchar *p = start + 2;
	putint(&p, a);
	putint(&p, b);
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	if (cn < 0)
		process(packet, -1);
	else
		send_(cn, packet);
	if (packet->referenceCount == 0)
		enet_packet_destroy(packet);
}

void
sendservmsg(OFString *msg)
{
	ENetPacket *packet = enet_packet_create(
	    NULL, _MAXDEFSTR + 10, ENET_PACKET_FLAG_RELIABLE);
	uchar *start = packet->data;
	uchar *p = start + 2;
	putint(&p, SV_SERVMSG);
	sendstring(msg, &p);
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	multicast(packet, -1);
	if (packet->referenceCount == 0)
		enet_packet_destroy(packet);
}

void







|
|


|














|
|


|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
}

void
send2(bool rel, int cn, int a, int b)
{
	ENetPacket *packet =
	    enet_packet_create(NULL, 32, rel ? ENET_PACKET_FLAG_RELIABLE : 0);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	putint(&p, a);
	putint(&p, b);
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	if (cn < 0)
		process(packet, -1);
	else
		send_(cn, packet);
	if (packet->referenceCount == 0)
		enet_packet_destroy(packet);
}

void
sendservmsg(OFString *msg)
{
	ENetPacket *packet = enet_packet_create(
	    NULL, _MAXDEFSTR + 10, ENET_PACKET_FLAG_RELIABLE);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	putint(&p, SV_SERVMSG);
	sendstring(msg, &p);
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	multicast(packet, -1);
	if (packet->referenceCount == 0)
		enet_packet_destroy(packet);
}

void
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
{
	[sents removeAllObjects];
	notgotitems = true;
}

// server side item pickup, acknowledge first client that gets it
static void
pickup(uint i, int sec, int sender)
{
	if (i >= (uint)sents.count)
		return;

	if (sents[i].spawned) {
		sents[i].spawned = false;
		sents[i].spawnsecs = sec;
		send2(true, sender, SV_ITEMACC, i);
	}
}








|

|

>







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{
	[sents removeAllObjects];
	notgotitems = true;
}

// server side item pickup, acknowledge first client that gets it
static void
pickup(size_t i, int sec, int sender)
{
	if (i >= sents.count)
		return;

	if (sents[i].spawned) {
		sents[i].spawned = false;
		sents[i].spawnsecs = sec;
		send2(true, sender, SV_ITEMACC, i);
	}
}

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// server side processing of updates: does very little and most state is tracked
// client only could be extended to move more gameplay to server (at expense of
// lag)

void
process(ENetPacket *packet, int sender) // sender may be -1
{
	if (ENET_NET_TO_HOST_16(*(ushort *)packet->data) !=
	    packet->dataLength) {
		disconnect_client(sender, @"packet length");
		return;
	}

	uchar *end = packet->data + packet->dataLength;
	uchar *p = packet->data + 2;
	char text[MAXTRANS];
	int cn = -1, type;

	while (p < end) {
		switch ((type = getint(&p))) {
		case SV_TEXT:
			sgetstr();







|





|
|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// server side processing of updates: does very little and most state is tracked
// client only could be extended to move more gameplay to server (at expense of
// lag)

void
process(ENetPacket *packet, int sender) // sender may be -1
{
	if (ENET_NET_TO_HOST_16(*(unsigned short *)packet->data) !=
	    packet->dataLength) {
		disconnect_client(sender, @"packet length");
		return;
	}

	unsigned char *end = packet->data + packet->dataLength;
	unsigned char *p = packet->data + 2;
	char text[MAXTRANS];
	int cn = -1, type;

	while (p < end) {
		switch ((type = getint(&p))) {
		case SV_TEXT:
			sgetstr();
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
}

void
send_welcome(int n)
{
	ENetPacket *packet =
	    enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
	uchar *start = packet->data;
	__block uchar *p = start + 2;
	putint(&p, SV_INITS2C);
	putint(&p, n);
	putint(&p, PROTOCOL_VERSION);
	putint(&p, *smapname.UTF8String);
	sendstring(serverpassword, &p);
	putint(&p, clients.count > maxclients);
	if (smapname.length > 0) {
		putint(&p, SV_MAPCHANGE);
		sendstring(smapname, &p);
		putint(&p, mode);
		putint(&p, SV_ITEMLIST);
		[sents enumerateObjectsUsingBlock:^(
		    ServerEntity *e, size_t i, bool *stop) {
			if (e.spawned)
				putint(&p, i);
		}];
		putint(&p, -1);
	}
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	send_(n, packet);
}

void
multicast(ENetPacket *packet, int sender)
{







|
|


















|







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
}

void
send_welcome(int n)
{
	ENetPacket *packet =
	    enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
	unsigned char *start = packet->data;
	__block unsigned char *p = start + 2;
	putint(&p, SV_INITS2C);
	putint(&p, n);
	putint(&p, PROTOCOL_VERSION);
	putint(&p, *smapname.UTF8String);
	sendstring(serverpassword, &p);
	putint(&p, clients.count > maxclients);
	if (smapname.length > 0) {
		putint(&p, SV_MAPCHANGE);
		sendstring(smapname, &p);
		putint(&p, mode);
		putint(&p, SV_ITEMLIST);
		[sents enumerateObjectsUsingBlock:^(
		    ServerEntity *e, size_t i, bool *stop) {
			if (e.spawned)
				putint(&p, i);
		}];
		putint(&p, -1);
	}
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	send_(n, packet);
}

void
multicast(ENetPacket *packet, int sender)
{

Modified src/serverbrowser.m from [3cbd2b77d6] to [5762ec3ef4].

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
	[servers addObject:[ServerInfo infoWithName:servername]];
}

void
pingservers()
{
	ENetBuffer buf;
	uchar ping[MAXTRANS];
	uchar *p;

	for (ServerInfo *si in servers) {
		if (si.address.host == ENET_HOST_ANY)
			continue;

		p = ping;
		putint(&p, lastmillis);







|
|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
	[servers addObject:[ServerInfo infoWithName:servername]];
}

void
pingservers()
{
	ENetBuffer buf;
	unsigned char ping[MAXTRANS];
	unsigned char *p;

	for (ServerInfo *si in servers) {
		if (si.address.host == ENET_HOST_ANY)
			continue;

		p = ping;
		putint(&p, lastmillis);
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

void
checkpings()
{
	enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
	ENetBuffer buf;
	ENetAddress addr;
	uchar ping[MAXTRANS], *p;
	char text[MAXTRANS];
	buf.data = ping;
	buf.dataLength = sizeof(ping);

	while (enet_socket_wait(pingsock, &events, 0) >= 0 && events) {
		if (enet_socket_receive(pingsock, &addr, &buf, 1) <= 0)
			return;







|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

void
checkpings()
{
	enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
	ENetBuffer buf;
	ENetAddress addr;
	unsigned char ping[MAXTRANS], *p;
	char text[MAXTRANS];
	buf.data = ping;
	buf.dataLength = sizeof(ping);

	while (enet_socket_wait(pingsock, &events, 0) >= 0 && events) {
		if (enet_socket_receive(pingsock, &addr, &buf, 1) <= 0)
			return;
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	menuset(1);
}

void
updatefrommaster()
{
	const int MAXUPD = 32000;
	uchar buf[MAXUPD];
	uchar *reply = retrieveservers(buf, MAXUPD);
	if (!*reply || strstr((char *)reply, "<html>") ||
	    strstr((char *)reply, "<HTML>"))
		conoutf(@"master server not replying");
	else {
		[servers removeAllObjects];
		execute(@((char *)reply), true);
	}







|
|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
	menuset(1);
}

void
updatefrommaster()
{
	const int MAXUPD = 32000;
	unsigned char buf[MAXUPD];
	unsigned char *reply = retrieveservers(buf, MAXUPD);
	if (!*reply || strstr((char *)reply, "<html>") ||
	    strstr((char *)reply, "<HTML>"))
		conoutf(@"master server not replying");
	else {
		[servers removeAllObjects];
		execute(@((char *)reply), true);
	}

Modified src/serverms.m from [c145a0420f] to [45981a3e7c].

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
		}
		buf->data = ((char *)buf->data) + len;
		((char *)buf->data)[0] = 0;
		buf->dataLength -= len;
	}
}

static uchar *
stripheader(uchar *b)
{
	char *s = strstr((char *)b, "\n\r\n");
	if (!s)
		s = strstr((char *)b, "\n\n");
	return s ? (uchar *)s : b;
}

static ENetAddress masterserver = { ENET_HOST_ANY, 80 };
static int updmaster = 0;
static OFString *masterbase;
static OFString *masterpath;
static uchar masterrep[MAXTRANS];
static ENetBuffer masterb;

static void
updatemasterserver(int seconds)
{
	// send alive signal to masterserver every hour of uptime
	if (seconds > updmaster) {







|
|




|






|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
		}
		buf->data = ((char *)buf->data) + len;
		((char *)buf->data)[0] = 0;
		buf->dataLength -= len;
	}
}

static unsigned char *
stripheader(unsigned char *b)
{
	char *s = strstr((char *)b, "\n\r\n");
	if (!s)
		s = strstr((char *)b, "\n\n");
	return s ? (unsigned char *)s : b;
}

static ENetAddress masterserver = { ENET_HOST_ANY, 80 };
static int updmaster = 0;
static OFString *masterbase;
static OFString *masterpath;
static unsigned char masterrep[MAXTRANS];
static ENetBuffer masterb;

static void
updatemasterserver(int seconds)
{
	// send alive signal to masterserver every hour of uptime
	if (seconds > updmaster) {
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{
	bool busy = mssock != ENET_SOCKET_NULL;
	httpgetrecieve(&masterb);
	if (busy && mssock == ENET_SOCKET_NULL)
		printf("masterserver reply: %s\n", stripheader(masterrep));
}

uchar *
retrieveservers(uchar *buf, int buflen)
{
	OFString *path =
	    [OFString stringWithFormat:@"%@retrieve.do?item=list", masterpath];
	httpgetsend(
	    &masterserver, masterbase, path, @"cubeserver", @"Cube Server");
	ENetBuffer eb;
	buf[0] = 0;







|
|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
{
	bool busy = mssock != ENET_SOCKET_NULL;
	httpgetrecieve(&masterb);
	if (busy && mssock == ENET_SOCKET_NULL)
		printf("masterserver reply: %s\n", stripheader(masterrep));
}

unsigned char *
retrieveservers(unsigned char *buf, int buflen)
{
	OFString *path =
	    [OFString stringWithFormat:@"%@retrieve.do?item=list", masterpath];
	httpgetsend(
	    &masterserver, masterbase, path, @"cubeserver", @"Cube Server");
	ENetBuffer eb;
	buf[0] = 0;
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{
	checkmasterreply();
	updatemasterserver(seconds);

	// reply all server info requests
	ENetBuffer buf;
	ENetAddress addr;
	uchar pong[MAXTRANS], *p;
	int len;
	enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
	buf.data = pong;
	while (enet_socket_wait(pongsock, &events, 0) >= 0 && events) {
		buf.dataLength = sizeof(pong);
		len = enet_socket_receive(pongsock, &addr, &buf, 1);
		if (len < 0)







|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{
	checkmasterreply();
	updatemasterserver(seconds);

	// reply all server info requests
	ENetBuffer buf;
	ENetAddress addr;
	unsigned char pong[MAXTRANS], *p;
	int len;
	enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
	buf.data = pong;
	while (enet_socket_wait(pongsock, &events, 0) >= 0 && events) {
		buf.dataLength = sizeof(pong);
		len = enet_socket_receive(pongsock, &addr, &buf, 1);
		if (len < 0)

Modified src/serverutil.m from [f5a43d9173] to [25b79fa395].

1
2
3
4
5
6
7
8
9
10
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
// misc useful functions used by the server

#include "cube.h"

// all network traffic is in 32bit ints, which are then compressed using the
// following simple scheme (assumes that most values are small).

void
putint(uchar **p, int n)
{
	if (n < 128 && n > -127) {
		*(*p)++ = n;
	} else if (n < 0x8000 && n >= -0x8000) {
		*(*p)++ = 0x80;
		*(*p)++ = n;
		*(*p)++ = n >> 8;
	} else {
		*(*p)++ = 0x81;
		*(*p)++ = n;
		*(*p)++ = n >> 8;
		*(*p)++ = n >> 16;
		*(*p)++ = n >> 24;
	}
}

int
getint(uchar **p)
{
	int c = *((char *)*p);
	(*p)++;
	if (c == -128) {
		int n = *(*p)++;
		n |= *((char *)*p) << 8;
		(*p)++;
		return n;
	} else if (c == -127) {
		int n = *(*p)++;
		n |= *(*p)++ << 8;
		n |= *(*p)++ << 16;
		return n | (*(*p)++ << 24);
	} else
		return c;
}

void
sendstring(OFString *t_, uchar **p)
{
	const char *t = t_.UTF8String;

	for (size_t i = 0; i < _MAXDEFSTR && *t != '\0'; i++)
		putint(p, *t++);

	putint(p, 0);








|

















|


















|







1
2
3
4
5
6
7
8
9
10
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
// misc useful functions used by the server

#include "cube.h"

// all network traffic is in 32bit ints, which are then compressed using the
// following simple scheme (assumes that most values are small).

void
putint(unsigned char **p, int n)
{
	if (n < 128 && n > -127) {
		*(*p)++ = n;
	} else if (n < 0x8000 && n >= -0x8000) {
		*(*p)++ = 0x80;
		*(*p)++ = n;
		*(*p)++ = n >> 8;
	} else {
		*(*p)++ = 0x81;
		*(*p)++ = n;
		*(*p)++ = n >> 8;
		*(*p)++ = n >> 16;
		*(*p)++ = n >> 24;
	}
}

int
getint(unsigned char **p)
{
	int c = *((char *)*p);
	(*p)++;
	if (c == -128) {
		int n = *(*p)++;
		n |= *((char *)*p) << 8;
		(*p)++;
		return n;
	} else if (c == -127) {
		int n = *(*p)++;
		n |= *(*p)++ << 8;
		n |= *(*p)++ << 16;
		return n | (*(*p)++ << 24);
	} else
		return c;
}

void
sendstring(OFString *t_, unsigned char **p)
{
	const char *t = t_.UTF8String;

	for (size_t i = 0; i < _MAXDEFSTR && *t != '\0'; i++)
		putint(p, *t++);

	putint(p, 0);
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	return -1;
}

// sending of maps between clients

static OFString *copyname;
int copysize;
uchar *copydata = NULL;

void
sendmaps(int n, OFString *mapname, int mapsize, uchar *mapdata)
{
	if (mapsize <= 0 || mapsize > 256 * 256)
		return;
	copyname = mapname;
	copysize = mapsize;
	if (copydata)
		OFFreeMemory(copydata);
	copydata = (uchar *)OFAllocMemory(1, mapsize);
	memcpy(copydata, mapdata, mapsize);
}

ENetPacket *
recvmap(int n)
{
	if (!copydata)
		return NULL;
	ENetPacket *packet = enet_packet_create(
	    NULL, MAXTRANS + copysize, ENET_PACKET_FLAG_RELIABLE);
	uchar *start = packet->data;
	uchar *p = start + 2;
	putint(&p, SV_RECVMAP);
	sendstring(copyname, &p);
	putint(&p, copysize);
	memcpy(p, copydata, copysize);
	p += copysize;
	*(ushort *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	return packet;
}

#ifdef STANDALONE

void
localservertoclient(uchar *buf, int len)
{
}

void
fatal(OFConstantString *s, ...)
{
	cleanupserver();







|


|







|










|
|





|







|







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	return -1;
}

// sending of maps between clients

static OFString *copyname;
int copysize;
unsigned char *copydata = NULL;

void
sendmaps(int n, OFString *mapname, int mapsize, unsigned char *mapdata)
{
	if (mapsize <= 0 || mapsize > 256 * 256)
		return;
	copyname = mapname;
	copysize = mapsize;
	if (copydata)
		OFFreeMemory(copydata);
	copydata = (unsigned char *)OFAllocMemory(1, mapsize);
	memcpy(copydata, mapdata, mapsize);
}

ENetPacket *
recvmap(int n)
{
	if (!copydata)
		return NULL;
	ENetPacket *packet = enet_packet_create(
	    NULL, MAXTRANS + copysize, ENET_PACKET_FLAG_RELIABLE);
	unsigned char *start = packet->data;
	unsigned char *p = start + 2;
	putint(&p, SV_RECVMAP);
	sendstring(copyname, &p);
	putint(&p, copysize);
	memcpy(p, copydata, copysize);
	p += copysize;
	*(unsigned short *)start = ENET_HOST_TO_NET_16(p - start);
	enet_packet_resize(packet, p - start);
	return packet;
}

#ifdef STANDALONE

void
localservertoclient(unsigned char *buf, int len)
{
}

void
fatal(OFConstantString *s, ...)
{
	cleanupserver();

Modified src/tools.h from [1e36fccfb6] to [0a7160063e].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#import <ObjFW/ObjFW.h>

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;

#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define rnd(max) (rand() % (max))
#define rndreset() (srand(1))
#define rndtime()                                            \
	{                                                    \
		for (int i = 0; i < (lastmillis & 0xF); i++) \







<
<
<
<







18
19
20
21
22
23
24




25
26
27
28
29
30
31
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#import <ObjFW/ObjFW.h>





#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define rnd(max) (rand() % (max))
#define rndreset() (srand(1))
#define rndtime()                                            \
	{                                                    \
		for (int i = 0; i < (lastmillis & 0xF); i++) \

Modified src/tools.m from [9fca1834ea] to [8e8dbaa306].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
    void *memory, int stride, int length) // little indians as storage format
{
	if (*((char *)&stride))
		return;

	for (int w = 0; w < length; w++) {
		for (int i = 0; i < stride / 2; i++) {
			uchar *p = (uchar *)memory + w * stride;
			uchar t = p[i];
			p[i] = p[stride - i - 1];
			p[stride - i - 1] = t;
		}
	}
}







|
|





9
10
11
12
13
14
15
16
17
18
19
20
21
22
    void *memory, int stride, int length) // little indians as storage format
{
	if (*((char *)&stride))
		return;

	for (int w = 0; w < length; w++) {
		for (int i = 0; i < stride / 2; i++) {
			unsigned char *p = (unsigned char *)memory + w * stride;
			unsigned char t = p[i];
			p[i] = p[stride - i - 1];
			p[stride - i - 1] = t;
		}
	}
}

Modified src/world.m from [9e368d7a28] to [b3c4009ae5].

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
			o[0] = SWS(w, x, y, ws); // the 4 constituent cubes
			o[1] = SWS(w, x + 1, y, ws);
			o[2] = SWS(w, x + 1, y + 1, ws);
			o[3] = SWS(w, x, y + 1, ws);
			// the target cube in the higher mip level
			struct sqr *r = SWS(v, x / 2, y / 2, vs);
			*r = *o[0];
			uchar nums[MAXTYPE];
			for (int i = 0; i < MAXTYPE; i++)
				nums[i] = 0;
			for (int j = 0; j < 4; j++)
				nums[o[j]->type]++;
			// cube contains both solid and space, treated
			// specially in the renderer
			r->type = SEMISOLID;







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
			o[0] = SWS(w, x, y, ws); // the 4 constituent cubes
			o[1] = SWS(w, x + 1, y, ws);
			o[2] = SWS(w, x + 1, y + 1, ws);
			o[3] = SWS(w, x, y + 1, ws);
			// the target cube in the higher mip level
			struct sqr *r = SWS(v, x / 2, y / 2, vs);
			*r = *o[0];
			unsigned char nums[MAXTYPE];
			for (int i = 0; i < MAXTYPE; i++)
				nums[i] = 0;
			for (int j = 0; j < 4; j++)
				nums[o[j]->type]++;
			// cube contains both solid and space, treated
			// specially in the renderer
			r->type = SEMISOLID;
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
			e.attr2 = 255;
		break;
	case MAPMODEL:
		e.attr4 = e.attr3;
		e.attr3 = e.attr2;
	case MONSTER:
	case TELEDEST:
		e.attr2 = (uchar)e.attr1;
	case PLAYERSTART:
		e.attr1 = (int)player1.yaw;
		break;
	}
	addmsg(1, 10, SV_EDITENT, ents.count, type, e.x, e.y, e.z, e.attr1,
	    e.attr2, e.attr3, e.attr4);








|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
			e.attr2 = 255;
		break;
	case MAPMODEL:
		e.attr4 = e.attr3;
		e.attr3 = e.attr2;
	case MONSTER:
	case TELEDEST:
		e.attr2 = (unsigned char)e.attr1;
	case PLAYERSTART:
		e.attr1 = (int)player1.yaw;
		break;
	}
	addmsg(1, 10, SV_EDITENT, ents.count, type, e.x, e.y, e.z, e.attr1,
	    e.attr2, e.attr3, e.attr4);

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
			e.type = NOTUSED;

	if (type == LIGHT)
		calclight();
}
COMMAND(clearents, ARG_1STR)

static uchar
scalecomp(uchar c, int intens)
{
	int n = c * intens / 100;
	if (n > 255)
		n = 255;
	return n;
}








|
|







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
			e.type = NOTUSED;

	if (type == LIGHT)
		calclight();
}
COMMAND(clearents, ARG_1STR)

static unsigned char
scalecomp(unsigned char c, int intens)
{
	int n = c * intens / 100;
	if (n > 255)
		n = 255;
	return n;
}

Modified src/worldio.m from [a9d5711584] to [7be3522f11].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// worldio.cpp: loading & saving of maps and savegames

#include "cube.h"

#import "Entity.h"

struct persistent_entity {
	short x, y, z; // cube aligned position
	short attr1;
	uchar type; // type is one of the above
	uchar attr2, attr3, attr4;
};

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









|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// worldio.cpp: loading & saving of maps and savegames

#include "cube.h"

#import "Entity.h"

struct persistent_entity {
	short x, y, z; // cube aligned position
	short attr1;
	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];
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
		}
	}
}

// these two are used by getmap/sendmap.. transfers compressed maps directly

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

	FILE *f = fopen([cgzname cStringWithEncoding:OFLocale.encoding], "wb");
	if (!f) {
		conoutf(@"could not write map to %@", cgzname);







|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
		}
	}
}

// these two are used by getmap/sendmap.. transfers compressed maps directly

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);

Modified src/worldlight.m from [20e5b19402] to [78382b218b].

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
	} else // the old (white) light code, here for the few people with old
	       // video cards that don't support overbright
	{
		for (int i = 0; i < steps; i++) {
			struct sqr *s = S(x >> PRECBITS, y >> PRECBITS);
			int light = l >> PRECBITS;
			if (light > s->r)
				s->r = s->g = s->b = (uchar)light;
			if (SOLID(s))
				return;
			x += stepx;
			y += stepy;
			l -= stepl;
		}
	}







|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
	} else // the old (white) light code, here for the few people with old
	       // video cards that don't support overbright
	{
		for (int i = 0; i < steps; i++) {
			struct sqr *s = S(x >> PRECBITS, y >> PRECBITS);
			int light = l >> PRECBITS;
			if (light > s->r)
				s->r = s->g = s->b = (unsigned char)light;
			if (SOLID(s))
				return;
			x += stepx;
			y += stepy;
			l -= stepl;
		}
	}