Cube  Check-in [0ee94739ce]

Overview
Comment:Clean up Variable
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 0ee94739cea768327664b83a23470a366e90ac45fd6c51537b5188268aa8e97c
User & Date: js on 2025-03-25 23:38:08
Other Links: manifest | tags
Context
2025-03-25
23:52
Make use of OF_DIRECT check-in: 7a98b92af9 user: js tags: trunk
23:38
Clean up Variable check-in: 0ee94739ce user: js tags: trunk
23:03
Add forgotten files check-in: 489bb6c39a user: js tags: trunk
Changes

Modified src/Command.h from [a73716cedf] to [06ddb224b0].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

#define COMMAND(name, nargs, block_)                                         \
	OF_CONSTRUCTOR()                                                     \
	{                                                                    \
		enqueueInit(^{                                               \
			[Identifier                                          \
			    addIdentifier:[Command commandWithName:@ #name   \
			                            argumentsTypes:nargs     \
			                                     block:block_]]; \
		});                                                          \
	}

@interface Command: Identifier
@property (readonly, nonatomic) int argumentsTypes;

+ (instancetype)commandWithName:(OFString *)name
                 argumentsTypes:(int)argumentsTypes




|
|
|
|
|
|
|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN

#define COMMAND(name, nargs, block_)                          \
	OF_CONSTRUCTOR()                                      \
	{                                                     \
		enqueueInit(^{                                \
			Identifier.identifiers[@ #name] =     \
			    [Command commandWithName:@ #name  \
			              argumentsTypes:nargs    \
			                       block:block_]; \
		});                                           \
	}

@interface Command: Identifier
@property (readonly, nonatomic) int argumentsTypes;

+ (instancetype)commandWithName:(OFString *)name
                 argumentsTypes:(int)argumentsTypes

Modified src/Cube.m from [8c59576626] to [5cd2f98f97].

1
2
3
4
5
6

7
8
9
10
11
12
13
// main.cpp: initialisation & main loop

#include "cube.h"

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


OF_APPLICATION_DELEGATE(Cube)

VARF(gamespeed, 10, 100, 1000, if (multiplayer()) gamespeed = 100);
VARP(minmillis, 0, 5, 1000);

@implementation Cube






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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

Modified src/Identifier.h from [8e21f78264] to [77172769a0].

1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface Identifier: OFObject
@property (readonly, copy, nonatomic) OFString *name;



+ (void)addIdentifier:(__kindof Identifier *)identifier;
+ (__kindof Identifier *)identifierForName:(OFString *)name;
+ (void)enumerateIdentifiersUsingBlock:(void (^)(__kindof Identifier *))block;
- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name;
@end

OF_ASSUME_NONNULL_END






>
>

<
<
<





1
2
3
4
5
6
7
8
9



10
11
12
13
14
#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

@interface Identifier: OFObject
@property (readonly, copy, nonatomic) OFString *name;
@property (class, readonly, nonatomic)
    OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;




- (instancetype)init OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name;
@end

OF_ASSUME_NONNULL_END

Modified src/Identifier.m from [a76ca7afae] to [9cd9c4b220].

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
#import "Identifier.h"

// contains ALL vars/commands/aliases
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;

@implementation Identifier
+ (void)initialize
{
	if (self == Identifier.class)
		identifiers = [[OFMutableDictionary alloc] init];
}

+ (void)addIdentifier:(__kindof Identifier *)identifier
{
	identifiers[identifier.name] = identifier;
}

+ (__kindof Identifier *)identifierForName:(OFString *)name
{
	return identifiers[name];
}

+ (void)enumerateIdentifiersUsingBlock:(void (^)(__kindof Identifier *))block
{
	[identifiers enumerateKeysAndObjectsUsingBlock:^(
	    OFString *name, __kindof Identifier *identifier, bool *stop) {
		block(identifier);
	}];
}

- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];












|

<
<
<
<
<
|
<
<
<
<
<
<
<
<







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





15








16
17
18
19
20
21
22
#import "Identifier.h"

// contains ALL vars/commands/aliases
static OFMutableDictionary<OFString *, __kindof Identifier *> *identifiers;

