shithub: choc

Download patch

ref: eb1e33f9dbbce358b5de557e6d8c366a60de9866
parent: edf7efbea35087a6f56ed71ed6f5db613386d39d
author: James Haley <[email protected]>
date: Wed Sep 29 14:16:24 EDT 2010

Significant work on savegames.

Subversion-branch: /branches/strife-branch
Subversion-revision: 2150

--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -771,7 +771,7 @@
             // We also need to cut off spaces to get the basic name
 
             gamename = Z_Malloc(strlen(deh_sub) + 10, PU_STATIC, 0);
-            sprintf(gamename, deh_sub, DOOM_VERSION / 100, DOOM_VERSION % 100);
+            sprintf(gamename, deh_sub, STRIFE_VERSION / 100, STRIFE_VERSION % 100);
 
             while (gamename[0] != '\0' && isspace(gamename[0]))
                 strcpy(gamename, gamename+1);
--- a/src/strife/d_player.h
+++ b/src/strife/d_player.h
@@ -94,6 +94,8 @@
     int amount; // amount being carried
 } inventory_t;
 
+#define NUMINVENTORY 32
+
 //
 // Extended player object info: player_t
 //
@@ -128,17 +130,17 @@
     int			powers[NUMPOWERS];
 
     // [STRIFE] Additions:
-    int			sigiltype;       // Type of Sigil carried
-    int			nukagecount;     // Nukage exposure counter
-    int			questflags;      // Quest bit flags
-    int			pitch;           // Up/down look angle
-    boolean		centerview;      // True if view should be centered
-    inventory_t		inventory[32];   // Player inventory items
-    boolean		st_update;       // If true, update status bar
-    short		numinventory;    // Num. active inventory items
-    short		inventorycursor; // Selected inventory item
-    short		accuracy;        // Accuracy stat
-    short		stamina;         // Stamina stat
+    int			sigiltype;               // Type of Sigil carried
+    int			nukagecount;             // Nukage exposure counter
+    int			questflags;              // Quest bit flags
+    int			pitch;                   // Up/down look angle
+    boolean		centerview;              // True if view should be centered
+    inventory_t		inventory[NUMINVENTORY]; // Player inventory items
+    boolean		st_update;               // If true, update status bar
+    short		numinventory;            // Num. active inventory items
+    short		inventorycursor;         // Selected inventory item
+    short		accuracy;                // Accuracy stat
+    short		stamina;                 // Stamina stat
     
     boolean		cards[NUMCARDS];
     boolean		backpack;
@@ -190,7 +192,7 @@
 
     // Player skin colorshift,
     //  0-3 for which color to draw player.
-    int			colormap;	
+    //int			colormap; [STRIFE] no such? or did it become the below?
 
     // [STRIFE] For use of teleport beacons
     short		allegiance;  
--- a/src/strife/doomdef.h
+++ b/src/strife/doomdef.h
@@ -39,7 +39,9 @@
 // Global parameters/defines.
 //
 // DOOM version
-#define DOOM_VERSION 109
+//
+// haleyjd 09/28/10: Replaced with Strife version
+#define STRIFE_VERSION 101
 
 // Version code for cph's longtics hack ("v1.91")
 #define DOOM_191_VERSION 111
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -1621,7 +1621,8 @@
     gameaction = ga_loadgame; 
 } 
  
-#define VERSIONSIZE		16 
+// haleyjd 09/28/10: [STRIFE] VERSIONSIZE == 8
+#define VERSIONSIZE		8 
 
 
 void G_DoLoadGame (void) 
@@ -2108,7 +2109,7 @@
     }
     else
     {
-        *demo_p++ = DOOM_VERSION;
+        *demo_p++ = STRIFE_VERSION;
     }
 
     *demo_p++ = gameskill; 
@@ -2186,7 +2187,7 @@
 
     demoversion = *demo_p++;
 
-    if (demoversion == DOOM_VERSION)
+    if (demoversion == STRIFE_VERSION)
     {
         longtics = false;
     }
@@ -2205,7 +2206,7 @@
                         "    See: http://doomworld.com/files/patches.shtml\n"
                         "    This appears to be %s.";
 
-        I_Error(message, demoversion, DOOM_VERSION,
+        I_Error(message, demoversion, STRIFE_VERSION,
                          DemoVersionDescription(demoversion));
     }
     
--- a/src/strife/p_saveg.c
+++ b/src/strife/p_saveg.c
@@ -40,8 +40,10 @@
 #include "r_state.h"
 
 #define SAVEGAME_EOF 0x1d
