diff --git a/src/Cube.m b/src/Cube.m index 347e68a..76ab2b9 100644 --- a/src/Cube.m +++ b/src/Cube.m @@ -8,8 +8,15 @@ OF_APPLICATION_DELEGATE(Cube) -VARF(gamespeed, 10, 100, 1000, if (multiplayer()) gamespeed = 100); -VARP(minmillis, 0, 5, 1000); +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 { diff --git a/src/Monster.m b/src/Monster.m index 2f622b1..e185359 100644 --- a/src/Monster.m +++ b/src/Monster.m @@ -35,7 +35,11 @@ static int nextmonster, spawnremain, numkilled, monstertotal, mtimestart; 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 + (void)restoreAll diff --git a/src/OFColor+Cube.h b/src/OFColor+Cube.h index d8a6a58..beeeb3b 100644 --- a/src/OFColor+Cube.h +++ b/src/OFColor+Cube.h @@ -2,4 +2,6 @@ @interface OFColor (Cube) - (void)cube_setAsGLColor; +- (void)cube_setAsGLClearColor; +- (void)cube_setAsGLFogColor; @end diff --git a/src/OFColor+Cube.m b/src/OFColor+Cube.m index 16a57d5..02934c6 100644 --- a/src/OFColor+Cube.m +++ b/src/OFColor+Cube.m @@ -6,7 +6,30 @@ - (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 diff --git a/src/Variable.h b/src/Variable.h index c3933f9..b644ca9 100644 --- a/src/Variable.h +++ b/src/Variable.h @@ -2,22 +2,6 @@ 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; \ \ @@ -29,14 +13,14 @@ OF_ASSUME_NONNULL_BEGIN 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) \ - static void var_##name(void); \ - static int name = cur; \ +#define VARP(name, min_, cur, max_) \ + int name = cur; \ \ OF_CONSTRUCTOR() \ { \ @@ -46,63 +30,67 @@ OF_ASSUME_NONNULL_BEGIN min: min_ \ max: max_ \ storage: &name \ - function: var_##name \ - persisted: false]; \ + persisted: true \ + getter: NULL \ + setter: NULL]; \ 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; \ - \ +#define VARB(name, min_, max_, getter_, setter_) \ OF_CONSTRUCTOR() \ { \ enqueueInit(^ { \ Variable *variable = [Variable \ - variableWithName: @#name \ - min: min_ \ - max: max_ \ - storage: &name \ - function: var_##name \ - persisted: true]; \ + variableWithName: @#name \ + min: min_ \ + max: max_ \ + storage: NULL \ + persisted: false \ + getter: getter_ \ + setter: setter_]; \ Identifier.identifiers[@#name] = variable; \ }); \ - } \ - \ - static void \ - var_##name(void) \ + } +#define VARBP(name, min_, max_, getter_, setter_) \ + OF_CONSTRUCTOR() \ { \ - 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 @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 (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 - function: (void (*_Nullable)())function - persisted: (bool)persisted OF_DIRECT; + 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: (int *)storage - function: (void (*_Nullable)())function - persisted: (bool)persisted OF_DESIGNATED_INITIALIZER - OF_DIRECT; + 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; -- (void)setValue: (int)value OF_DIRECT; @end OF_ASSUME_NONNULL_END diff --git a/src/Variable.m b/src/Variable.m index 7a81dc7..bf0ca40 100644 --- a/src/Variable.m +++ b/src/Variable.m @@ -3,42 +3,50 @@ #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 @@ -60,13 +68,22 @@ outOfRange = true; } - if (outOfRange) + if (outOfRange) { 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) - // call trigger function if available - _function(); +- (int)value +{ + if (_getter != NULL) + return _getter(); + else + return *_storage; } @end diff --git a/src/clients.m b/src/clients.m index 71716c0..2aa4dd7 100644 --- a/src/clients.m +++ b/src/clients.m @@ -42,26 +42,43 @@ allowedittoggle() 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)) - 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()); -VARF(throttle_accel, 0, 2, 32, throttle()); -VARF(throttle_decel, 0, 2, 32, throttle()); - -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) { diff --git a/src/commands.m b/src/commands.m index 3c9540c..5e49fb8 100644 --- a/src/commands.m +++ b/src/commands.m @@ -43,7 +43,7 @@ setvar(OFString *name, int i) Variable *variable = Identifier.identifiers[name]; if ([variable isKindOfClass: Variable.class]) - *variable.storage = i; + variable.value = i; } int @@ -52,7 +52,7 @@ getvar(OFString *name) Variable *variable = Identifier.identifiers[name]; if ([variable isKindOfClass: Variable.class]) - return *variable.storage; + return variable.value; return 0; } @@ -144,7 +144,7 @@ lookup(OFString *n) if ([identifier isKindOfClass: Variable.class]) { return [OFString stringWithFormat: - @"%d", *[identifier storage]]; + @"%d", [identifier value]]; } else if ([identifier isKindOfClass: Alias.class]) return [identifier action]; @@ -350,13 +350,12 @@ writecfg() [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: - @"%@ %d\n", identifier.name, *[identifier storage]]; + [stream writeFormat: @"%@ %d\n", variable.name, variable.value]; }]; [stream writeString: @"\n"]; diff --git a/src/editing.m b/src/editing.m index 49c1fb0..1f64699 100644 --- a/src/editing.m +++ b/src/editing.m @@ -24,8 +24,12 @@ OF_CONSTRUCTOR() 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 @@ -33,8 +37,9 @@ OF_CONSTRUCTOR() min: 0 max: 4096 storage: vars[i].storage - function: NULL - persisted: false]; + persisted: false + getter: NULL + setter: NULL]; Identifier.identifiers[vars[i].name] = variable; } }); @@ -634,13 +639,16 @@ COMMAND(perlin, ARG_3INT, ^ (int scale, int seed, int psize) { 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; diff --git a/src/rendercubes.m b/src/rendercubes.m index 1337523..55c09ee 100644 --- a/src/rendercubes.m +++ b/src/rendercubes.m @@ -320,8 +320,11 @@ render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2, 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) diff --git a/src/rendergl.m b/src/rendergl.m index fefc0e8..562021e 100644 --- a/src/rendergl.m +++ b/src/rendergl.m @@ -327,14 +327,17 @@ addstrip(int tex, int start, int n) #undef gamma -VARFP(gamma, 30, 100, 300, { - float f = gamma / 100.0f; +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) { + ramp, ramp, ramp) != -1) + gamma = value; + else { conoutf( @"Could not set gamma (card/driver doesn't support it?)"); conoutf(@"sdl: %s", SDL_GetError()); @@ -362,7 +365,29 @@ VARP(fov, 10, 105, 120); int xtraverts; 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); @@ -422,11 +447,8 @@ gl_drawframe(int w, int h, float curfps) 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; diff --git a/src/renderparticles.m b/src/renderparticles.m index f386a61..96a0eb5 100644 --- a/src/renderparticles.m +++ b/src/renderparticles.m @@ -2,6 +2,7 @@ #include "cube.h" +#import "OFColor+Cube.h" #import "Player.h" #import "Variable.h" @@ -66,19 +67,51 @@ render_particles(int time) glDisable(GL_FOG); struct parttype { - float r, g, b; + OFColor *color; 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 + /* + * 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; @@ -89,7 +122,7 @@ render_particles(int time) 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);