Merge branch 'master' into martin-t/globals
authorMartin Taibr <taibr.martin@gmail.com>
Sat, 17 Aug 2019 18:30:52 +0000 (20:30 +0200)
committerMartin Taibr <taibr.martin@gmail.com>
Sat, 17 Aug 2019 18:30:52 +0000 (20:30 +0200)
27 files changed:
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/common/debug.qh
qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/dpdefs/csprogsdefs.qh
qcsrc/dpdefs/dpextensions.qh
qcsrc/dpdefs/progsdefs.qh
qcsrc/ecs/systems/physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/csqcmodel/interpolate.qc
qcsrc/lib/deglobalization.qh [new file with mode: 0644]
qcsrc/lib/float.qh
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/anglestransform.qc
qcsrc/lib/warpzone/anglestransform.qh
qcsrc/lib/warpzone/common.qc
qcsrc/lib/warpzone/mathlib.qc
qcsrc/lib/warpzone/server.qc
qcsrc/lib/warpzone/util_server.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/tools/compilationunits.sh

index a0641955609138a43fc1f396e6c6be54469ee716..1272758f76cee3de642322d9ce6ffb2419660e7a 100644 (file)
@@ -540,8 +540,11 @@ void CSQCModel_Effects_Apply(entity this)
                tref = EFFECT_TR_BLOOD.m_id;
        if(this.csqcmodel_modelflags & MF_ROTATE)
        {
+               // This will be hard to replace with MAKE_VECTORS because it's called as part of the predraw function
+               // as documented in csprogs.h in the engine. The globals can then be read in many places in the engine.
+               // However MF_ROTATE is currently only used in one place - might be possible to get rid of it entirely.
                this.renderflags |= RF_USEAXIS;
-               MAKEVECTORS(makevectors, this.angles + '0 100 0' * fmod(time, 3.6), v_forward, v_right, v_up);
+               makevectors(this.angles + '0 100 0' * fmod(time, 3.6));
        }
        if(this.csqcmodel_modelflags & MF_TRACER)
                tref = EFFECT_TR_WIZSPIKE.m_id;
index 26de41e7245aaf2e323287d065eb90ec5c81f50e..c565651d4a3a0b49daee81ae6a76649b60889d66 100644 (file)
@@ -93,8 +93,8 @@ void draw_teamradar_player(vector coord3d, vector pangles, vector rgb)
 
        coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(coord3d));
 
-       vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-       MAKEVECTORS(makevectors, pangles - '0 1 0' * teamradar_angle, forward, right, up);
+       vector forward, right, up;
+       MAKE_VECTORS(pangles - '0 1 0' * teamradar_angle, forward, right, up);
        if(v_flipped)
        {
                forward.x = -forward.x;
index 7c3c1068b1dff2a6a0d096405cdc7d531c307552..dadf6069abfdad7010f7a8574366c87d843b0804 100644 (file)
@@ -133,8 +133,8 @@ void calc_followmodel_ofs(entity view)
                vel = view.velocity;
        else
        {
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               vector forward, right, up;
+               MAKE_VECTORS(view_angles, forward, right, up);
                vel.x = view.velocity * forward;
                vel.y = view.velocity * right * -1;
                vel.z = view.velocity * up;
@@ -159,8 +159,8 @@ void calc_followmodel_ofs(entity view)
        if (autocvar_cl_followmodel_velocity_absolute)
        {
                vector fixed_gunorg;
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               vector forward, right, up;
+               MAKE_VECTORS(view_angles, forward, right, up);
                fixed_gunorg.x = gunorg * forward;
                fixed_gunorg.y = gunorg * right * -1;
                fixed_gunorg.z = gunorg * up;
@@ -491,15 +491,16 @@ vector GetCurrentFov(float fov)
                        curspeed = 0;
                else
                {
-                       makevectors(view_angles);
+                       vector forward, right, up;
+                       MAKE_VECTORS(view_angles, forward, right, up);
                        v = pmove_vel;
                        if(csqcplayer)
                                v = csqcplayer.velocity;
 
                        switch(autocvar_cl_velocityzoom_type)
                        {
-                               case 3: curspeed = max(0, v_forward * v); break;
-                               case 2: curspeed = (v_forward * v); break;
+                               case 3: curspeed = max(0, forward * v); break;
+                               case 2: curspeed = (forward * v); break;
                                case 1: default: curspeed = vlen(v); break;
                        }
                }
@@ -1727,18 +1728,19 @@ void CSQC_UpdateView(entity this, float w, float h)
                        else if(eventchase_current_distance != chase_distance)
                                eventchase_current_distance = chase_distance;
 
-                       makevectors(view_angles);
+                       vector forward, right, up;
+                       MAKE_VECTORS(view_angles, forward, right, up);
 
-                       vector eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                       vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                        WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this);
 
                        // If the boxtrace fails, revert back to line tracing.
                        if(!local_player.viewloc)
                        if(trace_startsolid)
                        {
-                               eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                               eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                                WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this);
-                               setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins.z)));
+                               setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z)));
                        }
                        else { setproperty(VF_ORIGIN, trace_endpos); }
 