-#define VERSIONSIZE 16 
 
+// haleyjd 09/28/10: [STRIFE] VERSIONSIZE == 8
+#define VERSIONSIZE 8 
+
 FILE *save_stream;
 int savegamelength;
 boolean savegame_error;
@@ -304,6 +306,8 @@
 //
 // mobj_t
 //
+// haleyjd 09/28/10: [STRIFE] Changed to match Strife binary mobj_t structure.
+// 
 
 static void saveg_read_mobj_t(mobj_t *str)
 {
@@ -423,6 +427,9 @@
 
     // struct mobj_s* tracer;
     str->tracer = saveg_readp();
+
+    // byte miscdata;
+    str->miscdata = saveg_read8(); // [STRIFE] Only change to mobj_t.
 }
 
 static void saveg_write_mobj_t(mobj_t *str)
@@ -538,6 +545,9 @@
 
     // struct mobj_s* tracer;
     saveg_writep(str->tracer);
+
+    // byte miscdata;
+    saveg_write8(str->miscdata); // [STRIFE] Only change to mobj_t.
 }
 
 
@@ -544,10 +554,11 @@
 //
 // ticcmd_t
 //
+// haleyjd 09/28/10: [STRIFE] Modified for Strife binary ticcmd_t structure.
+//
 
 static void saveg_read_ticcmd_t(ticcmd_t *str)
 {
-
     // signed char forwardmove;
     str->forwardmove = saveg_read8();
 
@@ -558,7 +569,9 @@
     str->angleturn = saveg_read16();
 
     // short consistancy;
-    str->consistancy = saveg_read16();
+    // STRIFE-FIXME: throwing away top byte of consistancy until
+    // the true Strife ticcmd_t structure is available.
+    str->consistancy = (byte)saveg_read16();
 
     // byte chatchar;
     str->chatchar = saveg_read8();
@@ -565,11 +578,16 @@
 
     // byte buttons;
     str->buttons = saveg_read8();
+
+    // byte buttons2;
+    str->buttons2 = saveg_read8(); // [STRIFE]
+
+    // int inventory;
+    str->inventory = saveg_read32(); // [STRIFE]
 }
 
 static void saveg_write_ticcmd_t(ticcmd_t *str)
 {
-
     // signed char forwardmove;
     saveg_write8(str->forwardmove);
 
@@ -587,6 +605,12 @@
 
     // byte buttons;
     saveg_write8(str->buttons);
+
+    // byte buttons2;
+    saveg_write8(str->buttons2); // [STRIFE]
+
+    // int inventory;
+    saveg_write32(str->inventory); // [STRIFE]
 }
 
 //
@@ -642,8 +666,35 @@
 }
 
 //
+// inventory_t 
+//
+// haleyjd 09/28/10: [STRIFE] handle inventory input/output
+//
+
+static void saveg_read_inventory_t(inventory_t *str)
+{
+    //int sprite;
+    str->sprite = saveg_read32();
+
+    //int type;
+    str->type = saveg_read32();
+
+    //int amount;
+    str->amount = saveg_read32();
+}
+
+static void saveg_write_inventory_t(inventory_t *str)
+{
+    saveg_write32(str->sprite);
+    saveg_write32(str->type);
+    saveg_write32(str->amount);
+}
+
+//
 // player_t
 //
+// haleyjd 09/28/10: [STRIFE] Modified for Strife binary player_t structure.
+//
 
 static void saveg_read_player_t(player_t *str)
 {
@@ -674,10 +725,10 @@
     str->health = saveg_read32();
 
     // int armorpoints;
-    str->armorpoints = saveg_read32();
+    str->armorpoints = saveg_read16(); // [STRIFE] 32 -> 16
 
     // int armortype;
-    str->armortype = saveg_read32();
+    str->armortype = saveg_read16(); // [STRIFE] 32 -> 16
 
     // int powers[NUMPOWERS];
     for (i=0; i<NUMPOWERS; ++i)
@@ -685,6 +736,42 @@
         str->powers[i] = saveg_read32();
     }
 
