Skip to content

Commit

Permalink
Wad Map Converter|Refactor: Simplified format recognition
Browse files Browse the repository at this point in the history
The recent Doomsday API changes allow the map format recognition
logic to be simplified, removing unnecessary dynamic allocations.
  • Loading branch information
danij-deng committed Jul 23, 2012
1 parent af6a406 commit 6366ab3
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 266 deletions.
13 changes: 10 additions & 3 deletions doomsday/plugins/wadmapconverter/include/map.h
Expand Up @@ -57,6 +57,12 @@ typedef enum lumptype_e {
NUM_LUMP_TYPES
} lumptype_t;

typedef struct maplumpinfo_s {
lumpnum_t lumpNum;
lumptype_t lumpType;
size_t length;
} maplumpinfo_t;

typedef struct materialref_s {
char name[9];
materialid_t id; // Doomsday's unique identifier for this.
Expand Down Expand Up @@ -151,7 +157,8 @@ typedef struct mlight_s {
} surfacetint_t;

typedef enum {
MF_DOOM = 0,
MF_UNKNOWN = -1,
MF_DOOM = 0,
MF_HEXEN,
MF_DOOM64
} mapformatid_t;
Expand Down Expand Up @@ -186,9 +193,9 @@ typedef struct map_s {

extern map_t* DENG_PLUGIN_GLOBAL(map);

int IsSupportedFormat(const lumpnum_t* lumpList, int numLumps);
int IsSupportedFormat(maplumpinfo_t* lumpInfos[NUM_LUMP_TYPES]);

int LoadMap(const lumpnum_t* lumpList, int numLumps);
int LoadMap(maplumpinfo_t* lumpInfos[NUM_LUMP_TYPES]);
void AnalyzeMap(void);
int TransferMap(void);

Expand Down
60 changes: 60 additions & 0 deletions doomsday/plugins/wadmapconverter/include/maplumpinfo.h
@@ -0,0 +1,60 @@
/**
* @file maplumpinfo.h @ingroup wadmapconverter
*
* @authors Copyright &copy; 2007-2012 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef __WADMAPCONVERTER_MAPLUMPINFO_H__
#define __WADMAPCONVERTER_MAPLUMPINFO_H__

#include "doomsday.h"
#include "dd_types.h"

typedef enum lumptype_e {
ML_INVALID = -1,
FIRST_LUMP_TYPE,
ML_LABEL = FIRST_LUMP_TYPE, // A separator, name, ExMx or MAPxx
ML_THINGS, // Monsters, items..
ML_LINEDEFS, // LineDefs, from editing
ML_SIDEDEFS, // SideDefs, from editing
ML_VERTEXES, // Vertices, edited and BSP splits generated
ML_SEGS, // LineSegs, from LineDefs split by BSP
ML_SSECTORS, // Subsectors, list of LineSegs
ML_NODES, // BSP nodes
ML_SECTORS, // Sectors, from editing
ML_REJECT, // LUT, sector-sector visibility
ML_BLOCKMAP, // LUT, motion clipping, walls/grid element
ML_BEHAVIOR, // ACS Scripts (compiled).
ML_SCRIPTS, // ACS Scripts (source).
ML_LIGHTS, // Surface color tints.
ML_MACROS, // DOOM64 format, macro scripts.
ML_LEAFS, // DOOM64 format, segs (close subsectors).
ML_GLVERT, // GL vertexes
ML_GLSEGS, // GL segs
ML_GLSSECT, // GL subsectors
ML_GLNODES, // GL nodes
ML_GLPVS, // GL PVS dataset
NUM_LUMP_TYPES
} lumptype_t;

typedef struct maplumpinfo_s {
lumpnum_t lumpNum;
lumptype_t lumpType;
size_t length;
} maplumpinfo_t;

#endif /* __WADMAPCONVERTER_MAPLUMPINFO_H__ */
141 changes: 51 additions & 90 deletions doomsday/plugins/wadmapconverter/src/load.cpp
Expand Up @@ -515,49 +515,6 @@ static void buildReject(gamemap_t *map)
}
#endif

lumptype_t DataTypeForLumpName(const char* name)
{
static const struct lumptype_s {
lumptype_t type;
const char* name;
} knownLumps[] =
{
{ML_LABEL, "*"},
{ML_THINGS, "THINGS"},
{ML_LINEDEFS, "LINEDEFS"},
{ML_SIDEDEFS, "SIDEDEFS"},
{ML_VERTEXES, "VERTEXES"},
{ML_SEGS, "SEGS"},
{ML_SSECTORS, "SSECTORS"},
{ML_NODES, "NODES"},
{ML_SECTORS, "SECTORS"},
{ML_REJECT, "REJECT"},
{ML_BLOCKMAP, "BLOCKMAP"},
{ML_BEHAVIOR, "BEHAVIOR"},
{ML_SCRIPTS, "SCRIPTS"},
{ML_LIGHTS, "LIGHTS"},
{ML_MACROS, "MACROS"},
{ML_LEAFS, "LEAFS"},
{ML_GLVERT, "GL_VERT"},
{ML_GLSEGS, "GL_SEGS"},
{ML_GLSSECT, "GL_SSECT"},
{ML_GLNODES, "GL_NODES"},
{ML_GLPVS, "GL_PVS"},
{ML_INVALID, NULL},
};

if(name && name[0])
{
for(uint i = (uint)FIRST_LUMP_TYPE; knownLumps[i].type != ML_INVALID; ++i)
{
if(!strnicmp(knownLumps[i].name, name, strlen(knownLumps[i].name)))
return knownLumps[i].type;
}
}

return ML_INVALID;
}

/**
* Create a temporary polyobj (read from the original map data).
*/
Expand Down Expand Up @@ -838,92 +795,92 @@ void AnalyzeMap(void)
}
}

