From 7929e845d3092c14be9727fa30c44a19b1a1e412 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 17 May 2015 18:40:49 +0200 Subject: [PATCH] Fix bug with high velocities in vents in 32bit builds, fix MingW build See https://github.com/yquake2/yquake2/issues/71 and https://github.com/yquake2/xatrix/issues/4 In ClientThink(), the float value ent->velocity[i]*8 is saved into a short and if the value is too big for a short, in 32bit gcc builds the short is set to SHRT_MIN, resulting in the player being pressed down instead of up. Now we put the result in a 32bit int first (which should be big enough) and assign the int to the short. This still overflows, but with -fwrapv at least in a defined way (most probably the same way the original binaries did). The Makefile now sets $CC to gcc for MingW builds, this should fix https://github.com/yquake2/xatrix/issues/3 And while I was at it, when the game lib is loaded, it prints the date it was built, this is especially interesting for our Win32 binaries. --- .gitignore | 1 + Makefile | 6 ++++-- src/player/client.c | 5 ++++- src/savegame/savegame.c | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/Makefile b/Makefile index 24595e1..99aec4a 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,8 @@ endif ifeq ($(OSTYPE), Windows) # At this time only i386 is supported on Windows ARCH := i386 +# seems like mingw doesn't set CC by default +CC := gcc else # Some platforms call it "amd64" and some "x86_64" ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/amd64/x86_64/) @@ -66,10 +68,10 @@ endif # -MMD to generate header dependencies. ifeq ($(OSTYPE), Darwin) CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \ - -Wall -pipe -g -arch i386 -arch x86_64 + -Wall -pipe -g -fwrapv -arch i386 -arch x86_64 else CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \ - -Wall -pipe -g -MMD + -Wall -pipe -g -MMD -fwrapv endif # ---------- diff --git a/src/player/client.c b/src/player/client.c index ea8d9eb..abf4ab1 100644 --- a/src/player/client.c +++ b/src/player/client.c @@ -2225,7 +2225,10 @@ ClientThink(edict_t *ent, usercmd_t *ucmd) for (i = 0; i < 3; i++) { pm.s.origin[i] = ent->s.origin[i] * 8; - pm.s.velocity[i] = ent->velocity[i] * 8; + /* save to an int first, in case the short overflows + * so we get defined behavior (at least with -fwrapv) */ + int tmpVel = ent->velocity[i] * 8; + pm.s.velocity[i] = tmpVel; } if (memcmp(&client->old_pmove, &pm.s, sizeof(pm.s))) diff --git a/src/savegame/savegame.c b/src/savegame/savegame.c index ccdf51a..79943fa 100644 --- a/src/savegame/savegame.c +++ b/src/savegame/savegame.c @@ -181,7 +181,7 @@ void InitGame(void) { gi.dprintf("Game is starting up.\n"); - gi.dprintf("Game is %s.\n", GAMEVERSION); + gi.dprintf("Game is %s built on %s.\n", GAMEVERSION, __DATE__); gun_x = gi.cvar ("gun_x", "0", 0); gun_y = gi.cvar ("gun_y", "0", 0);