+    // int sigiltype;
+    str->sigiltype = saveg_read32(); // [STRIFE]
+
+    // int nukagecount;
+    str->nukagecount = saveg_read32(); // [STRIFE]
+
+    // int questflags;
+    str->questflags = saveg_read32(); // [STRIFE]
+
+    // int pitch;
+    str->pitch = saveg_read32(); // [STRIFE]
+
+    // int centerview;
+    str->centerview = saveg_read32(); // [STRIFE]
+
+    // inventory_t inventory[NUMINVENTORY];
+    for(i = 0; i < NUMINVENTORY; i++)
+    {
+        saveg_read_inventory_t(&(str->inventory[i])); // [STRIFE]
+    }
+
+    // int st_update;
+    str->st_update = saveg_read32(); // [STRIFE]
+
+    // short numinventory;
+    str->numinventory = saveg_read16(); // [STRIFE]
+
+    // short inventorycursor;
+    str->inventorycursor = saveg_read16(); // [STRIFE]
+
+    // short accuracy;
+    str->accuracy = saveg_read16(); // [STRIFE]
+
+    // short stamina;
+    str->stamina = saveg_read16(); // [STRIFE]
+
     // boolean cards[NUMCARDS];
     for (i=0; i<NUMCARDS; ++i)
     {
@@ -694,6 +781,15 @@
     // boolean backpack;
     str->backpack = saveg_read32();
 
+    // int attackdown;
+    str->attackdown = saveg_read32();
+
+    // int usedown;
+    str->usedown = saveg_read32();
+
+    // int inventorydown;
+    str->inventorydown = saveg_read32(); // [STRIFE]
+
     // int frags[MAXPLAYERS];
     for (i=0; i<MAXPLAYERS; ++i)
     {
@@ -724,12 +820,6 @@
         str->maxammo[i] = saveg_read32();
     }
 
-    // int attackdown;
-    str->attackdown = saveg_read32();
-
-    // int usedown;
-    str->usedown = saveg_read32();
-
     // int cheats;
     str->cheats = saveg_read32();
 
@@ -736,8 +826,8 @@
     // int refire;
     str->refire = saveg_read32();
 
-    // int killcount;
-    str->killcount = saveg_read32();
+    // short killcount;
+    str->killcount = saveg_read16(); // [STRIFE] 32 -> 16
 
     // haleyjd 08/30/10 [STRIFE] No itemcount.
     // int itemcount;
@@ -765,9 +855,12 @@
     // int fixedcolormap;
     str->fixedcolormap = saveg_read32();
 
-    // int colormap;
-    str->colormap = saveg_read32();
+    // int colormap; - [STRIFE] no such field
+    //str->colormap = saveg_read32();
 
+    // short allegiance;
+    str->allegiance = saveg_read16(); // [STRIFE]
+
     // pspdef_t psprites[NUMPSPRITES];
     for (i=0; i<NUMPSPRITES; ++i)
     {
@@ -774,6 +867,12 @@
         saveg_read_pspdef_t(&str->psprites[i]);
     }
 
+    // int mapstate[40];
+    for(i = 0; i < 40; ++i) // [STRIFE]
+    {
+        str->mapstate[i] = saveg_read32();
+    }
+
     // haleyjd 08/30/10: [STRIFE] No intermission, no didsecret.
     // boolean didsecret;
     //str->didsecret = saveg_read32();
@@ -808,10 +907,10 @@
     saveg_write32(str->health);
 
     // int armorpoints;
-    saveg_write32(str->armorpoints);
+    saveg_write16(str->armorpoints); // [STRIFE] 32 -> 16
 
     // int armortype;
-    saveg_write32(str->armortype);
+    saveg_write16(str->armortype); // [STRIFE] 32 -> 16
 
     // int powers[NUMPOWERS];
     for (i=0; i<NUMPOWERS; ++i)
@@ -819,6 +918,42 @@
         saveg_write32(str->powers[i]);
     }
 
