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
// main.cpp: initialisation & main loop

#include "cube.h"

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

OF_APPLICATION_DELEGATE(Cube)



VARF(gamespeed, 10, 100, 1000, if (multiplayer()) gamespeed = 100);





VARP(minmillis, 0, 5, 1000);

@implementation Cube
{
	int _width, _height;
}

+ (Cube *)sharedInstance










>
>
|
>
>
>
>
>
|







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) {
	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
	return [[self alloc] initWithType: type
				      yaw: yaw
				    state: state
				  trigger: trigger
				     move: move];
}




VARF(skill, 1, 3, 10, conoutf(@"skill is now %d", skill));


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







>
>
>
|
>







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;
	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
#import <ObjFW/ObjFW.h>

@interface OFColor (Cube)
- (void)cube_setAsGLColor;


@end




>
>

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





















@end








>

>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
#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];			\


			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARF(name, min_, cur, max_, body)				\
	static void var_##name(void);					\
	static int name = cur;						\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\
				    function: var_##name		\
				   persisted: false];			\


			Identifier.identifiers[@#name] = variable;	\
		});							\



	}								\
									\
	static void							\

	var_##name(void)						\
	{								\






		body;							\
	}
#define VARFP(name, min_, cur, max_, body)				\
	static void var_##name(void);					\
	static int name = cur;						\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			variableWithName: @#name			\
				     min: min_				\
				     max: max_				\
				 storage: &name				\
				function: var_##name			\
			       persisted: true];			\


			Identifier.identifiers[@#name] = variable;	\
		});							\
	}								\
									\
	static void							\
	var_##name(void)						\
	{								\
		body;							\
	}

@interface Variable: Identifier
@property (direct, readonly, nonatomic) int min, max;

@property (direct, readonly, nonatomic) int *storage;
@property (direct, readonly, nullable, nonatomic) void (*function)();
@property (readonly, nonatomic) bool persisted;

+ (instancetype)variableWithName: (OFString *)name
			     min: (int)min
			     max: (int)max
			 storage: (int *)storage
			function: (void (*_Nullable)())function
		       persisted: (bool)persisted OF_DIRECT;


- (instancetype)initWithName: (OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName: (OFString *)name
			 min: (int)min
			 max: (int)max
		     storage: (int *)storage
		    function: (void (*_Nullable)())function
		   persisted: (bool)persisted OF_DESIGNATED_INITIALIZER


    OF_DIRECT;
- (void)printValue OF_DIRECT;
- (void)setValue: (int)value OF_DIRECT;
@end

OF_ASSUME_NONNULL_END




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
|
>
>



|
<
|









<
|
>
>


>
>
>
|
<
|
>
|
|
>
>
>
>
>
>
|

|
<
<
<




|
|
|
|
<
|
>
>


<
<
<
<
<
<




>
|
|
|




|
<
|
>
>




|
<
|
>
>
|

<



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 VAR(name, min_, cur, max_)					\
	int name = cur;							\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\

				   persisted: false			\
				      getter: NULL			\
				      setter: NULL];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARP(name, min_, cur, max_)					\

	int name = cur;							\
									\
	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: &name			\

				   persisted: true			\
				      getter: NULL			\
				      setter: NULL];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARB(name, min_, max_, getter_, setter_)			\
	OF_CONSTRUCTOR()						\
	{								\

		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: NULL			\
				   persisted: false			\
				      getter: getter_			\
				      setter: setter_];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\
	}
