diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index f1c96a1e3..5cc596680 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -312,14 +312,11 @@ typedef struct { uint8_t filler; float alpha; spritetype *tspr; - - #if !defined UINTPTR_MAX # error Need UINTPTR_MAX define to select between 32- and 64-bit structs #endif #if UINTPTR_MAX == 0xffffffff - /* On a 32-bit build, pad the struct so it has the same size everywhere. - * REMINDER: Will break savegames. */ + /* On a 32-bit build, pad the struct so it has the same size everywhere. */ intptr_t dummy_; #endif } spriteext_t; diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 2894d8754..bc8c20db8 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -1281,8 +1281,8 @@ static spritetype *loadsprite; #define CM_CEILINGZ(Sec) (*(int32_t *)§or[Sec].visibility) // visibility,filler,lotag // backup of original normalized coordinates -#define CM_WALL_X(Wal) (*(int32_t *)&wall[Wal].picnum) -#define CM_WALL_Y(Wal) (*(int32_t *)&wall[Wal].lotag) +#define CM_WALL_X(Wal) (*(int32_t *)&wall[Wal].picnum) // picnum, overpicnum +#define CM_WALL_Y(Wal) (*(int32_t *)&wall[Wal].lotag) // lotag, hitag // don't rotate when applying clipping, for models with rotational symmetry #define CM_NOROT(Spri) (sprite[Spri].cstat&2) @@ -6605,6 +6605,19 @@ static void fillpolygon(int32_t npoints) faketimerhandler(); } +static inline int32_t addscaleclamp(int32_t a, int32_t b, int32_t s1, int32_t s2) +{ + // a + scale(b, s1, s1-s2), but without arithmetic exception when the + // scale() expression overflows + + double tmp = (double)a + ((double)b*s1)/(s1-s2); + + if (tmp <= INT32_MIN+1) + return INT32_MIN+1; + if (tmp >= INT32_MAX) + return INT32_MAX; + return tmp; +} // // clippoly (internal) @@ -6637,8 +6650,8 @@ static int32_t clippoly(int32_t npoints, int32_t clipstat) } if ((s1^s2) < 0) { - rx2[npoints2] = rx1[z]+scale(rx1[zz]-rx1[z],s1,s1-s2); - ry2[npoints2] = ry1[z]+scale(ry1[zz]-ry1[z],s1,s1-s2); + rx2[npoints2] = addscaleclamp(rx1[z], rx1[zz]-rx1[z], s1, s2); + ry2[npoints2] = addscaleclamp(ry1[z], ry1[zz]-ry1[z], s1, s2); if (s1 < 0) p2[splitcnt++] = npoints2; xb2[npoints2] = npoints2+1; npoints2++; @@ -6686,8 +6699,8 @@ static int32_t clippoly(int32_t npoints, int32_t clipstat) } if ((s1^s2) < 0) { - rx1[npoints] = rx2[z]+scale(rx2[zz]-rx2[z],s1,s1-s2); - ry1[npoints] = ry2[z]+scale(ry2[zz]-ry2[z],s1,s1-s2); + rx1[npoints] = addscaleclamp(rx2[z], rx2[zz]-rx2[z], s1, s2); + ry1[npoints] = addscaleclamp(ry2[z], ry2[zz]-ry2[z], s1, s2); if (s1 < 0) p2[splitcnt++] = npoints; xb1[npoints] = npoints+1; npoints++; @@ -6736,8 +6749,8 @@ static int32_t clippoly(int32_t npoints, int32_t clipstat) } if ((s1^s2) < 0) { - rx2[npoints2] = rx1[z]+scale(rx1[zz]-rx1[z],s1,s1-s2); - ry2[npoints2] = ry1[z]+scale(ry1[zz]-ry1[z],s1,s1-s2); + rx2[npoints2] = addscaleclamp(rx1[z], rx1[zz]-rx1[z], s1, s2); + ry2[npoints2] = addscaleclamp(ry1[z], ry1[zz]-ry1[z], s1, s2); if (s1 < 0) p2[splitcnt++] = npoints2; xb2[npoints2] = npoints2+1; npoints2++; @@ -6785,8 +6798,8 @@ static int32_t clippoly(int32_t npoints, int32_t clipstat) } if ((s1^s2) < 0) { - rx1[npoints] = rx2[z]+scale(rx2[zz]-rx2[z],s1,s1-s2); - ry1[npoints] = ry2[z]+scale(ry2[zz]-ry2[z],s1,s1-s2); + rx1[npoints] = addscaleclamp(rx2[z], rx2[zz]-rx2[z], s1, s2); + ry1[npoints] = addscaleclamp(ry2[z], ry2[zz]-ry2[z], s1, s2); if (s1 < 0) p2[splitcnt++] = npoints; xb1[npoints] = npoints+1; npoints++;