+    // int sigiltype;
+    saveg_write32(str->sigiltype); // [STRIFE]
+
+    // int nukagecount;
+    saveg_write32(str->nukagecount); // [STRIFE]
+
+    // int questflags;
+    saveg_write32(str->questflags); // [STRIFE]
+
+    // int pitch;
+    saveg_write32(str->pitch); // [STRIFE]
+
+    // int centerview;
+    saveg_write32(str->centerview); // [STRIFE]
+
+    // inventory_t inventory[NUMINVENTORY];
+    for(i = 0; i < NUMINVENTORY; ++i) // [STRIFE]
+    {
+        saveg_write_inventory_t(&str->inventory[i]);
+    }
+
+    // int st_update;
+    saveg_write32(str->st_update); // [STRIFE]
+
+    // short numinventory;
+    saveg_write16(str->numinventory); // [STRIFE]
+
+    // short inventorycursor;
+    saveg_write16(str->inventorycursor); // [STRIFE]
+
+    // short accuracy;
+    saveg_write16(str->accuracy); // [STRIFE]
+
+    // short stamina;
+    saveg_write16(str->stamina); // [STRIFE]
+
     // boolean cards[NUMCARDS];
     for (i=0; i<NUMCARDS; ++i)
     {
@@ -828,6 +963,15 @@
     // boolean backpack;
     saveg_write32(str->backpack);
 
+    // int attackdown;
+    saveg_write32(str->attackdown);
+
+    // int usedown;
+    saveg_write32(str->usedown);
+
+    // int inventorydown;
+    saveg_write32(str->inventorydown); // [STRIFE]
+
     // int frags[MAXPLAYERS];
     for (i=0; i<MAXPLAYERS; ++i)
     {
@@ -858,12 +1002,7 @@
         saveg_write32(str->maxammo[i]);
     }
 
-    // int attackdown;
-    saveg_write32(str->attackdown);
 
-    // int usedown;
-    saveg_write32(str->usedown);
-
     // int cheats;
     saveg_write32(str->cheats);
 
@@ -870,8 +1009,8 @@
     // int refire;
     saveg_write32(str->refire);
 
-    // int killcount;
-    saveg_write32(str->killcount);
+    // short killcount;
+    saveg_write16(str->killcount); // [STRIFE] 32 -> 16
 
     // haleyjd 08/30/10 [STRIFE] No itemcount
     // int itemcount;
@@ -899,9 +1038,12 @@
     // int fixedcolormap;
     saveg_write32(str->fixedcolormap);
 
-    // int colormap;
-    saveg_write32(str->colormap);
+    // int colormap; [STRIFE] no such field
+    //saveg_write32(str->colormap);
 
+    // short allegiance;
+    saveg_write16(str->allegiance); // [STRIFE]
+
     // pspdef_t psprites[NUMPSPRITES];
     for (i=0; i<NUMPSPRITES; ++i)
     {
@@ -908,6 +1050,12 @@
         saveg_write_pspdef_t(&str->psprites[i]);
     }
 
+    // int mapstate[40];
+    for(i = 0; i < 40; ++i) // [STRIFE]
+    {
+        saveg_write32(str->mapstate[i]);
+    }
+
     // haleyjd 08/30/10: [STRIFE] No intermission, no secret.
     // boolean didsecret;
     //saveg_write32(str->didsecret);
@@ -990,6 +1138,8 @@
 //
 // vldoor_t
 //
+// haleyjd 09/28/10: [STRIFE] Modified for Strife binary vldoor_t structure.
+//
 
 static void saveg_read_vldoor_t(vldoor_t *str)
 {
@@ -1019,6 +1169,14 @@
 
     // int topcountdown;
     str->topcountdown = saveg_read32();
+
+    // villsa [STRIFE] new field - sound to play when opening
+    //int         opensound;
+    str->opensound = saveg_read32();
+
+    // villsa [STRIFE] new field - sound to play when closing
+    //int         closesound;
+    str->closesound = saveg_read32();
 }
 
 static void saveg_write_vldoor_t(vldoor_t *str)
@@ -1046,9 +1204,87 @@
 
     // int topcountdown;
     saveg_write32(str->topcountdown);
+
+    // villsa [STRIFE] new field - sound to play when opening
+    //int         opensound;
+    saveg_write32(str->opensound);
+
+    // villsa [STRIFE] new field - sound to play when closing
+    //int         closesound;
+    saveg_write32(str->closesound);
 }
 
 //
+// slidedoor_t [STRIFE]: new thinker type
+//
+
+static void saveg_read_slidedoor_t(slidedoor_t *str)
+{
+    int sector;
+    int line;
+
+    // thinker_t thinker;
+    saveg_read_thinker_t(&str->thinker);
+
+    // sdt_e type;
+    str->type = saveg_read_enum();
+
+    // line_t *line1;
+    line = saveg_read32();
+    str->line1 = &lines[line];
+
+    // line_t *line2;
+    line = saveg_read32();
+    str->line2 = &lines[line];
+
+    // int frame;
+    str->frame = saveg_read32();
+
+    // int whichDoorIndex;
+    str->whichDoorIndex = saveg_read32();
+
+    // int timer;
+    str->timer = saveg_read32();
+
+    // sector_t *frontsector;
+    sector = saveg_read32();
+    str->frontsector = &sectors[sector];
+
+    // sd_e status;
+    str->status = saveg_read_enum();
+}
+
+static void saveg_write_slidedoor_t(slidedoor_t *str)
+{
+    // thinker_t thinker;
+    saveg_write_thinker_t(&str->thinker);
+
+    // sdt_e type;
+    saveg_write_enum(str->type);
+
+    // line_t *line1;
+    saveg_write32(str->line1 - lines);
+
+    // line_t *line2;
+    saveg_write32(str->line2 - lines);
+
+    // int frame;
+    saveg_write32(str->frame);
+
+    // int whichDoorIndex;
+    saveg_write32(str->whichDoorIndex);
+
+    // int timer;
+    saveg_write32(str->timer);
+
+    // sector_t *frontsector;
+    saveg_write32(str->frontsector - sectors);
+
+    // sd_e status;
+    saveg_write_enum(str->status);
+}
+
+//
 // floormove_t
 //
 