@implementation Identifier
+ (void)initialize
{
	if (self == Identifier.class)
		identifiers = [[OFMutableDictionary alloc] init];
}

+ (OFMutableDictionary<OFString *, __kindof Identifier *> *)identifiers
{





	return identifiers;








}

- (instancetype)initWithName:(OFString *)name
{
	self = [super init];

	_name = [name copy];

Modified src/Monster.m from [0a9cae30d2] to [96bb3308b2].

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
// monster.cpp: implements AI for single player monsters, currently client only

#import "Monster.h"

#include "cube.h"

#import "Entity.h"
#import "Player.h"


static OFMutableArray<Monster *> *monsters;
static int nextmonster, spawnremain, numkilled, monstertotal, mtimestart;

@implementation Monster
+ (void)initialize
{








>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// monster.cpp: implements AI for single player monsters, currently client only

#import "Monster.h"

#include "cube.h"

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

static OFMutableArray<Monster *> *monsters;
static int nextmonster, spawnremain, numkilled, monstertotal, mtimestart;

@implementation Monster
+ (void)initialize
{

Modified src/Variable.h from [1fe61b3c20] to [2cd074eb9f].

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
#import "Identifier.h"

OF_ASSUME_NONNULL_BEGIN








































































@interface Variable: Identifier
@property (readonly, nonatomic) int min, max;
@property (readonly, nonatomic) int *storage;
@property (readonly, nonatomic) void (*__cdecl function)();
@property (readonly, nonatomic) bool persisted;

+ (instancetype)variableWithName:(OFString *)name
                             min:(int)min
                             max:(int)max
                         storage:(int *)storage
                        function:(void (*__cdecl)())function
                       persisted:(bool)persisted;
- (instancetype)initWithName:(OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName:(OFString *)name
                         min:(int)min
                         max:(int)max
                     storage:(int *)storage
                    function:(void (*__cdecl)())function
                   persisted:(bool)persisted;
- (void)printValue;
- (void)setValue:(int)value;
@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
97
98
99
#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();                                   \
	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() { body; }
#define VARFP(name, min_, cur, max_, body)                          \
	static void var_##name();                                   \
	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() { body; }

@interface Variable: Identifier
@property (readonly, nonatomic) int min, max;
@property (readonly, nonatomic) int *storage;
@property (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;
- (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;
- (void)printValue;
- (void)setValue:(int)value;
@end

OF_ASSUME_NONNULL_END

Modified src/clientgame.m from [d1273c7a21] to [44aa449a31].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
// clientgame.cpp: core game related stuff

#include "cube.h"

#import "Command.h"
#import "DynamicEntity.h"
#import "Entity.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"


int nextmode = 0; // nextmode becomes gamemode after next map load
VAR(gamemode, 1, 0, 0);

COMMAND(mode, ARG_1INT, ^(int n) {
	addmsg(1, 2, SV_GAMEMODE, nextmode = n);
})










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// clientgame.cpp: core game related stuff

#include "cube.h"

#import "Command.h"
#import "DynamicEntity.h"
#import "Entity.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"
#import "Variable.h"

int nextmode = 0; // nextmode becomes gamemode after next map load
VAR(gamemode, 1, 0, 0);

COMMAND(mode, ARG_1INT, ^(int n) {
	addmsg(1, 2, SV_GAMEMODE, nextmode = n);
})

Modified src/clients.m from [b2ad70bf79] to [0fa2d4f6d1].

1
2
3
4
5
6

7
8
9
10
11
12
13
// client.cpp, mostly network related client game code

#include "cube.h"

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


static ENetHost *clienthost = NULL;
static int connecting = 0;
static int connattempts = 0;
static int disconnecting = 0;
// our client id in the game
int clientnum = -1;






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
// client.cpp, mostly network related client game code

#include "cube.h"

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

static ENetHost *clienthost = NULL;
static int connecting = 0;
static int connattempts = 0;
static int disconnecting = 0;
// our client id in the game
int clientnum = -1;

Modified src/commands.m from [116e44fb5b] to [45797ae2bc].

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
{
	free(*string);
}

void
alias(OFString *name, OFString *action)
{
	Alias *alias = [Identifier identifierForName:name];

	if (alias == nil)
		[Identifier addIdentifier:[Alias aliasWithName:name
		                                        action:action
		                                     persisted:true]];
	else {
		if ([alias isKindOfClass:Alias.class])
			alias.action = action;
		else
			conoutf(
			    @"cannot redefine builtin %@ with an alias", name);
	}
}

COMMAND(alias, ARG_2STR, ^(OFString *name, OFString *action) {
	alias(name, action);
})

int
variable(OFString *name, int min, int cur, int max, int *storage,
    void (*function)(), bool persisted)
{
	[Identifier addIdentifier:[Variable variableWithName:name
	                                                 min:min
	                                                 max:max
	                                             storage:storage
	                                            function:function
	                                           persisted:persisted]];
	return cur;
}

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

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

int
getvar(OFString *name)
{
	Variable *variable = [Identifier identifierForName:name];

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

	return 0;
}

bool
identexists(OFString *name)
{
	return ([Identifier identifierForName:name] != nil);
}

OFString *
getalias(OFString *name)
{
	Alias *alias = [Identifier identifierForName:name];

	if ([alias isKindOfClass:Alias.class])
		return alias.action;

	return nil;
}








|


|
|
|













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



|








|










|





|







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
{
	free(*string);
}

void
alias(OFString *name, OFString *action)
{
	Alias *alias = Identifier.identifiers[name];

	if (alias == nil)
		Identifier.identifiers[name] = [Alias aliasWithName:name
		                                             action:action
		                                          persisted:true];
	else {
		if ([alias isKindOfClass:Alias.class])
			alias.action = action;
		else
			conoutf(
			    @"cannot redefine builtin %@ with an alias", name);
	}
}

COMMAND(alias, ARG_2STR, ^(OFString *name, OFString *action) {
	alias(name, action);
})














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)
{
	return (Identifier.identifiers[name] != nil);
}

OFString *
getalias(OFString *name)
{
	Alias *alias = Identifier.identifiers[name];

	if ([alias isKindOfClass:Alias.class])
		return alias.action;

	return nil;
}

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
}

// find value of ident referenced with $ in exp
OFString *
lookup(OFString *n)
{
	__kindof Identifier *identifier =
	    [Identifier identifierForName:[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]);







|







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

// find value of ident referenced with $ in exp
OFString *
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]);
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
			c = [c substringFromIndex:1];
			w[0] = c;
		}
		// empty statement
		if (c.length == 0)
			continue;

		val = executeIdentifier([Identifier identifierForName:c],
		    [OFArray arrayWithObjects:w count:numargs], isDown);
	}

	return val;
}

