1 /* $Id: engine_sl.cpp 24810 2012-12-09 16:55:03Z frosch $ */
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file engine_sl.cpp Code handling saving and loading of engines */
12 #include "../stdafx.h"
13 #include "saveload_internal.h"
14 #include "../engine_base.h"
15 #include "../string_func.h"
18 #include "../safeguards.h"
20 static const SaveLoad _engine_desc
[] = {
21 SLE_CONDVAR(Engine
, intro_date
, SLE_FILE_U16
| SLE_VAR_I32
, 0, 30),
22 SLE_CONDVAR(Engine
, intro_date
, SLE_INT32
, 31, SL_MAX_VERSION
),
23 SLE_CONDVAR(Engine
, age
, SLE_FILE_U16
| SLE_VAR_I32
, 0, 30),
24 SLE_CONDVAR(Engine
, age
, SLE_INT32
, 31, SL_MAX_VERSION
),
25 SLE_VAR(Engine
, reliability
, SLE_UINT16
),
26 SLE_VAR(Engine
, reliability_spd_dec
, SLE_UINT16
),
27 SLE_VAR(Engine
, reliability_start
, SLE_UINT16
),
28 SLE_VAR(Engine
, reliability_max
, SLE_UINT16
),
29 SLE_VAR(Engine
, reliability_final
, SLE_UINT16
),
30 SLE_VAR(Engine
, duration_phase_1
, SLE_UINT16
),
31 SLE_VAR(Engine
, duration_phase_2
, SLE_UINT16
),
32 SLE_VAR(Engine
, duration_phase_3
, SLE_UINT16
),
34 SLE_CONDNULL(1, 0, 120),
35 SLE_VAR(Engine
, flags
, SLE_UINT8
),
36 SLE_CONDNULL(1, 0, 178), // old preview_company_rank
37 SLE_CONDVAR(Engine
, preview_asked
, SLE_UINT16
, 179, SL_MAX_VERSION
),
38 SLE_CONDVAR(Engine
, preview_company
, SLE_UINT8
, 179, SL_MAX_VERSION
),
39 SLE_VAR(Engine
, preview_wait
, SLE_UINT8
),
40 SLE_CONDNULL(1, 0, 44),
41 SLE_CONDVAR(Engine
, company_avail
, SLE_FILE_U8
| SLE_VAR_U16
, 0, 103),
42 SLE_CONDVAR(Engine
, company_avail
, SLE_UINT16
, 104, SL_MAX_VERSION
),
43 SLE_CONDVAR(Engine
, company_hidden
, SLE_UINT16
, 193, SL_PATCH_PACK
- 1),
44 SLE_CONDVAR(Engine
, company_hidden
, SLE_UINT16
, SL_PATCH_PACK_1_9
, SL_MAX_VERSION
),
45 SLE_CONDSTR(Engine
, name
, SLE_STR
, 0, 84, SL_MAX_VERSION
),
47 SLE_CONDNULL(16, 2, 143), // old reserved space
52 static std::vector
<Engine
*> _temp_engine
;
55 * Allocate an Engine structure, but not using the pools.
56 * The allocated Engine must be freed using FreeEngine;
57 * @return Allocated engine.
59 static Engine
* CallocEngine()
61 uint8
*zero
= CallocT
<uint8
>(sizeof(Engine
));
62 Engine
*engine
= new (zero
) Engine();
67 * Deallocate an Engine constructed by CallocEngine.
68 * @param e Engine to free.
70 static void FreeEngine(Engine
*e
)
78 Engine
*GetTempDataEngine(EngineID index
)
80 if (index
< _temp_engine
.size()) {
81 return _temp_engine
[index
];
82 } else if (index
== _temp_engine
.size()) {
83 _temp_engine
.push_back(CallocEngine());
84 return _temp_engine
[index
];
90 static void Save_ENGN()
94 SlSetArrayIndex(e
->index
);
95 SlObject(e
, _engine_desc
);
99 static void Load_ENGN()
101 /* As engine data is loaded before engines are initialized we need to load
102 * this information into a temporary array. This is then copied into the
103 * engine pool after processing NewGRFs by CopyTempEngineData(). */
105 while ((index
= SlIterateArray()) != -1) {
106 Engine
*e
= GetTempDataEngine(index
);
107 SlObject(e
, _engine_desc
);
109 if (IsSavegameVersionBefore(179)) {
110 /* preview_company_rank was replaced with preview_company and preview_asked.
111 * Just cancel any previews. */
112 e
->flags
&= ~4; // ENGINE_OFFER_WINDOW_OPEN
113 e
->preview_company
= INVALID_COMPANY
;
114 e
->preview_asked
= (CompanyMask
)-1;
120 * Copy data from temporary engine array into the real engine pool.
122 void CopyTempEngineData()
126 if (e
->index
>= _temp_engine
.size()) break;
128 const Engine
*se
= GetTempDataEngine(e
->index
);
129 e
->intro_date
= se
->intro_date
;
131 e
->reliability
= se
->reliability
;
132 e
->reliability_spd_dec
= se
->reliability_spd_dec
;
133 e
->reliability_start
= se
->reliability_start
;
134 e
->reliability_max
= se
->reliability_max
;
135 e
->reliability_final
= se
->reliability_final
;
136 e
->duration_phase_1
= se
->duration_phase_1
;
137 e
->duration_phase_2
= se
->duration_phase_2
;
138 e
->duration_phase_3
= se
->duration_phase_3
;
139 e
->flags
= se
->flags
;
140 e
->preview_asked
= se
->preview_asked
;
141 e
->preview_company
= se
->preview_company
;
142 e
->preview_wait
= se
->preview_wait
;
143 e
->company_avail
= se
->company_avail
;
144 e
->company_hidden
= se
->company_hidden
;
145 if (se
->name
!= NULL
) e
->name
= stredup(se
->name
);
148 /* Get rid of temporary data */
149 for (std::vector
<Engine
*>::iterator it
= _temp_engine
.begin(); it
!= _temp_engine
.end(); ++it
) {
152 _temp_engine
.clear();
155 static void Load_ENGS()
157 /* Load old separate String ID list into a temporary array. This
158 * was always 256 entries. */
161 SlArray(names
, lengthof(names
), SLE_STRINGID
);
163 /* Copy each string into the temporary engine array. */
164 for (EngineID engine
= 0; engine
< lengthof(names
); engine
++) {
165 Engine
*e
= GetTempDataEngine(engine
);
166 e
->name
= CopyFromOldName(names
[engine
]);
170 /** Save and load the mapping between the engine id in the pool, and the grf file it came from. */
171 static const SaveLoad _engine_id_mapping_desc
[] = {
172 SLE_VAR(EngineIDMapping
, grfid
, SLE_UINT32
),
173 SLE_VAR(EngineIDMapping
, internal_id
, SLE_UINT16
),
174 SLE_VAR(EngineIDMapping
, type
, SLE_UINT8
),
175 SLE_VAR(EngineIDMapping
, substitute_id
, SLE_UINT8
),
179 static void Save_EIDS()
181 const EngineIDMapping
*end
= _engine_mngr
.End();
183 for (EngineIDMapping
*eid
= _engine_mngr
.Begin(); eid
!= end
; eid
++, index
++) {
184 SlSetArrayIndex(index
);
185 SlObject(eid
, _engine_id_mapping_desc
);
189 static void Load_EIDS()
191 _engine_mngr
.Clear();
193 while (SlIterateArray() != -1) {
194 EngineIDMapping
*eid
= _engine_mngr
.Append();
195 SlObject(eid
, _engine_id_mapping_desc
);
199 extern const ChunkHandler _engine_chunk_handlers
[] = {
200 { 'EIDS', Save_EIDS
, Load_EIDS
, NULL
, NULL
, CH_ARRAY
},
201 { 'ENGN', Save_ENGN
, Load_ENGN
, NULL
, NULL
, CH_ARRAY
},
202 { 'ENGS', NULL
, Load_ENGS
, NULL
, NULL
, CH_RIFF
| CH_LAST
},