@@ -1356,26 +1592,33 @@
 //
 // Write the header for a savegame
 //
+// haleyjd 09/28/10: [STRIFE] numerous modifications.
+//
 
 void P_WriteSaveGameHeader(char *description)
 {
     char name[VERSIONSIZE]; 
     int i; 
-	
+
+    /*
+    [STRIFE] This is in the "NAME" file in a Strife save directory.
     for (i=0; description[i] != '\0'; ++i)
         saveg_write8(description[i]);
     for (; i<SAVESTRINGSIZE; ++i)
         saveg_write8(0);
+    */
 
     memset (name,0,sizeof(name)); 
-    sprintf (name,"version %i",DOOM_VERSION); 
+    sprintf (name,"ver %i",STRIFE_VERSION); 
 
     for (i=0; i<VERSIONSIZE; ++i)
         saveg_write8(name[i]);
-	 
+
     saveg_write8(gameskill);
-    saveg_write8(gameepisode);
-    saveg_write8(gamemap);
+    
+    // [STRIFE] This information is implicit in the file being loaded.
+    //saveg_write8(gameepisode);
+    //saveg_write8(gamemap);
 
     for (i=0 ; i<MAXPLAYERS ; i++) 
         saveg_write8(playeringame[i]);
@@ -1395,26 +1638,29 @@
     byte a, b, c; 
     char vcheck[VERSIONSIZE]; 
     char read_vcheck[VERSIONSIZE];
-	 
-    // skip the description field 
 
+    // skip the description field 
+    /*
     for (i=0; i<SAVESTRINGSIZE; ++i)
         saveg_read8();
+    */
     
     for (i=0; i<VERSIONSIZE; ++i)
         read_vcheck[i] = saveg_read8();
 
     memset (vcheck,0,sizeof(vcheck)); 
-    sprintf (vcheck,"version %i",DOOM_VERSION); 
+    sprintf (vcheck,"ver %i",STRIFE_VERSION); 
     if (strcmp(read_vcheck, vcheck) != 0)
-	return false;				// bad version 
-			 
+        return false;                       // bad version 
+
     gameskill = saveg_read8();
-    gameepisode = saveg_read8();
-    gamemap = saveg_read8();
 
+    // [STRIFE] This info is implicit in the file being read.
+    //gameepisode = saveg_read8();
+    //gamemap = saveg_read8();
+
     for (i=0 ; i<MAXPLAYERS ; i++) 
-	playeringame[i] = saveg_read8();
+        playeringame[i] = saveg_read8();
 
     // get the times 
     a = saveg_read8();
@@ -1450,17 +1696,19 @@
 //
 // P_ArchivePlayers
 //
+// [STRIFE] Verified unmodified.
+//
 void P_ArchivePlayers (void)
 {
-    int		i;
-		
+    int         i;
+
     for (i=0 ; i<MAXPLAYERS ; i++)
     {
-	if (!playeringame[i])
-	    continue;
-	
-	saveg_write_pad();
+        if (!playeringame[i])
+            continue;
 
+        saveg_write_pad();
+
         saveg_write_player_t(&players[i]);
     }
 }
@@ -1470,23 +1718,25 @@
 //
 // P_UnArchivePlayers
 //
+// [STRIFE] Verified unmodified.
+//
 void P_UnArchivePlayers (void)
 {
-    int		i;
-	
+    int         i;
+
     for (i=0 ; i<MAXPLAYERS ; i++)
     {
-	if (!playeringame[i])
-	    continue;
-	
-	saveg_read_pad();
+        if (!playeringame[i])
+            continue;
 
+        saveg_read_pad();
+
         saveg_read_player_t(&players[i]);
-	
-	// will be set when unarc thinker
-	players[i].mo = NULL;	
-	players[i].message = NULL;
-	players[i].attacker = NULL;
+
+        // will be set when unarc thinker
+        players[i].mo = NULL;	
+        players[i].message = NULL;
+        players[i].attacker = NULL;
     }
 }
 
@@ -1494,24 +1744,26 @@
 //
 // P_ArchiveWorld
 //
+// haleyjd 09/28/10: [STRIFE] Minor modifications.
+//
 void P_ArchiveWorld (void)
 {
-    int			i;
-    int			j;
-    sector_t*		sec;
-    line_t*		li;
-    side_t*		si;
+    int                 i;
+    int                 j;
+    sector_t*           sec;
+    line_t*             li;
+    side_t*             si;
     
     // do sectors
     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
     {
-	saveg_write16(sec->floorheight >> FRACBITS);
-	saveg_write16(sec->ceilingheight >> FRACBITS);
-	saveg_write16(sec->floorpic);
-	saveg_write16(sec->ceilingpic);
-	saveg_write16(sec->lightlevel);
-	saveg_write16(sec->special);		// needed?
-	saveg_write16(sec->tag);		// needed?
+        saveg_write16(sec->floorheight >> FRACBITS);
+        saveg_write16(sec->ceilingheight >> FRACBITS);
+        saveg_write16(sec->floorpic);
+        //saveg_write16(sec->ceilingpic); [STRIFE] not saved.
+        saveg_write16(sec->lightlevel);
+        saveg_write16(sec->special);            // needed?
+        //saveg_write16(sec->tag);                // needed? [STRIFE] not saved.
     }
 
     
@@ -1518,22 +1770,23 @@
     // do lines
     for (i=0, li = lines ; i<numlines ; i++,li++)
     {
-	saveg_write16(li->flags);
-	saveg_write16(li->special);
-	saveg_write16(li->tag);
-	for (j=0 ; j<2 ; j++)
-	{
-	    if (li->sidenum[j] == -1)
-		continue;
-	    
-	    si = &sides[li->sidenum[j]];
+        saveg_write16(li->flags);
+        saveg_write16(li->special);
+        //saveg_write16(li->tag); [STRIFE] not saved.
+        for (j=0 ; j<2 ; j++)
+        {
+            if (li->sidenum[j] == -1)
+                continue;
 
-	    saveg_write16(si->textureoffset >> FRACBITS);
-	    saveg_write16(si->rowoffset >> FRACBITS);
-	    saveg_write16(si->toptexture);
-	    saveg_write16(si->bottomtexture);
-	    saveg_write16(si->midtexture);	
-	}
+            si = &sides[li->sidenum[j]];
+
+            // [STRIFE] offsets not saved.
+            //saveg_write16(si->textureoffset >> FRACBITS);
+            //saveg_write16(si->rowoffset >> FRACBITS);
+            saveg_write16(si->toptexture);
+            saveg_write16(si->bottomtexture);
+            saveg_write16(si->midtexture);
+        }
     }
 }
 
@@ -1553,34 +1806,35 @@
     // do sectors
     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
     {
-	sec->floorheight = saveg_read16() << FRACBITS;
-	sec->ceilingheight = saveg_read16() << FRACBITS;
-	sec->floorpic = saveg_read16();
-	sec->ceilingpic = saveg_read16();
-	sec->lightlevel = saveg_read16();
-	sec->special = saveg_read16();		// needed?
-	sec->tag = saveg_read16();		// needed?
-	sec->specialdata = 0;
-	sec->soundtarget = 0;
+        sec->floorheight = saveg_read16() << FRACBITS;
+        sec->ceilingheight = saveg_read16() << FRACBITS;
+        sec->floorpic = saveg_read16();
+        //sec->ceilingpic = saveg_read16(); [STRIFE] not saved
+        sec->lightlevel = saveg_read16();
+        sec->special = saveg_read16();          // needed?
+        //sec->tag = saveg_read16();              // needed? [STRIFE] not saved
+        sec->specialdata = 0;
+        sec->soundtarget = 0;
     }
     
     // do lines
     for (i=0, li = lines ; i<numlines ; i++,li++)
     {
-	li->flags = saveg_read16();
-	li->special = saveg_read16();
-	li->tag = saveg_read16();
-	for (j=0 ; j<2 ; j++)
-	{
-	    if (li->sidenum[j] == -1)
-		continue;
-	    si = &sides[li->sidenum[j]];
-	    si->textureoffset = saveg_read16() << FRACBITS;
-	    si->rowoffset = saveg_read16() << FRACBITS;
-	    si->toptexture = saveg_read16();
-	    si->bottomtexture = saveg_read16();
-	    si->midtexture = saveg_read16();
-	}
+        li->flags = saveg_read16();
+        li->special = saveg_read16();
+        //li->tag = saveg_read16(); [STRIFE] not saved
+        for (j=0 ; j<2 ; j++)
+        {
+            if (li->sidenum[j] == -1)
+                continue;
+            si = &sides[li->sidenum[j]];
+            // [STRIFE] offsets not saved.
+            //si->textureoffset = saveg_read16() << FRACBITS;
+            //si->rowoffset = saveg_read16() << FRACBITS;
+            si->toptexture = saveg_read16();
+            si->bottomtexture = saveg_read16();
+            si->midtexture = saveg_read16();
+        }
     }
 }
 