// tab-completion of all identifiers







|







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
			c = [c substringFromIndex:1];
			w[0] = c;
		}
		// empty statement
		if (c.length == 0)
			continue;

		val = executeIdentifier(Identifier.identifiers[c],
		    [OFArray arrayWithObjects:w count:numargs], isDown);
	}

	return val;
}

// tab-completion of all identifiers
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

	if (!completesize) {
		completesize = s.length - 1;
		completeidx = 0;
	}

	__block int idx = 0;
	[Identifier enumerateIdentifiersUsingBlock:^(
	    __kindof Identifier *identifier) {
		if (strncmp(identifier.name.UTF8String, s.UTF8String + 1,
		        completesize) == 0 &&
		    idx++ == completeidx)
			[s replaceCharactersInRange:OFMakeRange(1, s.length - 1)
			                 withString:identifier.name];
	}];








|
|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290

	if (!completesize) {
		completesize = s.length - 1;
		completeidx = 0;
	}

	__block int idx = 0;
	[Identifier.identifiers enumerateKeysAndObjectsUsingBlock:^(
	    OFString *name, __kindof Identifier *identifier, bool *stop) {
		if (strncmp(identifier.name.UTF8String, s.UTF8String + 1,
		        completesize) == 0 &&
		    idx++ == completeidx)
			[s replaceCharactersInRange:OFMakeRange(1, s.length - 1)
			                 withString:identifier.name];
	}];

