foxygit / doom Log in
commit ab0dc8fcb49a71db33e26f9c01e88d24e43c556e
Author:     James Haley <haleyjd@hotmail.com>
AuthorDate: Fri Sep 3 04:30:52 2010 +0000
Commit:     James Haley <haleyjd@hotmail.com>
CommitDate: Fri Sep 3 04:30:52 2010 +0000

    Code to read dialog lump field-by-field to avoid any possible problems
    with structure packing. Also a minor fix to Kaiser's key look code.

    Subversion-branch: /branches/strife-branch
    Subversion-revision: 2004
---
 src/strife/p_dialog.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++-----
 src/strife/p_dialog.h | 24 +++++++++-----
 src/strife/r_main.c   |  2 +-
 3 files changed, 97 insertions(+), 17 deletions(-)

diff --git a/src/strife/p_dialog.c b/src/strife/p_dialog.c
index d22e217b..2b20f55d 100644
--- a/src/strife/p_dialog.c
+++ b/src/strife/p_dialog.c
@@ -53,11 +53,13 @@ static boolean script0loaded;
 // Number of dialogs defined in the current level's script.
 static int numleveldialogs;

-// Pointer to level dialog script data
-static byte *leveldialogptr;
+// The actual level dialogs. This didn't exist in Strife, but is new to account
+// for structure alignment/packing concerns, given that Chocolate Doom is
+// multiplatform.
+static mapdialog_t *leveldialogs;

-// Pointer to SCRIPT0 data
-static byte *script0ptr;
+// The actual script00 dialogs. As above.
+static mapdialog_t *script0dialogs;

 // Number of dialogs defined in the SCRIPT00 lump.
 static int numscript0dialogs;
@@ -66,6 +68,68 @@ static int numscript0dialogs;
 // Routines
 //

+#define DIALOG_INT(field, ptr)  \
+    field = ((int)ptr[0]        | \
+            ((int)ptr[1] <<  8) | \
+            ((int)ptr[2] << 16) | \
+            ((int)ptr[3] << 24)); \
+    ptr += 4;
+
+#define DIALOG_STR(field, ptr, len) \
+    memcpy(field, ptr, len); \
+    ptr += len;
+
+//
+// P_ParseDialogLump
+//
+// haleyjd 09/02/10: This is a new function added to parse out the dialogs
+// from the dialog lump rather than reading them raw from the lump pointer.
+// This avoids problems with structure packing.
+//
+static void P_ParseDialogLump(byte *lump, mapdialog_t **dialogs,
+                              int numdialogs, int tag)
+{
+    int i;
+    byte *rover = lump;
+
+    *dialogs = Z_Malloc(numdialogs * sizeof(mapdialog_t), tag, NULL);
+
+    for(i = 0; i < numdialogs; i++)
+    {
+        int j;
+        mapdialog_t *curdialog = &((*dialogs)[i]);
+
+        DIALOG_INT(curdialog->speakerid,  rover);
+        DIALOG_INT(curdialog->dropitem,   rover);
+        DIALOG_INT(curdialog->checkitem1, rover);
+        DIALOG_INT(curdialog->checkitem2, rover);
+        DIALOG_INT(curdialog->checkitem3, rover);
+        DIALOG_INT(curdialog->jumptoconv, rover);
+        DIALOG_STR(curdialog->name,       rover, MDLG_NAMELEN);
+        DIALOG_STR(curdialog->voice,      rover, MDLG_LUMPLEN);
+        DIALOG_STR(curdialog->backpic,    rover, MDLG_LUMPLEN);
+        DIALOG_STR(curdialog->text,       rover, MDLG_TEXTLEN);
+
+        // copy choices
+        for(j = 0; j < 5; j++)
+        {
+            mapdlgchoice_t *curchoice = &(curdialog->choices[j]);
+            DIALOG_INT(curchoice->giveitem, rover);
+            DIALOG_INT(curchoice->needitem1, rover);
+            DIALOG_INT(curchoice->needitem2, rover);
+            DIALOG_INT(curchoice->needitem3, rover);
+            DIALOG_INT(curchoice->needamount1, rover);
+            DIALOG_INT(curchoice->needamount2, rover);
+            DIALOG_INT(curchoice->needamount3, rover);
+            DIALOG_STR(curchoice->text,        rover, MDLG_CHOICELEN);
+            DIALOG_STR(curchoice->textok,      rover, MDLG_MSGLEN);
+            DIALOG_INT(curchoice->next,        rover);
+            DIALOG_INT(curchoice->objective,   rover);
+            DIALOG_STR(curchoice->textno,      rover, MDLG_MSGLEN);
+        }
+    }
+}
+
 //
 // P_DialogLoad
 //