@@ -1602,23 +1856,32 @@
 //
 // P_ArchiveThinkers
 //
+// [STRIFE] Verified unmodified.
+//
 void P_ArchiveThinkers (void)
 {
-    thinker_t*		th;
+    thinker_t*          th;
 
     // save off the current thinkers
     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
     {
-	if (th->function.acp1 == (actionf_p1)P_MobjThinker)
-	{
+        if (th->function.acp1 == (actionf_p1)P_MobjThinker)
+        {
             saveg_write8(tc_mobj);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_mobj_t((mobj_t *) th);
 
-	    continue;
-	}
-		
-	// I_Error ("P_ArchiveThinkers: Unknown thinker function");
+            continue;
+        }
+
+        // haleyjd: This may seem mysterious but in the DOOM prebeta, 
+        // different types of things used different thinker functions. 
+        // Those would have all been handled here and this message is 
+        // probably a relic of that old system, not to mention the odd
+        // name of this function, and use of an enumeration with only
+        // two values in it.
+
+        // I_Error ("P_ArchiveThinkers: Unknown thinker function");
     }
 
     // add a terminating marker
@@ -1632,23 +1895,23 @@
 //
 void P_UnArchiveThinkers (void)
 {
-    byte		tclass;
-    thinker_t*		currentthinker;
-    thinker_t*		next;
-    mobj_t*		mobj;
+    byte                tclass;
+    thinker_t*          currentthinker;
+    thinker_t*          next;
+    mobj_t*             mobj;
     
     // remove all the current thinkers
     currentthinker = thinkercap.next;
     while (currentthinker != &thinkercap)
     {
-	next = currentthinker->next;
-	
-	if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
-	    P_RemoveMobj ((mobj_t *)currentthinker);
-	else
-	    Z_Free (currentthinker);
+        next = currentthinker->next;
 
-	currentthinker = next;
+        if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
+            P_RemoveMobj ((mobj_t *)currentthinker);
+        else
+            Z_Free (currentthinker);
+
+        currentthinker = next;
     }
     P_InitThinkers ();
     
@@ -1655,33 +1918,52 @@
     // read in saved thinkers
     while (1)
     {
-	tclass = saveg_read8();
-	switch (tclass)
-	{
-	  case tc_end:
-	    return; 	// end of list
-			
-	  case tc_mobj:
-	    saveg_read_pad();
-	    mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
+        tclass = saveg_read8();
+        switch (tclass)
+        {
+        case tc_end:
+            return; 	// end of list
+
+        case tc_mobj:
+            saveg_read_pad();
+            mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
             saveg_read_mobj_t(mobj);
 
-	    mobj->target = NULL;
+            // haleyjd 09/29/10: Strife sets the targets of non-allied creatures
+            // who had a non-NULL target at save time to players[0].mo so that
+            // they won't fall back asleep.
+            //
+            // BUG: As the player may not have been spawned yet, we could be
+            // setting monsters' targets to the mobj which was spawned by 
+            // P_SetupLevel and then removed just above. Due to a subtle glitch
+            // in the DOOM engine whereby all things removed in this function
+            // are leaked until the next time P_SetupLevel is called, this is a
+            // safe operation - the call to P_InitThinkers above stops any of
+            // the objects removed, including the player's previous body, from
+            // being passed to Z_Free. One glitch relying on another!
+
+            if(mobj->target != NULL && (mobj->flags & MF_ALLY) != MF_ALLY)
+                mobj->target = players[0].mo;
+            else
+                mobj->target = NULL;
+
+            // WARNING! Strife does not seem to set tracer! I am leaving it be
+            // for now because so far no crashes have been observed, and failing
+            // to set this here will almost certainly crash Choco.
             mobj->tracer = NULL;
-	    P_SetThingPosition (mobj);
-	    mobj->info = &mobjinfo[mobj->type];
-	    mobj->floorz = mobj->subsector->sector->floorheight;
-	    mobj->ceilingz = mobj->subsector->sector->ceilingheight;
-	    mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
-	    P_AddThinker (&mobj->thinker);
-	    break;
+            P_SetThingPosition (mobj);
+            mobj->info = &mobjinfo[mobj->type];
+            // [STRIFE]: doesn't set these
+            //mobj->floorz = mobj->subsector->sector->floorheight;
+            //mobj->ceilingz = mobj->subsector->sector->ceilingheight;
+            mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
+            P_AddThinker (&mobj->thinker);
+            break;
 
-	  default:
-	    I_Error ("Unknown tclass %i in savegame",tclass);
-	}
-	
+        default:
+            I_Error ("Unknown tclass %i in savegame",tclass);
+        }
     }
-
 }
 
 
@@ -1697,9 +1979,10 @@
     tc_flash,
     tc_strobe,
     tc_glow,
+    tc_slidingdoor, // [STRIFE]
     tc_endspecials
 
-} specials_e;	
+} specials_e;
 
 
 