355
356
357
358
359
360
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
	                    @"overwrite these settings\n"
	                    @"// modify settings in game, or put settings in "
	                    @"autoexec.cfg to override anything\n"
	                    @"\n"];
	writeclientinfo(stream);
	[stream writeString:@"\n"];

	[Identifier
	    enumerateIdentifiersUsingBlock:^(__kindof Identifier *identifier) {
		    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
	    enumerateIdentifiersUsingBlock:^(__kindof Identifier *identifier) {
		    if (![identifier isKindOfClass:Alias.class] ||
		        [identifier.name hasPrefix:@"nextmap_"])
			    return;

		    [stream writeFormat:@"alias \"%@\" [%@]\n", identifier.name,
		            [identifier action]];
	    }];

	[stream close];
}

COMMAND(writecfg, ARG_NONE, ^{
	writecfg();
})







|
|
|
|
|

|
|
|





|
|
|
|
|

|
|
|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
	                    @"overwrite these settings\n"
	                    @"// 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:^(
	    OFString *name, __kindof Identifier *identifier, bool *stop) {
		if (![identifier isKindOfClass:Alias.class] ||
		    [identifier.name hasPrefix:@"nextmap_"])
			return;

		[stream writeFormat:@"alias \"%@\" [%@]\n", identifier.name,
		        [identifier action]];
	}];

	[stream close];
}

COMMAND(writecfg, ARG_NONE, ^{
	writecfg();
})

Modified src/cube.h from [40ed8384d1] to [bcce88bfd4].

327
328
329
330
331
332
333
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
	ARG_1EXP,
	ARG_2EXP,
	ARG_1EST,
	ARG_2EST,
	ARG_VARI
};