@@ -1865,7 +1867,7 @@ void CSQC_UpdateView(entity this, float w, float h)
        // Render the Scene
        view_origin = getpropertyvec(VF_ORIGIN);
        view_angles = getpropertyvec(VF_ANGLES);
-       MAKEVECTORS(makevectors, view_angles, view_forward, view_right, view_up);
+       MAKE_VECTORS(view_angles, view_forward, view_right, view_up);
 
 #ifdef BLURTEST
        if(time > blurtest_time0 && time < blurtest_time1)
@@ -2416,14 +2418,15 @@ void CSQC_UpdateView(entity this, float w, float h)
                setproperty(VF_ORIGIN, '0 0 0');
                setproperty(VF_ANGLES, '0 0 0');
                setproperty(VF_PERSPECTIVE, 1);
-               makevectors('0 0 0');
+               vector forward, right, up;
+               MAKE_VECTORS('0 0 0', forward, right, up);
                vector v1, v2;
                cvar_set("vid_conwidth", "800");
                cvar_set("vid_conheight", "600");
-               v1 = cs_project(v_forward);
+               v1 = cs_project(forward);
                cvar_set("vid_conwidth", "640");
                cvar_set("vid_conheight", "480");
-               v2 = cs_project(v_forward);
+               v2 = cs_project(forward);
                if(v1 == v2)
                        cs_project_is_b0rked = 1;
                else
index 55b634a624ce91619b15054f7325ca5cbe071cd7..05064ca96742c395ab0beb863f6bffb186549867 100644 (file)
@@ -295,7 +295,7 @@ MUTATOR_HOOKFUNCTION(trace, SV_StartFrame)
                        it.solid = SOLID_BBOX;
                });
                vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0';
-               MAKEVECTORS(makevectors, it.v_angle, forward, right, up);
+               MAKE_VECTORS(it.v_angle, forward, right, up);
                vector pos = it.origin + it.view_ofs;
                traceline(pos, pos + forward * max_shot_distance, MOVE_NORMAL, it);
                FOREACH_ENTITY(true, {
index 5e59fd9f3274471f866e363894bcb5c510eed6f8..899c6d63c1284fce107e2a348ab482d731d620ab 100644 (file)
@@ -74,9 +74,10 @@ CLASS(DamageText, Object)
         if (this.m_screen_coords) {
             screen_pos = this.origin + since_hit * autocvar_cl_damagetext_2d_velocity;
         } else {
-            makevectors(view_angles);
+            vector forward, right, up;
+            MAKE_VECTORS(view_angles, forward, right, up);
             vector world_offset = since_hit * autocvar_cl_damagetext_velocity_world + autocvar_cl_damagetext_offset_world;
-            vector world_pos = this.origin + world_offset.x * v_forward + world_offset.y * v_right + world_offset.z * v_up;
+            vector world_pos = this.origin + world_offset.x * forward + world_offset.y * right + world_offset.z * up;
             screen_pos = project_3d_to_2d(world_pos) + since_hit * autocvar_cl_damagetext_velocity_screen + autocvar_cl_damagetext_offset_screen;
         }
         screen_pos.y += size / 2;
index 6640cb8bf23a51a48c08cdd4662fbd89a4fcefcf..652f7a2b7b8e9aa7c4a19d7f5832cd769224aed2 100644 (file)
@@ -113,20 +113,20 @@ REGISTER_MUTATOR(dodging, true);
                return true;
 
 // returns true if the player is close to a wall
-bool is_close_to_wall(entity this, float threshold)
+bool is_close_to_wall(entity this, float threshold, vector forward, vector right)
 {
-       X(v_right);
-       X(-v_right);
-       X(v_forward);
-       X(-v_forward);
+       X(right);
+       X(-right);
+       X(forward);
+       X(-forward);
 
        return false;
 }
 
-bool is_close_to_ground(entity this, float threshold)
+bool is_close_to_ground(entity this, float threshold, vector up)
 {
        if (IS_ONGROUND(this)) return true;
-       X(-v_up); // necessary for dodging down a slope using doubletap (using `+dodge` works anyway)
+       X(-up); // necessary for dodging down a slope using doubletap (using `+dodge` works anyway)
 
        return false;
 }
@@ -180,10 +180,11 @@ bool PM_dodging_checkpressedkeys(entity this)
        if ((time - this.last_dodging_time) < PHYS_DODGING_DELAY)
                return false;
 
-       makevectors(this.angles);
+       vector forward, right, up;
+       MAKE_VECTORS(this.angles, forward, right, up);
 
-       bool can_dodge = (is_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD) && (PHYS_DODGING_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_MAXSPEED)));
-       bool can_wall_dodge = (PHYS_DODGING_WALL && is_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD));
+       bool can_dodge = (is_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD, up) && (PHYS_DODGING_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_MAXSPEED)));
+       bool can_wall_dodge = (PHYS_DODGING_WALL && is_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD, forward, right));
        bool can_air_dodge = (PHYS_DODGING_AIR && (PHYS_DODGING_AIR_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_AIR_MAXSPEED)));
        if (!can_dodge && !can_wall_dodge && !can_air_dodge) return false;
 