@@ -1708,6 +1991,7 @@
 //
 // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
 // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
+// T_SlidingDoor, (slidedoor_t: sector_t *, line_t * x 2 swizzle)
 // T_MoveFloor, (floormove_t: sector_t * swizzle),
 // T_LightFlash, (lightflash_t: sector_t * swizzle),
 // T_StrobeFlash, (strobe_t: sector_t *),
@@ -1716,87 +2000,93 @@
 //
 void P_ArchiveSpecials (void)
 {
-    thinker_t*		th;
-    int			i;
-	
+    thinker_t*          th;
+    int                 i;
+
     // save off the current thinkers
     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
     {
-	if (th->function.acv == (actionf_v)NULL)
-	{
-	    for (i = 0; i < MAXCEILINGS;i++)
-		if (activeceilings[i] == (ceiling_t *)th)
-		    break;
-	    
-	    if (i<MAXCEILINGS)
-	    {
+        if (th->function.acv == (actionf_v)NULL)
+        {
+            for (i = 0; i < MAXCEILINGS;i++)
+                if (activeceilings[i] == (ceiling_t *)th)
+                    break;
+
+            if (i<MAXCEILINGS)
+            {
                 saveg_write8(tc_ceiling);
-		saveg_write_pad();
+                saveg_write_pad();
                 saveg_write_ceiling_t((ceiling_t *) th);
-	    }
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
-	{
+            }
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
+        {
             saveg_write8(tc_ceiling);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_ceiling_t((ceiling_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
+        {
             saveg_write8(tc_door);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_vldoor_t((vldoor_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_MoveFloor)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_SlidingDoor)
+        {
+            saveg_write8(tc_slidingdoor);
+            saveg_write_pad();
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_MoveFloor)
+        {
             saveg_write8(tc_floor);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_floormove_t((floormove_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_PlatRaise)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_PlatRaise)
+        {
             saveg_write8(tc_plat);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_plat_t((plat_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_LightFlash)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_LightFlash)
+        {
             saveg_write8(tc_flash);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_lightflash_t((lightflash_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
+        {
             saveg_write8(tc_strobe);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_strobe_t((strobe_t *) th);
-	    continue;
-	}
-			
-	if (th->function.acp1 == (actionf_p1)T_Glow)
-	{
+            continue;
+        }
+
+        if (th->function.acp1 == (actionf_p1)T_Glow)
+        {
             saveg_write8(tc_glow);
-	    saveg_write_pad();
+            saveg_write_pad();
             saveg_write_glow_t((glow_t *) th);
-	    continue;
-	}
+            continue;
+        }
     }
-	
+
     // add a terminating marker
     saveg_write8(tc_endspecials);
-
 }
 
 
--- a/src/strife/p_spec.h
+++ b/src/strife/p_spec.h
@@ -480,6 +480,8 @@
 
 } slideframe_t;
 
+// haleyjd 09/29/10: [STRIFE] Externalized for savegames
+void T_SlidingDoor(slidedoor_t* door);
 
 
 // how many frames of animation