Cube  Check-in [cd2ac12a14]

Overview
Comment:Add variables with a getter / setter block
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: cd2ac12a141a97a05449c82fbacc67cd3b6a172e66b7fb68bfd785b31d9776c0
User & Date: js on 2025-03-29 22:29:22
Other Links: manifest | tags
Context
2025-04-18
22:18
Check for GL_ARB_texture_env_combine as well check-in: ca2bc91bc3 user: js tags: trunk
2025-03-29
22:29
Add variables with a getter / setter block check-in: cd2ac12a14 user: js tags: trunk
17:13
More style fixes check-in: c634a689e7 user: js tags: trunk
Changes

Modified src/Cube.m from [4173147859] to [1868ef5fa1].

1
2
3
4
5
6
7
8
9
10


11
12







13
14
15
16
17
18
19
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










+
+
-
-
+
+
+
+
+
+
+







// main.cpp: initialisation & main loop

#include "cube.h"

#import "Command.h"
#import "Player.h"
#import "Variable.h"

OF_APPLICATION_DELEGATE(Cube)

static int gamespeed = 100;
VARB(gamespeed, 10, 1000, ^ { return gamespeed; }, ^ (int value) {
VARF(gamespeed, 10, 100, 1000, if (multiplayer()) gamespeed = 100);
VARP(minmillis, 0, 5, 1000);
	if (multiplayer())
		gamespeed = 100;
	else
		gamespeed = value;
})

VARP(minmillis, 0, 5, 1000)

@implementation Cube
{
	int _width, _height;
}

+ (Cube *)sharedInstance

Modified src/Monster.m from [aa7be47ff2] to [08ccfa5f00].

31
32
33
34
35
36
37



38


39
40
41
42
43
44
45
31
32
33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49







+
+
+
-
+
+







	return [[self alloc] initWithType: type
				      yaw: yaw
				    state: state
				  trigger: trigger
				     move: move];
}

static int skill = 3;
VARB(skill, 1, 10, ^ { return skill; }, ^ (int value) {
	skill = value;
VARF(skill, 1, 3, 10, conoutf(@"skill is now %d", skill));
	conoutf(@"skill is now %d", skill);
})

// for savegames
+ (void)restoreAll
{
	for (Monster *monster in monsters)
		if (monster.state == CS_DEAD)
			numkilled++;

Modified src/OFColor+Cube.h from [7398d21dd3] to [fe964137ac].

1
2
3
4


5
1
2
3
4
5
6
7




+
+

#import <ObjFW/ObjFW.h>

@interface OFColor (Cube)
- (void)cube_setAsGLColor;
- (void)cube_setAsGLClearColor;
- (void)cube_setAsGLFogColor;
@end

Modified src/OFColor+Cube.m from [a418a3dce6] to [054d4ed36a].

1
2
3
4
5
6
7
8

9

10
11





















12
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








+

+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

#include "cube.h"

#import "OFColor+Cube.h"

@implementation OFColor (Cube)
- (void)cube_setAsGLColor
{
	float red, green, blue, alpha;

	[self getRed: &red green: &green blue: &blue alpha: &alpha];

	glColor4f(red, green, blue, alpha);
}

- (void)cube_setAsGLClearColor
{
	float red, green, blue, alpha;

	[self getRed: &red green: &green blue: &blue alpha: &alpha];

	glClearColor(red, green, blue, alpha);
}

- (void)cube_setAsGLFogColor
{
	float color[4];

	[self getRed: &color[0]
	       green: &color[1]
		blue: &color[2]
	       alpha: &color[3]];

	glFogfv(GL_FOG_COLOR, color);
}
@end

Modified src/Variable.h from [237ce5cd40] to [9c9dde493b].

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

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
80
81
82
83
84
85

86
87
88



89
90
91
92
93

94
95



96
97
98
99
100

101
102
103




104
105
106
107
108
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

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

80


81
82
83
84
85
86
87

88



89
90
91
92
93

94
95
96




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
-
+
+
+



-
+
-
-
+









-
-
+
+
+


+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
+
-
-
-




-
-
-
-
+
+
+
+
-
-
+
+
+


-
-
-
-
-
-




+
-
-
-
+
+
+




-
+
-
-
+
+
+




-
+
-
-
-
+
+
+
+

-



#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

#define VARP(name, min_, cur, max_)					\
	int name = cur;							\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\
				    function: NULL			\
				   persisted: true];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VAR(name, min_, cur, max_)					\
	int name = cur;							\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\
				    function: NULL			\
				   persisted: false];			\
				   persisted: false			\
				      getter: NULL			\
				      setter: NULL];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARF(name, min_, cur, max_, body)				\
