diff --git a/doomsday/client/include/def_main.h b/doomsday/client/include/def_main.h index e5f90d32a0..5701aa8986 100644 --- a/doomsday/client/include/def_main.h +++ b/doomsday/client/include/def_main.h @@ -3,7 +3,7 @@ * @ingroup defs * * @authors Copyright © 2003-2014 Jaakko Keränen - * @authors Copyright © 2006-2014 Daniel Swanson + * @authors Copyright © 2006-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -231,9 +231,9 @@ StringArray *Def_ListMobjTypeIDs(void); StringArray *Def_ListStateIDs(void); /** - * Returns @c true iff @a def is compatible with the specified context. + * Returns @c true iff @a decorDef is compatible with the specified context. */ -bool Def_IsAllowedDecoration(ded_decoration_t const *def, /*bool hasExternal,*/ bool isCustom); +bool Def_IsAllowedDecoration(de::Record const &decorDef, /*bool hasExternal,*/ bool isCustom); /** * Returns @c true iff @a def is compatible with the specified context. diff --git a/doomsday/client/include/r_util.h b/doomsday/client/include/r_util.h index d3dd1577fc..bec3760cf3 100644 --- a/doomsday/client/include/r_util.h +++ b/doomsday/client/include/r_util.h @@ -1,7 +1,7 @@ -/** @file r_util.h Refresh Utility Routines. +/** @file r_util.h Refresh Utility Routines. * * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2006-2013 Daniel Swanson + * @authors Copyright © 2006-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -42,7 +42,7 @@ struct LightRange LightRange(float _min = 0, float _max = 0) : min(_min), max(_max) {} LightRange(float const minMax[2]) : min(minMax[0]), max(minMax[1]) {} - LightRange(de::Vector2f const minMax) : min(minMax.x), max(minMax.y) {} + LightRange(de::Vector2f const &minMax) : min(minMax.x), max(minMax.y) {} LightRange(LightRange const &other) : min(other.min), max(other.max) {} /// Returns a textual representation of the lightlevels. diff --git a/doomsday/client/include/resource/materiallightdecoration.h b/doomsday/client/include/resource/materiallightdecoration.h index 8fd560cacc..ed746baba3 100644 --- a/doomsday/client/include/resource/materiallightdecoration.h +++ b/doomsday/client/include/resource/materiallightdecoration.h @@ -69,7 +69,6 @@ class MaterialLightDecoration : public Material::Decoration * Construct a new AnimationStage from the given @a stageDef. */ static AnimationStage *fromDef(de::Record const &stageDef); - static AnimationStage *fromDef(ded_decorlight_stage_t const &stageDef); de::String description() const; }; diff --git a/doomsday/client/src/def_main.cpp b/doomsday/client/src/def_main.cpp index 6744c08b4f..ab87595790 100644 --- a/doomsday/client/src/def_main.cpp +++ b/doomsday/client/src/def_main.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -829,22 +831,27 @@ static void generateMaterialDefs() #ifdef __CLIENT__ /// @todo $revise-texture-animation -static ded_decoration_t *tryFindDecoration(de::Uri const &uri, /*bool hasExternal,*/ bool isCustom) +static Record const *tryFindDecoration(de::Uri const &uri, /*bool hasExternal,*/ bool isCustom) { - for(int i = defs.decorations.size() - 1; i >= 0; i--) + if(!uri.isEmpty()) { - ded_decoration_t *def = &defs.decorations[i]; - if(def->material && *def->material == uri) + DictionaryValue::Elements const &decorationsByMaterial = defs.decorations.lookup("material").elements(); + for(auto const &pair : decorationsByMaterial) { - // Is this suitable? - if(Def_IsAllowedDecoration(def, /*hasExternal,*/ isCustom)) - return def; + Record const &decorDef = *pair.second->as().record(); + de::Uri const materialUri(decorDef.gets("material"), RC_NULL); + if(materialUri == uri) + { + // Is this suitable? + if(Def_IsAllowedDecoration(decorDef, /*hasExternal,*/ isCustom)) + return &decorDef; + } } } - return nullptr; // None found. + return nullptr; // Not found. } -static inline ded_decoration_t *tryFindDecorationForMaterial(Material const &mat) +static inline Record const *tryFindDecorationForMaterial(Material const &mat) { return tryFindDecoration(mat.manifest().composeUri(), mat.manifest().isCustom()); } @@ -867,9 +874,6 @@ static void redecorateMaterial(Material &material, Record const &def) { defn::MaterialDecoration decorDef(matDef.decoration(i)); - // Is this valid? (A zero number of stages signifies the last). - //if(!decorDef.stageCount()) break; - for(int k = 0; k < decorDef.stageCount(); ++k) { Record const &st = decorDef.stage(k); @@ -888,21 +892,12 @@ static void redecorateMaterial(Material &material, Record const &def) // Perhaps old style linked decoration definitions? /// @todo fixme: Need to factor in the decoration definitions for all animation frames. - if(ded_decoration_t *decorDef = tryFindDecorationForMaterial(material)) + if(Record const *definition = tryFindDecorationForMaterial(material)) { - for(int i = 0; i < DED_DECOR_NUM_LIGHTS; ++i) + defn::Decoration decorDef(*definition); + for(int i = 0; i < decorDef.lightCount(); ++i) { - ded_decorlight_t const &lightDef = decorDef->lights[i]; - - // Is this valid? (A zero-strength color signifies the last). - if(Vector3f(lightDef.stage.color) == Vector3f(0, 0, 0)) - break; - - // Translate the old style definition. - std::unique_ptr decor(new MaterialLightDecoration(lightDef.patternSkip, lightDef.patternOffset)); - std::unique_ptr tempStage(MaterialLightDecoration::AnimationStage::fromDef(lightDef.stage)); - decor->addStage(*tempStage); // makes a copy. - material.addDecoration(decor.release()); // takes ownership. + material.addDecoration(MaterialLightDecoration::fromDef(decorDef.light(i))); } } } @@ -1285,16 +1280,16 @@ void Def_Read() // Decorations. (Define textures). for(int i = 0; i < defs.decorations.size(); ++i) { - ded_decoration_t *dec = &defs.decorations[i]; - for(int k = 0; k < DED_DECOR_NUM_LIGHTS; ++k) + defn::Decoration decorDef(defs.decorations[i]); + for(int k = 0; k < decorDef.lightCount(); ++k) { - ded_decorlight_t *dl = &dec->lights[k]; - if(Vector3f(dl->stage.color) != Vector3f(0, 0, 0)) + Record const &st = defn::MaterialDecoration(decorDef.light(k)).stage(0); + if(Vector3f(st.geta("color")) != Vector3f(0, 0, 0)) { - if(dl->stage.up) defineLightmap(*dl->stage.up); - if(dl->stage.down) defineLightmap(*dl->stage.down); - if(dl->stage.sides) defineLightmap(*dl->stage.sides); - if(dl->stage.flare) defineFlaremap(*dl->stage.flare); + defineLightmap(de::Uri(st["lightmapUp"], RC_NULL)); + defineLightmap(de::Uri(st["lightmapDown"], RC_NULL)); + defineLightmap(de::Uri(st["lightmapSide"], RC_NULL)); + defineFlaremap(de::Uri(st["haloTexture"], RC_NULL)); } } } @@ -2042,11 +2037,11 @@ StringArray *Def_ListStateIDs() return array; } -bool Def_IsAllowedDecoration(ded_decoration_t const *def, /*bool hasExternal,*/ bool isCustom) +bool Def_IsAllowedDecoration(Record const &decorDef, /*bool hasExternal,*/ bool isCustom) { - //if(hasExternal) return (def->flags & DCRF_EXTERNAL) != 0; - if(!isCustom) return (def->flags & DCRF_NO_IWAD) == 0; - return (def->flags & DCRF_PWAD) != 0; + //if(hasExternal) return (decorDef.geti("flags") & DCRF_EXTERNAL) != 0; + if(!isCustom) return (decorDef.geti("flags") & DCRF_NO_IWAD) == 0; + return (decorDef.geti("flags") & DCRF_PWAD) != 0; } bool Def_IsAllowedReflection(ded_reflection_t const *def, /*bool hasExternal,*/ bool isCustom) diff --git a/doomsday/client/src/resource/materiallightdecoration.cpp b/doomsday/client/src/resource/materiallightdecoration.cpp index fa609facb9..41a652b6c2 100644 --- a/doomsday/client/src/resource/materiallightdecoration.cpp +++ b/doomsday/client/src/resource/materiallightdecoration.cpp @@ -1,6 +1,6 @@ /** @file materiallightdecoration.cpp Logical material, light decoration. * - * @authors Copyright © 2011-2014 Daniel Swanson + * @authors Copyright © 2011-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -95,41 +95,6 @@ MaterialLightDecoration::AnimationStage::fromDef(Record const &stageDef) haloTexture, haloTextureIndex); } -MaterialLightDecoration::AnimationStage * -MaterialLightDecoration::AnimationStage::fromDef(ded_decorlight_stage_t const &stageDef) -{ - Texture *lightmapUp = stageDef.up? resSys().texture("Lightmaps", *stageDef.up) : nullptr; - Texture *lightmapDown = stageDef.down? resSys().texture("Lightmaps", *stageDef.down) : nullptr; - Texture *lightmapSide = stageDef.sides? resSys().texture("Lightmaps", *stageDef.sides) : nullptr; - - int haloTextureIndex = stageDef.sysFlareIdx; - Texture *haloTexture = nullptr; - if(stageDef.flare && !stageDef.flare->isEmpty()) - { - DENG2_ASSERT(stageDef.flare); - de::Uri const &haloTextureUri = *stageDef.flare; - - // Select a system flare by numeric identifier? - if(haloTextureUri.path().length() == 1 && - haloTextureUri.path().toStringRef().first().isDigit()) - { - haloTextureIndex = haloTextureUri.path().toStringRef().first().digitValue(); - } - else - { - haloTexture = resSys().texture("Flaremaps", haloTextureUri); - } - } - - return new AnimationStage(stageDef.tics, stageDef.variance, - Vector2f(stageDef.pos), stageDef.elevation, - Vector3f(stageDef.color), stageDef.radius, - stageDef.haloRadius, - LightRange(stageDef.lightLevels), - lightmapUp, lightmapDown, lightmapSide, - haloTexture, haloTextureIndex); -} - String MaterialLightDecoration::AnimationStage::description() const { return String(_E(l) "Tics: ") + _E(.) + (tics > 0? String("%1 (~%2)").arg(tics).arg(variance, 0, 'g', 2) : "-1") diff --git a/doomsday/libdoomsday/include/doomsday/defs/decoration.h b/doomsday/libdoomsday/include/doomsday/defs/decoration.h new file mode 100644 index 0000000000..24dce410f6 --- /dev/null +++ b/doomsday/libdoomsday/include/doomsday/defs/decoration.h @@ -0,0 +1,56 @@ +/** @file decoration.h Decoration definition accessor. + * + * @authors Copyright © 2015 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, see: + * http://www.gnu.org/licenses + */ + +#ifndef LIBDOOMSDAY_DEFN_DECORATION_H +#define LIBDOOMSDAY_DEFN_DECORATION_H + +#include "definition.h" +#include + +// Flags for decoration definitions. +#define DCRF_NO_IWAD 0x1 ///< Don't use if from IWAD. +#define DCRF_PWAD 0x2 ///< Can use if from PWAD. +#define DCRF_EXTERNAL 0x4 ///< Can use if from external resource. + +namespace defn { + +/** + * Utility for handling oldschool decoration definitions. + */ +class LIBDOOMSDAY_PUBLIC Decoration : public Definition +{ +public: + Decoration() : Definition() {} + Decoration(Decoration const &other) : Definition(other) {} + Decoration(de::Record &d) : Definition(d) {} + Decoration(de::Record const &d) : Definition(d) {} + + void resetToDefaults(); + + int lightCount() const; + bool hasLight(int index) const; + + de::Record &light(int index); + de::Record const &light(int index) const; + + de::Record &addLight(); +}; + +} // namespace defn + +#endif // LIBDOOMSDAY_DEFN_DECORATION_H diff --git a/doomsday/libdoomsday/include/doomsday/defs/ded.h b/doomsday/libdoomsday/include/doomsday/defs/ded.h index a62faa3ece..64b29f1e03 100644 --- a/doomsday/libdoomsday/include/doomsday/defs/ded.h +++ b/doomsday/libdoomsday/include/doomsday/defs/ded.h @@ -1,7 +1,7 @@ -/** @file defs/ded.h Definition namespace. +/** @file ded.h Definition namespace. * * @authors Copyright © 2003-2014 Jaakko Keränen - * @authors Copyright © 2006-2014 Daniel Swanson + * @authors Copyright © 2006-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -104,11 +104,10 @@ struct LIBDOOMSDAY_PUBLIC ded_s DEDArray ptcGens; // Finales. - //DEDArray finales; DEDRegister finales; // Decorations. - DEDArray decorations; + DEDRegister decorations; // Reflections. DEDArray reflections; diff --git a/doomsday/libdoomsday/include/doomsday/defs/dedtypes.h b/doomsday/libdoomsday/include/doomsday/defs/dedtypes.h index cf7a95553d..48808b4100 100644 --- a/doomsday/libdoomsday/include/doomsday/defs/dedtypes.h +++ b/doomsday/libdoomsday/include/doomsday/defs/dedtypes.h @@ -1,7 +1,7 @@ -/** @file defs/dedtypes.h Definition types and structures (DED v1). +/** @file dedtypes.h Definition types and structures (DED v1). * * @authors Copyright © 2003-2014 Jaakko Keränen - * @authors Copyright © 2006-2014 Daniel Swanson + * @authors Copyright © 2006-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -30,23 +30,22 @@ #include "api_gl.h" #include "dedarray.h" -#define DED_DUP_URI(u) u = (u? new de::Uri(*u) : 0) +#define DED_DUP_URI(u) u = (u? new de::Uri(*u) : 0) -#define DED_SPRITEID_LEN 4 -#define DED_STRINGID_LEN 31 -#define DED_FUNC_LEN 255 +#define DED_SPRITEID_LEN 4 +#define DED_STRINGID_LEN 31 +#define DED_FUNC_LEN 255 -#define DED_MAX_MATERIAL_LAYERS 1 ///< Maximum number of material layers. -#define DED_MAX_MATERIAL_DECORATIONS 16 ///< Maximum number of material (light) decorations. +#define DED_MAX_MATERIAL_LAYERS 1 ///< Maximum number of material layers (map renderer limitations). +#define DED_MAX_MATERIAL_DECORATIONS 16 ///< Maximum number of material decorations (arbitrary). -#define DED_PTCGEN_ANY_MOBJ_TYPE -2 ///< Particle generator applies to ANY mobj type. +#define DED_PTCGEN_ANY_MOBJ_TYPE -2 ///< Particle generator applies to ANY mobj type. typedef char ded_stringid_t[DED_STRINGID_LEN + 1]; typedef ded_stringid_t ded_string_t; typedef ded_stringid_t ded_mobjid_t; typedef ded_stringid_t ded_stateid_t; typedef ded_stringid_t ded_soundid_t; -//typedef ded_stringid_t ded_musicid_t; typedef ded_stringid_t ded_funcid_t; typedef char ded_func_t[DED_FUNC_LEN + 1]; typedef int ded_flags_t; @@ -197,119 +196,6 @@ typedef struct LIBDOOMSDAY_PUBLIC ded_light_s { } } ded_light_t; -#if 0 -struct LIBDOOMSDAY_PUBLIC ded_submodel_t -{ - de::Uri* filename; - de::Uri* skinFilename; // Optional; override model's skin. - ded_string_t frame; - int frameRange; - ded_flags_t flags; // ASCII string of the flags. - int skin; - int skinRange; - de::Vector3f offset; // Offset XYZ within model. - float alpha; - float parm; // Custom parameter. - unsigned char selSkinBits[2]; // Mask and offset. - unsigned char selSkins[8]; - de::Uri* shinySkin; - float shiny; - de::Vector3f shinyColor; - float shinyReact; - blendmode_t blendMode; // bm_* - - ded_submodel_t() - : filename(0) - , skinFilename(0) - , frameRange(0) - , flags(0) - , skin(0) - , skinRange(0) - , alpha(0) - , parm(0) - , shinySkin(0) - , shiny(0) - , shinyColor(1, 1, 1) - , shinyReact(1.0f) - , blendMode(BM_NORMAL) - { - de::zap(frame); - de::zap(selSkinBits); - de::zap(selSkins); - } -}; - -struct LIBDOOMSDAY_PUBLIC ded_model_t -{ - ded_stringid_t id; // Optional identifier for the definition. - ded_stateid_t state; - int off; - ded_sprid_t sprite; // Only used by autoscale. - int spriteFrame; // Only used by autoscale. - ded_flags_t group; - int selector; - ded_flags_t flags; - float interMark; - float interRange[2]; // 0-1 by default. - int skinTics; // Tics per skin in range. - de::Vector3f scale; // Scale XYZ - float resize; - de::Vector3f offset; // Offset XYZ - float shadowRadius; // Radius for shadow (0=auto). - - typedef std::vector Submodels; - Submodels _sub; - - ded_model_t(char const *spriteId = "") - : off(0) - , spriteFrame(0) - , group(0) - , selector(0) - , flags(0) - , interMark(0) - , skinTics(0) - , scale(1, 1, 1) - , resize(0) - , shadowRadius(0) - { - de::zap(id); - de::zap(state); - de::zap(sprite); - de::zap(interRange); - - strcpy(sprite.id, spriteId); - interRange[1] = 1; - } - - bool hasSub(unsigned int subnum) const - { - return subnum < _sub.size(); - } - - unsigned int subCount() const - { - return _sub.size(); - } - - ded_submodel_t &sub(unsigned int subnum) - { - DENG2_ASSERT(hasSub(subnum)); - return _sub[subnum]; - } - - ded_submodel_t const &sub(unsigned int subnum) const - { - DENG2_ASSERT(hasSub(subnum)); - return _sub[subnum]; - } - - void appendSub() - { - _sub.push_back(ded_submodel_t()); - } -}; -#endif - typedef struct LIBDOOMSDAY_PUBLIC ded_sound_s { ded_soundid_t id; // ID of this sound, refered to by others. ded_string_t name; // A tag name for the sound. @@ -331,111 +217,6 @@ typedef struct LIBDOOMSDAY_PUBLIC ded_sound_s { } } ded_sound_t; -#if 0 -typedef struct LIBDOOMSDAY_PUBLIC ded_music_s { - ded_musicid_t id; // ID of this piece of music. - ded_string_t lumpName; // Lump name. - de::Uri* path; // External file (not a normal MUS file). - int cdTrack; // 0 = no track. - - void release() { - delete path; - } - void reallocate() { - DED_DUP_URI(path); - } -} ded_music_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_skylayer_s { - ded_flags_t flags; - de::Uri* material; - float offset; - float colorLimit; - - void release() { - delete material; - } - void reallocate() { - DED_DUP_URI(material); - } -} ded_skylayer_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_skymodel_s { - ded_stringid_t id; - int layer; // Defaults to -1. - float frameInterval; // Seconds per frame. - float yaw; - float yawSpeed; // Angles per second. - float coordFactor[3]; - float rotate[2]; - ded_anystring_t execute; // Executed on every frame change. - float color[4]; // RGBA - - void release() { - M_Free(execute); - } - void reallocate() { - execute = M_StrDup(execute); - } -} ded_skymodel_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_sky_s { - ded_stringid_t id; - ded_flags_t flags; // Flags. - float height; - float horizonOffset; - float color[3]; // Color of sky-lit sectors. - ded_skylayer_t layers[NUM_SKY_LAYERS]; - ded_skymodel_t models[NUM_SKY_MODELS]; - - void release() { - for(int i = 0; i < NUM_SKY_LAYERS; ++i) { - layers[i].release(); - } - for(int i = 0; i < NUM_SKY_MODELS; ++i) { - models[i].release(); - } - } - void reallocate() { - for(int i = 0; i < NUM_SKY_LAYERS; ++i) { - layers[i].reallocate(); - } - for(int i = 0; i < NUM_SKY_MODELS; ++i) { - models[i].reallocate(); - } - } -} ded_sky_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_mapinfo_s { - de::Uri* uri; // ID of the map (e.g. E2M3 or MAP21). - ded_string_t name; // Name of the map. - ded_string_t author; // Author of the map. - ded_flags_t flags; // Flags. - ded_musicid_t music; // Music to play. - float parTime; // Par time, in seconds. - float fogColor[3]; // Fog color (RGB). - float fogStart; - float fogEnd; - float fogDensity; - float ambient; // Ambient light level. - float gravity; // 1 = normal. - ded_stringid_t skyID; // ID of the sky definition to use with this map. If not set, use the sky data in the mapinfo. - ded_sky_t sky; - ded_anystring_t execute; // Executed during map setup (savegames, too). - - void release() { - delete uri; - delete execute; - sky.release(); - } - void reallocate() { - DED_DUP_URI(uri); - execute = M_StrDup(execute); - sky.reallocate(); - } -} ded_mapinfo_t; -#endif - struct ded_text_t { ded_stringid_t id; @@ -470,21 +251,6 @@ typedef struct { } } ded_value_t; -#if 0 -typedef struct { - ded_stringid_t id; - de::Uri* before; - de::Uri* after; - char* script; - - void release() { - delete before; - delete after; - M_Free(script); - } -} ded_finale_t; -#endif - typedef struct LIBDOOMSDAY_PUBLIC ded_linetype_s { int id; char comment[64]; @@ -495,7 +261,6 @@ typedef struct LIBDOOMSDAY_PUBLIC ded_linetype_s { float actTime; int actTag; int aparm[9]; - //ded_stringid_t aparm_str[3]; // aparms 4, 6, 9 ded_stringid_t aparm9; float tickerStart; float tickerEnd; @@ -717,161 +482,6 @@ typedef struct LIBDOOMSDAY_PUBLIC ded_group_s { } } ded_group_t; -#if 0 -typedef struct LIBDOOMSDAY_PUBLIC ded_material_layer_stage_s { - de::Uri* texture; - int tics; - float variance; // Stage variance (time). - float glowStrength; - float glowStrengthVariance; - float texOrigin[2]; - - void release() { - delete texture; - } - void reallocate() { - DED_DUP_URI(texture); - } -} ded_material_layer_stage_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_material_layer_s { - DEDArray stages; - - void release() { - stages.clear(); - } - void reallocate() { - stages.reallocate(); - } - int addStage() { - ded_material_layer_stage_t *stage = stages.append(); - return stages.indexOf(stage); - } -} ded_material_layer_t; -#endif - -typedef struct LIBDOOMSDAY_PUBLIC ded_decorlight_stage_s { - int tics; - float variance; // Stage variance (time). - float pos[2]; // Coordinates on the surface. - float elevation; // Distance from the surface. - float color[3]; // Light color. - float radius; // Dynamic light radius (-1 = no light). - float haloRadius; // Halo radius (zero = no halo). - float lightLevels[2]; // Fade by sector lightlevel. - int sysFlareIdx; - de::Uri *up, *down, *sides; - de::Uri *flare; // Overrides sysFlareIdx - - void release() { - delete up; - delete down; - delete sides; - delete flare; - } - void reallocate() { - DED_DUP_URI(up); - DED_DUP_URI(down); - DED_DUP_URI(sides); - DED_DUP_URI(flare); - } -} ded_decorlight_stage_t; - -#if 0 -typedef struct LIBDOOMSDAY_PUBLIC ded_material_lightdecoration_s { - int patternOffset[2]; - int patternSkip[2]; - DEDArray stages; - - void release() { - stages.clear(); - } - void reallocate() { - stages.reallocate(); - } - int addStage() { - ded_decorlight_stage_t *stage = stages.append(); - - // The color (0,0,0) means the light is not visible during this stage. - stage->elevation = 1; - stage->radius = 1; - - return stages.indexOf(stage); - } -} ded_material_lightdecoration_t; - -typedef struct LIBDOOMSDAY_PUBLIC ded_material_s { - de::Uri *uri; - dd_bool autoGenerated; - ded_flags_t flags; - int width; - int height; // In world units. - ded_material_layer_t layers[DED_MAX_MATERIAL_LAYERS]; - ded_material_lightdecoration_t decorations[DED_MAX_MATERIAL_DECORATIONS]; - - void release() { - delete uri; - for(int i = 0; i < DED_MAX_MATERIAL_LAYERS; ++i) { - layers[i].release(); - } - for(int i = 0; i < DED_MAX_MATERIAL_DECORATIONS; ++i) { - decorations[i].release(); - } - } - void reallocate() { - DED_DUP_URI(uri); - for(int i = 0; i < DED_MAX_MATERIAL_LAYERS; ++i) { - layers[i].reallocate(); - } - for(int i = 0; i < DED_MAX_MATERIAL_DECORATIONS; ++i) { - decorations[i].reallocate(); - } - } -} ded_material_t; -#endif - -// An oldschool material-linked decoration definition. -typedef struct LIBDOOMSDAY_PUBLIC ded_decorlight_s { - int patternOffset[2]; - int patternSkip[2]; - // There is only one stage. - ded_decorlight_stage_t stage; - - void release() { - stage.release(); - } - void reallocate() { - stage.reallocate(); - } -} ded_decorlight_t; - -// There is a fixed number of light decorations in each decoration. -#define DED_DECOR_NUM_LIGHTS 16 - -// Flags for decoration definitions. -#define DCRF_NO_IWAD 0x1 // Don't use if from IWAD. -#define DCRF_PWAD 0x2 // Can use if from PWAD. -#define DCRF_EXTERNAL 0x4 // Can use if from external resource. - -typedef struct LIBDOOMSDAY_PUBLIC ded_decoration_s { - de::Uri *material; - ded_flags_t flags; - ded_decorlight_t lights[DED_DECOR_NUM_LIGHTS]; - - void release() { - delete material; - for(int i = 0; i < DED_DECOR_NUM_LIGHTS; ++i) { - lights[i].release(); - } - } - void reallocate() { - DED_DUP_URI(material); - for(int i = 0; i < DED_DECOR_NUM_LIGHTS; ++i) { - lights[i].reallocate(); - } - } -} ded_decoration_t; - typedef struct LIBDOOMSDAY_PUBLIC ded_compositefont_mappedcharacter_s { unsigned char ch; de::Uri* path; @@ -894,4 +504,4 @@ typedef struct LIBDOOMSDAY_PUBLIC ded_compositefont_s { } } ded_compositefont_t; -#endif // LIBDOOMSDAY_DEFINITION_TYPES_H +#endif // LIBDOOMSDAY_DEFINITION_TYPES_H diff --git a/doomsday/libdoomsday/include/doomsday/defs/material.h b/doomsday/libdoomsday/include/doomsday/defs/material.h index 9d09410771..0a1296969e 100644 --- a/doomsday/libdoomsday/include/doomsday/defs/material.h +++ b/doomsday/libdoomsday/include/doomsday/defs/material.h @@ -1,6 +1,6 @@ /** @file material.h Material definition accessor. * - * @authors Copyright © 2014 Daniel Swanson + * @authors Copyright © 2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -20,8 +20,6 @@ #define LIBDOOMSDAY_DEFN_MATERIAL_H #include "definition.h" - -#include #include namespace defn { diff --git a/doomsday/libdoomsday/libdoomsday.pro b/doomsday/libdoomsday/libdoomsday.pro index 6773b63832..dfd475f19d 100644 --- a/doomsday/libdoomsday/libdoomsday.pro +++ b/doomsday/libdoomsday/libdoomsday.pro @@ -64,6 +64,7 @@ HEADERS += \ include/doomsday/console/exec.h \ include/doomsday/console/knownword.h \ include/doomsday/console/var.h \ + include/doomsday/defs/decoration.h \ include/doomsday/defs/ded.h \ include/doomsday/defs/dedarray.h \ include/doomsday/defs/dedfile.h \ @@ -114,6 +115,7 @@ SOURCES += \ src/console/exec.cpp \ src/console/knownword.cpp \ src/console/var.cpp \ + src/defs/decoration.cpp \ src/defs/ded.cpp \ src/defs/dedfile.cpp \ src/defs/definition.cpp \ diff --git a/doomsday/libdoomsday/src/defs/decoration.cpp b/doomsday/libdoomsday/src/defs/decoration.cpp new file mode 100644 index 0000000000..4735ad5cba --- /dev/null +++ b/doomsday/libdoomsday/src/defs/decoration.cpp @@ -0,0 +1,68 @@ +/** @file decoration.cpp Decoration definition accessor. + * + * @authors Copyright © 2015 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, see: + * http://www.gnu.org/licenses + */ + +#include "doomsday/defs/decoration.h" + +#include +#include +#include "doomsday/defs/ded.h" +#include "doomsday/defs/material.h" + +using namespace de; + +namespace defn { + +void Decoration::resetToDefaults() +{ + Definition::resetToDefaults(); + + // Add all expected fields with their default values. + def().addText ("material", ""); // URI. Unknown. + def().addNumber("flags", 0); + def().addArray ("light", new ArrayValue); +} + +Record &Decoration::addLight() +{ + auto *decor = new Record; + MaterialDecoration(*decor).resetToDefaults(); + def()["light"].value().add(new RecordValue(decor, RecordValue::OwnsRecord)); + return *decor; +} + +int Decoration::lightCount() const +{ + return int(geta("light").size()); +} + +bool Decoration::hasLight(int index) const +{ + return index >= 0 && index < lightCount(); +} + +Record &Decoration::light(int index) +{ + return *def().geta("light")[index].as().record(); +} + +Record const &Decoration::light(int index) const +{ + return *geta("light")[index].as().record(); +} + +} // namespace defn diff --git a/doomsday/libdoomsday/src/defs/ded.cpp b/doomsday/libdoomsday/src/defs/ded.cpp index 8ad1406782..80f75cdf48 100644 --- a/doomsday/libdoomsday/src/defs/ded.cpp +++ b/doomsday/libdoomsday/src/defs/ded.cpp @@ -1,7 +1,7 @@ -/** @file database.cpp Doomsday Engine Definition database. +/** @file ded.cpp Doomsday Engine Definition database. * * @authors Copyright © 2003-2014 Jaakko Keränen - * @authors Copyright © 2006-2014 Daniel Swanson + * @authors Copyright © 2006-2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -28,6 +28,7 @@ #include #include +#include "doomsday/defs/decoration.h" #include "doomsday/defs/episode.h" #include "doomsday/defs/finale.h" #include "doomsday/defs/mapinfo.h" @@ -53,20 +54,22 @@ float ded_ptcstage_t::particleRadius(int ptcIDX) const } ded_s::ded_s() - : flags (names.addRecord("flags")) - , episodes (names.addRecord("episodes")) - , materials(names.addRecord("materials")) - , models (names.addRecord("models")) - , skies (names.addRecord("skies")) - , musics (names.addRecord("musics")) - , mapInfos (names.addRecord("mapInfos")) - , finales (names.addRecord("finales")) -{ - flags.addLookupKey("id"); + : flags (names.addRecord("flags")) + , episodes (names.addRecord("episodes")) + , materials (names.addRecord("materials")) + , models (names.addRecord("models")) + , skies (names.addRecord("skies")) + , musics (names.addRecord("musics")) + , mapInfos (names.addRecord("mapInfos")) + , finales (names.addRecord("finales")) + , decorations(names.addRecord("decorations")) +{ + decorations.addLookupKey("material"); episodes.addLookupKey("id"); finales.addLookupKey("id"); finales.addLookupKey("before"); finales.addLookupKey("after"); + flags.addLookupKey("id"); mapInfos.addLookupKey("id"); materials.addLookupKey("id"); models.addLookupKey("id", DEDRegister::OnlyFirst); @@ -104,14 +107,9 @@ int ded_s::addEpisode() int ded_s::addDecoration() { - ded_decoration_t *decor = decorations.append(); - for(int i = 0; i < DED_DECOR_NUM_LIGHTS; ++i) - { - // The color (0,0,0) means the light is not active. - decor->lights[i].stage.elevation = 1; - decor->lights[i].stage.radius = 1; - } - return decorations.indexOf(decor); + Record &def = decorations.append(); + defn::Decoration(def).resetToDefaults(); + return def.geti("__order__"); } int ded_s::addFinale() diff --git a/doomsday/libdoomsday/src/defs/dedparser.cpp b/doomsday/libdoomsday/src/defs/dedparser.cpp index e1845fd838..ec0518a0aa 100644 --- a/doomsday/libdoomsday/src/defs/dedparser.cpp +++ b/doomsday/libdoomsday/src/defs/dedparser.cpp @@ -36,6 +36,21 @@ #define DENG_NO_API_MACROS_URI #include "doomsday/defs/dedparser.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "doomsday/defs/decoration.h" #include "doomsday/defs/ded.h" #include "doomsday/defs/dedfile.h" #include "doomsday/defs/episode.h" @@ -52,19 +67,6 @@ #include "doomsday/uri.h" #include "xgclass.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - #ifdef WIN32 # define stricmp _stricmp #endif @@ -2605,77 +2607,82 @@ DENG2_PIMPL(DEDParser) if(ISTOKEN("Decoration")) { idx = ded->addDecoration(); - ded_decoration_t *decor = &ded->decorations[idx]; + Record &decor = ded->decorations[idx]; // Should we copy the previous definition? if(prevDecorDefIdx >= 0 && bCopyNext) { - ded->decorations.copyTo(decor, prevDecorDefIdx); + ded->decorations.copy(prevDecorDefIdx, decor); } - uint sub = 0; + defn::Decoration mainDef(decor); + int light = 0; FINDBEGIN; - for(;;) + forever { READLABEL; - RV_FLAGS("Flags", decor->flags, "dcf_") + RV_FLAGS("Flags", decor["flags"], "dcf_") if(ISLABEL("Material")) { - READURI(&decor->material, 0) + READURI(decor["material"], 0) } else if(ISLABEL("Texture")) { - READURI(&decor->material, "Textures") + READURI(decor["material"], "Textures") } else if(ISLABEL("Flat")) { - READURI(&decor->material, "Flats") + READURI(decor["material"], "Flats") } else if(ISLABEL("Light")) { - if(sub == DED_DECOR_NUM_LIGHTS) + if(light == DED_MAX_MATERIAL_DECORATIONS) { - setError("Too many lights in decoration"); + setError("Too many Decoration.Lights"); retVal = false; goto ded_end_read; } - ded_decorlight_t *dl = &decor->lights[sub]; + // Add another light. + if(light >= mainDef.lightCount()) mainDef.addLight(); + defn::MaterialDecoration lightDef(mainDef.light(light)); + + // One implicit stage. + Record &st = lightDef.addStage(); FINDBEGIN; - for(;;) + forever { READLABEL; - RV_VEC("Offset", dl->stage.pos, 2) - RV_FLT("Distance", dl->stage.elevation) - RV_VEC("Color", dl->stage.color, 3) - RV_FLT("Radius", dl->stage.radius) - RV_FLT("Halo radius", dl->stage.haloRadius) - RV_IVEC("Pattern offset", dl->patternOffset, 2) - RV_IVEC("Pattern skip", dl->patternSkip, 2) + RV_VEC_VAR("Offset", st["origin"], 2) + RV_FLT("Distance", st["elevation"]) + RV_VEC_VAR("Color", st["color"], 3) + RV_FLT("Radius", st["radius"]) + RV_FLT("Halo radius", st["haloRadius"]) + RV_VEC_VAR("Pattern offset", lightDef.def()["patternOffset"], 2) + RV_VEC_VAR("Pattern skip", lightDef.def()["patternSkip"], 2) if(ISLABEL("Levels")) { FINDBEGIN; + Vector2f levels; for(int b = 0; b < 2; ++b) { - READFLT(dl->stage.lightLevels[b]) - dl->stage.lightLevels[b] /= 255.0f; - if(dl->stage.lightLevels[b] < 0) - dl->stage.lightLevels[b] = 0; - else if(dl->stage.lightLevels[b] > 1) - dl->stage.lightLevels[b] = 1; + float val; + READFLT(val) + levels[b] = de::clamp(0.f, val / 255.0f, 1.f); } ReadToken(); + st["lightLevels"] = new ArrayValue(levels); } else - RV_INT("Flare texture", dl->stage.sysFlareIdx) - RV_URI("Flare map", &dl->stage.flare, "LightMaps") - RV_URI("Top map", &dl->stage.up, "LightMaps") - RV_URI("Bottom map", &dl->stage.down, "LightMaps") - RV_URI("Side map", &dl->stage.sides, "LightMaps") + RV_INT("Flare texture", st["haloTextureIndex"]) + RV_URI("Flare map", st["haloTexture"], "LightMaps") + RV_URI("Top map", st["lightmapUp"], "LightMaps") + RV_URI("Bottom map", st["lightmapDown"], "LightMaps") + RV_URI("Side map", st["lightmapSide"], "LightMaps") RV_END CHECKSC; } - sub++; + light++; } else RV_END CHECKSC; diff --git a/doomsday/libdoomsday/src/defs/material.cpp b/doomsday/libdoomsday/src/defs/material.cpp index ce2074c492..78b5405f0f 100644 --- a/doomsday/libdoomsday/src/defs/material.cpp +++ b/doomsday/libdoomsday/src/defs/material.cpp @@ -1,6 +1,6 @@ /** @file material.cpp Material definition accessor. * - * @authors Copyright © 2014 Daniel Swanson + * @authors Copyright © 2015 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -82,6 +82,8 @@ Record const &MaterialDecoration::stage(int index) const return *geta("stage")[index].as().record(); } +// ------------------------------------------------------------------------------------ + void MaterialLayer::resetToDefaults() { Definition::resetToDefaults(); @@ -127,6 +129,8 @@ Record const &MaterialLayer::stage(int index) const return *geta("stage")[index].as().record(); } +// ------------------------------------------------------------------------------------ + void Material::resetToDefaults() { Definition::resetToDefaults();