00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028
00029 #if !defined __cplusplus
00030 #error C++ compiler required
00031 #endif
00032
00033
00034 #include <exception>
00035 #include <sstream>
00036 #include <stdexcept>
00037 #include <string>
00038
00039
00040 #include "global.hpp"
00041 #include "lump.hpp"
00042 #include "sectors.hpp"
00043 #include "wadentry.hpp"
00044
00045 using namespace Doomwad;
00046
00047 const size_t Sector::LENGTH = 0x0000001A;
00048 const std::string Sectors::NAME = "SECTORS";
00049
00050
00051 const std::string Sector::NOFLAT = "-";
00052
00053 const uint16 Sector::NORMAL = 0x0000;
00054
00055 const uint16 Sector::LIGHT_RANDOM = 0x0001;
00056 const uint16 Sector::LIGHT_BLINK_HALF = 0x0002;
00057 const uint16 Sector::LIGHT_BLINK_SEC = 0x0003;
00058 const uint16 Sector::LIGHT_BLINK_DAMAGE = 0x0004;
00059 const uint16 Sector::LIGHT_OSCILLATE = 0x0008;
00060 const uint16 Sector::LIGHT_BLINK_HALF_SYNC = 0x000C;
00061 const uint16 Sector::LIGHT_BLINK_SEC_SYNC = 0x000D;
00062 const uint16 Sector::LIGHT_FLICKER = 0x0011;
00063
00064 const uint16 Sector::DAMAGE_5 = 0x0020;
00065 const uint16 Sector::DAMAGE_10 = 0x0040;
00066 const uint16 Sector::DAMAGE_20 = 0x0060;
00067
00068 const uint16 Sector::SECRET = 0x0080;
00069 const uint16 Sector::FRICTION = 0x0100;
00070 const uint16 Sector::WIND = 0x0200;
00071 const uint16 Sector::NO_SOUND = 0x0400;
00072 const uint16 Sector::NO_MOTION_SOUND = 0x0800;
00073
00074 const uint16 Sector::INVALID = 0xFFFF;
00075
00076 const uint16 Sector::GENERALIZED_MASK = 0x01FF;
00077
00092 Sector::Sector (int16 _z_f, int16 _z_c, const std::string &_flat_f, const std::string &_flat_c, uint16 _light, uint16 _type, uint16 _tag) throw () : z_floor (_z_f), z_ceil (_z_c), flat_floor (_flat_f), flat_ceil (_flat_c), light (_light), type (_type), tag (_tag)
00093 {
00094 }
00095
00101 Sector::~Sector (void) throw ()
00102 {
00103 }
00104
00105 std::string Sector::toString (void) const throw ()
00106 {
00107 std::ostringstream str;
00108
00109 str << '(' << z_floor << ',' << z_ceil << ','
00110 << flat_floor << ',' << flat_ceil << ','
00111 << light << ',' << type << ',' << tag << ')';
00112
00113 return str.str ();
00114 }
00115
00116 size_t Sector::getLength (void) const throw ()
00117 {
00118 return LENGTH;
00119 }
00120
00121 bool Sector::write (Lump &lump, Lump::size_type i) const throw ()
00122 {
00123 try
00124 {
00125 lump.setInt16 (this->z_floor, i);
00126 lump.setInt16 (this->z_ceil, i + 2);
00127 lump.setDString (this->flat_floor, i + 4);
00128 lump.setDString (this->flat_ceil, i + 12);
00129 lump.setUInt16 (this->light, i + 20);
00130 lump.setUInt16 (this->type, i + 22);
00131 lump.setUInt16 (this->tag, i + 24);
00132 }
00133 catch (std::range_error &e)
00134 {
00135 return false;
00136 }
00137 return true;
00138 }
00139
00140 bool Sector::read (const Lump &lump, Lump::size_type i) throw ()
00141 {
00142 try
00143 {
00144 this->z_floor = lump.getInt16 (i);
00145 this->z_ceil = lump.getInt16 (i + 2);
00146 this->flat_floor = lump.getDString (i + 4);
00147 this->flat_ceil = lump.getDString (i + 12);
00148 this->light = lump.getUInt16 (i + 20);
00149 this->type = lump.getUInt16 (i + 22);
00150 this->tag = lump.getUInt16 (i + 24);
00151 }
00152 catch (std::range_error &e)
00153 {
00154 return false;
00155 }
00156 return true;
00157 }
00158
00165 uint16 Sector::makeGeneralized (uint16 flags) throw ()
00166 {
00167 uint16 low = flags & GENERALIZED_MASK;
00168
00169 if (flags > NO_MOTION_SOUND || low > LIGHT_FLICKER || (low > LIGHT_BLINK_DAMAGE && low < LIGHT_OSCILLATE) || (low > LIGHT_OSCILLATE && low < LIGHT_BLINK_HALF_SYNC) || (low > LIGHT_BLINK_SEC_SYNC && low < LIGHT_FLICKER))
00170 flags = INVALID;
00171
00172 return flags;
00173 }
00174
00178 Sectors::Sectors (void) throw ()
00179 {
00180 return;
00181 }
00182
00192 Sectors::Sectors (const Lump &lump) throw ()
00193 {
00194 this->setFromLump (lump);
00195 return;
00196 }
00197
00203 Sectors::~Sectors (void) throw ()
00204 {
00205 return;
00206 }
00207
00208 bool Sectors::setFromLump (const Lump &lump) throw ()
00209 {
00210 size_t q = lump.size ();
00211 if (q % Sector::LENGTH != 0) return false;
00212 Sector s;
00213 this->clear ();
00214 for (size_t i = 0; i < q; i += Sector::LENGTH)
00215 {
00216 s.read (lump, i);
00217 this->push_back (s);
00218 }
00219 return true;
00220 }
00221
00222 Lump Sectors::toLump (void) const throw ()
00223 {
00224 Lump lump (NAME, this->size () * Sector::LENGTH);
00225 const_iterator iter = this->begin ();
00226 for (size_t i = 0; iter != this->end (); i += Sector::LENGTH, ++iter)
00227 {
00228 iter->write (lump, i);
00229 }
00230 return lump;
00231 }
00232
00233 std::string Sectors::toString (void) const throw ()
00234 {
00235 std::ostringstream str;
00236 for (const_iterator iter = this->begin (); iter != this->end (); ++iter)
00237 str << iter->toString () << '\n';
00238 return str.str ();
00239 }