# map_sl.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD 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, version 2.
    00006  * OpenTTD 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.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "../stdafx.h"
    00013 #include "../map_func.h"
    00014 #include "../core/bitmath_func.hpp"
    00015 #include "../fios.h"
    00016 #include "../tile_map.h"
    00017
    00018 #include "saveload.h"
    00019
    00020 static uint32 _map_dim_x;
    00021 static uint32 _map_dim_y;
    00022
    00023 static const SaveLoadGlobVarList _map_dimensions[] = {
    00024   SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
    00025   SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
    00026       SLEG_END()
    00027 };
    00028
    00029 static void Save_MAPS()
    00030 {
    00031   _map_dim_x = MapSizeX();
    00032   _map_dim_y = MapSizeY();
    00033   SlGlobList(_map_dimensions);
    00034 }
    00035
    00036 static void Load_MAPS()
    00037 {
    00038   SlGlobList(_map_dimensions);
    00039   /* Don't construct _map_heightdata here, because we don't know wether
    00040    * we need it before Load_MAPH. */
    00041   AllocateMap(_map_dim_x, _map_dim_y, false);
    00042 }
    00043
    00044 static void Check_MAPS()
    00045 {
    00046   SlGlobList(_map_dimensions);
    00047   _load_check_data.map_size_x = _map_dim_x;
    00048   _load_check_data.map_size_y = _map_dim_y;
    00049 }
    00050
    00051 static const uint MAP_SL_BUF_SIZE = 4096;
    00052
    00053 static void Load_MAPT()
    00054 {
    00055   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00056   TileIndex size = MapSize();
    00057
    00058   for (TileIndex i = 0; i != size;) {
    00059     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00060     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
    00061   }
    00062 }
    00063
    00064 static void Save_MAPT()
    00065 {
    00066   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00067   TileIndex size = MapSize();
    00068
    00069   SlSetLength(size);
    00070   for (TileIndex i = 0; i != size;) {
    00071     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
    00072     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00073   }
    00074 }
    00075
    00076 static void Load_MAP1()
    00077 {
    00078   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00079   TileIndex size = MapSize();
    00080
    00081   for (TileIndex i = 0; i != size;) {
    00082     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00083     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
    00084   }
    00085 }
    00086
    00087 static void Save_MAP1()
    00088 {
    00089   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00090   TileIndex size = MapSize();
    00091
    00092   SlSetLength(size);
    00093   for (TileIndex i = 0; i != size;) {
    00094     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
    00095     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00096   }
    00097 }
    00098
    00099 static void Load_MAP2()
    00100 {
    00101   SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00102   TileIndex size = MapSize();
    00103
    00104   for (TileIndex i = 0; i != size;) {
    00105     SlArray(buf, MAP_SL_BUF_SIZE,
    00106       /* In those versions the m2 was 8 bits */
    00107       IsSavegameVersionBefore(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
    00108     );
    00109     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
    00110   }
    00111 }
    00112
    00113 static void Save_MAP2()
    00114 {
    00115   SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00116   TileIndex size = MapSize();
    00117
    00118   SlSetLength(size * sizeof(uint16));
    00119   for (TileIndex i = 0; i != size;) {
    00120     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
    00121     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
    00122   }
    00123 }
    00124
    00125 static void Load_MAP3()
    00126 {
    00127   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00128   TileIndex size = MapSize();
    00129
    00130   for (TileIndex i = 0; i != size;) {
    00131     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00132     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
    00133   }
    00134 }
    00135
    00136 static void Save_MAP3()
    00137 {
    00138   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00139   TileIndex size = MapSize();
    00140
    00141   SlSetLength(size);
    00142   for (TileIndex i = 0; i != size;) {
    00143     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
    00144     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00145   }
    00146 }
    00147
    00148 static void Load_MAP4()
    00149 {
    00150   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00151   TileIndex size = MapSize();
    00152
    00153   for (TileIndex i = 0; i != size;) {
    00154     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00155     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
    00156   }
    00157 }
    00158
    00159 static void Save_MAP4()
    00160 {
    00161   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00162   TileIndex size = MapSize();
    00163
    00164   SlSetLength(size);
    00165   for (TileIndex i = 0; i != size;) {
    00166     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
    00167     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00168   }
    00169 }
    00170
    00171 static void Load_MAP5()
    00172 {
    00173   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00174   TileIndex size = MapSize();
    00175
    00176   for (TileIndex i = 0; i != size;) {
    00177     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00178     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
    00179   }
    00180 }
    00181
    00182 static void Save_MAP5()
    00183 {
    00184   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00185   TileIndex size = MapSize();
    00186
    00187   SlSetLength(size);
    00188   for (TileIndex i = 0; i != size;) {
    00189     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
    00190     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00191   }
    00192 }
    00193
    00194 static void Load_MAP6()
    00195 {
    00196   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00197   TileIndex size = MapSize();
    00198
    00199   if (IsSavegameVersionBefore(42)) {
    00200     for (TileIndex i = 0; i != size;) {
    00201       /* 1024, otherwise we overflow on 64x64 maps! */
    00202       SlArray(buf, 1024, SLE_UINT8);
    00203       for (uint j = 0; j != 1024; j++) {
    00204         _m[i++].m6 = GB(buf[j], 0, 2);
    00205         _m[i++].m6 = GB(buf[j], 2, 2);
    00206         _m[i++].m6 = GB(buf[j], 4, 2);
    00207         _m[i++].m6 = GB(buf[j], 6, 2);
    00208       }
    00209     }
    00210   } else {
    00211     for (TileIndex i = 0; i != size;) {
    00212       SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00213       for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
    00214     }
    00215   }
    00216 }
    00217
    00218 static void Save_MAP6()
    00219 {
    00220   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00221   TileIndex size = MapSize();
    00222
    00223   SlSetLength(size);
    00224   for (TileIndex i = 0; i != size;) {
    00225     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
    00226     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00227   }
    00228 }
    00229
    00230 static void Load_MAP7()
    00231 {
    00232   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00233   TileIndex size = MapSize();
    00234
    00235   for (TileIndex i = 0; i != size;) {
    00236     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00237     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
    00238   }
    00239 }
    00240
    00241 static void Save_MAP7()
    00242 {
    00243   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00244   TileIndex size = MapSize();
    00245
    00246   SlSetLength(size);
    00247   for (TileIndex i = 0; i != size;) {
    00248     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
    00249     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00250   }
    00251 }
    00281 static void Load_MAPH()
    00282 {
    00283   /* Maybe it was still filled from the previous game. */
    00284   free(_map_heightdata);
    00285   /* Does free set it to NULL?  I don't know, so I better do it explicitely. */
    00286   _map_heightdata = NULL;
    00287   if (SlGetFieldLength() != 0) {
    00288     /* We didn't construct it before because we didn't know wether we need it
    00289      * before - see comment of AllocateMap for a detailed explanation. */
    00290     _map_heightdata = CallocT<TileHeightData>(MapSize());
    00291
    00292     SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00293     TileIndex size = MapSize();
    00294
    00295     for (TileIndex i = 0; i != size;) {
    00296       SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
    00297       for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) {
    00298       _map_heightdata[i++].heightlevel = buf[j];
    00299       }
    00300     }
    00301   }
    00302 }
    00303
    00304 static void Save_MAPH()
    00305 {
    00306   /* Assure that configuration setting is consistent to the data. */
    00307   assert(AllowMoreHeightlevels() == (_map_heightdata != NULL));
    00308
    00309   if (!AllowMoreHeightlevels()) {
    00310     SlSetLength(0);
    00311   } else {
    00312     SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00313     TileIndex size = MapSize();
    00314
    00315     SlSetLength(size * sizeof(uint16));
    00316     for (TileIndex i = 0; i != size;) {
    00317       for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _map_heightdata[i++].heightlevel;
    00318       SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
    00319     }
    00320   }
    00321 }
    00322
    00323 extern const ChunkHandler _map_chunk_handlers[] = {
    00324   { 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF },
    00325   { 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL,       CH_RIFF },
    00326   { 'MAPO', Save_MAP1, Load_MAP1, NULL, NULL,       CH_RIFF },
    00327   { 'MAP2', Save_MAP2, Load_MAP2, NULL, NULL,       CH_RIFF },
    00328   { 'M3LO', Save_MAP3, Load_MAP3, NULL, NULL,       CH_RIFF },
    00329   { 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL,       CH_RIFF },
    00330   { 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL,       CH_RIFF },
    00331   { 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL,       CH_RIFF },
    00332   { 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL,       CH_RIFF },
    00333   { 'MAPH', Save_MAPH, Load_MAPH, NULL, NULL,       CH_RIFF | CH_LAST },
    00334 };