@@ -221,11 +222,11 @@ void PM_dodging(entity this)
                return;
        }
 
-       // make sure v_up, v_right and v_forward are sane
+       vector forward, right, up;
        if(PHYS_DODGING_AIR)
-               makevectors(this.v_angle);
+               MAKE_VECTORS(this.v_angle, forward, right, up);
        else
-               makevectors(this.angles);
+               MAKE_VECTORS(this.angles, forward, right, up);
 
        // fraction of the force to apply each frame
        // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
@@ -237,15 +238,15 @@ void PM_dodging(entity this)
 
        float velocity_increase = min(common_factor * this.dodging_force_total, this.dodging_force_remaining);
        this.dodging_force_remaining -= velocity_increase;
-       this.velocity += this.dodging_direction.x * velocity_increase * v_forward
-                      + this.dodging_direction.y * velocity_increase * v_right;
+       this.velocity += this.dodging_direction.x * velocity_increase * forward
+                      + this.dodging_direction.y * velocity_increase * right;
 
        // the up part of the dodge is a single shot action
        if (this.dodging_single_action == 1)
        {
                UNSET_ONGROUND(this);
 
-               this.velocity += PHYS_DODGING_UP_SPEED * v_up;
+               this.velocity += PHYS_DODGING_UP_SPEED * up;
 
 #ifdef SVQC
                if (autocvar_sv_dodging_sound)
index 73435841d87c296f1119c3078b1f4c0833ba02d8..2243c9872cba4d3ed6d1b1f4c47e25d7cf41a2e9 100644 (file)
@@ -103,10 +103,15 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                        vector horiz_vel = vec2(it.velocity);
                        // when walking slowly sideways, we assume the player wants a clear shot ahead - spawn behind him according to where he's looking
                        // when running fast, spawn behind him according to his direction of movement to prevent colliding with the newly spawned player
+                       vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0';
                        if (vdist(horiz_vel, >, autocvar_sv_maxspeed + 50))
-                               fixedmakevectors(vectoangles(horiz_vel));
+                       {
+                               FIXED_MAKE_VECTORS(vectoangles(horiz_vel), forward, right, up);
+                       }
                        else
-                               fixedmakevectors(it.angles); // .angles is the angle of the model - usually/always 0 pitch
+                       {
+                               FIXED_MAKE_VECTORS(it.angles, forward, right, up);
+                       }
 
                        // test different spots close to mate - trace upwards so it works on uneven surfaces
                        // don't spawn in front of player or directly behind to avoid players shooting each other
@@ -117,22 +122,22 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                                switch(i)
                                {
                                        case 0:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 + v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 + right * 128 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 1:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 - v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 - right * 128 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 2:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + right * 192 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 3:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - right * 192 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 4:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 + v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 + right * 64 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 5:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 - v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 - right * 64 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                }
 
@@ -142,7 +147,7 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
 
                                // 400 is about the height of a typical laser jump (in overkill)
                                // not traceline because we need space for the whole player, not just his origin
-                               tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - '0 0 400', MOVE_NORMAL, it);
+                               tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - 400 * up, MOVE_NORMAL, it);
                                vector vectical_trace_endpos = trace_endpos;
                                //te_lightning1(NULL, horizontal_trace_endpos, vectical_trace_endpos);
                                if (trace_startsolid) goto skip; // inside another player
@@ -152,8 +157,9 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                                if (tracebox_hits_trigger_hurt(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), vectical_trace_endpos)) goto skip;
 
                                // make sure the spawned player will have floor ahead (or at least a wall - he shouldn't fall as soon as he starts moving)
