shithub: choc

Download patch

ref: c4873e6cfc5d8af776c109a79729065400e99e3d
parent: e5f5cd88637a662e8bf6ce4b9929b9875acfb257
author: Simon Howard <[email protected]>
date: Fri Sep 27 17:50:34 EDT 2013

Map thing type and state table indexes to those used by Vanilla Heretic
v1.3, for savegame compatibility.

Subversion-branch: /branches/v2-branch
Subversion-revision: 2686

--- a/src/heretic/p_saveg.c
+++ b/src/heretic/p_saveg.c
@@ -268,24 +268,79 @@
 
 
 //
-// pspdef_t
+// state_t *
 //
 
-static void saveg_read_pspdef_t(pspdef_t *str)
+static void saveg_read_state_ptr(state_t **state)
 {
-    int i;
+    int statenum;
 
-    // state_t *state;
-    i = SV_ReadLong();
-    if (i == 0)
+    statenum = SV_ReadLong();
+
+    // We have read a state number, but it is indexed according to the state
+    // table in Vanilla Heretic v1.3. To support v1.0 Dehacked patches we
+    // have three extra states, so map the state number to our internal state
+    // number.
+
+    if (statenum >= S_PHOENIXFXIX_1)
     {
-        str->state = NULL;
+        statenum = (statenum - S_PHOENIXFXIX_1) + S_PHOENIXPUFF1;
     }
+
+    if (statenum == 0)
+    {
+        *state = NULL;
+    }
     else
     {
-        str->state = &states[i];
+        *state = &states[statenum];
     }
+}
 
+static void saveg_write_state_ptr(state_t *state)
+{
+    int statenum;
+
+    // NULL states are just written as zero.
+
+    if (state == NULL)
+    {
+        SV_WriteLong(0);
+        return;
+    }
+
+    statenum = state - states;
+
+    // Our internal state table has three extra states than Vanilla, so map
+    // to the state numbers used by Vanilla Heretic v1.3 for savegame
+    // compatibility.
+
+    if (statenum >= S_PHOENIXPUFF1)
+    {
+        statenum = (statenum - S_PHOENIXPUFF1) + S_PHOENIXFXIX_1;
+    }
+    else if (statenum >= S_PHOENIXFXIX_1)
+    {
+        // Now we're really in trouble. This state doesn't exist in Vanilla
+        // Heretic v1.3 (but does in v1.0). Map to a frame that might be
+        // vaguely sensible.
+
+        statenum = S_PHOENIXFXI1_8;
+    }
+
+    SV_WriteLong(statenum);
+}
+
+
+//
+// pspdef_t
+//
+
+static void saveg_read_pspdef_t(pspdef_t *str)
+{
+    // state_t *state;
+    saveg_read_state_ptr(&str->state);
+
     // int tics;
     str->tics = SV_ReadLong();
 
@@ -297,14 +352,7 @@
 static void saveg_write_pspdef_t(pspdef_t *str)
 {
     // state_t *state;
-    if (str->state != NULL)
-    {
-        SV_WriteLong(str->state - states);
-    }
-    else
-    {
-        SV_WriteLong(0);
-    }
+    saveg_write_state_ptr(str->state);
 
     // int tics;
     SV_WriteLong(str->tics);
@@ -799,6 +847,13 @@
     // mobjtype_t type;
     str->type = SV_ReadLong();
 
+    // An extra thing type was added for v1.0 dehacked compatibility.
+    // Map from the v1.3 thing type index to the internal one.
+    if (str->type >= MT_PHOENIXFX_REMOVED)
+    {
+        ++str->type;
+    }
+
     // mobjinfo_t *info;
     SV_ReadLong();
     str->info = NULL;
@@ -807,8 +862,7 @@
     str->tics = SV_ReadLong();
 
     // state_t *state;
-    i = SV_ReadLong();
-    str->state = &states[i];
+    saveg_read_state_ptr(&str->state);
 
     // int damage;
     str->damage = SV_ReadLong();
@@ -910,8 +964,25 @@
     SV_WriteLong(str->validcount);
 
     // mobjtype_t type;
-    SV_WriteLong(str->type);
+    // Our mobjinfo table has an extra entry, for compatibility with v1.0
+    // HHE patches. So translate the internal thing type index to the
+    // equivalent for Vanilla Heretic v1.3, for savegame compatibility.
 
+    if (str->type > MT_PHOENIXFX_REMOVED)
+    {
+        SV_WriteLong(str->type - 1);
+    }
+    else if (str->type == MT_PHOENIXFX_REMOVED)
+    {
+        // This should never happen, but just in case, do something
+        // vaguely sensible ... ?
+        SV_WriteLong(MT_PHOENIXFX1);
+    }
+    else
+    {
+        SV_WriteLong(str->type);
+    }
+
     // mobjinfo_t *info;
     SV_WritePtr(str->info);
 
@@ -919,7 +990,7 @@
     SV_WriteLong(str->tics);
 
     // state_t *state;
-    SV_WriteLong(str->state - states);
+    saveg_write_state_ptr(str->state);
 
     // int damage;
     SV_WriteLong(str->damage);