ref: 6520e0ef21504fe8ec4757b32e5e47a9a92a00df
parent: c1de8d063ea798f0d0bfbd126e7a61a3bfdb873c
author: Simon Howard <fraggle@gmail.com>
date: Sat Oct 8 20:25:49 EDT 2005
Improved sprite merging Subversion-branch: /trunk/chocolate-doom Subversion-revision: 179
--- a/src/w_merge.c
+++ b/src/w_merge.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: w_merge.c 168 2005-10-08 18:23:18Z fraggle $
+// $Id: w_merge.c 179 2005-10-09 00:25:49Z fraggle $
//
// Copyright(C) 2005 Simon Howard
//
@@ -21,6 +21,9 @@
// 02111-1307, USA.
//
// $Log$
+// Revision 1.2 2005/10/09 00:25:49 fraggle
+// Improved sprite merging
+//
// Revision 1.1 2005/10/08 18:23:18 fraggle
// WAD merging code
//
@@ -53,6 +56,13 @@
int numlumps;
} searchlist_t;
+typedef struct
+{
+ char sprname[4];
+ char frame;
+ int angles;
+} replace_frame_t;
+
static searchlist_t iwad;
static searchlist_t pwad;
@@ -60,6 +70,11 @@
static searchlist_t pwad_sprites;
static searchlist_t pwad_flats;
+// lumps with these sprites must be replaced in the IWAD
+static replace_frame_t *replace_frames;
+static int num_replace_frames;
+static int replace_frames_alloced;
+
// Search in a list to find a lump with a particular name
// Linear search (slow!)
//
@@ -152,6 +167,135 @@
}
}
+// Initialise the replace list
+
+static void InitReplaceList(void)
+{
+ if (replace_frames == NULL)
+ {
+ replace_frames_alloced = 128;
+ replace_frames = Z_Malloc(sizeof(*replace_frames) * replace_frames_alloced,
+ PU_STATIC, NULL);
+ }
+
+ num_replace_frames = 0;
+}
+
+// Add new sprite to the replace list
+
+static void AddReplaceFrame(replace_frame_t *frame)
+{
+ int i;
+
+ // Find if this is already in the list
+
+ for (i=0; i<num_replace_frames; ++i)
+ {
+ if (!strncasecmp(replace_frames[i].sprname, frame->sprname, 4)
+ && replace_frames[i].frame == frame->frame)
+ {
+ replace_frames[i].angles |= frame->angles;
+ return;
+ }
+ }
+
+ // Need to add to the list
+
+ if (num_replace_frames >= replace_frames_alloced)
+ {
+ replace_frame_t *newframes;
+
+ newframes = Z_Malloc(replace_frames_alloced * 2 * sizeof(*replace_frames),
+ PU_STATIC, NULL);
+ memcpy(newframes, replace_frames,
+ replace_frames_alloced * sizeof(*replace_frames));
+ Z_Free(replace_frames);
+ replace_frames_alloced *= 2;
+ replace_frames = newframes;
+ }
+
+ // Add to end of list
+
+ replace_frames[num_replace_frames++] = *frame;
+}
+
+// Converts a sprite name into an replace_frame_t
+
+static void ParseSpriteName(char *name, replace_frame_t *result)
+{
+ int angle_num;
+
+ strncpy(result->sprname, name, 4);
+ result->frame = name[4];
+
+ angle_num = name[5] - '0';
+
+ if (angle_num == 0)
+ {
+ // '0' sprites are used for all angles
+
+ result->angles = 0xffff;
+ }
+ else
+ {
+ result->angles = 1 << angle_num;
+ }
+
+ if (name[6] != '\0')
+ {
+ // second angle
+
+ angle_num = name[7] - '0';
+
+ if (angle_num == 0)
+ {
+ result->angles = 0xffff;
+ }
+ else
+ {
+ result->angles |= 1 << angle_num;
+ }
+ }
+}
+
+// Check if a sprite is in the replace list
+
+static boolean InReplaceList(char *name)
+{
+ replace_frame_t igsprite;
+ int i;
+
+ ParseSpriteName(name, &igsprite);
+
+ for (i=0; i<num_replace_frames; ++i)
+ {
+ if (!strncasecmp(replace_frames[i].sprname, igsprite.sprname, 4)
+ && replace_frames[i].frame == igsprite.frame
+ && (replace_frames[i].angles & igsprite.angles) != 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Generate the list. Run at the start, before merging
+
+static void GenerateReplaceList(void)
+{
+ replace_frame_t igsprite;
+ int i;
+
+ InitReplaceList();
+
+ for (i=0; i<pwad_sprites.numlumps; ++i)
+ {
+ ParseSpriteName(pwad_sprites.lumps[i].name, &igsprite);
+ AddReplaceFrame(&igsprite);
+ }
+}
+
// Perform the merge.
//
// The merge code creates a new lumpinfo list, adding entries from the
@@ -159,10 +303,13 @@
//
// For the IWAD:
// * Flats are added. If a flat with the same name is in the PWAD,
-// it is ignored. At the end of the section, all flats in the PWAD
-// are inserted. This is consistent with the behavior of deutex/deusf.
-// * Sprites are added. If a sprite with the same name exists in the PWAD,
-// it is used to replace the sprite.
+// it is ignored(deleted). At the end of the section, all flats in the
+// PWAD are inserted. This is consistent with the behavior of
+// deutex/deusf.
+// * Sprites are added. The "replace list" is generated before the merge
+// from the list of sprites in the PWAD. Any sprites in the IWAD found
+// to match the replace list are removed. At the end of the section,
+// the sprites from the PWAD are inserted.
//
// For the PWAD:
// * All Sprites and Flats are ignored, with the assumption they have
@@ -245,6 +392,14 @@
if (!strncasecmp(lump->name, "S_END", 8))
{
+ // add all the pwad sprites
+
+ for (n=0; n<pwad_sprites.numlumps; ++n)
+ {
+ newlumps[num_newlumps++] = pwad_sprites.lumps[n];
+ }
+
+ // copy the ending
newlumps[num_newlumps++] = *lump;
// back to normal reading
@@ -252,22 +407,11 @@
}
else
{
- // If there is a sprite in the PWAD with the same name,
- // replace this sprite
+ // Is this lump holding a sprite to be replaced in the
+ // PWAD? If so, wait until the end to add it.
- // Note: This is rather limited. A PWAD sprite has to
- // have EXACTLY the same name as that in the IWAD. It
- // does not allow the number of sides per frame to be
- // changed in the PWAD. FIXME?
-
- lumpindex = FindInList(&pwad_sprites, lump->name);
-
- if (lumpindex >= 0)
+ if (!InReplaceList(lump->name))
{
- newlumps[num_newlumps++] = pwad_sprites.lumps[lumpindex];
- }
- else
- {
newlumps[num_newlumps++] = *lump;
}
}
@@ -365,6 +509,10 @@
// Setup sprite/flat lists
SetupLists();
+
+ // Generate list of sprites to be replaced by the PWAD
+
+ GenerateReplaceList();
// Perform the merge