#define VARP(name, min_, cur, max_)					\
	static void var_##name(void);					\
	static int name = cur;						\
	int name = cur;							\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\
				    function: var_##name		\
				   persisted: false];			\
				   persisted: true			\
				      getter: NULL			\
				      setter: NULL];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARB(name, min_, max_, getter_, setter_)			\
	OF_CONSTRUCTOR()						\
	}								\
	{								\
									\
	static void							\
	var_##name(void)						\
	{								\
		body;							\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: NULL			\
				   persisted: false			\
				      getter: getter_			\
				      setter: setter_];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARFP(name, min_, cur, max_, body)				\
#define VARBP(name, min_, max_, getter_, setter_)			\
	static void var_##name(void);					\
	static int name = cur;						\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			variableWithName: @#name			\
				     min: min_				\
				     max: max_				\
				 storage: &name				\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: NULL			\
				function: var_##name			\
			       persisted: true];			\
				   persisted: true			\
				      getter: getter_			\
				      setter: setter_];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}								\
									\
	static void							\
	var_##name(void)						\
	{								\
		body;							\
	}

@interface Variable: Identifier
@property (direct, readonly, nonatomic) int min, max;
@property (readonly, nonatomic) bool persisted;
@property (direct, readonly, nonatomic) int *storage;
@property (direct, readonly, nullable, nonatomic) void (*function)();
@property (readonly, nonatomic) bool persisted;
@property (direct, readonly, nullable, nonatomic) int (^getter)(void);
@property (direct, readonly, nullable, nonatomic) void (^setter)(int);
@property (direct, nonatomic) int value;

+ (instancetype)variableWithName: (OFString *)name
			     min: (int)min
			     max: (int)max
			 storage: (int *)storage
			 storage: (nullable int *)storage
			function: (void (*_Nullable)())function
		       persisted: (bool)persisted OF_DIRECT;
		       persisted: (bool)persisted
			  getter: (int (^_Nullable)(void))getter
			  setter: (void (^_Nullable)(int))setter OF_DIRECT;
- (instancetype)initWithName: (OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName: (OFString *)name
			 min: (int)min
			 max: (int)max
		     storage: (int *)storage
		     storage: (nullable int *)storage
		    function: (void (*_Nullable)())function
		   persisted: (bool)persisted OF_DESIGNATED_INITIALIZER
    OF_DIRECT;
		   persisted: (bool)persisted
		      getter: (int (^_Nullable)(void))getter
		      setter: (void (^_Nullable)(int))setter
    OF_DESIGNATED_INITIALIZER OF_DIRECT;
- (void)printValue OF_DIRECT;
- (void)setValue: (int)value OF_DIRECT;
@end

OF_ASSUME_NONNULL_END

Modified src/Variable.m from [892ebc7d62] to [9d395dd08f].

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
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
54
55
56





+
+
+
+




-

+
+





-
-
+
+
+






-

+
+






-

+
+






-
+







#import "Variable.h"

#include "cube.h"

@implementation Variable
{
	int *_storage;
}

+ (instancetype)variableWithName: (OFString *)name
			     min: (int)min
			     max: (int)max
			 storage: (int *)storage
			function: (void (*__cdecl)())function
		       persisted: (bool)persisted
			  getter: (int (^)(void))getter
			  setter: (void (^)(int))setter
{
	return [[self alloc] initWithName: name
				      min: min
				      max: max
				  storage: storage
				 function: function
				persisted: persisted];
				persisted: persisted
				   getter: getter
				   setter: setter];
}

