From f76a56a6199666636cb1d1ab461c5d60fcd9e580 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 28 Jul 2012 07:28:13 +0100 Subject: [PATCH] Wad Map Converter|Refactor: Further cleanup refactorings --- .../plugins/wadmapconverter/include/id1map.h | 87 +++ .../include/id1map_datatypes.h | 28 - .../wadmapconverter/include/id1map_load.h | 21 +- .../wadmapconverter/include/wadmapconverter.h | 6 +- .../plugins/wadmapconverter/src/id1map.cpp | 614 +++++++++++++++++ .../wadmapconverter/src/id1map_analyze.cpp | 5 +- .../wadmapconverter/src/id1map_load.cpp | 650 +----------------- .../wadmapconverter/src/wadmapconverter.cpp | 8 +- .../wadmapconverter/wadmapconverter.pro | 2 + 9 files changed, 746 insertions(+), 675 deletions(-) create mode 100644 doomsday/plugins/wadmapconverter/include/id1map.h create mode 100644 doomsday/plugins/wadmapconverter/src/id1map.cpp diff --git a/doomsday/plugins/wadmapconverter/include/id1map.h b/doomsday/plugins/wadmapconverter/include/id1map.h new file mode 100644 index 0000000000..fcdec30542 --- /dev/null +++ b/doomsday/plugins/wadmapconverter/include/id1map.h @@ -0,0 +1,87 @@ +/** + * @file id1map_load.h @ingroup wadmapconverter + * + * @authors Copyright © 2007-2012 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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 + */ + +#ifndef __WADMAPCONVERTER_ID1MAP_H__ +#define __WADMAPCONVERTER_ID1MAP_H__ + +#include "doomsday.h" +#include "dd_types.h" +#include "maplumpinfo.h" +#include "id1map_datatypes.h" +#include "id1map_load.h" +#include "id1map_util.h" +#include +#include + +typedef std::vector Lines; +typedef std::vector Sides; +typedef std::vector Sectors; +typedef std::vector Things; +typedef std::vector SurfaceTints; +typedef std::list Polyobjs; + +class Id1Map +{ +public: + uint numVertexes; + coord_t* vertexes; ///< Array of vertex coords [v0:X, vo:Y, v1:X, v1:Y, ..] + + Lines lines; + Sides sides; + Sectors sectors; + Things things; + SurfaceTints surfaceTints; + Polyobjs polyobjs; + + StringPool* materials; ///< Material dictionary. + + Id1Map(); + ~Id1Map(); + + int load(MapLumpInfo* lumpInfos[NUM_MAPLUMP_TYPES]); + + void analyze(void); + + int transfer(void); + + MaterialDictId addMaterialToDictionary(const char* name, MaterialDictGroup group); + +private: + inline const Str* findMaterialInDictionary(MaterialDictId id) + { + return StringPool_String(materials, id); + } + + bool loadVertexes(Reader* reader, uint numElements); + bool loadLineDefs(Reader* reader, uint numElements); + bool loadSideDefs(Reader* reader, uint numElements); + bool loadSectors(Reader* reader, uint numElements); + bool loadThings(Reader* reader, uint numElements); + bool loadSurfaceTints(Reader* reader, uint numElements); + + void transferVertexes(void); + void transferSectors(void); + void transferLinesAndSides(void); + void transferSurfaceTints(void); + void transferPolyobjs(void); + void transferThings(void); +}; + +#endif /* __WADMAPCONVERTER_ID1MAP_H__ */ diff --git a/doomsday/plugins/wadmapconverter/include/id1map_datatypes.h b/doomsday/plugins/wadmapconverter/include/id1map_datatypes.h index c3214d6062..fba0318dd0 100644 --- a/doomsday/plugins/wadmapconverter/include/id1map_datatypes.h +++ b/doomsday/plugins/wadmapconverter/include/id1map_datatypes.h @@ -24,8 +24,6 @@ #include "doomsday.h" #include "dd_types.h" #include "id1map_util.h" -#include -#include /// Sizes of the map data structures in the arrived map formats (in int8_ts). #define SIZEOF_64VERTEX (4 * 2) @@ -155,30 +153,4 @@ typedef struct mlight_s { int8_t xx[3]; } surfacetint_t; -typedef std::vector Lines; -typedef std::vector Sides; -typedef std::vector Sectors; -typedef std::vector Things; -typedef std::vector SurfaceTints; -typedef std::list Polyobjs; - -class Id1Map -{ -public: - uint numVertexes; - coord_t* vertexes; ///< Array of vertex coords [v0:X, vo:Y, v1:X, v1:Y, ..] - - Lines lines; - Sides sides; - Sectors sectors; - Things things; - SurfaceTints surfaceTints; - Polyobjs polyobjs; - - StringPool* materials; ///< Material dictionary. - - Id1Map(); - ~Id1Map(); -}; - #endif /* __WADMAPCONVERTER_ID1MAP_DATATYPES_H__ */ diff --git a/doomsday/plugins/wadmapconverter/include/id1map_load.h b/doomsday/plugins/wadmapconverter/include/id1map_load.h index 77e31f6235..a5301bfd96 100644 --- a/doomsday/plugins/wadmapconverter/include/id1map_load.h +++ b/doomsday/plugins/wadmapconverter/include/id1map_load.h @@ -22,17 +22,18 @@ #define __WADMAPCONVERTER_ID1MAP_LOAD_H__ #include "doomsday.h" -#include "dd_types.h" -#include "maplumpinfo.h" #include "id1map_datatypes.h" -extern mapformatid_t DENG_PLUGIN_GLOBAL(mapFormat); -extern Id1Map* DENG_PLUGIN_GLOBAL(map); - -int LoadMap(MapLumpInfo* lumpInfos[NUM_MAPLUMP_TYPES]); - -void AnalyzeMap(void); - -int TransferMap(void); +void MLine_Read(mline_t* l, Reader* reader); +void MLine64_Read(mline_t* l, Reader* reader); +void MLineHx_Read(mline_t* l, Reader* reader); +void MSide_Read(mside_t* s, Reader* reader); +void MSide64_Read(mside_t* s, Reader* reader); +void MSector_Read(msector_t* s, Reader* reader); +void MSector64_Read(msector_t* s, Reader* reader); +void MThing_Read(mthing_t* t, Reader* reader); +void MThing64_Read(mthing_t* t, Reader* reader); +void MThingHx_Read(mthing_t* t, Reader* reader); +void SurfaceTint_Read(surfacetint_t* t, Reader* reader); #endif /* __WADMAPCONVERTER_ID1MAP_LOAD_H__ */ diff --git a/doomsday/plugins/wadmapconverter/include/wadmapconverter.h b/doomsday/plugins/wadmapconverter/include/wadmapconverter.h index fee9224e33..0697e0f6b3 100644 --- a/doomsday/plugins/wadmapconverter/include/wadmapconverter.h +++ b/doomsday/plugins/wadmapconverter/include/wadmapconverter.h @@ -29,7 +29,9 @@ #include "doomsday.h" #include "dd_plugin.h" -#include "id1map_load.h" -#include "id1map_util.h" +#include "id1map.h" + +extern mapformatid_t DENG_PLUGIN_GLOBAL(mapFormat); +extern Id1Map* DENG_PLUGIN_GLOBAL(map); #endif /* end of include guard: __WADMAPCONVERTER_H__ */ diff --git a/doomsday/plugins/wadmapconverter/src/id1map.cpp b/doomsday/plugins/wadmapconverter/src/id1map.cpp new file mode 100644 index 0000000000..50da4c3e39 --- /dev/null +++ b/doomsday/plugins/wadmapconverter/src/id1map.cpp @@ -0,0 +1,614 @@ +/** + * @file id1map.cpp @ingroup wadmapconverter + * + * @authors Copyright © 2003-2012 Jaakko Keränen + * @authors Copyright © 2006-2012 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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 + */ + +#include "wadmapconverter.h" +#include +#include +#include + +#define mapFormat DENG_PLUGIN_GLOBAL(mapFormat) + +static Reader* bufferLump(MapLumpInfo* info); +static void clearReadBuffer(void); + +Id1Map::Id1Map() + : numVertexes(0), vertexes(0), materials(0) +{} + +Id1Map::~Id1Map() +{ + if(vertexes) + { + free(vertexes); + vertexes = 0; + } + + DENG2_FOR_EACH(i, polyobjs, Polyobjs::iterator) + { + free((i)->lineIndices); + } + + if(materials) + { + StringPool_Clear(materials); + StringPool_Delete(materials); + materials = 0; + } +} + +MaterialDictId Id1Map::addMaterialToDictionary(const char* name, MaterialDictGroup group) +{ + DENG2_ASSERT(name); + + // Are we yet to instantiate the dictionary itself? + if(!materials) + { + materials = StringPool_New(); + } + + // Prepare the encoded URI for insertion into the dictionary. + Str* uriCString; + if(mapFormat == MF_DOOM64) + { + // Doom64 maps reference materials with unique ids. + int uniqueId = *((int*) name); + //char name[9]; + //sprintf(name, "UNK%05i", uniqueId); name[8] = '\0'; + + Uri* uri = Materials_ComposeUri(DD_MaterialForTextureUniqueId((group == MG_PLANE? TN_FLATS : TN_TEXTURES), uniqueId)); + uriCString = Uri_Compose(uri); + Uri_Delete(uri); + } + else + { + // In original DOOM, texture name references beginning with the + // hypen '-' character are always treated as meaning "no reference" + // or "invalid texture" and surfaces using them were not drawn. + if(group != MG_PLANE && name[0] == '-') + { + return 0; // Not a valid id. + } + + // Material paths must be encoded. + AutoStr* path = Str_PercentEncode(AutoStr_FromText(name)); + Uri* uri = Uri_NewWithPath2(Str_Text(path), RC_NULL); + Uri_SetScheme(uri, group == MG_PLANE? MN_FLATS_NAME : MN_TEXTURES_NAME); + uriCString = Uri_Compose(uri); + Uri_Delete(uri); + } + + // Intern this material URI in the dictionary. + MaterialDictId internId = StringPool_Intern(materials, uriCString); + + // We're done (phew!). + Str_Delete(uriCString); + return internId; +} + +bool Id1Map::loadVertexes(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing vertexes..."); + for(uint n = 0; n < numElements; ++n) + { + switch(mapFormat) + { + default: + case MF_DOOM: + vertexes[n * 2] = coord_t( SHORT(Reader_ReadInt16(reader)) ); + vertexes[n * 2 + 1] = coord_t( SHORT(Reader_ReadInt16(reader)) ); + break; + + case MF_DOOM64: + vertexes[n * 2] = coord_t( FIX2FLT(LONG(Reader_ReadInt32(reader))) ); + vertexes[n * 2 + 1] = coord_t( FIX2FLT(LONG(Reader_ReadInt32(reader))) ); + break; + } + } + + return true; +} + +bool Id1Map::loadLineDefs(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing line definitions..."); + if(numElements) + { + lines.reserve(lines.size() + numElements); + for(uint n = 0; n < numElements; ++n) + { + switch(mapFormat) + { + default: + case MF_DOOM: + lines.push_back(mline_t()); + MLine_Read(&lines.back(), reader); + break; + + case MF_DOOM64: + lines.push_back(mline_t()); + MLine64_Read(&lines.back(), reader); + break; + + case MF_HEXEN: + lines.push_back(mline_t()); + MLineHx_Read(&lines.back(), reader); + break; + } + } + } + + return true; +} + +bool Id1Map::loadSideDefs(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing side definitions..."); + if(numElements) + { + sides.reserve(sides.size() + numElements); + for(uint n = 0; n < numElements; ++n) + { + switch(mapFormat) + { + default: + case MF_DOOM: + sides.push_back(mside_t()); + MSide_Read(&sides.back(), reader); + break; + + case MF_DOOM64: + sides.push_back(mside_t()); + MSide64_Read(&sides.back(), reader); + break; + } + } + } + + return true; +} + +bool Id1Map::loadSectors(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing sectors..."); + if(numElements) + { + sectors.reserve(sectors.size() + numElements); + for(uint n = 0; n < numElements; ++n) + { + switch(mapFormat) + { + default: + sectors.push_back(msector_t()); + MSector_Read(§ors.back(), reader); + break; + + case MF_DOOM64: + sectors.push_back(msector_t()); + MSector64_Read(§ors.back(), reader); + break; + } + } + } + + return true; +} + +bool Id1Map::loadThings(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing things..."); + if(numElements) + { + things.reserve(things.size() + numElements); + for(uint n = 0; n < numElements; ++n) + { + switch(mapFormat) + { + default: + case MF_DOOM: + things.push_back(mthing_t()); + MThing_Read(&things.back(), reader); + break; + + case MF_DOOM64: + things.push_back(mthing_t()); + MThing64_Read(&things.back(), reader); + break; + + case MF_HEXEN: + things.push_back(mthing_t()); + MThingHx_Read(&things.back(), reader); + break; + } + } + } + + return true; +} + +bool Id1Map::loadSurfaceTints(Reader* reader, uint numElements) +{ + DENG2_ASSERT(reader); + + LOG_TRACE("Processing surface tints..."); + if(numElements) + { + surfaceTints.reserve(surfaceTints.size() + numElements); + for(uint n = 0; n < numElements; ++n) + { + surfaceTints.push_back(surfacetint_t()); + SurfaceTint_Read(&surfaceTints.back(), reader); + } + } + + return true; +} + +int Id1Map::load(MapLumpInfo* lumpInfos[NUM_MAPLUMP_TYPES]) +{ + DENG2_ASSERT(lumpInfos); + + /** + * Allocate the vertices first as a large contiguous array suitable for passing + * directly to Doomsday's MPE interface. + */ + size_t elmSize = (mapFormat == MF_DOOM64? SIZEOF_64VERTEX : SIZEOF_VERTEX); + numVertexes = lumpInfos[ML_VERTEXES]->length / elmSize; + vertexes = (coord_t*)malloc(numVertexes * 2 * sizeof(*vertexes)); + + for(uint i = 0; i < (uint)NUM_MAPLUMP_TYPES; ++i) + { + MapLumpInfo* info = lumpInfos[i]; + uint numElements; + Reader* reader; + + if(!info) continue; + + // Process this data lump. + switch(info->type) + { + default: break; + + case ML_VERTEXES: + numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64VERTEX : SIZEOF_VERTEX); + reader = bufferLump(info); + loadVertexes(reader, numElements); + Reader_Delete(reader); + break; + + case ML_LINEDEFS: + numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64LINEDEF : + mapFormat == MF_HEXEN ? SIZEOF_XLINEDEF : SIZEOF_LINEDEF); + reader = bufferLump(info); + loadLineDefs(reader, numElements); + Reader_Delete(reader); + break; + + case ML_SIDEDEFS: + numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64SIDEDEF : SIZEOF_SIDEDEF); + reader = bufferLump(info); + loadSideDefs(reader, numElements); + Reader_Delete(reader); + break; + + case ML_SECTORS: + numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64SECTOR : SIZEOF_SECTOR); + reader = bufferLump(info); + loadSectors(reader, numElements); + Reader_Delete(reader); + break; + + case ML_THINGS: + if(info->length) + { + numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64THING : + mapFormat == MF_HEXEN ? SIZEOF_XTHING : SIZEOF_THING); + reader = bufferLump(info); + loadThings(reader, numElements); + Reader_Delete(reader); + } + break; + + case ML_LIGHTS: + if(info->length) + { + numElements = info->length / SIZEOF_LIGHT; + reader = bufferLump(info); + loadSurfaceTints(reader, numElements); + Reader_Delete(reader); + } + break; + } + } + + // We're done with the read buffer. + clearReadBuffer(); + + return false; // Success. +} + +void Id1Map::transferVertexes(void) +{ + LOG_TRACE("Transfering vertexes..."); + MPE_VertexCreatev(numVertexes, vertexes, NULL); +} + +void Id1Map::transferSectors(void) +{ + LOG_TRACE("Transfering sectors..."); + + DENG2_FOR_EACH(i, sectors, Sectors::iterator) + { + uint idx = MPE_SectorCreate(float((i)->lightLevel) / 255.0f, 1, 1, 1); + + MPE_PlaneCreate(idx, (i)->floorHeight, findMaterialInDictionary((i)->floorMaterial), + 0, 0, 1, 1, 1, 1, 0, 0, 1); + MPE_PlaneCreate(idx, (i)->ceilHeight, findMaterialInDictionary((i)->ceilMaterial), + 0, 0, 1, 1, 1, 1, 0, 0, -1); + + MPE_GameObjProperty("XSector", idx-1, "Tag", DDVT_SHORT, &(i)->tag); + MPE_GameObjProperty("XSector", idx-1, "Type", DDVT_SHORT, &(i)->type); + + if(mapFormat == MF_DOOM64) + { + MPE_GameObjProperty("XSector", idx-1, "Flags", DDVT_SHORT, &(i)->d64flags); + MPE_GameObjProperty("XSector", idx-1, "CeilingColor", DDVT_SHORT, &(i)->d64ceilingColor); + MPE_GameObjProperty("XSector", idx-1, "FloorColor", DDVT_SHORT, &(i)->d64floorColor); + MPE_GameObjProperty("XSector", idx-1, "UnknownColor", DDVT_SHORT, &(i)->d64unknownColor); + MPE_GameObjProperty("XSector", idx-1, "WallTopColor", DDVT_SHORT, &(i)->d64wallTopColor); + MPE_GameObjProperty("XSector", idx-1, "WallBottomColor", DDVT_SHORT, &(i)->d64wallBottomColor); + } + } +} + +void Id1Map::transferLinesAndSides(void) +{ + LOG_TRACE("Transfering lines and sides..."); + DENG2_FOR_EACH(i, lines, Lines::iterator) + { + uint frontIdx = 0; + mside_t* front = ((i)->sides[RIGHT] != 0? &sides[(i)->sides[RIGHT]-1] : NULL); + if(front) + { + frontIdx = + MPE_SidedefCreate((mapFormat == MF_DOOM64? SDF_MIDDLE_STRETCH : 0), + findMaterialInDictionary(front->topMaterial), + front->offset[VX], front->offset[VY], 1, 1, 1, + findMaterialInDictionary(front->middleMaterial), + front->offset[VX], front->offset[VY], 1, 1, 1, 1, + findMaterialInDictionary(front->bottomMaterial), + front->offset[VX], front->offset[VY], 1, 1, 1); + } + + uint backIdx = 0; + mside_t* back = ((i)->sides[LEFT] != 0? &sides[(i)->sides[LEFT]-1] : NULL); + if(back) + { + backIdx = + MPE_SidedefCreate((mapFormat == MF_DOOM64? SDF_MIDDLE_STRETCH : 0), + findMaterialInDictionary(back->topMaterial), + back->offset[VX], back->offset[VY], 1, 1, 1, + findMaterialInDictionary(back->middleMaterial), + back->offset[VX], back->offset[VY], 1, 1, 1, 1, + findMaterialInDictionary(back->bottomMaterial), + back->offset[VX], back->offset[VY], 1, 1, 1); + } + + uint lineIdx = MPE_LinedefCreate((i)->v[0], (i)->v[1], front? front->sector : 0, + back? back->sector : 0, frontIdx, backIdx, (i)->ddFlags); + + MPE_GameObjProperty("XLinedef", lineIdx-1, "Flags", DDVT_SHORT, &(i)->flags); + + switch(mapFormat) + { + default: + case MF_DOOM: + MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_SHORT, &(i)->dType); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Tag", DDVT_SHORT, &(i)->dTag); + break; + + case MF_DOOM64: + MPE_GameObjProperty("XLinedef", lineIdx-1, "DrawFlags", DDVT_BYTE, &(i)->d64drawFlags); + MPE_GameObjProperty("XLinedef", lineIdx-1, "TexFlags", DDVT_BYTE, &(i)->d64texFlags); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_BYTE, &(i)->d64type); + MPE_GameObjProperty("XLinedef", lineIdx-1, "UseType", DDVT_BYTE, &(i)->d64useType); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Tag", DDVT_SHORT, &(i)->d64tag); + break; + + case MF_HEXEN: + MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_BYTE, &(i)->xType); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg0", DDVT_BYTE, &(i)->xArgs[0]); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg1", DDVT_BYTE, &(i)->xArgs[1]); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg2", DDVT_BYTE, &(i)->xArgs[2]); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg3", DDVT_BYTE, &(i)->xArgs[3]); + MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg4", DDVT_BYTE, &(i)->xArgs[4]); + break; + } + } +} + +void Id1Map::transferSurfaceTints(void) +{ + if(surfaceTints.empty()) return; + + LOG_TRACE("Transfering surface tints..."); + DENG2_FOR_EACH(i, surfaceTints, SurfaceTints::iterator) + { + uint idx = i - surfaceTints.begin(); + + MPE_GameObjProperty("Light", idx, "ColorR", DDVT_FLOAT, &(i)->rgb[0]); + MPE_GameObjProperty("Light", idx, "ColorG", DDVT_FLOAT, &(i)->rgb[1]); + MPE_GameObjProperty("Light", idx, "ColorB", DDVT_FLOAT, &(i)->rgb[2]); + MPE_GameObjProperty("Light", idx, "XX0", DDVT_BYTE, &(i)->xx[0]); + MPE_GameObjProperty("Light", idx, "XX1", DDVT_BYTE, &(i)->xx[1]); + MPE_GameObjProperty("Light", idx, "XX2", DDVT_BYTE, &(i)->xx[2]); + } +} + +void Id1Map::transferPolyobjs(void) +{ + if(polyobjs.empty()) return; + + LOG_TRACE("Transfering polyobjs..."); + DENG2_FOR_EACH(i, polyobjs, Polyobjs::iterator) + { + MPE_PolyobjCreate((i)->lineIndices, (i)->lineCount, (i)->tag, (i)->seqType, + coord_t((i)->anchor[VX]), coord_t((i)->anchor[VY])); + } +} + +void Id1Map::transferThings(void) +{ + if(things.empty()) return; + + LOG_TRACE("Transfering things..."); + DENG2_FOR_EACH(i, things, Things::iterator) + { + uint idx = i - things.begin(); + + MPE_GameObjProperty("Thing", idx, "X", DDVT_SHORT, &(i)->origin[VX]); + MPE_GameObjProperty("Thing", idx, "Y", DDVT_SHORT, &(i)->origin[VY]); + MPE_GameObjProperty("Thing", idx, "Z", DDVT_SHORT, &(i)->origin[VZ]); + MPE_GameObjProperty("Thing", idx, "Angle", DDVT_ANGLE, &(i)->angle); + MPE_GameObjProperty("Thing", idx, "DoomEdNum", DDVT_SHORT, &(i)->doomEdNum); + MPE_GameObjProperty("Thing", idx, "SkillModes", DDVT_INT, &(i)->skillModes); + MPE_GameObjProperty("Thing", idx, "Flags", DDVT_INT, &(i)->flags); + + if(mapFormat == MF_DOOM64) + { + MPE_GameObjProperty("Thing", idx, "ID", DDVT_SHORT, &(i)->d64TID); + } + else if(mapFormat == MF_HEXEN) + { + MPE_GameObjProperty("Thing", idx, "Special", DDVT_BYTE, &(i)->xSpecial); + MPE_GameObjProperty("Thing", idx, "ID", DDVT_SHORT, &(i)->xTID); + MPE_GameObjProperty("Thing", idx, "Arg0", DDVT_BYTE, &(i)->xArgs[0]); + MPE_GameObjProperty("Thing", idx, "Arg1", DDVT_BYTE, &(i)->xArgs[1]); + MPE_GameObjProperty("Thing", idx, "Arg2", DDVT_BYTE, &(i)->xArgs[2]); + MPE_GameObjProperty("Thing", idx, "Arg3", DDVT_BYTE, &(i)->xArgs[3]); + MPE_GameObjProperty("Thing", idx, "Arg4", DDVT_BYTE, &(i)->xArgs[4]); + } + } +} + +int Id1Map::transfer(void) +{ + uint startTime = Sys_GetRealTime(); + + LOG_AS("Id1Map"); + + transferVertexes(); + transferSectors(); + transferLinesAndSides(); + transferSurfaceTints(); + transferPolyobjs(); + transferThings(); + + LOG_VERBOSE("Done in %.2f seconds.") << ((Sys_GetRealTime() - startTime) / 1000.0f); + + return false; // Success. +} + +static uint8_t* readPtr; +static uint8_t* readBuffer = NULL; +static size_t readBufferSize = 0; + +static char readInt8(Reader* r) +{ + if(!r) return 0; + char value = *((const int8_t*) (readPtr)); + readPtr += 1; + return value; +} + +static short readInt16(Reader* r) +{ + if(!r) return 0; + short value = *((const int16_t*) (readPtr)); + readPtr += 2; + return value; +} + +static int readInt32(Reader* r) +{ + if(!r) return 0; + int value = *((const int32_t*) (readPtr)); + readPtr += 4; + return value; +} + +static float readFloat(Reader* r) +{ + DENG2_ASSERT(sizeof(float) == 4); + if(!r) return 0; + int32_t val = *((const int32_t*) (readPtr)); + float returnValue = 0; + memcpy(&returnValue, &val, 4); + return returnValue; +} + +static void readData(Reader* r, char* data, int len) +{ + if(!r) return; + memcpy(data, readPtr, len); + readPtr += len; +} + +/// @todo It should not be necessary to buffer the lump data here. +static Reader* bufferLump(MapLumpInfo* info) +{ + // Need to enlarge our read buffer? + if(info->length > readBufferSize) + { + readBuffer = (uint8_t*)realloc(readBuffer, info->length); + if(!readBuffer) + { + throw de::Error("WadMapConverter::bufferLump", + QString("Failed on (re)allocation of %1 bytes for the read buffer.") + .arg(info->length)); + } + readBufferSize = info->length; + } + + // Buffer the entire lump. + W_ReadLump(info->lump, readBuffer); + + // Create the reader. + readPtr = readBuffer; + return Reader_NewWithCallbacks(readInt8, readInt16, readInt32, readFloat, readData); +} + +static void clearReadBuffer(void) +{ + if(!readBuffer) return; + free(readBuffer); + readBuffer = 0; + readBufferSize = 0; +} diff --git a/doomsday/plugins/wadmapconverter/src/id1map_analyze.cpp b/doomsday/plugins/wadmapconverter/src/id1map_analyze.cpp index 321263d3e5..ae95b7f73c 100644 --- a/doomsday/plugins/wadmapconverter/src/id1map_analyze.cpp +++ b/doomsday/plugins/wadmapconverter/src/id1map_analyze.cpp @@ -224,9 +224,7 @@ static bool findAndCreatePolyobj(int16_t tag, int16_t anchorX, int16_t anchorY) static void findPolyobjs(void) { - LOG_AS("WadMapConverter"); LOG_TRACE("Locating polyobjs..."); - DENG2_FOR_EACH(i, map->things, Things::iterator) { // A polyobj anchor? @@ -238,8 +236,9 @@ static void findPolyobjs(void) } } -void AnalyzeMap(void) +void Id1Map::analyze(void) { + LOG_AS("WadMapConverter::Id1Map"); if(mapFormat == MF_HEXEN) { findPolyobjs(); diff --git a/doomsday/plugins/wadmapconverter/src/id1map_load.cpp b/doomsday/plugins/wadmapconverter/src/id1map_load.cpp index 77347c5f52..7e76fc2865 100644 --- a/doomsday/plugins/wadmapconverter/src/id1map_load.cpp +++ b/doomsday/plugins/wadmapconverter/src/id1map_load.cpp @@ -23,116 +23,10 @@ #include "wadmapconverter.h" #include -#include -#include #define mapFormat DENG_PLUGIN_GLOBAL(mapFormat) #define map DENG_PLUGIN_GLOBAL(map) -Id1Map::Id1Map() - : numVertexes(0), vertexes(0), materials(0) -{} - -Id1Map::~Id1Map() -{ - if(vertexes) - { - free(vertexes); - vertexes = 0; - } - - DENG2_FOR_EACH(i, polyobjs, Polyobjs::iterator) - { - free((i)->lineIndices); - } - - if(materials) - { - StringPool_Clear(materials); - StringPool_Delete(materials); - materials = 0; - } -} - -static const Str* findMaterialInDictionary(MaterialDictId id) -{ - return StringPool_String(map->materials, id); -} - -static MaterialDictId addMaterialToDictionary(const char* name, MaterialDictGroup group) -{ - DENG2_ASSERT(name); - - // Are we yet to instantiate the dictionary itself? - if(!map->materials) - { - map->materials = StringPool_New(); - } - - // Prepare the encoded URI for insertion into the dictionary. - Str* uriCString; - if(mapFormat == MF_DOOM64) - { - // Doom64 maps reference materials with unique ids. - int uniqueId = *((int*) name); - //char name[9]; - //sprintf(name, "UNK%05i", uniqueId); name[8] = '\0'; - - Uri* uri = Materials_ComposeUri(DD_MaterialForTextureUniqueId((group == MG_PLANE? TN_FLATS : TN_TEXTURES), uniqueId)); - uriCString = Uri_Compose(uri); - Uri_Delete(uri); - } - else - { - // In original DOOM, texture name references beginning with the - // hypen '-' character are always treated as meaning "no reference" - // or "invalid texture" and surfaces using them were not drawn. - if(group != MG_PLANE && name[0] == '-') - { - return 0; // Not a valid id. - } - - // Material paths must be encoded. - AutoStr* path = Str_PercentEncode(AutoStr_FromText(name)); - Uri* uri = Uri_NewWithPath2(Str_Text(path), RC_NULL); - Uri_SetScheme(uri, group == MG_PLANE? MN_FLATS_NAME : MN_TEXTURES_NAME); - uriCString = Uri_Compose(uri); - Uri_Delete(uri); - } - - // Intern this material URI in the dictionary. - MaterialDictId internId = StringPool_Intern(map->materials, uriCString); - - // We're done (phew!). - Str_Delete(uriCString); - return internId; -} - -static bool loadVertexes(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing vertexes..."); - for(uint n = 0; n < numElements; ++n) - { - switch(mapFormat) - { - default: - case MF_DOOM: - map->vertexes[n * 2] = coord_t( SHORT(Reader_ReadInt16(reader)) ); - map->vertexes[n * 2 + 1] = coord_t( SHORT(Reader_ReadInt16(reader)) ); - break; - - case MF_DOOM64: - map->vertexes[n * 2] = coord_t( FIX2FLT(LONG(Reader_ReadInt32(reader))) ); - map->vertexes[n * 2 + 1] = coord_t( FIX2FLT(LONG(Reader_ReadInt32(reader))) ); - break; - } - } - - return true; -} - /** * Translate the line definition flags for Doomsday. */ @@ -199,7 +93,7 @@ static void interpretLineDefFlags(mline_t* l) #undef ML_BLOCKING } -static void MLine_Read(mline_t* l, Reader* reader) +void MLine_Read(mline_t* l, Reader* reader) { DENG2_ASSERT(l); DENG2_ASSERT(reader); @@ -232,7 +126,7 @@ static void MLine_Read(mline_t* l, Reader* reader) interpretLineDefFlags(l); } -static void MLine64_Read(mline_t* l, Reader* reader) +void MLine64_Read(mline_t* l, Reader* reader) { DENG2_ASSERT(l); DENG2_ASSERT(reader); @@ -268,7 +162,7 @@ static void MLine64_Read(mline_t* l, Reader* reader) interpretLineDefFlags(l); } -static void MLineHx_Read(mline_t* l, Reader* reader) +void MLineHx_Read(mline_t* l, Reader* reader) { DENG2_ASSERT(l); DENG2_ASSERT(reader); @@ -305,37 +199,7 @@ static void MLineHx_Read(mline_t* l, Reader* reader) interpretLineDefFlags(l); } -static bool loadLineDefs(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing line definitions..."); - for(uint n = 0; n < numElements; ++n) - { - switch(mapFormat) - { - default: - case MF_DOOM: - map->lines.push_back(mline_t()); - MLine_Read(&map->lines.back(), reader); - break; - - case MF_DOOM64: - map->lines.push_back(mline_t()); - MLine64_Read(&map->lines.back(), reader); - break; - - case MF_HEXEN: - map->lines.push_back(mline_t()); - MLineHx_Read(&map->lines.back(), reader); - break; - } - } - - return true; -} - -static void MSide_Read(mside_t* s, Reader* reader) +void MSide_Read(mside_t* s, Reader* reader) { DENG2_ASSERT(s); DENG2_ASSERT(reader); @@ -345,20 +209,20 @@ static void MSide_Read(mside_t* s, Reader* reader) char name[9]; Reader_Read(reader, name, 8); name[8] = '\0'; - s->topMaterial = addMaterialToDictionary(name, MG_WALL); + s->topMaterial = map->addMaterialToDictionary(name, MG_WALL); Reader_Read(reader, name, 8); name[8] = '\0'; - s->bottomMaterial = addMaterialToDictionary(name, MG_WALL); + s->bottomMaterial = map->addMaterialToDictionary(name, MG_WALL); Reader_Read(reader, name, 8); name[8] = '\0'; - s->middleMaterial = addMaterialToDictionary(name, MG_WALL); + s->middleMaterial = map->addMaterialToDictionary(name, MG_WALL); int idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); if(idx == 0xFFFF) s->sector = 0; else s->sector = idx + 1; } -static void MSide64_Read(mside_t* s, Reader* reader) +void MSide64_Read(mside_t* s, Reader* reader) { DENG2_ASSERT(s); DENG2_ASSERT(reader); @@ -368,45 +232,20 @@ static void MSide64_Read(mside_t* s, Reader* reader) int idx; idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); - s->topMaterial = addMaterialToDictionary((const char*) &idx, MG_WALL); + s->topMaterial = map->addMaterialToDictionary((const char*) &idx, MG_WALL); idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); - s->bottomMaterial = addMaterialToDictionary((const char*) &idx, MG_WALL); + s->bottomMaterial = map->addMaterialToDictionary((const char*) &idx, MG_WALL); idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); - s->middleMaterial = addMaterialToDictionary((const char*) &idx, MG_WALL); + s->middleMaterial = map->addMaterialToDictionary((const char*) &idx, MG_WALL); idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); if(idx == 0xFFFF) s->sector = 0; else s->sector = idx + 1; } -static bool loadSideDefs(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing side definitions..."); - for(uint n = 0; n < numElements; ++n) - { - switch(mapFormat) - { - default: - case MF_DOOM: - map->sides.push_back(mside_t()); - MSide_Read(&map->sides.back(), reader); - break; - - case MF_DOOM64: - map->sides.push_back(mside_t()); - MSide64_Read(&map->sides.back(), reader); - break; - } - } - - return true; -} - -static void MSector_Read(msector_t* s, Reader* reader) +void MSector_Read(msector_t* s, Reader* reader) { DENG2_ASSERT(s); DENG2_ASSERT(reader); @@ -416,17 +255,17 @@ static void MSector_Read(msector_t* s, Reader* reader) char name[9]; Reader_Read(reader, name, 8); name[8] = '\0'; - s->floorMaterial= addMaterialToDictionary(name, MG_PLANE); + s->floorMaterial= map->addMaterialToDictionary(name, MG_PLANE); Reader_Read(reader, name, 8); name[8] = '\0'; - s->ceilMaterial = addMaterialToDictionary(name, MG_PLANE); + s->ceilMaterial = map->addMaterialToDictionary(name, MG_PLANE); s->lightLevel = SHORT( Reader_ReadInt16(reader) ); s->type = SHORT( Reader_ReadInt16(reader) ); s->tag = SHORT( Reader_ReadInt16(reader) ); } -static void MSector64_Read(msector_t* s, Reader* reader) +void MSector64_Read(msector_t* s, Reader* reader) { DENG2_ASSERT(s); DENG2_ASSERT(reader); @@ -436,10 +275,10 @@ static void MSector64_Read(msector_t* s, Reader* reader) int idx; idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); - s->floorMaterial= addMaterialToDictionary((const char*) &idx, MG_PLANE); + s->floorMaterial= map->addMaterialToDictionary((const char*) &idx, MG_PLANE); idx = USHORT( uint16_t(Reader_ReadInt16(reader)) ); - s->ceilMaterial = addMaterialToDictionary((const char*) &idx, MG_PLANE); + s->ceilMaterial = map->addMaterialToDictionary((const char*) &idx, MG_PLANE); s->d64ceilingColor = USHORT( uint16_t(Reader_ReadInt16(reader)) ); s->d64floorColor = USHORT( uint16_t(Reader_ReadInt16(reader)) ); @@ -454,30 +293,6 @@ static void MSector64_Read(msector_t* s, Reader* reader) s->lightLevel = 160; ///? } -static bool loadSectors(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing sectors..."); - for(uint n = 0; n < numElements; ++n) - { - switch(mapFormat) - { - default: - map->sectors.push_back(msector_t()); - MSector_Read(&map->sectors.back(), reader); - break; - - case MF_DOOM64: - map->sectors.push_back(msector_t()); - MSector64_Read(&map->sectors.back(), reader); - break; - } - } - - return true; -} - /// @todo Get these from a game api header. #define MTF_Z_FLOOR 0x20000000 ///< Spawn relative to floor height. #define MTF_Z_CEIL 0x40000000 ///< Spawn relative to ceiling height (minus thing height). @@ -485,7 +300,7 @@ static bool loadSectors(Reader* reader, uint numElements) #define ANG45 0x20000000 -static void MThing_Read(mthing_t* t, Reader* reader) +void MThing_Read(mthing_t* t, Reader* reader) { /** * DOOM Thing flags: @@ -536,7 +351,7 @@ static void MThing_Read(mthing_t* t, Reader* reader) #undef MTF_EASY } -static void MThing64_Read(mthing_t* t, Reader* reader) +void MThing64_Read(mthing_t* t, Reader* reader) { /** * DOOM64 Thing flags: @@ -597,7 +412,7 @@ static void MThing64_Read(mthing_t* t, Reader* reader) #undef MTF_EASY } -static void MThingHx_Read(mthing_t* t, Reader* reader) +void MThingHx_Read(mthing_t* t, Reader* reader) { /** * Hexen Thing flags: @@ -688,37 +503,7 @@ static void MThingHx_Read(mthing_t* t, Reader* reader) #undef MTF_EASY } -static bool loadThings(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing things..."); - for(uint n = 0; n < numElements; ++n) - { - switch(mapFormat) - { - default: - case MF_DOOM: - map->things.push_back(mthing_t()); - MThing_Read(&map->things.back(), reader); - break; - - case MF_DOOM64: - map->things.push_back(mthing_t()); - MThing64_Read(&map->things.back(), reader); - break; - - case MF_HEXEN: - map->things.push_back(mthing_t()); - MThingHx_Read(&map->things.back(), reader); - break; - } - } - - return true; -} - -static void SurfaceTint_Read(surfacetint_t* t, Reader* reader) +void SurfaceTint_Read(surfacetint_t* t, Reader* reader) { DENG2_ASSERT(t); DENG2_ASSERT(reader); @@ -730,396 +515,3 @@ static void SurfaceTint_Read(surfacetint_t* t, Reader* reader) t->xx[1] = Reader_ReadByte(reader); t->xx[2] = Reader_ReadByte(reader); } - -static bool loadSurfaceTints(Reader* reader, uint numElements) -{ - DENG2_ASSERT(reader); - - LOG_TRACE("Processing surface tints..."); - for(uint n = 0; n < numElements; ++n) - { - map->surfaceTints.push_back(surfacetint_t()); - SurfaceTint_Read(&map->surfaceTints.back(), reader); - } - - return true; -} - -static uint8_t* readPtr; -static uint8_t* readBuffer = NULL; -static size_t readBufferSize = 0; - -static char readInt8(Reader* r) -{ - if(!r) return 0; - char value = *((const int8_t*) (readPtr)); - readPtr += 1; - return value; -} - -static short readInt16(Reader* r) -{ - if(!r) return 0; - short value = *((const int16_t*) (readPtr)); - readPtr += 2; - return value; -} - -static int readInt32(Reader* r) -{ - if(!r) return 0; - int value = *((const int32_t*) (readPtr)); - readPtr += 4; - return value; -} - -static float readFloat(Reader* r) -{ - DENG2_ASSERT(sizeof(float) == 4); - if(!r) return 0; - int32_t val = *((const int32_t*) (readPtr)); - float returnValue = 0; - memcpy(&returnValue, &val, 4); - return returnValue; -} - -static void readData(Reader* r, char* data, int len) -{ - if(!r) return; - memcpy(data, readPtr, len); - readPtr += len; -} - -/// @todo It should not be necessary to buffer the lump data here. -static Reader* bufferLump(MapLumpInfo* info) -{ - // Need to enlarge our read buffer? - if(info->length > readBufferSize) - { - readBuffer = (uint8_t*)realloc(readBuffer, info->length); - if(!readBuffer) - { - throw de::Error("WadMapConverter::bufferLump", - QString("Failed on (re)allocation of %1 bytes for the read buffer.") - .arg(info->length)); - } - readBufferSize = info->length; - } - - // Buffer the entire lump. - W_ReadLump(info->lump, readBuffer); - - // Create the reader. - readPtr = readBuffer; - return Reader_NewWithCallbacks(readInt8, readInt16, readInt32, readFloat, readData); -} - -static void clearReadBuffer(void) -{ - if(!readBuffer) return; - free(readBuffer); - readBuffer = 0; - readBufferSize = 0; -} - -int LoadMap(MapLumpInfo* lumpInfos[NUM_MAPLUMP_TYPES]) -{ - DENG2_ASSERT(lumpInfos); - - map = new Id1Map; - - /** - * Determine how many map data objects we'll need of each type. - */ - size_t elmSize; - - // Verts. - elmSize = (mapFormat == MF_DOOM64? SIZEOF_64VERTEX : SIZEOF_VERTEX); - map->numVertexes = lumpInfos[ML_VERTEXES]->length / elmSize; - - // Things. - if(lumpInfos[ML_THINGS]) - { - elmSize = (mapFormat == MF_DOOM64? SIZEOF_64THING : mapFormat == MF_HEXEN? SIZEOF_XTHING : SIZEOF_THING); - map->things.reserve(lumpInfos[ML_THINGS]->length / elmSize); - } - - // Lines. - elmSize = (mapFormat == MF_DOOM64? SIZEOF_64LINEDEF : mapFormat == MF_HEXEN? SIZEOF_XLINEDEF : SIZEOF_LINEDEF); - map->lines.reserve(lumpInfos[ML_LINEDEFS]->length / elmSize); - - // Sides. - elmSize = (mapFormat == MF_DOOM64? SIZEOF_64SIDEDEF : SIZEOF_SIDEDEF); - map->sides.reserve(lumpInfos[ML_SIDEDEFS]->length / elmSize); - - // Sectors. - elmSize = (mapFormat == MF_DOOM64? SIZEOF_64SECTOR : SIZEOF_SECTOR); - map->sectors.reserve(lumpInfos[ML_SECTORS]->length / elmSize); - - if(lumpInfos[ML_LIGHTS]) - { - elmSize = SIZEOF_LIGHT; - map->surfaceTints.reserve(lumpInfos[ML_LIGHTS]->length / elmSize); - } - - /** - * Allocate the temporary map data objects used during conversion. - */ - map->vertexes = (coord_t*)malloc(map->numVertexes * 2 * sizeof(*map->vertexes)); - - for(uint i = 0; i < (uint)NUM_MAPLUMP_TYPES; ++i) - { - MapLumpInfo* info = lumpInfos[i]; - uint numElements; - Reader* reader; - - if(!info) continue; - - // Process this data lump. - switch(info->type) - { - case ML_VERTEXES: - numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64VERTEX : SIZEOF_VERTEX); - reader = bufferLump(info); - loadVertexes(reader, numElements); - Reader_Delete(reader); - break; - - case ML_LINEDEFS: - numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64LINEDEF : - mapFormat == MF_HEXEN ? SIZEOF_XLINEDEF : SIZEOF_LINEDEF); - reader = bufferLump(info); - loadLineDefs(reader, numElements); - Reader_Delete(reader); - break; - - case ML_SIDEDEFS: - numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64SIDEDEF : SIZEOF_SIDEDEF); - reader = bufferLump(info); - loadSideDefs(reader, numElements); - Reader_Delete(reader); - break; - - case ML_SECTORS: - numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64SECTOR : SIZEOF_SECTOR); - reader = bufferLump(info); - loadSectors(reader, numElements); - Reader_Delete(reader); - break; - - case ML_THINGS: - if(info->length) - { - numElements = info->length / (mapFormat == MF_DOOM64? SIZEOF_64THING : - mapFormat == MF_HEXEN ? SIZEOF_XTHING : SIZEOF_THING); - reader = bufferLump(info); - loadThings(reader, numElements); - Reader_Delete(reader); - } - break; - - case ML_LIGHTS: - if(info->length) - { - numElements = info->length / SIZEOF_LIGHT; - reader = bufferLump(info); - loadSurfaceTints(reader, numElements); - Reader_Delete(reader); - } - break; - - case ML_MACROS: - /// @todo Write me! - break; - - default: break; - } - } - - // We're done with the read buffer. - clearReadBuffer(); - - return false; // Success. -} - -static void transferVertexes(void) -{ - LOG_TRACE("Transfering vertexes..."); - MPE_VertexCreatev(map->numVertexes, map->vertexes, NULL); -} - -static void transferSectors(void) -{ - LOG_TRACE("Transfering sectors..."); - - DENG2_FOR_EACH(i, map->sectors, Sectors::iterator) - { - uint idx = MPE_SectorCreate(float((i)->lightLevel) / 255.0f, 1, 1, 1); - - MPE_PlaneCreate(idx, (i)->floorHeight, findMaterialInDictionary((i)->floorMaterial), - 0, 0, 1, 1, 1, 1, 0, 0, 1); - MPE_PlaneCreate(idx, (i)->ceilHeight, findMaterialInDictionary((i)->ceilMaterial), - 0, 0, 1, 1, 1, 1, 0, 0, -1); - - MPE_GameObjProperty("XSector", idx-1, "Tag", DDVT_SHORT, &(i)->tag); - MPE_GameObjProperty("XSector", idx-1, "Type", DDVT_SHORT, &(i)->type); - - if(mapFormat == MF_DOOM64) - { - MPE_GameObjProperty("XSector", idx-1, "Flags", DDVT_SHORT, &(i)->d64flags); - MPE_GameObjProperty("XSector", idx-1, "CeilingColor", DDVT_SHORT, &(i)->d64ceilingColor); - MPE_GameObjProperty("XSector", idx-1, "FloorColor", DDVT_SHORT, &(i)->d64floorColor); - MPE_GameObjProperty("XSector", idx-1, "UnknownColor", DDVT_SHORT, &(i)->d64unknownColor); - MPE_GameObjProperty("XSector", idx-1, "WallTopColor", DDVT_SHORT, &(i)->d64wallTopColor); - MPE_GameObjProperty("XSector", idx-1, "WallBottomColor", DDVT_SHORT, &(i)->d64wallBottomColor); - } - } -} - -static void transferLinesAndSides(void) -{ - LOG_TRACE("Transfering lines and sides..."); - DENG2_FOR_EACH(i, map->lines, Lines::iterator) - { - uint frontIdx = 0; - mside_t* front = ((i)->sides[RIGHT] != 0? &map->sides[(i)->sides[RIGHT]-1] : NULL); - if(front) - { - frontIdx = - MPE_SidedefCreate((mapFormat == MF_DOOM64? SDF_MIDDLE_STRETCH : 0), - findMaterialInDictionary(front->topMaterial), - front->offset[VX], front->offset[VY], 1, 1, 1, - findMaterialInDictionary(front->middleMaterial), - front->offset[VX], front->offset[VY], 1, 1, 1, 1, - findMaterialInDictionary(front->bottomMaterial), - front->offset[VX], front->offset[VY], 1, 1, 1); - } - - uint backIdx = 0; - mside_t* back = ((i)->sides[LEFT] != 0? &map->sides[(i)->sides[LEFT]-1] : NULL); - if(back) - { - backIdx = - MPE_SidedefCreate((mapFormat == MF_DOOM64? SDF_MIDDLE_STRETCH : 0), - findMaterialInDictionary(back->topMaterial), - back->offset[VX], back->offset[VY], 1, 1, 1, - findMaterialInDictionary(back->middleMaterial), - back->offset[VX], back->offset[VY], 1, 1, 1, 1, - findMaterialInDictionary(back->bottomMaterial), - back->offset[VX], back->offset[VY], 1, 1, 1); - } - - uint lineIdx = MPE_LinedefCreate((i)->v[0], (i)->v[1], front? front->sector : 0, - back? back->sector : 0, frontIdx, backIdx, (i)->ddFlags); - - MPE_GameObjProperty("XLinedef", lineIdx-1, "Flags", DDVT_SHORT, &(i)->flags); - - switch(mapFormat) - { - default: - case MF_DOOM: - MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_SHORT, &(i)->dType); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Tag", DDVT_SHORT, &(i)->dTag); - break; - - case MF_DOOM64: - MPE_GameObjProperty("XLinedef", lineIdx-1, "DrawFlags", DDVT_BYTE, &(i)->d64drawFlags); - MPE_GameObjProperty("XLinedef", lineIdx-1, "TexFlags", DDVT_BYTE, &(i)->d64texFlags); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_BYTE, &(i)->d64type); - MPE_GameObjProperty("XLinedef", lineIdx-1, "UseType", DDVT_BYTE, &(i)->d64useType); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Tag", DDVT_SHORT, &(i)->d64tag); - break; - - case MF_HEXEN: - MPE_GameObjProperty("XLinedef", lineIdx-1, "Type", DDVT_BYTE, &(i)->xType); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg0", DDVT_BYTE, &(i)->xArgs[0]); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg1", DDVT_BYTE, &(i)->xArgs[1]); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg2", DDVT_BYTE, &(i)->xArgs[2]); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg3", DDVT_BYTE, &(i)->xArgs[3]); - MPE_GameObjProperty("XLinedef", lineIdx-1, "Arg4", DDVT_BYTE, &(i)->xArgs[4]); - break; - } - } -} - -static void transferSurfaceTints(void) -{ - if(map->surfaceTints.empty()) return; - - LOG_TRACE("Transfering surface tints..."); - DENG2_FOR_EACH(i, map->surfaceTints, SurfaceTints::iterator) - { - uint idx = i - map->surfaceTints.begin(); - - MPE_GameObjProperty("Light", idx, "ColorR", DDVT_FLOAT, &(i)->rgb[0]); - MPE_GameObjProperty("Light", idx, "ColorG", DDVT_FLOAT, &(i)->rgb[1]); - MPE_GameObjProperty("Light", idx, "ColorB", DDVT_FLOAT, &(i)->rgb[2]); - MPE_GameObjProperty("Light", idx, "XX0", DDVT_BYTE, &(i)->xx[0]); - MPE_GameObjProperty("Light", idx, "XX1", DDVT_BYTE, &(i)->xx[1]); - MPE_GameObjProperty("Light", idx, "XX2", DDVT_BYTE, &(i)->xx[2]); - } -} - -static void transferPolyobjs(void) -{ - if(map->polyobjs.empty()) return; - - LOG_TRACE("Transfering polyobjs..."); - DENG2_FOR_EACH(i, map->polyobjs, Polyobjs::iterator) - { - MPE_PolyobjCreate((i)->lineIndices, (i)->lineCount, (i)->tag, (i)->seqType, - coord_t((i)->anchor[VX]), coord_t((i)->anchor[VY])); - } -} - -static void transferThings(void) -{ - if(map->things.empty()) return; - - LOG_TRACE("Transfering things..."); - DENG2_FOR_EACH(i, map->things, Things::iterator) - { - uint idx = i - map->things.begin(); - - MPE_GameObjProperty("Thing", idx, "X", DDVT_SHORT, &(i)->origin[VX]); - MPE_GameObjProperty("Thing", idx, "Y", DDVT_SHORT, &(i)->origin[VY]); - MPE_GameObjProperty("Thing", idx, "Z", DDVT_SHORT, &(i)->origin[VZ]); - MPE_GameObjProperty("Thing", idx, "Angle", DDVT_ANGLE, &(i)->angle); - MPE_GameObjProperty("Thing", idx, "DoomEdNum", DDVT_SHORT, &(i)->doomEdNum); - MPE_GameObjProperty("Thing", idx, "SkillModes", DDVT_INT, &(i)->skillModes); - MPE_GameObjProperty("Thing", idx, "Flags", DDVT_INT, &(i)->flags); - - if(mapFormat == MF_DOOM64) - { - MPE_GameObjProperty("Thing", idx, "ID", DDVT_SHORT, &(i)->d64TID); - } - else if(mapFormat == MF_HEXEN) - { - MPE_GameObjProperty("Thing", idx, "Special", DDVT_BYTE, &(i)->xSpecial); - MPE_GameObjProperty("Thing", idx, "ID", DDVT_SHORT, &(i)->xTID); - MPE_GameObjProperty("Thing", idx, "Arg0", DDVT_BYTE, &(i)->xArgs[0]); - MPE_GameObjProperty("Thing", idx, "Arg1", DDVT_BYTE, &(i)->xArgs[1]); - MPE_GameObjProperty("Thing", idx, "Arg2", DDVT_BYTE, &(i)->xArgs[2]); - MPE_GameObjProperty("Thing", idx, "Arg3", DDVT_BYTE, &(i)->xArgs[3]); - MPE_GameObjProperty("Thing", idx, "Arg4", DDVT_BYTE, &(i)->xArgs[4]); - } - } -} - -int TransferMap(void) -{ - uint startTime = Sys_GetRealTime(); - - LOG_AS("WadMapConverter::TransferMap"); - - transferVertexes(); - transferSectors(); - transferLinesAndSides(); - transferSurfaceTints(); - transferPolyobjs(); - transferThings(); - - LOG_VERBOSE("Done in %.2f seconds.") << ((Sys_GetRealTime() - startTime) / 1000.0f); - - return false; // Success. -} diff --git a/doomsday/plugins/wadmapconverter/src/wadmapconverter.cpp b/doomsday/plugins/wadmapconverter/src/wadmapconverter.cpp index 979a19370d..daef3c16ea 100644 --- a/doomsday/plugins/wadmapconverter/src/wadmapconverter.cpp +++ b/doomsday/plugins/wadmapconverter/src/wadmapconverter.cpp @@ -242,7 +242,8 @@ int ConvertMapHook(int hookType, int parm, void* context) } // Read the archived map. - loadError = LoadMap(lumpInfos); + DENG_PLUGIN_GLOBAL(map) = new Id1Map; + loadError = DENG_PLUGIN_GLOBAL(map)->load(lumpInfos); if(loadError) { LOG_AS("WadMapConverter"); @@ -252,12 +253,13 @@ int ConvertMapHook(int hookType, int parm, void* context) } // Perform post read analyses. - AnalyzeMap(); + DENG_PLUGIN_GLOBAL(map)->analyze(); // Rebuild the map in Doomsday's native format. MPE_Begin(""); { - TransferMap(); + LOG_AS("WadMapConverter"); + DENG_PLUGIN_GLOBAL(map)->transfer(); // We have now finished with our local for-conversion map representation. delete DENG_PLUGIN_GLOBAL(map); diff --git a/doomsday/plugins/wadmapconverter/wadmapconverter.pro b/doomsday/plugins/wadmapconverter/wadmapconverter.pro index 560986ccb3..a6abb23cf7 100644 --- a/doomsday/plugins/wadmapconverter/wadmapconverter.pro +++ b/doomsday/plugins/wadmapconverter/wadmapconverter.pro @@ -18,6 +18,7 @@ deng_debug: DEFINES += DENG_WADMAPCONVERTER_DEBUG INCLUDEPATH += include HEADERS += \ + include/id1map.h \ include/id1map_datatypes.h \ include/id1map_load.h \ include/id1map_util.h \ @@ -26,6 +27,7 @@ HEADERS += \ include/wadmapconverter.h SOURCES += \ + src/id1map.cpp \ src/id1map_analyze.cpp \ src/id1map_load.cpp \ src/id1map_loadblockmap.cpp \