Add variables with a getter / setter block

FossilOrigin-Name: cd2ac12a141a97a05449c82fbacc67cd3b6a172e66b7fb68bfd785b31d9776c0
This commit is contained in:
Jonathan Schleifer 2025-03-29 22:29:22 +00:00
parent a838f496b1
commit cc73f6ed78
12 changed files with 241 additions and 118 deletions

View file

@ -8,8 +8,15 @@
OF_APPLICATION_DELEGATE(Cube) OF_APPLICATION_DELEGATE(Cube)
VARF(gamespeed, 10, 100, 1000, if (multiplayer()) gamespeed = 100); static int gamespeed = 100;
VARP(minmillis, 0, 5, 1000); VARB(gamespeed, 10, 1000, ^ { return gamespeed; }, ^ (int value) {
if (multiplayer())
gamespeed = 100;
else
gamespeed = value;
})
VARP(minmillis, 0, 5, 1000)
@implementation Cube @implementation Cube
{ {

View file

@ -35,7 +35,11 @@ static int nextmonster, spawnremain, numkilled, monstertotal, mtimestart;
move: move]; move: move];
} }
VARF(skill, 1, 3, 10, conoutf(@"skill is now %d", skill)); static int skill = 3;
VARB(skill, 1, 10, ^ { return skill; }, ^ (int value) {
skill = value;
conoutf(@"skill is now %d", skill);
})
// for savegames // for savegames
+ (void)restoreAll + (void)restoreAll

View file

@ -2,4 +2,6 @@
@interface OFColor (Cube) @interface OFColor (Cube)
- (void)cube_setAsGLColor; - (void)cube_setAsGLColor;
- (void)cube_setAsGLClearColor;
- (void)cube_setAsGLFogColor;
@end @end

View file

