00001
00002
00005 #include "../stdafx.h"
00006 #include "../gamelog.h"
00007 #include "../gamelog_internal.h"
00008 #include "../core/alloc_func.hpp"
00009
00010 #include "saveload.h"
00011
00012 static const SaveLoad _glog_action_desc[] = {
00013 SLE_VAR(LoggedAction, tick, SLE_UINT16),
00014 SLE_END()
00015 };
00016
00017 static const SaveLoad _glog_mode_desc[] = {
00018 SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
00019 SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
00020 SLE_END()
00021 };
00022
00023 static const SaveLoad _glog_revision_desc[] = {
00024 SLE_ARR(LoggedChange, revision.text, SLE_UINT8, NETWORK_REVISION_LENGTH),
00025 SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
00026 SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
00027 SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
00028 SLE_END()
00029 };
00030
00031 static const SaveLoad _glog_oldver_desc[] = {
00032 SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
00033 SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
00034 SLE_END()
00035 };
00036
00037 static const SaveLoad _glog_setting_desc[] = {
00038 SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
00039 SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
00040 SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
00041 SLE_END()
00042 };
00043
00044 static const SaveLoad _glog_grfadd_desc[] = {
00045 SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
00046 SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
00047 SLE_END()
00048 };
00049
00050 static const SaveLoad _glog_grfrem_desc[] = {
00051 SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
00052 SLE_END()
00053 };
00054
00055 static const SaveLoad _glog_grfcompat_desc[] = {
00056 SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
00057 SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
00058 SLE_END()
00059 };
00060
00061 static const SaveLoad _glog_grfparam_desc[] = {
00062 SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
00063 SLE_END()
00064 };
00065
00066 static const SaveLoad _glog_grfmove_desc[] = {
00067 SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
00068 SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
00069 SLE_END()
00070 };
00071
00072 static const SaveLoad _glog_grfbug_desc[] = {
00073 SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
00074 SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
00075 SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
00076 SLE_END()
00077 };
00078
00079 static const SaveLoad *_glog_desc[] = {
00080 _glog_mode_desc,
00081 _glog_revision_desc,
00082 _glog_oldver_desc,
00083 _glog_setting_desc,
00084 _glog_grfadd_desc,
00085 _glog_grfrem_desc,
00086 _glog_grfcompat_desc,
00087 _glog_grfparam_desc,
00088 _glog_grfmove_desc,
00089 _glog_grfbug_desc,
00090 };
00091
00092 assert_compile(lengthof(_glog_desc) == GLCT_END);
00093
00094 static void Load_GLOG()
00095 {
00096 assert(_gamelog_action == NULL);
00097 assert(_gamelog_actions == 0);
00098
00099 GamelogActionType at;
00100 while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
00101 _gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
00102 LoggedAction *la = &_gamelog_action[_gamelog_actions++];
00103
00104 la->at = at;
00105
00106 SlObject(la, _glog_action_desc);
00107 la->change = NULL;
00108 la->changes = 0;
00109
00110 GamelogChangeType ct;
00111 while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
00112 la->change = ReallocT(la->change, la->changes + 1);
00113
00114 LoggedChange *lc = &la->change[la->changes++];
00115
00116 memset(lc, 0, sizeof(*lc));
00117 lc->ct = ct;
00118
00119 assert((uint)ct < GLCT_END);
00120
00121 SlObject(lc, _glog_desc[ct]);
00122 }
00123 }
00124 }
00125
00126 static void Save_GLOG()
00127 {
00128 const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
00129 size_t length = 0;
00130
00131 for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
00132 const LoggedChange *lcend = &la->change[la->changes];
00133 for (LoggedChange *lc = la->change; lc != lcend; lc++) {
00134 assert((uint)lc->ct < lengthof(_glog_desc));
00135 length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
00136 }
00137 length += 4;
00138 }
00139 length++;
00140
00141 SlSetLength(length);
00142
00143 for (LoggedAction *la = _gamelog_action; la != laend; la++) {
00144 SlWriteByte(la->at);
00145 SlObject(la, _glog_action_desc);
00146
00147 const LoggedChange *lcend = &la->change[la->changes];
00148 for (LoggedChange *lc = la->change; lc != lcend; lc++) {
00149 SlWriteByte(lc->ct);
00150 assert((uint)lc->ct < GLCT_END);
00151 SlObject(lc, _glog_desc[lc->ct]);
00152 }
00153 SlWriteByte(GLCT_NONE);
00154 }
00155 SlWriteByte(GLAT_NONE);
00156 }
00157
00158
00159 extern const ChunkHandler _gamelog_chunk_handlers[] = {
00160 { 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
00161 };