- (instancetype)initWithName: (OFString *)name
			 min: (int)min
			 max: (int)max
		     storage: (int *)storage
		    function: (void (*__cdecl)())function
		   persisted: (bool)persisted
		      getter: (int (^)(void))getter
		      setter: (void (^)(int))setter
{
	self = [super initWithName: name];

	_min = min;
	_max = max;
	_storage = storage;
	_function = function;
	_persisted = persisted;
	_getter = [getter copy];
	_setter = [setter copy];

	return self;
}

- (void)printValue
{
	conoutf(@"%@ = %d", self.name, *_storage);
	conoutf(@"%@ = %d", self.name, self.value);
}

- (void)setValue: (int)value
{
	bool outOfRange = false;

	if (_min > _max) {
56
57
58
59
60
61
62
63

64

65
66
67
68
69
70














71
72
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







-
+

+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+


	}

	if (value > _max) {
		value = _max;
		outOfRange = true;
	}

	if (outOfRange)
	if (outOfRange) {
		conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max);
		return;

	*_storage = value;

	if (_function != NULL)
		// call trigger function if available
		_function();
	}

	if (_setter != NULL)
		_setter(value);
	else
		*_storage = value;
}

- (int)value
{
	if (_getter != NULL)
		return _getter();
	else
		return *_storage;
}
@end

Modified src/clients.m from [895b86000b] to [6f1a324e2b].

38
39
40
41
42
43
44



45

46
47
48


49
50
51
52
53



54
55
56


57
58
59

60

61
62
63













64
65
66
67
68
69
70
38
39
40
41
42
43
44
45
46
47

48
49


50
51

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
80
81
82
83
84
85
86
87







+
+
+
-
+

-
-
+
+
-

-
-
-
+
+
+

-
-
+
+



+

+



+
+
+
+
+
+
+
+
+
+
+
+
+








	if (!allow)
		conoutf(@"editing in multiplayer requires coopedit mode (1)");

	return allow;
}

static int rate = 0;
VARB(rate, 0, 25000, ^ { return rate; }, ^ (int value) {
	rate = value;
VARF(rate, 0, 0, 25000,

	if (clienthost && (!rate || rate > 1000))
		enet_host_bandwidth_limit(clienthost, rate, rate));

		enet_host_bandwidth_limit(clienthost, rate, rate);
})
void throttle();

VARF(throttle_interval, 0, 5, 30, throttle());
VARF(throttle_accel, 0, 2, 32, throttle());
VARF(throttle_decel, 0, 2, 32, throttle());
static int throttle_interval = 5;
static int throttle_accel = 2;
static int throttle_decel = 2;

void
throttle()
static void
throttle(void)
{
	if (!clienthost || connecting)
		return;

	assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32);

	enet_peer_throttle_configure(clienthost->peers,
	    throttle_interval * 1000, throttle_accel, throttle_decel);
}

VARB(throttle_interval, 0, 30, ^ { return throttle_interval; }, ^ (int value) {
	throttle_interval = value;
	throttle();
})
VARB(throttle_accel, 0, 32, ^ { return throttle_accel; }, ^ (int value) {
	throttle_accel = value;
	throttle();
})
VARB(throttle_decel, 0, 32, ^ { return throttle_decel; }, ^ (int value) {
	throttle_decel = value;
	throttle();
})