// nasty macros for registering script functions, abuses globals to avoid
// excessive infrastructure
#define VARP(name, min, cur, max)                                       \
	int name;                                                       \
	OF_CONSTRUCTOR()                                                \
	{                                                               \
		enqueueInit(^{                                          \
			name = variable(                                \
			    @ #name, min, cur, max, &name, NULL, true); \
		});                                                     \
	}
#define VAR(name, min, cur, max)                                         \
	int name;                                                        \
	OF_CONSTRUCTOR()                                                 \
	{                                                                \
		enqueueInit(^{                                           \
			name = variable(                                 \
			    @ #name, min, cur, max, &name, NULL, false); \
		});                                                      \
	}
#define VARF(name, min, cur, max, body)                                        \
	void var_##name();                                                     \
	static int name;                                                       \
	OF_CONSTRUCTOR()                                                       \
	{                                                                      \
		enqueueInit(^{                                                 \
			name = variable(                                       \
			    @ #name, min, cur, max, &name, var_##name, false); \
		});                                                            \
	}                                                                      \
	void var_##name() { body; }
#define VARFP(name, min, cur, max, body)                                      \
	void var_##name();                                                    \
	static int name;                                                      \
	OF_CONSTRUCTOR()                                                      \
	{                                                                     \
		enqueueInit(^{                                                \
			name = variable(                                      \
			    @ #name, min, cur, max, &name, var_##name, true); \
		});                                                           \
	}                                                                     \
	void var_##name() { body; }

#define ATOI(s) strtol(s, NULL, 0) // supports hexadecimal numbers

#ifdef WIN32
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
# define _WINDOWS
# define ZLIB_DLL
#else
# include <dlfcn.h>







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







327
328
329
330
331
332
333













































334
335
336
337
338
339
340
	ARG_1EXP,
	ARG_2EXP,
	ARG_1EST,
	ARG_2EST,
	ARG_VARI
};














































#ifdef WIN32
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
# define _WINDOWS
# define ZLIB_DLL
#else
# include <dlfcn.h>

Modified src/editing.m from [7c6be4eed6] to [03b89b7ddc].

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
// editing.cpp: most map editing commands go here, entity editing commands are
// in world.cpp

#include "cube.h"

#import "Command.h"
#import "DynamicEntity.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"


bool editmode = false;

// the current selection, used by almost all editing commands
// invariant: all code assumes that these are kept inside MINBORD distance of
// the edge of the map

struct block sel;

OF_CONSTRUCTOR()
{
	enqueueInit(^{
		sel = (struct block) {


			variable(@"selx", 0, 0, 4096, &sel.x, NULL, false),

			variable(@"sely", 0, 0, 4096, &sel.y, NULL, false),

			variable(@"selxs", 0, 0, 4096, &sel.xs, NULL, false),
			variable(@"selys", 0, 0, 4096, &sel.ys, NULL, false),
		};







	});
}

int selh = 0;
bool selset = false;

#define loopselxy(b)                                                       \










>







|




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







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
// editing.cpp: most map editing commands go here, entity editing commands are
// in world.cpp

#include "cube.h"

#import "Command.h"
#import "DynamicEntity.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"
#import "Variable.h"

bool editmode = false;

// the current selection, used by almost all editing commands
// invariant: all code assumes that these are kept inside MINBORD distance of
// the edge of the map

struct block sel = { 0, 0, 0, 0 };

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;

#define loopselxy(b)                                                       \

Modified src/physics.m from [7410504650] to [8500b9ce45].

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

14
15
16
17
18
19
20
// physics.cpp: no physics books were hurt nor consulted in the construction of
// this code. All physics computations and constants were invented on the fly
// and simply tweaked until they "felt right", and have no basis in reality.
// Collision detection is simplistic but very robust (uses discrete steps at
// fixed fps).

#include "cube.h"

#import "DynamicEntity.h"
#import "Entity.h"
#import "MapModelInfo.h"
#import "Monster.h"
#import "Player.h"


// collide with player or monster
static bool
plcollide(
    DynamicEntity *d, DynamicEntity *o, float *headspace, float *hi, float *lo)
{
	if (o.state != CS_ALIVE)













>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// physics.cpp: no physics books were hurt nor consulted in the construction of
// this code. All physics computations and constants were invented on the fly
// and simply tweaked until they "felt right", and have no basis in reality.
// Collision detection is simplistic but very robust (uses discrete steps at
// fixed fps).

#include "cube.h"

#import "DynamicEntity.h"
#import "Entity.h"
#import "MapModelInfo.h"
#import "Monster.h"
#import "Player.h"
#import "Variable.h"

// collide with player or monster
static bool
plcollide(
    DynamicEntity *d, DynamicEntity *o, float *headspace, float *hi, float *lo)
{
	if (o.state != CS_ALIVE)

Modified src/protos.h from [056cf22e2e] to [f47d376175].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// protos for ALL external functions in cube...

#ifdef __cplusplus
extern "C" {
#endif

// command
extern int variable(OFString *name, int min, int cur, int max, int *storage,
    void (*fun)(), bool persist);
extern void setvar(OFString *name, int i);
extern int getvar(OFString *name);
extern bool identexists(OFString *name);
extern int execute(OFString *p, bool down);
extern void exec(OFString *cfgfile);
extern bool execfile(OFIRI *cfgfile);
extern void resetcomplete();







<
<







1
2
3
4
5
6
7


8
9
10
11
12
13
14
// protos for ALL external functions in cube...

#ifdef __cplusplus
extern "C" {
#endif

// command


extern void setvar(OFString *name, int i);
extern int getvar(OFString *name);
extern bool identexists(OFString *name);
extern int execute(OFString *p, bool down);
extern void exec(OFString *cfgfile);
extern bool execfile(OFIRI *cfgfile);
extern void resetcomplete();

Modified src/rendercubes.m from [03979e8529] to [4e2c5682e1].

1
2
3
4
5
6

7
8
9
10
11
12
13
// rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills
// the vertex array for different cube surfaces.

#include "cube.h"

#import "Command.h"


static struct vertex *verts = NULL;
int curvert;
static int curmaxverts = 10000;

void
setarraypointers()






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
// rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills
// the vertex array for different cube surfaces.

#include "cube.h"

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

static struct vertex *verts = NULL;
int curvert;
static int curmaxverts = 10000;

void
setarraypointers()

Modified src/renderextras.m from [429e6fcead] to [cde282f0a8].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
// renderextras.cpp: misc gl render code and the HUD

#include "cube.h"

#import "Command.h"
#import "Entity.h"
#import "Player.h"


void
line(int x1, int y1, float z1, int x2, int y2, float z2)
{
	glBegin(GL_POLYGON);
	glVertex3f((float)x1, z1, (float)y1);
	glVertex3f((float)x1, z1, y1 + 0.01f);







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// renderextras.cpp: misc gl render code and the HUD

#include "cube.h"

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

void
line(int x1, int y1, float z1, int x2, int y2, float z2)
{
	glBegin(GL_POLYGON);
	glVertex3f((float)x1, z1, (float)y1);
	glVertex3f((float)x1, z1, y1 + 0.01f);

Modified src/rendergl.m from [6b51df5263] to [a437681d0a].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
// rendergl.cpp: core opengl rendering stuff

#define gamma math_gamma

#include "cube.h"

#import "Command.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"


#ifdef DARWIN
# define GL_COMBINE_EXT GL_COMBINE_ARB
# define GL_COMBINE_RGB_EXT GL_COMBINE_RGB_ARB
# define GL_SOURCE0_RBG_EXT GL_SOURCE0_RGB_ARB
# define GL_SOURCE1_RBG_EXT GL_SOURCE1_RGB_ARB
# define GL_RGB_SCALE_EXT GL_RGB_SCALE_ARB










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// rendergl.cpp: core opengl rendering stuff

#define gamma math_gamma

#include "cube.h"

#import "Command.h"
#import "Monster.h"
#import "OFString+Cube.h"
#import "Player.h"
#import "Variable.h"

#ifdef DARWIN
# define GL_COMBINE_EXT GL_COMBINE_ARB
# define GL_COMBINE_RGB_EXT GL_COMBINE_RGB_ARB
# define GL_SOURCE0_RBG_EXT GL_SOURCE0_RGB_ARB
# define GL_SOURCE1_RBG_EXT GL_SOURCE1_RGB_ARB
# define GL_RGB_SCALE_EXT GL_RGB_SCALE_ARB

Modified src/renderparticles.m from [7fffcaae48] to [f1b52c549a].

1
2
3
4
5

6
7
8
9
10
11
12
// renderparticles.cpp

#include "cube.h"

#import "Player.h"


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





>







1
2
3
4
5
6
7
8
9
10
11
12
13
// renderparticles.cpp

#include "cube.h"

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

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

Modified src/savegamedemo.m from [822ad5d4d5] to [fe0624b79b].

1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
// loading and saving of savegames & demos, dumps the spawn state of all
// mapents, the full state of all dynents (monsters + player)

#include "cube.h"

#import "Command.h"
#import "Entity.h"
#import "Monster.h"
#import "Player.h"


#ifdef OF_BIG_ENDIAN
static const int islittleendian = 0;
#else
static const int islittleendian = 1;
#endif










>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// loading and saving of savegames & demos, dumps the spawn state of all
// mapents, the full state of all dynents (monsters + player)

#include "cube.h"

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

#ifdef OF_BIG_ENDIAN
static const int islittleendian = 0;
#else
static const int islittleendian = 1;
#endif

Modified src/sound.m from [432ff899cb] to [0732f14714].

1
2
3
4

5
6
7
8
9
10
11
#include "cube.h"

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


#include <SDL_mixer.h>

VARP(soundvol, 0, 255, 255);
VARP(musicvol, 0, 128, 255);
bool nosound = false;





>







1
2
3
4
5
6
7
8
9
10
11
12
#include "cube.h"

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

#include <SDL_mixer.h>

VARP(soundvol, 0, 255, 255);
VARP(musicvol, 0, 128, 255);
bool nosound = false;

Modified src/worldlight.m from [230a66c274] to [279400f849].

1
2
3
4
5
6
7

8
9
10
11
12
13
14
// worldlight.cpp

#include "cube.h"

#import "DynamicEntity.h"
#import "Entity.h"
#import "Monster.h"


extern bool hasoverbright;

VAR(lightscale, 1, 4, 100);

// done in realtime, needs to be fast
void







>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// worldlight.cpp

#include "cube.h"

#import "DynamicEntity.h"
#import "Entity.h"
#import "Monster.h"
#import "Variable.h"

extern bool hasoverbright;

VAR(lightscale, 1, 4, 100);

// done in realtime, needs to be fast
void