foxygit / doom Log in
commit 11178d5abc068eeadf32f5cc7379a1ac53fc470c
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Fri Aug 31 07:27:44 2007 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Fri Aug 31 07:27:44 2007 +0000

    Use gcc packed attribute for all structures read/written to disk. This
    fixes architectures where structure fields are aligned differently to
    optimise reads, causing the game to crash.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 960
---
 src/doomdata.h | 16 ++++++++--------
 src/doomdef.h  | 15 +++++++++++++++
 src/m_misc.c   |  2 +-
 src/mus2mid.c  |  3 ++-
 src/r_data.c   |  6 +++---
 src/r_defs.h   |  4 ++--
 src/w_wad.c    | 18 ++++++++++++++++++
 src/w_wad.h    | 15 ---------------
 8 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/src/doomdata.h b/src/doomdata.h
index bc436090..66733aea 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -66,7 +66,7 @@ typedef struct
 {
   short		x;
   short		y;
-} mapvertex_t;
+} PACKEDATTR mapvertex_t;


 // A SideDef, defining the visual appearance of a wall,
@@ -80,7 +80,7 @@ typedef struct
   char		midtexture[8];
   // Front sector, towards viewer.
   short		sector;
-} mapsidedef_t;
+} PACKEDATTR mapsidedef_t;



@@ -95,7 +95,7 @@ typedef struct
   short		tag;
   // sidenum[1] will be -1 if one sided
   short		sidenum[2];
-} maplinedef_t;
+} PACKEDATTR maplinedef_t;


 //
@@ -152,7 +152,7 @@ typedef	struct
   short		lightlevel;
   short		special;
   short		tag;
-} mapsector_t;
+} PACKEDATTR mapsector_t;

 // SubSector, as generated by BSP.
 typedef struct
@@ -160,7 +160,7 @@ typedef struct
   short		numsegs;
   // Index of first one, segs are stored sequentially.
   short		firstseg;
-} mapsubsector_t;
+} PACKEDATTR mapsubsector_t;


 // LineSeg, generated by splitting LineDefs
@@ -173,7 +173,7 @@ typedef struct
   short		linedef;
   short		side;
   short		offset;
-} mapseg_t;
+} PACKEDATTR mapseg_t;



@@ -198,7 +198,7 @@ typedef struct
   // else it's a node of another subtree.
   unsigned short	children[2];

-} mapnode_t;
+} PACKEDATTR mapnode_t;



@@ -212,7 +212,7 @@ typedef struct
     short		angle;
     short		type;
     short		options;
-} mapthing_t;
+} PACKEDATTR mapthing_t;



diff --git a/src/doomdef.h b/src/doomdef.h
index 37c6810c..bcd27e27 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -31,6 +31,21 @@
 #include <stdio.h>
 #include <string.h>

+//
+// The packed attribute forces structures to be packed into the minimum
+// space necessary.  If this is not done, the compiler may align structure
+// fields differently to optimise memory access, inflating the overall
+// structure size.  It is important to use the packed attribute on certain
+// structures where alignment is important, particularly data read/written
+// to disk.
+//
+
+#ifdef __GNUC__
+#define PACKEDATTR __attribute__((packed))
+#else
+#define PACKEDATTR
+#endif
+
 //
 // Global parameters/defines.
 //
diff --git a/src/m_misc.c b/src/m_misc.c
index 191a45c0..edf76a5f 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -815,7 +815,7 @@ typedef struct

     char		filler[58];
     unsigned char	data;		// unbounded
-} pcx_t;
+} PACKEDATTR pcx_t;


 //
diff --git a/src/mus2mid.c b/src/mus2mid.c
index 6844bfd9..45468f73 100644
--- a/src/mus2mid.c
+++ b/src/mus2mid.c
@@ -25,6 +25,7 @@

 #include <stdio.h>

+#include "doomdef.h"
 #include "doomtype.h"
 #include "i_swap.h"

@@ -64,7 +65,7 @@ typedef struct
 	unsigned short primarychannels;
 	unsigned short secondarychannels;
 	unsigned short instrumentcount;
-} musheader;
+} PACKEDATTR musheader;

 // Standard MIDI type 0 header + track header
 static byte midiheader[] =
diff --git a/src/r_data.c b/src/r_data.c
index 1fdc0a85..37827d14 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -70,7 +70,7 @@ typedef struct
     short	patch;
     short	stepdir;
     short	colormap;
-} mappatch_t;
+} PACKEDATTR mappatch_t;


 //
@@ -81,13 +81,13 @@ typedef struct
 typedef struct
 {
     char		name[8];
-    boolean		masked;
+    int			masked;
     short		width;
     short		height;
     int                 obsolete;
     short		patchcount;
     mappatch_t	patches[1];
-} maptexture_t;
+} PACKEDATTR maptexture_t;


 // A single patch from a texture definition,
diff --git a/src/r_defs.h b/src/r_defs.h
index e5bbb2df..4e0d85b7 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -288,7 +288,7 @@ typedef struct
 {
     byte		topdelta;	// -1 is the last post in a column
     byte		length; 	// length data bytes follows
-} post_t;
+} PACKEDATTR post_t;

 // column_t is a list of 0 or more post_t, (byte)-1 terminated
 typedef post_t	column_t;
@@ -363,7 +363,7 @@ typedef struct
     short		topoffset;	// pixels below the origin
     int			columnofs[8];	// only [width] used
     // the [0] is &columnofs[width]
-} patch_t;
+} PACKEDATTR patch_t;



diff --git a/src/w_wad.c b/src/w_wad.c
index 598794c4..2d58b574 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -32,7 +32,9 @@
 #include <stdlib.h>
 #include <string.h>

+#include "doomdef.h"
 #include "doomtype.h"
+
 #include "i_swap.h"
 #include "i_system.h"
 #include "i_video.h"
@@ -40,6 +42,22 @@

 #include "w_wad.h"

+typedef struct
+{
+    // Should be "IWAD" or "PWAD".
+    char		identification[4];
+    int			numlumps;
+    int			infotableofs;
+} PACKEDATTR wadinfo_t;
+
+
+typedef struct
+{
+    int			filepos;
+    int			size;
+    char		name[8];
+} PACKEDATTR filelump_t;
+
 //
 // GLOBALS
 //
diff --git a/src/w_wad.h b/src/w_wad.h
index bf010d5b..cb267dd3 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -36,21 +36,6 @@
 //
 // TYPES
 //
-typedef struct
-{
-    // Should be "IWAD" or "PWAD".
-    char		identification[4];
-    int			numlumps;
-    int			infotableofs;
-} wadinfo_t;
-
-
-typedef struct
-{
-    int			filepos;
-    int			size;
-    char		name[8];
-} filelump_t;

 //
 // WADFILE I/O related stuff.