static void
newname(OFString *name)
{
	c2sinit = false;

	if (name.length > 16)

Modified src/commands.m from [e486b084f6] to [1ba8e7e154].

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+








-
+








void
setvar(OFString *name, int i)
{
	Variable *variable = Identifier.identifiers[name];

	if ([variable isKindOfClass: Variable.class])
		*variable.storage = i;
		variable.value = i;
}

int
getvar(OFString *name)
{
	Variable *variable = Identifier.identifiers[name];

	if ([variable isKindOfClass: Variable.class])
		return *variable.storage;
		return variable.value;

	return 0;
}

bool
identexists(OFString *name)
{
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154







-
+







lookup(OFString *n)
{
	__kindof Identifier *identifier =
	    Identifier.identifiers[[n substringFromIndex: 1]];

	if ([identifier isKindOfClass: Variable.class]) {
		return [OFString stringWithFormat:
		    @"%d", *[identifier storage]];
		    @"%d", [identifier value]];
	} else if ([identifier isKindOfClass: Alias.class])
		return [identifier action];

	conoutf(@"unknown alias lookup: %@", [n substringFromIndex: 1]);
	return n;
}

346
347
348
349
350
351
352
353
354
355



356
357
358

359
360
361
362
363
364
365
366
346
347
348
349
350
351
352



353
354
355
356
357

358

359
360
361
362
363
364
365







-
-
-
+
+
+


-
+
-







	    @"// modify settings in game, or put settings in autoexec.cfg to "
	    @"override anything\n"
	    @"\n"];
	writeclientinfo(stream);
	[stream writeString: @"\n"];

	[Identifier.identifiers enumerateKeysAndObjectsUsingBlock:
	    ^ (OFString *name, __kindof Identifier *identifier, bool *stop) {
		if (![identifier isKindOfClass: Variable.class] ||
		    ![identifier persisted])
	    ^ (OFString *name, Variable *variable, bool *stop) {
		if (![variable isKindOfClass: Variable.class] ||
		    !variable.persisted)
			return;

		[stream writeFormat:
		[stream writeFormat: @"%@ %d\n", variable.name, variable.value];
		    @"%@ %d\n", identifier.name, *[identifier storage]];
	}];
	[stream writeString: @"\n"];

	writebinds(stream);
	[stream writeString: @"\n"];

	[Identifier.identifiers enumerateKeysAndObjectsUsingBlock:

Modified src/editing.m from [974268cfe4] to [554de9b14f].

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







-
-
+
+
+
+
+
+







-
-
+
+
+








OF_CONSTRUCTOR()
{
	enqueueInit(^ {
		static const struct {
			OFString *name;
			int *storage;
		} vars[4] = { { @"selx", &sel.x }, { @"sely", &sel.y },
			{ @"selxs", &sel.xs }, { @"selys", &sel.ys } };
		} vars[4] = {
			{ @"selx", &sel.x },
			{ @"sely", &sel.y },
			{ @"selxs", &sel.xs },
			{ @"selys", &sel.ys }
		};

		for (size_t i = 0; i < 4; i++) {
			Variable *variable = [Variable
			    variableWithName: vars[i].name
					 min: 0
					 max: 4096
				     storage: vars[i].storage
				    function: NULL
				   persisted: false];
				   persisted: false
				      getter: NULL
				      setter: NULL];
			Identifier.identifiers[vars[i].name] = variable;
		}
	});
}

int selh = 0;
bool selset = false;
630
631
632
633
634
635
636
637
638
639
640
641
642
643










644
645
646
647
648
649
650
635
636
637
638
639
640
641







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658







-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+








	remipmore(&sel, 0);

	sel.xs--;
	sel.ys--;
})

VARF(
    fullbright, 0, 0, 1, if (fullbright) {
	    if (noteditmode())
		    return;
	    for (int i = 0; i < mipsize; i++)
		    world[i].r = world[i].g = world[i].b = 176;
    });
static int fullbright = 0;
VARB(fullbright, 0, 1, ^ { return fullbright; }, ^ (int value) {
	if (fullbright) {
		if (noteditmode())
			return;

		for (int i = 0; i < mipsize; i++)
			world[i].r = world[i].g = world[i].b = 176;
	}
});