@ -6,7 +6,30 @@
- (void)cube_setAsGLColor - (void)cube_setAsGLColor
{ {
float red, green, blue, alpha; float red, green, blue, alpha;
[self getRed: &red green: &green blue: &blue alpha: &alpha]; [self getRed: &red green: &green blue: &blue alpha: &alpha];
glColor4f(red, green, blue, 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 @end

View file

@ -2,22 +2,6 @@
OF_ASSUME_NONNULL_BEGIN 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_) \ #define VAR(name, min_, cur, max_) \
int name = cur; \ int name = cur; \
\ \
@ -29,14 +13,14 @@ OF_ASSUME_NONNULL_BEGIN
min: min_ \ min: min_ \
max: max_ \ max: max_ \
storage: &name \ storage: &name \
function: NULL \ persisted: false \
persisted: false]; \ getter: NULL \
setter: NULL]; \
Identifier.identifiers[@#name] = variable; \ Identifier.identifiers[@#name] = variable; \
}); \ }); \
} }
#define VARF(name, min_, cur, max_, body) \ #define VARP(name, min_, cur, max_) \
static void var_##name(void); \ int name = cur; \
static int name = cur; \
\ \
OF_CONSTRUCTOR() \ OF_CONSTRUCTOR() \
{ \ { \
@ -46,63 +30,67 @@ OF_ASSUME_NONNULL_BEGIN
min: min_ \ min: min_ \
max: max_ \ max: max_ \
storage: &name \ storage: &name \
function: var_##name \ persisted: true \
persisted: false]; \ getter: NULL \
setter: NULL]; \
Identifier.identifiers[@#name] = variable; \ Identifier.identifiers[@#name] = variable; \
}); \ }); \
} \
\
static void \
var_##name(void) \
{ \
body; \
} }
#define VARFP(name, min_, cur, max_, body) \ #define VARB(name, min_, max_, getter_, setter_) \
static void var_##name(void); \
static int name = cur; \
\
OF_CONSTRUCTOR() \ OF_CONSTRUCTOR() \
{ \ { \
enqueueInit(^ { \ enqueueInit(^ { \
Variable *variable = [Variable \ Variable *variable = [Variable \
variableWithName: @#name \ variableWithName: @#name \
min: min_ \ min: min_ \
max: max_ \ max: max_ \
storage: &name \ storage: NULL \
function: var_##name \ persisted: false \
persisted: true]; \ getter: getter_ \
setter: setter_]; \
Identifier.identifiers[@#name] = variable; \ Identifier.identifiers[@#name] = variable; \
}); \ }); \
} \ }
\ #define VARBP(name, min_, max_, getter_, setter_) \
static void \ OF_CONSTRUCTOR() \
var_##name(void) \
{ \ { \
body; \ 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 @interface Variable: Identifier
@property (direct, readonly, nonatomic) int min, max; @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; @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 + (instancetype)variableWithName: (OFString *)name
min: (int)min min: (int)min
max: (int)max max: (int)max
storage: (int *)storage storage: (nullable int *)storage
function: (void (*_Nullable)())function persisted: (bool)persisted
persisted: (bool)persisted OF_DIRECT; getter: (int (^_Nullable)(void))getter
setter: (void (^_Nullable)(int))setter OF_DIRECT;
- (instancetype)initWithName: (OFString *)name OF_UNAVAILABLE; - (instancetype)initWithName: (OFString *)name OF_UNAVAILABLE;
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name
min: (int)min min: (int)min
max: (int)max max: (int)max
storage: (int *)storage storage: (nullable int *)storage
function: (void (*_Nullable)())function persisted: (bool)persisted
persisted: (bool)persisted OF_DESIGNATED_INITIALIZER getter: (int (^_Nullable)(void))getter
OF_DIRECT; setter: (void (^_Nullable)(int))setter
OF_DESIGNATED_INITIALIZER OF_DIRECT;
- (void)printValue OF_DIRECT; - (void)printValue OF_DIRECT;
- (void)setValue: (int)value OF_DIRECT;
@end @end
OF_ASSUME_NONNULL_END OF_ASSUME_NONNULL_END

View file

@ -3,42 +3,50 @@
#include "cube.h" #include "cube.h"
@implementation Variable @implementation Variable
{
int *_storage;
}
+ (instancetype)variableWithName: (OFString *)name + (instancetype)variableWithName: (OFString *)name
min: (int)min min: (int)min
max: (int)max max: (int)max
storage: (int *)storage storage: (int *)storage
function: (void (*__cdecl)())function
persisted: (bool)persisted persisted: (bool)persisted
getter: (int (^)(void))getter
setter: (void (^)(int))setter
{ {
return [[self alloc] initWithName: name return [[self alloc] initWithName: name
min: min min: min
max: max max: max
storage: storage storage: storage
function: function persisted: persisted
persisted: persisted]; getter: getter
setter: setter];
} }
- (instancetype)initWithName: (OFString *)name - (instancetype)initWithName: (OFString *)name
min: (int)min min: (int)min
max: (int)max max: (int)max
storage: (int *)storage storage: (int *)storage
function: (void (*__cdecl)())function
persisted: (bool)persisted persisted: (bool)persisted
getter: (int (^)(void))getter
setter: (void (^)(int))setter
{ {
self = [super initWithName: name]; self = [super initWithName: name];
_min = min; _min = min;
_max = max; _max = max;
_storage = storage; _storage = storage;
_function = function;
_persisted = persisted; _persisted = persisted;
_getter = [getter copy];
_setter = [setter copy];
return self; return self;
} }
- (void)printValue - (void)printValue
{ {
conoutf(@"%@ = %d", self.name, *_storage); conoutf(@"%@ = %d", self.name, self.value);
} }
- (void)setValue: (int)value - (void)setValue: (int)value
@ -60,13 +68,22 @@
outOfRange = true; outOfRange = true;
} }
if (outOfRange) if (outOfRange) {
conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max); conoutf(@"valid range for %@ is %d..%d", self.name, _min, _max);
return;
}
*_storage = value; if (_setter != NULL)
_setter(value);
else
*_storage = value;
}
if (_function != NULL) - (int)value
// call trigger function if available {
_function(); if (_getter != NULL)
return _getter();
else
return *_storage;
} }
@end @end

View file