#define VARBP(name, min_, max_, getter_, setter_)			\



	OF_CONSTRUCTOR()						\
	{								\
		enqueueInit(^ {						\
			Variable *variable = [Variable			\
			    variableWithName: @#name			\
					 min: min_			\
					 max: max_			\
				     storage: NULL			\

				   persisted: true			\
				      getter: getter_			\
				      setter: setter_];			\
			Identifier.identifiers[@#name] = variable;	\
		});							\






	}

@interface Variable: Identifier
@property (direct, readonly, nonatomic) int min, max;
@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: (nullable int *)storage

		       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: (nullable int *)storage

		   persisted: (bool)persisted
		      getter: (int (^_Nullable)(void))getter
		      setter: (void (^_Nullable)(int))setter
    OF_DESIGNATED_INITIALIZER OF_DIRECT;
- (void)printValue 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
#import "Variable.h"

#include "cube.h"

@implementation Variable




+ (instancetype)variableWithName: (OFString *)name
			     min: (int)min
			     max: (int)max
			 storage: (int *)storage
			function: (void (*__cdecl)())function
		       persisted: (bool)persisted


{
	return [[self alloc] initWithName: name
				      min: min
				      max: max
				  storage: storage
				 function: function
				persisted: persisted];


}

- (instancetype)initWithName: (OFString *)name
			 min: (int)min
			 max: (int)max
		     storage: (int *)storage
		    function: (void (*__cdecl)())function
		   persisted: (bool)persisted


{
	self = [super initWithName: name];

	_min = min;
	_max = max;
	_storage = storage;
	_function = function;
	_persisted = persisted;



	return self;
}

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

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

	if (_min > _max) {





>
>
>
>




<

>
>





<
|
>
>






<

>
>






<

>
>






|







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

		       persisted: (bool)persisted
			  getter: (int (^)(void))getter
			  setter: (void (^)(int))setter
{
	return [[self alloc] initWithName: name
				      min: min
				      max: max
				  storage: storage

				persisted: persisted
				   getter: getter
				   setter: setter];
}

- (instancetype)initWithName: (OFString *)name
			 min: (int)min
			 max: (int)max
		     storage: (int *)storage

		   persisted: (bool)persisted
		      getter: (int (^)(void))getter
		      setter: (void (^)(int))setter
{
	self = [super initWithName: name];

	_min = min;
	_max = max;
	_storage = storage;

	_persisted = persisted;
	_getter = [getter copy];
	_setter = [setter copy];

	return self;
}

- (void)printValue
{
	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
	}

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

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






	*_storage = value;

	if (_function != NULL)


		// call trigger function if available
		_function();


}
@end







|

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


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) {
		conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max);
		return;
	}

	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

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

	return allow;
}




VARF(rate, 0, 0, 25000,
	if (clienthost && (!rate || rate > 1000))
		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());

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

	assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32);

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














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

	if (name.length > 16)







>
>
>
|

|
|
<

|
|
|

|
|



>

>



>
>
>
>
>
>
>
>
>
>
>
>
>







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;

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


static int throttle_interval = 5;
static int throttle_accel = 2;
static int throttle_decel = 2;

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

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

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

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

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

	return 0;
}

bool
identexists(OFString *name)
{







|








|







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.value = i;
}

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

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

	return 0;
}

bool
identexists(OFString *name)
{
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]];
	} else if ([identifier isKindOfClass: Alias.class])
		return [identifier action];

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








|







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 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
	    @"// 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])
			return;

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

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

	[Identifier.identifiers enumerateKeysAndObjectsUsingBlock:







|
|
|


|
<







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, Variable *variable, bool *stop) {
		if (![variable isKindOfClass: Variable.class] ||
		    !variable.persisted)
			return;

		[stream writeFormat: @"%@ %d\n", variable.name, variable.value];

	}];
	[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

OF_CONSTRUCTOR()
{
	enqueueInit(^ {
		static const struct {
			OFString *name;
			int *storage;
		} 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];


			Identifier.identifiers[vars[i].name] = variable;
		}
	});
}

int selh = 0;
bool selset = false;







|
>
>
|
>
>







<
|
>
>







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

		for (size_t i = 0; i < 4; i++) {
			Variable *variable = [Variable
			    variableWithName: vars[i].name
					 min: 0
					 max: 4096
				     storage: vars[i].storage

				   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

	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;

    });

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

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







<
>
>
|
|
|
>
|
|
>
|







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


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



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







>
|
|
>
>







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

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

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

#undef gamma


VARFP(gamma, 30, 100, 300, {
	float f = gamma / 100.0f;
	Uint16 ramp[256];

	SDL_CalculateGammaRamp(f, ramp);

	if (SDL_SetWindowGammaRamp(Cube.sharedInstance.window,
	    ramp, ramp, ramp) == -1) {


		conoutf(
		    @"Could not set gamma (card/driver doesn't support it?)");
		conoutf(@"sdl: %s", SDL_GetError());
	}
})

void







>
|
|





|
>
>







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

VARP(fov, 10, 105, 120);

int xtraverts;

VAR(fog, 64, 180, 1024);


VAR(fogcolour, 0, 0x8099B3, 0xFFFFFF);





















VARP(hudgun, 0, 1, 1);

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

void







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







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

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







<
<
<
|
|







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



	[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
// renderparticles.cpp

#include "cube.h"


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

#define MAXPARTICLES 10500
const int NUMPARTCUTOFF = 20;
struct particle {
	OFVector3D o, d;




>







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

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

	struct parttype {
		float r, g, b;
		int gr, tex;
		float sz;
	} parttypes[] = {





		{ 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
	};

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







|



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










|







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 {
		OFColor *color;
		int gr, tex;
		float sz;
	} parttypes[] = {
		/*
		 * Note: Some comments don't match the color. This was already
		 *	 the case in the original.
		 */

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

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