COMMAND(edittag, ARG_1INT, ^ (int tag) {
	EDITSELMP;

	struct block *sel_ = &sel;
	// Ugly hack to make the macro work.
	struct block *sel = sel_;

Modified src/rendercubes.m from [ee90f3d4f5] to [87348a3299].

316
317
318
319
320
321
322

323
324




325
326
327
328
329
330
331
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
331
332
333
334







+
-
-
+
+
+
+







	nquads++;
	addstrip(gltex, curvert - 4, 4);
}

int wx1, wy1, wx2, wy2;

VAR(watersubdiv, 1, 4, 64);

VARF(waterlevel, -128, -128, 127,
    if (!noteditmode()) hdr.waterlevel = waterlevel);
VARB(waterlevel, -128, 127, ^ { return hdr.waterlevel; }, ^ (int value) {
	if (!noteditmode())
		hdr.waterlevel = value;
})

static inline void
vertw(int v1, float v2, int v3, struct sqr *c, float t1, float t2, float t)
{
	vertcheck();
	vertf((float)v1, v2 - (float)sin(v1 * v3 * 0.1 + t) * 0.2f, (float)v3,
	    c, t1, t2);

Modified src/rendergl.m from [e10c3367c9] to [072d71a9b6].

323
324
325
326
327
328
329

330
331


332
333
334
335
336
337



338
339
340
341
342
343
344
323
324
325
326
327
328
329
330


331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
347







+
-
-
+
+





-
+
+
+








	struct strip s = { .tex = tex, .start = start, .num = n };
	[strips addItem: &s];
}

#undef gamma

static int gamma = 100;
VARFP(gamma, 30, 100, 300, {
	float f = gamma / 100.0f;
VARBP(gamma, 30, 300, ^ { return gamma; }, ^ (int value) {
	float f = value / 100.0f;
	Uint16 ramp[256];

	SDL_CalculateGammaRamp(f, ramp);

	if (SDL_SetWindowGammaRamp(Cube.sharedInstance.window,
	    ramp, ramp, ramp) == -1) {
	    ramp, ramp, ramp) != -1)
		gamma = value;
	else {
		conoutf(
		    @"Could not set gamma (card/driver doesn't support it?)");
		conoutf(@"sdl: %s", SDL_GetError());
	}
})

void
358
359
360
361
362
363
364


365





















366
367
368
369
370
371
372
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397







+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







}

VARP(fov, 10, 105, 120);

int xtraverts;

VAR(fog, 64, 180, 1024);

static OFColor *fogColor;
VAR(fogcolour, 0, 0x8099B3, 0xFFFFFF);
VARB(fogcolour, 0, 0xFFFFFF, (^ {
	float red, green, blue;

	if (fogColor == nil)
		return 0x8099B3;

	[fogColor getRed: &red green: &green blue: &blue alpha: NULL];

	return ((unsigned char)(red * 255.0f) << 16) |
	    ((unsigned char)(green * 255.0f) << 8) |
	    (unsigned char)(blue * 255.0f);
}), ^ (int value) {
	unsigned char red = (value >> 16) & 0xFF;
	unsigned char green = (value >> 8) & 0xFF;
	unsigned char blue = value & 0xFF;

	fogColor = [OFColor colorWithRed: red / 255.0f
				   green: green / 255.0f
				    blue: blue / 255.0f
				   alpha: 1.f];
})

VARP(hudgun, 0, 1, 1);

OFString *hudgunnames[] = { @"hudguns/fist", @"hudguns/shotg",
	@"hudguns/chaing", @"hudguns/rocket", @"hudguns/rifle" };

void
418
419
420
421
422
423
424
425
426
427
428
429


430
431
432
433
434
435
436
443
444
445
446
447
448
449





450
451
452
453
454
455
456
457
458







-
-
-
-
-
+
+







	float hf = hdr.waterlevel - 0.3f;
	float fovy = (float)fov * h / w;
	float aspect = w / (float)h;
	bool underwater = (player1.origin.z < hf);

	glFogi(GL_FOG_START, (fog + 64) / 8);
	glFogi(GL_FOG_END, fog);
	float fogc[4] = { (fogcolour >> 16) / 256.0f,
		((fogcolour >> 8) & 255) / 256.0f, (fogcolour & 255) / 256.0f,
		1.0f };
	glFogfv(GL_FOG_COLOR, fogc);
	glClearColor(fogc[0], fogc[1], fogc[2], 1.0f);
	[fogColor cube_setAsGLFogColor];
	[fogColor cube_setAsGLClearColor];

	if (underwater) {
		fovy += (float)sin(lastmillis / 1000.0) * 2.0f;
		aspect += (float)sin(lastmillis / 1000.0 + PI) * 0.1f;
		glFogi(GL_FOG_START, 0);
		glFogi(GL_FOG_END, (fog + 96) / 8);
	}

Modified src/renderparticles.m from [187397123f] to [afec899fb1].

1
2
3
4

5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
12




+







// renderparticles.cpp

#include "cube.h"

#import "OFColor+Cube.h"
#import "Player.h"
#import "Variable.h"

#define MAXPARTICLES 10500
const int NUMPARTCUTOFF = 20;
struct particle {
	OFVector3D o, d;
62
63
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
63
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
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







-
+



+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










-
+








	glDepthMask(GL_FALSE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
	glDisable(GL_FOG);

	struct parttype {
		float r, g, b;
		OFColor *color;
		int gr, tex;
		float sz;
	} parttypes[] = {
		/*
		 * Note: Some comments don't match the color. This was already
		 *	 the case in the original.
		 */

		{ 0.7f, 0.6f, 0.3f, 2, 3, 0.06f },  // yellow: sparks
		{ 0.5f, 0.5f, 0.5f, 20, 7, 0.15f }, // grey:   small smoke
		{ 0.2f, 0.2f, 1.0f, 20, 3, 0.08f }, // blue:   edit mode entities
		{ 1.0f, 0.1f, 0.1f, 1, 7, 0.06f },  // red:    blood spats
		{ 1.0f, 0.8f, 0.8f, 20, 6, 1.2f },  // yellow: fireball1
		{ 0.5f, 0.5f, 0.5f, 20, 7, 0.6f },  // grey:   big smoke
		{ 1.0f, 1.0f, 1.0f, 20, 8, 1.2f },  // blue:   fireball2
		{ 1.0f, 1.0f, 1.0f, 20, 9, 1.2f },  // green:  fireball3
		{ 1.0f, 0.1f, 0.1f, 0, 7, 0.2f },   // red:    demotrack
		// yellow: sparks
		{ [OFColor colorWithRed: 0.7f
				  green: 0.6f
				   blue: 0.3f
				  alpha: 1.0f], 2, 3, 0.06f },
		// grey: small smoke
		{ OFColor.gray, 20, 7, 0.15f },
		// blue: edit mode entities
		{ [OFColor colorWithRed: 0.2f
				  green: 0.2f
				   blue: 1.0f
				  alpha: 1.0f], 20, 3, 0.08f },
		// red: blood spats
		{ [OFColor colorWithRed: 1.0f
				  green: 0.1f
				   blue: 0.1f
				  alpha: 1.0f], 1, 7, 0.06f },
		// yellow: fireball1
		{ [OFColor colorWithRed: 1.0f
				  green: 0.8f
				   blue: 0.8f
				  alpha: 1.0f], 20, 6, 1.2f },
		// grey: big smoke
		{ [OFColor colorWithRed: 0.5f
				  green: 0.5f
				   blue: 0.5f
				  alpha: 1.0f], 20, 7, 0.6f },
		// blue: fireball2
		{ OFColor.white, 20, 8, 1.2f },
		// green: fireball3
		{ OFColor.white, 20, 9, 1.2f },
		// red: demotrack
		{ [OFColor colorWithRed: 1.0f
				  green: 0.1f
				   blue: 0.1f
				  alpha: 1.0f], 0, 7, 0.2f }
	};

	int numrender = 0;

	for (struct particle *p, **pp = &parlist; (p = *pp) != NULL;) {
		struct parttype *pt = &parttypes[p->type];

		glBindTexture(GL_TEXTURE_2D, pt->tex);
		glBegin(GL_QUADS);

		glColor3d(pt->r, pt->g, pt->b);
		[pt->color cube_setAsGLColor];
		float sz = pt->sz * particlesize / 100.0f;
		// perf varray?
		glTexCoord2f(0.0, 1.0);
		glVertex3d(p->o.x + (-right.x + up.x) * sz,
		    p->o.z + (-right.y + up.y) * sz,
		    p->o.y + (-right.z + up.z) * sz);
		glTexCoord2f(1.0, 1.0);