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_MAX_VERSION
),
44 SLE_CONDSTR(Engine
, name
, SLE_STR
, 0, 84, SL_MAX_VERSION
),
46 SLE_CONDNULL(16, 2, 143), // old reserved space
51 static std::vector
<Engine
*> _temp_engine
;
54 * Allocate an Engine structure, but not using the pools.
55 * The allocated Engine must be freed using FreeEngine;
56 * @return Allocated engine.
58 static Engine
* CallocEngine()
60 uint8
*zero
= CallocT
<uint8
>(sizeof(Engine
));
61 Engine
*engine
= new (zero
) Engine();
66 * Deallocate an Engine constructed by CallocEngine.
67 * @param e Engine to free.
69 static void FreeEngine(Engine
*e
)
77 Engine
*GetTempDataEngine(EngineID index
)
79 if (index
< _temp_engine
.size()) {
80 return _temp_engine
[index
];
81 } else if (index
== _temp_engine
.size()) {
82 _temp_engine
.push_back(CallocEngine());
83 return _temp_engine
[index
];
89 static void Save_ENGN()
93 SlSetArrayIndex(e
->index
);
94 SlObject(e
, _engine_desc
);
98 static void Load_ENGN()
100 /* As engine data is loaded before engines are initialized we need to load
101 * this information into a temporary array. This is then copied into the
102 * engine pool after processing NewGRFs by CopyTempEngineData(). */
104 while ((index
= SlIterateArray()) != -1) {
105 Engine
*e
= GetTempDataEngine(index
);
106 SlObject(e
, _engine_desc
);
108 if (IsSavegameVersionBefore(179)) {
109 /* preview_company_rank was replaced with preview_company and preview_asked.
110 * Just cancel any previews. */
111 e
->flags
&= ~4; // ENGINE_OFFER_WINDOW_OPEN
112 e
->preview_company
= INVALID_COMPANY
;
113 e
->preview_asked
= (CompanyMask
)-1;
119 * Copy data from temporary engine array into the real engine pool.
121 void CopyTempEngineData()
125 if (e
->index
>= _temp_engine
.size()) break;
127 const Engine
*se
= GetTempDataEngine(e
->index
);
128 e
->intro_date
= se
->intro_date
;
130 e
->reliability
= se
->reliability
;
131 e
->reliability_spd_dec
= se
->reliability_spd_dec
;
132 e
->reliability_start
= se
->reliability_start
;
133 e
->reliability_max
= se
->reliability_max
;
134 e
->reliability_final
= se
->reliability_final
;
135 e
->duration_phase_1
= se
->duration_phase_1
;
136 e
->duration_phase_2
= se
->duration_phase_2
;
137 e
->duration_phase_3
= se
->duration_phase_3
;
138 e
->flags
= se
->flags
;
139 e
->preview_asked
= se
->preview_asked
;
140 e
->preview_company
= se
->preview_company
;
141 e
->preview_wait
= se
->preview_wait
;
142 e
->company_avail
= se
->company_avail
;
143 e
->company_hidden
= se
->company_hidden
;
144 if (se
->name
!= NULL
) e
->name
= stredup(se
->name
);
147 /* Get rid of temporary data */
148 for (std::vector
<Engine
*>::iterator it
= _temp_engine
.begin(); it
!= _temp_engine
.end(); ++it
) {
151 _temp_engine
.clear();
154 static void Load_ENGS()
156 /* Load old separate String ID list into a temporary array. This
157 * was always 256 entries. */
160 SlArray(names
, lengthof(names
), SLE_STRINGID
);
162 /* Copy each string into the temporary engine array. */
163 for (EngineID engine
= 0; engine
< lengthof(names
); engine
++) {
164 Engine
*e
= GetTempDataEngine(engine
);
165 e
->name
= CopyFromOldName(names
[engine
]);
169 /** Save and load the mapping between the engine id in the pool, and the grf file it came from. */
170 static const SaveLoad _engine_id_mapping_desc
[] = {
171 SLE_VAR(EngineIDMapping
, grfid
, SLE_UINT32
),
172 SLE_VAR(EngineIDMapping
, internal_id
, SLE_UINT16
),
173 SLE_VAR(EngineIDMapping
, type
, SLE_UINT8
),
174 SLE_VAR(EngineIDMapping
, substitute_id
, SLE_UINT8
),
178 static void Save_EIDS()
180 const EngineIDMapping
*end
= _engine_mngr
.End();
182 for (EngineIDMapping
*eid
= _engine_mngr
.Begin(); eid
!= end
; eid
++, index
++) {
183 SlSetArrayIndex(index
);
184 SlObject(eid
, _engine_id_mapping_desc
);
188 static void Load_EIDS()
190 _engine_mngr
.Clear();
192 while (SlIterateArray() != -1) {
193 EngineIDMapping
*eid
= _engine_mngr
.Append();
194 SlObject(eid
, _engine_id_mapping_desc
);
198 extern const ChunkHandler _engine_chunk_handlers
[] = {
199 { 'EIDS', Save_EIDS
, Load_EIDS
, NULL
, NULL
, CH_ARRAY
},
200 { 'ENGN', Save_ENGN
, Load_ENGN
, NULL
, NULL
, CH_ARRAY
},
201 { 'ENGS', NULL
, Load_ENGS
, NULL
, NULL
, CH_RIFF
| CH_LAST
},