From cc86eaf27b63c6e1a02dc170556703c939add4b7 Mon Sep 17 00:00:00 2001 From: Justin <95296300+Toodles2You@users.noreply.github.com> Date: Tue, 3 Feb 2026 16:28:54 -0800 Subject: [PATCH] Expose horizontal model flipping to QC --- engine/client/pr_csqc.c | 2 ++ engine/client/pr_menu.c | 2 ++ engine/common/pr_common.h | 1 + engine/server/pr_cmds.c | 1 + 4 files changed, 6 insertions(+) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 07ad698bc..4000ab0dc 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -793,6 +793,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *fte_restrict in, entity_t *ft if (rflags & CSQCRF_NOSHADOW) out->flags |= RF_NOSHADOW; //CSQCRF_FRAMETIMESARESTARTTIMES is handled by cs_getframestate below + if (rflags & CSQCRF_XFLIP) + out->flags |= RF_XFLIP; // if (rflags & CSQCRF_REMOVED) // Con_Printf("Warning: CSQCRF_NOAUTOADD is no longer supported\n"); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 0fbf8645f..7fe5952a1 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -2273,6 +2273,8 @@ static qboolean CopyMenuEdictToEntity(pubprogfuncs_t *prinst, menuedict_t *in, e out->flags |= RF_ADDITIVE; if (rflags & CSQCRF_DEPTHHACK) out->flags |= RF_DEPTHHACK; + if (rflags & CSQCRF_XFLIP) + out->flags |= RF_XFLIP; if (out->model) return true; diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index cf00c3e3e..2dbd5d06d 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -877,6 +877,7 @@ typedef enum #define CSQCRF_NOSHADOW 32 //don't cast shadows upon other entities (can still be self shadowing, if the engine wishes, and not additive) #define CSQCRF_FRAMETIMESARESTARTTIMES 64 //EXT_CSQC_1: frame times should be read as (time-frametime). #define CSQCRF_FIRSTPERSON 1024 //also not drawn in mirrors, just without the VIEWMODEL hacks attached +#define CSQCRF_XFLIP 2048 //flip horizontally (for q2's left-handed weapons) //#define CSQCRFDP_USETRANSPARENTOFFSET 64 // Allows QC to customize origin used for transparent sorting via transparent_origin global, helps to fix transparent sorting bugs on a very large entities ////#define CSQCRF_NOAUTOADD 128 // removed in favour of predraw return values. //#define CSQCRFDP_WORLDOBJECT 128 // for large outdoor entities that should not be culled. diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 0c7b70eab..bc6a3d817 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -13964,6 +13964,7 @@ void PR_DumpPlatform_f(void) {"RF_NOSHADOW", "const float", CS, D("This entity will not cast shadows. Often useful on view models."), CSQCRF_NOSHADOW}, {"RF_FRAMETIMESARESTARTTIMES","const float", CS, D("Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation."), CSQCRF_FRAMETIMESARESTARTTIMES}, {"RF_FIRSTPERSON","const float", CS, D("This is basically the opposite of RF_EXTERNALMODEL. Don't draw in third-person or mirrors."), CSQCRF_FIRSTPERSON}, + {"RF_XFLIP", "const float", CS|MENU, D("Flip the entity horizontally. Useful for left-handed view models."), CSQCRF_XFLIP}, {"IE_KEYDOWN", "const float", CS|MENU, D("Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument."), CSIE_KEYDOWN}, {"IE_KEYUP", "const float", CS|MENU, D("Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired."), CSIE_KEYUP},