@@ -84,18 +148,26 @@ void P_DialogLoad(int eax0, int a2, int a3, int a4)
         numleveldialogs = 0;
     else
     {
-        leveldialogptr = W_CacheLumpNum(lumpnum, PU_LEVEL);
+        byte *leveldialogptr = W_CacheLumpNum(lumpnum, PU_STATIC);
         numleveldialogs = W_LumpLength(lumpnum) / ORIG_MAPDIALOG_SIZE;
+        P_ParseDialogLump(leveldialogptr, &leveldialogs, numleveldialogs,
+                          PU_LEVEL);
+        Z_Free(leveldialogptr); // haleyjd: free the original lump
     }

     // also load SCRIPT00 if it has not been loaded yet
     if(!script0loaded)
     {
+        byte *script0ptr;
+
         script0loaded = true;
         // BUG: Rogue should have used W_GetNumForName here...
         lumpnum = W_CheckNumForName(DEH_String("script00"));
         script0ptr = W_CacheLumpNum(lumpnum, PU_STATIC);
         numscript0dialogs = W_LumpLength(lumpnum) / ORIG_MAPDIALOG_SIZE;
+        P_ParseDialogLump(script0ptr, &script0dialogs, numscript0dialogs,
+                          PU_STATIC);
+        Z_Free(script0ptr); // haleyjd: free the original lump
     }
 }

@@ -114,15 +186,15 @@ int P_PlayerHasItem(player_t *player, mobjtype_t type)
     {
         // check keys
         if(type >= MT_KEY_BASE && type < MT_INV_SHADOWARMOR)
-            return 1; // STRIFE-FIXME: wtf is it doing here??? Should be player->cards...
+            return (player->cards[type - MT_KEY_BASE]);

         // check sigil pieces
         if(type >= MT_SIGIL_A && type <= MT_SIGIL_E)
-            return type - MT_SIGIL_A <= player->sigiltype;
+            return (type - MT_SIGIL_A <= player->sigiltype);

         // check quest tokens
         if(type >= MT_TOKEN_QUEST1 && type <= MT_TOKEN_QUEST31)
-            return player->questflags & (1 << (type - MT_TOKEN_QUEST1));
+            return (player->questflags & (1 << (type - MT_TOKEN_QUEST1)));

         // check inventory
         for(i = 0; i < 32; i++)
diff --git a/src/strife/p_dialog.h b/src/strife/p_dialog.h
index e90f5df4..17ff46ca 100644
--- a/src/strife/p_dialog.h
+++ b/src/strife/p_dialog.h
@@ -31,6 +31,13 @@
 #ifndef P_DIALOG_H__
 #define P_DIALOG_H__

+#define MDLG_CHOICELEN   32
+#define MDLG_MSGLEN      80
+#define MDLG_NAMELEN     16
+#define MDLG_LUMPLEN      8
+#define MDLG_TEXTLEN    320
+#define MDLG_MAXCHOICES   5
+
 typedef struct mapdlgchoice_s
 {
     int giveitem;    // item given when successful
@@ -40,11 +47,11 @@ typedef struct mapdlgchoice_s
     int needamount1; // amount of first item needed
     int needamount2; // amount of second item needed
     int needamount3; // amount of third item needed
-    char text[32];   // normal text
-    char textok[80]; // message given on success
+    char text[MDLG_CHOICELEN]; // normal text
+    char textok[MDLG_MSGLEN];  // message given on success
     int next;        // next dialog?
     int objective;   // ???
-    char textno[80]; // message given on failure
+    char textno[MDLG_MSGLEN]; // message given on failure
 } mapdlgchoice_t;

 typedef struct mapdialog_s
@@ -55,12 +62,13 @@ typedef struct mapdialog_s
     int checkitem2;  // second item needed to see this dialog, if any
     int checkitem3;  // third item needed to see this dialog, if any
     int jumptoconv;  // conversation to jump to when... ?
-    char name[16];   // name of speaker
-    char voice[8];   // voice file to play
-    char backpic[8]; // backdrop pic for character, if any
-    char text[320];  // main message text
+    char name[MDLG_NAMELEN];    // name of speaker
+    char voice[MDLG_LUMPLEN];   // voice file to play
+    char backpic[MDLG_LUMPLEN]; // backdrop pic for character, if any
+    char text[MDLG_TEXTLEN];    // main message text

-    mapdlgchoice_t choices[5]; // options that this dialog gives the player
+    // options that this dialog gives the player
+    mapdlgchoice_t choices[MDLG_MAXCHOICES];
 } mapdialog_t;


diff --git a/src/strife/r_main.c b/src/strife/r_main.c
index dea4603b..ddb583d3 100644
--- a/src/strife/r_main.c
+++ b/src/strife/r_main.c
@@ -844,7 +844,7 @@ void R_SetupPitch(player_t* player)
     {
         viewpitch   = player->pitch;
         pitchfrac   = ((setblocks*player->pitch)/10);
-        centery     = (pitchfrac+viewheight)/2;
+        centery     = pitchfrac+viewheight/2;
         centeryfrac = centery<<FRACBITS;

         if(viewheight > 0)