@ -42,26 +42,43 @@ allowedittoggle()
return allow; return allow;
} }
VARF(rate, 0, 0, 25000, static int rate = 0;
VARB(rate, 0, 25000, ^ { return rate; }, ^ (int value) {
rate = value;
if (clienthost && (!rate || rate > 1000)) if (clienthost && (!rate || rate > 1000))
enet_host_bandwidth_limit(clienthost, rate, rate)); enet_host_bandwidth_limit(clienthost, rate, rate);
})
void throttle(); static int throttle_interval = 5;
static int throttle_accel = 2;
static int throttle_decel = 2;
VARF(throttle_interval, 0, 5, 30, throttle()); static void
VARF(throttle_accel, 0, 2, 32, throttle()); throttle(void)
VARF(throttle_decel, 0, 2, 32, throttle());
void
throttle()
{ {
if (!clienthost || connecting) if (!clienthost || connecting)
return; return;
assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32); assert(ENET_PEER_PACKET_THROTTLE_SCALE == 32);
enet_peer_throttle_configure(clienthost->peers, enet_peer_throttle_configure(clienthost->peers,
throttle_interval * 1000, throttle_accel, throttle_decel); 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 static void
newname(OFString *name) newname(OFString *name)
{ {

View file

@ -43,7 +43,7 @@ setvar(OFString *name, int i)
Variable *variable = Identifier.identifiers[name]; Variable *variable = Identifier.identifiers[name];
if ([variable isKindOfClass: Variable.class]) if ([variable isKindOfClass: Variable.class])
*variable.storage = i; variable.value = i;
} }
int int
@ -52,7 +52,7 @@ getvar(OFString *name)
Variable *variable = Identifier.identifiers[name]; Variable *variable = Identifier.identifiers[name];
if ([variable isKindOfClass: Variable.class]) if ([variable isKindOfClass: Variable.class])
return *variable.storage; return variable.value;
return 0; return 0;
} }
@ -144,7 +144,7 @@ lookup(OFString *n)
if ([identifier isKindOfClass: Variable.class]) { if ([identifier isKindOfClass: Variable.class]) {
return [OFString stringWithFormat: return [OFString stringWithFormat:
@"%d", *[identifier storage]]; @"%d", [identifier value]];
} else if ([identifier isKindOfClass: Alias.class]) } else if ([identifier isKindOfClass: Alias.class])
return [identifier action]; return [identifier action];
@ -350,13 +350,12 @@ writecfg()
[stream writeString: @"\n"]; [stream writeString: @"\n"];
[Identifier.identifiers enumerateKeysAndObjectsUsingBlock: [Identifier.identifiers enumerateKeysAndObjectsUsingBlock:
^ (OFString *name, __kindof Identifier *identifier, bool *stop) { ^ (OFString *name, Variable *variable, bool *stop) {
if (![identifier isKindOfClass: Variable.class] || if (![variable isKindOfClass: Variable.class] ||
![identifier persisted]) !variable.persisted)
return; return;
[stream writeFormat: [stream writeFormat: @"%@ %d\n", variable.name, variable.value];
@"%@ %d\n", identifier.name, *[identifier storage]];
}]; }];
[stream writeString: @"\n"]; [stream writeString: @"\n"];

View file

