shithub: choc

Download patch

ref: ab0dc8fcb49a71db33e26f9c01e88d24e43c556e
parent: d1c8cb2cfed18f5c5c32347011f33a210c96ff38
author: James Haley <haleyjd@hotmail.com>
date: Fri Sep 3 00:30:52 EDT 2010

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

--- a/src/strife/p_dialog.c
+++ b/src/strife/p_dialog.c
@@ -53,11 +53,13 @@
 // 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,7 +68,69 @@
 // 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
 //
 // [STRIFE] New function
@@ -84,18 +148,26 @@
         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 @@
     {
         // 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++)
--- 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 @@
     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 @@
     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;
 
 
--- a/src/strife/r_main.c
+++ b/src/strife/r_main.c
@@ -844,7 +844,7 @@
     {
         viewpitch   = player->pitch;
         pitchfrac   = ((setblocks*player->pitch)/10);
-        centery     = (pitchfrac+viewheight)/2;
+        centery     = pitchfrac+viewheight/2;
         centeryfrac = centery<<FRACBITS;
 
         if(viewheight > 0)