shithub: duke3d

Download patch

ref: 48170b9f442772d2275e51d3a63b7bfb51881491
parent: 5260668388110f1de7c36c41eacc0fb99d477e58
author: Tanguy Fautre <tanguy@fautre.com>
date: Sat Feb 22 07:39:38 EST 2020

Fix crash when saving games

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,11 @@
 	add_definitions(-DUNIX)
 	add_compile_options("-Wall")
 
+	# Duke 3D source code is not at all thought out for strict aliasing.
+	# Really not! It's full of dangerous pointer casting.
+	# Without this option, game will crash at random places when compiled with -O2 or-O3.
+	add_compile_options("-fno-strict-aliasing") 
+
 endif ()
 
 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
--- a/Engine/src/fixedPoint_math.c
+++ b/Engine/src/fixedPoint_math.c
@@ -1,13 +1,33 @@
 // converted from asm to c by Jonof
 
 #include <stdio.h>
+#include <string.h>
 #include "platform.h"
 #include "fixedPoint_math.h"
 
 void clearbuf(void *d, int32_t c, int32_t a)
 {
-	int32_t *p = (int32_t*)d;
-	while ((c--) > 0) *(p++) = a;
+    // tanguyf: this completely violates strict-aliasing.
+	//int32_t *p = (int32_t*)d;
+	//while ((c--) > 0) *(p++) = a;
+
+	union
+    {
+	    struct { uint8_t a,b,c,d; };
+	    int32_t value;
+    } src;
+
+	src.value = a;
+
+	uint8_t* dst = (uint8_t*) d;
+
+	for (int32_t i = 0; i < c; ++i)
+    {
+	    dst[i*4 + 0] = src.a;
+        dst[i*4 + 1] = src.b;
+        dst[i*4 + 2] = src.c;
+        dst[i*4 + 3] = src.d;
+    }
 }
 
 void clearbufbyte(void *D, int32_t c, int32_t a)
@@ -24,8 +44,10 @@
 
 void copybuf(void *s, void *d, int32_t c)
 {
-	int32_t *p = (int32_t*)s, *q = (int32_t*)d;
-	while ((c--) > 0) *(q++) = *(p++);
+    // tanguyf: this completely violates strict-aliasing.
+	//int32_t *p = (int32_t*)s, *q = (int32_t*)d;
+	//while ((c--) > 0) *(q++) = *(p++);
+	memcpy(d, s, c * sizeof(int32_t));
 }
 
 void copybufbyte(void *S, void *D, int32_t c)
--- a/README.md
+++ b/README.md
@@ -23,7 +23,6 @@
 
 ### Known Issues
 
-* Linux: savegames do not work or crash the engine.
 * Engine: Leaning left/right falls back to low-res rendering.
 * Engine: Minimap has rendering glitches when fully-textured (i.e. sprites).
 * Engine: Pixel imprecision when rendering health/ammo numbers in the status bar, leaving ghost pixels.