@ -24,8 +24,12 @@ OF_CONSTRUCTOR()
static const struct { static const struct {
OFString *name; OFString *name;
int *storage; int *storage;
} vars[4] = { { @"selx", &sel.x }, { @"sely", &sel.y }, } vars[4] = {
{ @"selxs", &sel.xs }, { @"selys", &sel.ys } }; { @"selx", &sel.x },
{ @"sely", &sel.y },
{ @"selxs", &sel.xs },
{ @"selys", &sel.ys }
};
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
Variable *variable = [Variable Variable *variable = [Variable
@ -33,8 +37,9 @@ OF_CONSTRUCTOR()
min: 0 min: 0
max: 4096 max: 4096
storage: vars[i].storage storage: vars[i].storage
function: NULL persisted: false
persisted: false]; getter: NULL
setter: NULL];
Identifier.identifiers[vars[i].name] = variable; Identifier.identifiers[vars[i].name] = variable;
} }
}); });
@ -634,13 +639,16 @@ COMMAND(perlin, ARG_3INT, ^ (int scale, int seed, int psize) {
sel.ys--; sel.ys--;
}) })
VARF( static int fullbright = 0;
fullbright, 0, 0, 1, if (fullbright) { VARB(fullbright, 0, 1, ^ { return fullbright; }, ^ (int value) {
if (noteditmode()) if (fullbright) {
return; if (noteditmode())
for (int i = 0; i < mipsize; i++) return;
world[i].r = world[i].g = world[i].b = 176;
}); for (int i = 0; i < mipsize; i++)
world[i].r = world[i].g = world[i].b = 176;
}
});
COMMAND(edittag, ARG_1INT, ^ (int tag) { COMMAND(edittag, ARG_1INT, ^ (int tag) {
EDITSELMP; EDITSELMP;

View file

@ -320,8 +320,11 @@ render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2,
int wx1, wy1, wx2, wy2; int wx1, wy1, wx2, wy2;
VAR(watersubdiv, 1, 4, 64); 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 static inline void
vertw(int v1, float v2, int v3, struct sqr *c, float t1, float t2, float t) vertw(int v1, float v2, int v3, struct sqr *c, float t1, float t2, float t)

View file

@ -327,14 +327,17 @@ addstrip(int tex, int start, int n)
#undef gamma #undef gamma
VARFP(gamma, 30, 100, 300, { static int gamma = 100;
float f = gamma / 100.0f; VARBP(gamma, 30, 300, ^ { return gamma; }, ^ (int value) {
float f = value / 100.0f;
Uint16 ramp[256]; Uint16 ramp[256];
SDL_CalculateGammaRamp(f, ramp); SDL_CalculateGammaRamp(f, ramp);
if (SDL_SetWindowGammaRamp(Cube.sharedInstance.window, if (SDL_SetWindowGammaRamp(Cube.sharedInstance.window,
ramp, ramp, ramp) == -1) { ramp, ramp, ramp) != -1)
gamma = value;
else {
conoutf( conoutf(
@"Could not set gamma (card/driver doesn't support it?)"); @"Could not set gamma (card/driver doesn't support it?)");
conoutf(@"sdl: %s", SDL_GetError()); conoutf(@"sdl: %s", SDL_GetError());
@ -362,7 +365,29 @@ VARP(fov, 10, 105, 120);
int xtraverts; int xtraverts;
VAR(fog, 64, 180, 1024); VAR(fog, 64, 180, 1024);
VAR(fogcolour, 0, 0x8099B3, 0xFFFFFF);
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); VARP(hudgun, 0, 1, 1);
@ -422,11 +447,8 @@ gl_drawframe(int w, int h, float curfps)
glFogi(GL_FOG_START, (fog + 64) / 8); glFogi(GL_FOG_START, (fog + 64) / 8);
glFogi(GL_FOG_END, fog); glFogi(GL_FOG_END, fog);
float fogc[4] = { (fogcolour >> 16) / 256.0f, [fogColor cube_setAsGLFogColor];
((fogcolour >> 8) & 255) / 256.0f, (fogcolour & 255) / 256.0f, [fogColor cube_setAsGLClearColor];
1.0f };
glFogfv(GL_FOG_COLOR, fogc);
glClearColor(fogc[0], fogc[1], fogc[2], 1.0f);
if (underwater) { if (underwater) {
fovy += (float)sin(lastmillis / 1000.0) * 2.0f; fovy += (float)sin(lastmillis / 1000.0) * 2.0f;

View file

@ -2,6 +2,7 @@
#include "cube.h" #include "cube.h"
#import "OFColor+Cube.h"
#import "Player.h" #import "Player.h"
#import "Variable.h" #import "Variable.h"
@ -66,19 +67,51 @@ render_particles(int time)
glDisable(GL_FOG); glDisable(GL_FOG);
struct parttype { struct parttype {
float r, g, b; OFColor *color;
int gr, tex; int gr, tex;
float sz; float sz;
} parttypes[] = { } 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 * Note: Some comments don't match the color. This was already
{ 0.2f, 0.2f, 1.0f, 20, 3, 0.08f }, // blue: edit mode entities * the case in the original.
{ 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 // yellow: sparks
{ 1.0f, 1.0f, 1.0f, 20, 8, 1.2f }, // blue: fireball2 { [OFColor colorWithRed: 0.7f
{ 1.0f, 1.0f, 1.0f, 20, 9, 1.2f }, // green: fireball3 green: 0.6f
{ 1.0f, 0.1f, 0.1f, 0, 7, 0.2f }, // red: demotrack 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; int numrender = 0;
@ -89,7 +122,7 @@ render_particles(int time)
glBindTexture(GL_TEXTURE_2D, pt->tex); glBindTexture(GL_TEXTURE_2D, pt->tex);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor3d(pt->r, pt->g, pt->b); [pt->color cube_setAsGLColor];
float sz = pt->sz * particlesize / 100.0f; float sz = pt->sz * particlesize / 100.0f;
// perf varray? // perf varray?
glTexCoord2f(0.0, 1.0); glTexCoord2f(0.0, 1.0);