-                               vector floor_test_start = vectical_trace_endpos + v_up * STAT(PL_MAX, player).z + v_forward * STAT(PL_MAX, player).x; // top front of player's bbox - highest point we know is not inside solid
-                               traceline(floor_test_start, floor_test_start + v_forward * 100 - v_up * 128, MOVE_NOMONSTERS, it);
+                               // top front of player's bbox - highest point we know is not inside solid
+                               vector floor_test_start = vectical_trace_endpos + up * STAT(PL_MAX, player).z + forward * STAT(PL_MAX, player).x; 
+                               traceline(floor_test_start, floor_test_start + forward * 100 - up * 128, MOVE_NOMONSTERS, it);
                                //te_beam(NULL, floor_test_start, trace_endpos);
                                if (trace_fraction == 1.0) goto skip;
 
@@ -171,7 +177,7 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
 
                                // here, we know we found a good spot
                                RandomSelection_Add(it, 0, string_null, vectical_trace_endpos, 1, 1);
-                               //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + v_forward * 10);
+                               //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + forward * 10);
 
 LABEL(skip)
                                if (i % 2 == 1 && RandomSelection_chosen_ent)
index cdd0a0f92a315ecf1b3e774aa21b93ea17a5edfb..9b1dd6c0b8536b31029d7c87771d4806a6a9ee3b 100644 (file)
@@ -663,9 +663,8 @@ void Draw_Shockwave(entity this)
        // WEAPONTODO: trace to find what we actually hit
        vector endpos = (this.sw_shotorg + (this.sw_shotdir * this.sw_distance));
 
-       vectorvectors(this.sw_shotdir);
-       vector right = v_right; // save this for when we do makevectors later
-       vector up = v_up; // save this for when we do makevectors later
+       vector _forward, right, up;
+       VECTOR_VECTORS(this.sw_shotdir, _forward, right, up);
 
        // WEAPONTODO: combine and simplify these calculations
        vector min_end = ((this.sw_shotorg + (this.sw_shotdir * SW_DISTTOMIN)) + (up * this.sw_spread_min));
index 29d797585efbe10117995db27925b739109abae6..9453157f7000591bf273c07ed20aff7438404636 100644 (file)
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
 #define touch move_touch
+
+// deglobalization:
+
+void(vector ang) _makevectors_hidden = #1;
+//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
+
+#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
+//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
+
+void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
+//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
+
+#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+void(vector org, float radius, vector lightcolours) _adddynamiclight_hidden = #305;
+//#define adddynamiclight DO_NOT_USE_GLOBALS_PREFER_ADD_DYNAMIC_LIGHT_MACRO_INSTEAD
+#define adddynamiclight2 DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+void(vector dir) _vectorvectors_hidden = #432;
+#define vectorvectors DO_NOT_USE_GLOBALS_PREFER_VECTOR_VECTORS_MACRO_INSTEAD
+
+vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
+//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
+
+#define getentity DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+#define getentityvec DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
index 2ed0f9063889af40f2270740e069f47d29f62789..d6f6a072a0fea688e192219b28e21184a8c7b76b 100644 (file)
@@ -63,3 +63,20 @@ int() _buf_create = #460;
 #define buf_create _buf_create
 
 #pragma noref 0
+
+// deglobalization:
+
+#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
+//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
+
+void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
+//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
+
+#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
+//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
index ccdf9bc0c4293353a7e8392b059831e313474958..a8d8a4a486a0824cb200182a176ebf856762f8ed 100644 (file)
@@ -29,3 +29,12 @@ MACRO_END
 
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
+
+// deglobalization:
+
+void(vector ang) _makevectors_hidden = #1;
+//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
+
+#define aim DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
index ae5f119e7fe8db0eea039a57032af553cd4d7d24..f73ade3d12ea58ea6f5652554909505c0a335f79 100644 (file)
@@ -193,8 +193,8 @@ void sys_phys_simulate(entity this, float dt)
                // this mimics quakeworld code
                if (this.com_in_jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc) {
                        vector yawangles = '0 1 0' * this.v_angle.y;
-                       makevectors(yawangles);
-                       vector forward = v_forward;
+                       vector forward, right, up;
+                       MAKE_VECTORS(yawangles, forward, right, up);
                        vector spot = this.origin + 24 * forward;
                        spot_z += 8;
                        traceline(spot, spot, MOVE_NOMONSTERS, this);
@@ -210,10 +210,12 @@ void sys_phys_simulate(entity this, float dt)
                        }
                }
        }
