OpenTTD
gamelog_sl.cpp
Go to the documentation of this file.
1 /* $Id: gamelog_sl.cpp 26482 2014-04-23 20:13:33Z rubidium $ */
2 
3 /*
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/>.
8  */
9 
12 #include "../stdafx.h"
13 #include "../gamelog_internal.h"
14 #include "../fios.h"
15 
16 #include "saveload.h"
17 
18 #include "../safeguards.h"
19 
20 static const SaveLoad _glog_action_desc[] = {
21  SLE_VAR(LoggedAction, tick, SLE_UINT16),
22  SLE_END()
23 };
24 
25 static const SaveLoad _glog_mode_desc[] = {
26  SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
27  SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
28  SLE_END()
29 };
30 
31 static const SaveLoad _glog_revision_desc[] = {
32  SLE_ARR(LoggedChange, revision.text, SLE_UINT8, NETWORK_REVISION_LENGTH),
33  SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
34  SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
35  SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
36  SLE_END()
37 };
38 
39 static const SaveLoad _glog_oldver_desc[] = {
40  SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
41  SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
42  SLE_END()
43 };
44 
45 static const SaveLoad _glog_setting_desc[] = {
46  SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
47  SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
48  SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
49  SLE_END()
50 };
51 
52 static const SaveLoad _glog_grfadd_desc[] = {
53  SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
54  SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
55  SLE_END()
56 };
57 
58 static const SaveLoad _glog_grfrem_desc[] = {
59  SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
60  SLE_END()
61 };
62 
63 static const SaveLoad _glog_grfcompat_desc[] = {
64  SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
65  SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
66  SLE_END()
67 };
68 
69 static const SaveLoad _glog_grfparam_desc[] = {
70  SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
71  SLE_END()
72 };
73 
74 static const SaveLoad _glog_grfmove_desc[] = {
75  SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
76  SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
77  SLE_END()
78 };
79 
80 static const SaveLoad _glog_grfbug_desc[] = {
81  SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
82  SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
83  SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
84  SLE_END()
85 };
86 
87 static const SaveLoad _glog_emergency_desc[] = {
88  SLE_END()
89 };
90 
91 static const SaveLoad * const _glog_desc[] = {
92  _glog_mode_desc,
93  _glog_revision_desc,
94  _glog_oldver_desc,
95  _glog_setting_desc,
96  _glog_grfadd_desc,
97  _glog_grfrem_desc,
98  _glog_grfcompat_desc,
99  _glog_grfparam_desc,
100  _glog_grfmove_desc,
101  _glog_grfbug_desc,
102  _glog_emergency_desc,
103 };
104 
105 assert_compile(lengthof(_glog_desc) == GLCT_END);
106 
107 static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions)
108 {
109  assert(gamelog_action == NULL);
110  assert(gamelog_actions == 0);
111 
113  while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
114  gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
115  LoggedAction *la = &gamelog_action[gamelog_actions++];
116 
117  la->at = at;
118 
119  SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
120  la->change = NULL;
121  la->changes = 0;
122 
124  while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
125  la->change = ReallocT(la->change, la->changes + 1);
126 
127  LoggedChange *lc = &la->change[la->changes++];
128  /* for SLE_STR, pointer has to be valid! so make it NULL */
129  memset(lc, 0, sizeof(*lc));
130  lc->ct = ct;
131 
132  assert((uint)ct < GLCT_END);
133 
134  SlObject(lc, _glog_desc[ct]);
135  }
136  }
137 }
138 
139 static void Save_GLOG()
140 {
142  size_t length = 0;
143 
144  for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
145  const LoggedChange *lcend = &la->change[la->changes];
146  for (LoggedChange *lc = la->change; lc != lcend; lc++) {
147  assert((uint)lc->ct < lengthof(_glog_desc));
148  length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
149  }
150  length += 4;
151  }
152  length++;
153 
154  SlSetLength(length);
155 
156  for (LoggedAction *la = _gamelog_action; la != laend; la++) {
157  SlWriteByte(la->at);
158  SlObject(la, _glog_action_desc);
159 
160  const LoggedChange *lcend = &la->change[la->changes];
161  for (LoggedChange *lc = la->change; lc != lcend; lc++) {
162  SlWriteByte(lc->ct);
163  assert((uint)lc->ct < GLCT_END);
164  SlObject(lc, _glog_desc[lc->ct]);
165  }
167  }
169 }
170 
171 static void Load_GLOG()
172 {
173  Load_GLOG_common(_gamelog_action, _gamelog_actions);
174 }
175 
176 static void Check_GLOG()
177 {
179 }
180 
181 extern const ChunkHandler _gamelog_chunk_handlers[] = {
182  { 'GLOG', Save_GLOG, Load_GLOG, NULL, Check_GLOG, CH_RIFF | CH_LAST }
183 };