int IsSupportedFormat(const lumpnum_t* lumpList, int numLumps)
int IsSupportedFormat(maplumpinfo_t* lumpInfos[NUM_LUMP_TYPES])
{
boolean supported = false;
DENG_ASSERT(lumpInfos);

// Lets first check for format specific lumps, as their prescense
// determines the format of the map data. Assume DOOM format by default.
bool recognised = false;
// Assume DOOM format by default.
map->format = MF_DOOM;
for(int i = 0; i < numLumps; ++i)
{
const char* lumpName = W_LumpName(lumpList[i]);

if(!lumpName || !lumpName[0])
continue;
// Check for format specific lumps.
for(uint i = 0; i < (uint)NUM_LUMP_TYPES; ++i)
{
const maplumpinfo_t* info = lumpInfos[i];
if(!info) continue;

if(!strncmp(lumpName, "BEHAVIOR", 8))
switch(info->lumpType)
{
map->format = MF_HEXEN;
break;
}
case ML_BEHAVIOR: map->format = MF_HEXEN; break;

if(!strncmp(lumpName, "MACROS", 6) ||
!strncmp(lumpName, "LIGHTS", 6) ||
!strncmp(lumpName, "LEAFS", 5))
{
map->format = MF_DOOM64;
break;
case ML_MACROS:
case ML_LIGHTS:
case ML_LEAFS: map->format = MF_DOOM64; break;

default: break;
}
}

for(int i = 0; i < numLumps; ++i)
for(uint i = 0; i < (uint)NUM_LUMP_TYPES; ++i)
{
const char* lumpName = W_LumpName(lumpList[i]);
size_t elmSize = 0; // Num of bytes.
const maplumpinfo_t* info = lumpInfos[i];
if(!info) continue;

// Determine the number of map data objects of each data type.
uint* ptr = NULL;
switch(DataTypeForLumpName(lumpName))
uint* elmCountAddr = NULL;
size_t elmSize = 0; // Num of bytes.
switch(info->lumpType)
{
case ML_VERTEXES:
ptr = &map->numVertexes;
elmCountAddr = &map->numVertexes;
elmSize = (map->format == MF_DOOM64? SIZEOF_64VERTEX : SIZEOF_VERTEX);
break;

case ML_THINGS:
ptr = &map->numThings;
elmCountAddr = &map->numThings;
elmSize = (map->format == MF_DOOM64? SIZEOF_64THING : map->format == MF_HEXEN? SIZEOF_XTHING : SIZEOF_THING);
break;

case ML_LINEDEFS:
ptr = &map->numLines;
elmCountAddr = &map->numLines;
elmSize = (map->format == MF_DOOM64? SIZEOF_64LINEDEF : map->format == MF_HEXEN? SIZEOF_XLINEDEF : SIZEOF_LINEDEF);
break;

case ML_SIDEDEFS:
ptr = &map->numSides;
elmCountAddr = &map->numSides;
elmSize = (map->format == MF_DOOM64? SIZEOF_64SIDEDEF : SIZEOF_SIDEDEF);
break;

case ML_SECTORS:
ptr = &map->numSectors;
elmCountAddr = &map->numSectors;
elmSize = (map->format == MF_DOOM64? SIZEOF_64SECTOR : SIZEOF_SECTOR);
break;

case ML_LIGHTS:
ptr = &map->numLights;
elmCountAddr = &map->numLights;
elmSize = SIZEOF_LIGHT;
break;

default: break;
}

if(ptr)
if(elmCountAddr)
{
size_t lumpLength = W_LumpLength(lumpList[i]);
if(0 != lumpLength % elmSize)
if(0 != info->length % elmSize)
{
return false; // What is this??
*ptr += lumpLength / elmSize;
}

*elmCountAddr += info->length / elmSize;
}
}

if(map->numVertexes > 0 && map->numLines > 0 && map->numSides > 0 && map->numSectors > 0)
{
supported = true;
recognised = true;
}

return supported;
return (int)recognised;
}

static void freeMapData(void)
Expand Down Expand Up @@ -1638,8 +1595,10 @@ static void bufferLump(lumpnum_t lumpNum, uint8_t** buf, size_t* len, size_t* ol
W_ReadLump(lumpNum, *buf);
}

int LoadMap(const lumpnum_t* lumpList, int numLumps)
int LoadMap(maplumpinfo_t* lumpInfos[NUM_LUMP_TYPES])
{
DENG_ASSERT(lumpInfos);

VERBOSE( Con_Message("WadMapConverter: Recognised a %s format map.\n",
(map->format == MF_DOOM64? "DOOM64" :
map->format == MF_HEXEN? "Hexen" : "DOOM")) );
Expand All @@ -1656,52 +1615,54 @@ int LoadMap(const lumpnum_t* lumpList, int numLumps)
uint8_t* buf = NULL;
size_t oldLen = 0;

for(int i = 0; i < numLumps; ++i)
for(uint i = 0; i < (uint)NUM_LUMP_TYPES; ++i)
{
lumptype_t lumpType = DataTypeForLumpName(W_LumpName(lumpList[i]));
const maplumpinfo_t* info = lumpInfos[i];
size_t len;

if(!info) continue;

// Process it, transforming it into our local representation.
switch(lumpType)
switch(info->lumpType)
{
case ML_VERTEXES:
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadVertexes(buf, len);
break;

case ML_LINEDEFS:
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadLinedefs(buf, len);
break;

case ML_SIDEDEFS:
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadSidedefs(buf, len);
break;

case ML_SECTORS:
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadSectors(buf, len);
break;

case ML_THINGS:
if(map->numThings)
{
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadThings(buf, len);
}
break;

case ML_LIGHTS:
if(map->numLights)
{
bufferLump(lumpList[i], &buf, &len, &oldLen);
bufferLump(info->lumpNum, &buf, &len, &oldLen);
loadLights(buf, len);
}
break;

case ML_MACROS:
//// \todo Write me!
/// @todo Write me!
break;

default: break;
Expand Down

0 comments on commit 6366ab3

Please sign in to comment.