-       makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')));
-       // wishvel = v_forward * PHYS_CS(this).movement.x + v_right * PHYS_CS(this).movement.y + v_up * PHYS_CS(this).movement.z;
-       vector wishvel = v_forward * PHYS_CS(this).movement.x
-           + v_right * PHYS_CS(this).movement.y
+
+       vector forward, right, up;
+       MAKE_VECTORS(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')), forward, right, up);
+       // wishvel = forward * PHYS_CS(this).movement.x + right * PHYS_CS(this).movement.y + up * PHYS_CS(this).movement.z;
+       vector wishvel = forward * PHYS_CS(this).movement.x
+           + right * PHYS_CS(this).movement.y
            + '0 0 1' * PHYS_CS(this).movement.z * (this.com_phys_vel_2d ? 0 : 1);
        if (this.com_phys_water) {
                if (PHYS_INPUT_BUTTON_CROUCH(this)) {
index ab74531605f29a44d7f69c23b7ba99e4f30a3479..3bbb17ccf8715ddfced52d63453e41e7f40cc3e2 100644 (file)
 #include "counting.qh"
 #include "cvar.qh"
 #include "defer.qh"
+#include "deglobalization.qh"
 #include "draw.qh"
 #include "enumclass.qh"
 #include "file.qh"
+#include "float.qh"
 #include "functional.qh"
 #include "i18n.qh"
 #include "intrusivelist.qh"
index 4fd138360a3548bea865f8d7292f432e477865f0..7600fdde606f5d7a5c6733c0f2822b448140d806 100644 (file)
@@ -58,7 +58,8 @@ void InterpolateOrigin_Note(entity this)
 
        if (this.iflags & IFLAG_ANGLES)
        {
-               fixedmakevectors(this.angles);
+               vector forward, right, up;
+               FIXED_MAKE_VECTORS(this.angles, forward, right, up);
                if (f0 & IFLAG_VALID)
                {
                        this.iforward1 = this.iforward2;
@@ -66,16 +67,17 @@ void InterpolateOrigin_Note(entity this)
                }
                else
                {
-                       this.iforward1 = v_forward;
-                       this.iup1 = v_up;
+                       this.iforward1 = forward;
+                       this.iup1 = up;
                }
-               this.iforward2 = v_forward;
-               this.iup2 = v_up;
+               this.iforward2 = forward;
+               this.iup2 = up;
        }
 
        if (this.iflags & IFLAG_V_ANGLE)
        {
-               fixedmakevectors(this.v_angle);
+               vector forward, right, up;
+               FIXED_MAKE_VECTORS(this.v_angle, forward, right, up);
                if (f0 & IFLAG_VALID)
                {
                        this.ivforward1 = this.ivforward2;
@@ -83,11 +85,11 @@ void InterpolateOrigin_Note(entity this)
                }
                else
                {
-                       this.ivforward1 = v_forward;
-                       this.ivup1 = v_up;
+                       this.ivforward1 = forward;
+                       this.ivup1 = up;
                }
-               this.ivforward2 = v_forward;
-               this.ivup2 = v_up;
+               this.ivforward2 = forward;
+               this.ivup2 = up;
        }
        else if (this.iflags & IFLAG_V_ANGLE_X)
        {
diff --git a/qcsrc/lib/deglobalization.qh b/qcsrc/lib/deglobalization.qh
new file mode 100644 (file)
index 0000000..3d7f820
--- /dev/null
@@ -0,0 +1,73 @@
+#include "lib/float.qh"
+#include "lib/misc.qh"
+#include "lib/static.qh"
+#include "lib/vector.qh"
+
+// These macros wrap functions which use globals so mutation only occurs inside them and is not visible from outside.
+// Functions for which all usages are replaced with these macros can be hidden by #defines inside our `*defs.qh` files
+// to prevent anyone from using them accidentally in the future
+
+// TODO stuff in the engine that uses the v_forward/v_right/v_up globals and is not wrapped yet:
+//  - RF_USEAXIS, addentities, predraw,
+//    - CL_GetEntityMatrix (in engine but is called from other functions so transitively any of them can use the globals - e.g. V_CalcRefdef, maybe others)
+//    - however RF_USEAXIS is only used if MF_ROTATE is used which is only set in one place
+//  - e.camera_transform / CL_VM_TransformView (in engine)
+//    - this is the only used function that both sets and gets the globals (aim does too but isn't used in our code)
+
+// convenience for deglobalization code - don't use these just to hide that globals are still used
+#define CLEAR_V_GLOBALS() v_forward = VEC_NAN; v_right = VEC_NAN; v_up = VEC_NAN
+#define GET_V_GLOBALS(forward, right, up) forward = v_forward; right = v_right; up = v_up
+#define SET_V_GLOBALS(forward, right, up) v_forward = forward; v_right = right; v_up = up
+
+#ifdef GAMEQC
+STATIC_INIT(globals) {
+       // set to NaN to more easily detect uninitialized use
+       // TODO when all functions are wrapped and the raw functions are not used anymore,
+       // uncomment the defines in *progs.qh files that hide the raw functions
+       // and assert that the global vectors are NaN before calling the raw functions here
+       // to make sure nobody (even builtins) is accidentally using them - NaN is the most likely value to expose remaining usages
+
+       CLEAR_V_GLOBALS();
+}
+#endif
+
+/// Same as the `makevectors` builtin but uses the provided locals instead of the `v_*` globals.
+/// Always use this instead of raw `makevectors` to make the data flow clear.
+/// Note that you might prefer `FIXED_MAKE_VECTORS` for new code.
+#define MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \
+       _makevectors_hidden(angles); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+/// Returns all 4 vectors by assigning to them (instead of returning a value) for consistency (and sanity)
+#define SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) MACRO_BEGIN \
+       origin = _skel_get_boneabs_hidden(skel, bonenum) \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define SKEL_SET_BONE(skel, bonenum, org, forward, right, up) MACRO_BEGIN \
+       SET_V_GLOBALS(forward, right, up); \
+       _skel_set_bone_hidden(skel, bonenum, org); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define ADD_DYNAMIC_LIGHT(org, radius, lightcolours, forward, right, up) MACRO_BEGIN \
+       SET_V_GLOBALS(forward, right, up); \
+       _adddynamiclight_hidden(org, radius, lightcolours); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define VECTOR_VECTORS(forward_in, forward, right, up) MACRO_BEGIN \
+       _vectorvectors_hidden(forward_in); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+/// Note that this only avoids the v_* globals, not the gettaginfo_* ones
+#define GET_TAG_INFO(ent, tagindex, forward, right, up, origin) MACRO_BEGIN \
+       origin = _gettaginfo_hidden(ent, tagindex); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
index b4d1f0bd768c785f103ad3886f5453769e10c2ff..b35494de44c0334f776d296f808565dd33af8be8 100644 (file)
@@ -2,3 +2,5 @@
 
 const float FLOAT_MAX = 340282346638528859811704183484516925440.0f;
 const float FLOAT_EPSILON = 0.00000011920928955078125f;
+/// Always use `isnan` function to compare because `float x = FLOAT_NAN; x == x;` gives true
+const float FLOAT_NAN = 0.0 / 0.0;
index 0d09ea8e6a50767bf181376b671423a9b7918070..ca0e84f67a95b4b8f118eac268d461a64ae6a8a7 100644 (file)
@@ -93,13 +93,6 @@ float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { ret
 #define YAW(v) ((v).y)
 #define ROLL(v) ((v).z)
 
-#define MAKEVECTORS(f, angles, forward, right, up) MACRO_BEGIN \
-       f(angles); \
-       forward = v_forward; \
-       right = v_right; \
-       up = v_up; \
-MACRO_END
-
 //pseudo prototypes:
 // vector vec2(vector v); // returns a vector with just the x and y components of the given vector
 // vector vec2(float x, float y); // returns a vector with the given x and y components
@@ -112,6 +105,13 @@ noref vector _vec2;
 noref vector _vec3;
 #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
 
+#define VEC_NAN vec3(FLOAT_NAN, FLOAT_NAN, FLOAT_NAN);
+
+ERASEABLE
+bool is_all_nans(vector v) {
+       return isnan(v.x) && isnan(v.y) && isnan(v.z);
+}
+
 ERASEABLE
 vector Rotate(vector v, float a)
 {
index 9e98199f34be62fcd74fd742dc329f900c169d32..76e8d37f9a668c92bdb4e1b7ea79e010973b5e39 100644 (file)
@@ -4,34 +4,35 @@
 // angles in fixedmakevectors/fixedvectoangles space
 vector AnglesTransform_Apply(vector transform, vector v)
 {
-       fixedmakevectors(transform);
-       return v_forward * v.x
-               + v_right   * (-v.y)
-               + v_up      * v.z;
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(transform, forward, right, up);
+       return forward * v.x + right * (-v.y) + up * v.z;
 }
 
 vector AnglesTransform_Multiply(vector t1, vector t2)
 {
-       vector m_forward, m_up;
-       fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
-       m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up);
-       return fixedvectoangles2(m_forward, m_up);
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(t2, forward, right, up);
+       forward = AnglesTransform_Apply(t1, forward);
+       up = AnglesTransform_Apply(t1, up);
+       return fixedvectoangles2(forward, up);
 }
 
 vector AnglesTransform_Invert(vector transform)
 {
        vector i_forward, i_up;
-       fixedmakevectors(transform);
-       // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1'
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(transform, forward, right, up);
+       // we want angles that turn forward into '1 0 0', right into '0 1 0' and up into '0 0 1'
        // but these are orthogonal unit vectors!
        // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
        // TODO is this always -transform?
-       i_forward.x = v_forward.x;
-       i_forward.y = -v_right.x;
-       i_forward.z = v_up.x;
-       i_up.x = v_forward.z;
-       i_up.y = -v_right.z;
-       i_up.z = v_up.z;
+       i_forward.x = forward.x;
+       i_forward.y = -right.x;
+       i_forward.z = up.x;
+       i_up.x = forward.z;
+       i_up.y = -right.z;
+       i_up.z = up.z;
        return fixedvectoangles2(i_forward, i_up);
 }
 
index b287651a10a4fb868acdfeca18d2c0dfaf77b4d0..92362f982fee1590b31c6340b7d576d4bcd7f68e 100644 (file)
@@ -6,6 +6,7 @@
 
 #if POSITIVE_PITCH_IS_DOWN
     #define fixedmakevectors makevectors
+    #define FIXED_MAKE_VECTORS MAKE_VECTORS
     noref vector _fixedvectoangles;
     #define fixedvectoangles(a) (_fixedvectoangles = vectoangles(a), _fixedvectoangles.x *= -1, _fixedvectoangles)
     noref vector _fixedvectoangles2;
         a.x = -a.x;
         makevectors(a);
     }
+    #define FIXED_MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \
+        fixedmakevectors(angles); \
+        GET_V_GLOBALS(forward, right, up); \
+        CLEAR_V_GLOBALS(); \
+    MACRO_END
     #define fixedvectoangles2 vectoangles2
     #define fixedvectoangles vectoangles
 #endif
index b70e938fe7e987ee9dded47a2e721b151bd9d10d..3bff39be1fd954f89ff4984828aa0af67dad42bd 100644 (file)
@@ -71,8 +71,11 @@ void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, ve
        e.warpzone_targetorigin = other_org;
        e.warpzone_angles = my_ang;
        e.warpzone_targetangles = other_ang;
-       fixedmakevectors(my_ang); e.warpzone_forward = v_forward;
-       fixedmakevectors(other_ang); e.warpzone_targetforward = v_forward;
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(my_ang, forward, right, up);
+       e.warpzone_forward = forward;
+       FIXED_MAKE_VECTORS(other_ang, forward, right, up);
+       e.warpzone_targetforward = forward;
        setcamera_transform(e, WarpZone_camera_transform);
 }
 
@@ -201,7 +204,6 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        float nomonsters_adjusted;
        float frac, sol, i;
        float contentshack;
-       vector o0, e0;
        entity wz;
        vector vf, vr, vu;
 
@@ -231,8 +233,6 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        vf = v_forward;
        vr = v_right;
        vu = v_up;
-       o0 = org;
-       e0 = end;
 
        switch(nomonsters)
        {
index 4a7c8861069f7eb8420ec819b9525d606ffbe2d2..9105269ff32ebbc00d9c54e832557943412cedd4 100644 (file)
@@ -24,8 +24,13 @@ bool isinf(float e)
 }
 bool isnan(float e)
 {
-       float f = e;
-       return (e != f);
+       // the sane way to detect NaN is broken because of a compiler bug
+       // (works with constants but breaks when assigned to variables)
+       // use conversion to string instead
+
+       //float f = e;
+       //return (e != f);
+       return ftos(e) == "-nan";
 }
 bool isnormal(float e)
 {
@@ -217,6 +222,7 @@ float copysign(float e, float f)
 {
        return fabs(e) * ((f>0) ? 1 : -1);
 }
+/// Always use `isnan` function to compare because `float x = nan(); x == x;` gives true
 float nan(string tag)
 {
        return sqrt(-1);
index 9958a5df4a4497242afc4b0f7028bba54500be64..0244b40a9d724c33713d95e4b694cce4b6f84849 100644 (file)
@@ -602,15 +602,16 @@ void WarpZone_InitStep_UpdateTransform(entity this)
                if(area > 0)
                {
                        org = org - ((org - point) * norm) * norm; // project to plane
-                       makevectors(ang);
-                       if(norm * v_forward < 0)
+                       vector forward, right, up;
+                       MAKE_VECTORS(ang, forward, right, up);
+                       if(norm * forward < 0)
                        {
                                LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.");
                                norm = -1 * norm;
                        }
-                       ang = vectoangles2(norm, v_up); // keep rotation, but turn exactly against plane
+                       ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane
                        ang.x = -ang.x;
-                       if(norm * v_forward < 0.99)
+                       if(norm * forward < 0.99)
                                LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang));
                        if(vdist(org - this.aiment.origin, >, 0.5))
                                LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").");
index d5533647f51e7727cb19b886e9fd3eea6887bb8c..658716052f6e9d0f2865a12808328b4bb2e74870 100644 (file)
@@ -15,8 +15,9 @@ void WarpZoneLib_ExactTrigger_Init(entity this)
        if (this.movedir == '0 0 0')
        if (this.angles != '0 0 0')
        {
-               makevectors (this.angles);
-               this.movedir = v_forward;
+               vector forward, _r, _u;
+               MAKE_VECTORS(this.angles, forward, _r, _u);
+               this.movedir = forward;
        }
        if(this.model == "")
        {
index 730c92884f75b09ddf7ff1cf890a610272ad084e..5aa81a2a73b0e9ad3fae1304237f863e71c9a2ed 100644 (file)
@@ -119,9 +119,10 @@ void relocate_spawnpoint(entity this)
     if (autocvar_r_showbboxes)
     {
         // show where spawnpoints point at too
-        makevectors(this.angles);
+        vector forward, right, up;
+        MAKE_VECTORS(this.angles, forward, right, up);
         entity e = new(info_player_foo);
-        setorigin(e, this.origin + v_forward * 24);
+        setorigin(e, this.origin + forward * 24);
         setsize(e, '-8 -8 -8', '8 8 8');
         e.solid = SOLID_TRIGGER;
     }
index 99fa2df749eb9215c09789e86ec24bfd22d6fad5..ef7f1a832b6f77dc4b334b322931ad81e0a37930 100644 (file)
@@ -51,14 +51,14 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent);
        ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 
-       vector vf, vr, vu;
-       vf = v_forward;
-       vr = v_right;
-       vu = v_up;
+       vector forward, right, up;
+       forward = v_forward;
+       right = v_right;
+       up = v_up;
        w_shotend = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support
-       v_forward = vf;
-       v_right = vr;
-       v_up = vu;
+       v_forward = forward;
+       v_right = right;
+       v_up = up;
 
        // un-adjust trueaim if shotend is too close
        if(vdist(w_shotend - (ent.origin + ent.view_ofs), <, autocvar_g_trueaim_minrange))
@@ -69,27 +69,27 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                accuracy_add(ent, wep, maxdamage, 0);
 
        if(IS_PLAYER(ent))
-               W_HitPlotAnalysis(ent, wep, v_forward, v_right, v_up);
+               W_HitPlotAnalysis(ent, wep, forward, right, up);
 
        vector md = ent.(weaponentity).movedir;
        vector vecs = ((md.x > 0) ? md : '0 0 0');
 
        // TODO this is broken - see 637056bea7bf7f5c9c0fc6113e94731a2767476 for an attempted fix
        // which fixes issue #1957 but causes #2129
-       vector dv = v_right * -vecs.y + v_up * vecs.z;
+       vector dv = right * -vecs.y + up * vecs.z;
        w_shotorg = ent.origin + ent.view_ofs + dv;
 
        // now move the shotorg forward as much as requested if possible
        if(antilag)
        {
                if(CS(ent).antilag_debug)
-                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
+                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
                else
-                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
        }
        else
-               tracebox(w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent);
-       w_shotorg = trace_endpos - v_forward * nudge;
+               tracebox(w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent);
+       w_shotorg = trace_endpos - forward * nudge;
        // calculate the shotdir from the chosen shotorg
        if(W_DualWielding(ent))
                w_shotdir = s_forward;
index b75881127a219008f56faaad9d086817d922ab4c..5702c2e3c1bcef94c7b5ecd5ad95c30341dfdb38 100644 (file)
@@ -373,10 +373,6 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
                restartanim = fr != WFRAME_IDLE;
        }
 
-       vector of = v_forward;
-       vector or = v_right;
-       vector ou = v_up;
-
        vector a = '0 0 0';
     this.wframe = fr;
     if (fr == WFRAME_IDLE) a = this.anim_idle;
@@ -386,10 +382,6 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
         a = this.anim_reload;
     a.z *= g_weaponratefactor;
 
-       v_forward = of;
-       v_right = or;
-       v_up = ou;
-
        if (this.weapon_think == w_ready && func != w_ready && this.state == WS_RAISE) backtrace(
                        "Tried to override initial weapon think function - should this really happen?");
 
@@ -507,10 +499,8 @@ void W_WeaponFrame(Player actor, .entity weaponentity)
                return;
        }
 
-       makevectors(actor.v_angle);
-       vector fo = v_forward;  // save them in case the weapon think functions change it
-       vector ri = v_right;
-       vector up = v_up;
+       vector fo, ri, up;
+       MAKE_VECTORS(actor.v_angle, fo, ri, up);
 
        // Change weapon
        if (this.m_weapon != this.m_switchweapon)
index e3d1eb01368df1c714c55d7264eda99e89ff8bbd..68f2eb9d5628ae7df244e70e2ef158be1d69124b 100755 (executable)
@@ -38,6 +38,7 @@ QCCDEFS="${QCCDEFS[@]}"
 
 declare -a QCCFLAGS=(
     -std=gmqcc
+    -O3 # optimization to accept variable initialization inside `if (1)` blocks and avoid warnings
     -Wall -Werror
     -futf8
     -freturn-assignments