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.