12 #include "../stdafx.h" 
   14 #include "../strings_type.h" 
   15 #include "../string_func.h" 
   16 #include "../settings_type.h" 
   17 #include "../fileio_func.h" 
   19 #include "table/strings.h" 
   26 #include "../safeguards.h" 
   28 static const int TTO_HEADER_SIZE = 41;
 
   29 static const int TTD_HEADER_SIZE = 49;
 
   31 uint32 _bump_assert_value;
 
   39   static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8};
 
   40   byte length = 
GB(type, 8, 8);
 
   41   assert(length != 0 && length < 
lengthof(type_mem_size));
 
   42   return type_mem_size[length];
 
   54   if (ls->buffer_cur >= ls->buffer_count) {
 
   57     int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
 
   61       DEBUG(oldloader, 0, 
"Read past end of file, loading failed");
 
   62       throw std::exception();
 
   65     ls->buffer_count = count;
 
   69   return ls->buffer[ls->buffer_cur++];
 
   85   if (ls->chunk_size == 0) {
 
   93       ls->chunk_size  = -new_byte + 1;
 
   96       ls->chunk_size  = new_byte + 1;
 
  113   byte *base_ptr = (byte*)base;
 
  122     byte *ptr = (byte*)chunk->ptr;
 
  125     for (uint i = 0; i < chunk->amount; i++) {
 
  127       if (GetOldChunkType(chunk->type) != 0) {
 
  128         switch (GetOldChunkType(chunk->type)) {
 
  135             if (!chunk->proc(ls, i)) 
return false;
 
  139             DEBUG(oldloader, 4, 
"Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
 
  140             if (ls->total_read != chunk->offset + _bump_assert_value) 
throw std::exception();
 
  147         switch (GetOldChunkFileType(chunk->type)) {
 
  148           case OC_FILE_I8:  res = (int8)
ReadByte(ls); 
break;
 
  149           case OC_FILE_U8:  res = 
ReadByte(ls); 
break;
 
  150           case OC_FILE_I16: res = (int16)ReadUint16(ls); 
break;
 
  151           case OC_FILE_U16: res = ReadUint16(ls); 
break;
 
  152           case OC_FILE_I32: res = (int32)ReadUint32(ls); 
break;
 
  153           case OC_FILE_U32: res = ReadUint32(ls); 
break;
 
  154           default: NOT_REACHED();
 
  158         if (base_ptr == NULL && chunk->ptr == NULL) 
continue;
 
  161         if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
 
  164         switch (GetOldChunkVarType(chunk->type)) {
 
  165           case OC_VAR_I8: *(int8  *)ptr = 
GB(res, 0, 8); 
break;
 
  166           case OC_VAR_U8: *(uint8 *)ptr = 
GB(res, 0, 8); 
break;
 
  167           case OC_VAR_I16:*(int16 *)ptr = 
GB(res, 0, 16); 
break;
 
  168           case OC_VAR_U16:*(uint16*)ptr = 
GB(res, 0, 16); 
break;
 
  169           case OC_VAR_I32:*(int32 *)ptr = res; 
break;
 
  170           case OC_VAR_U32:*(uint32*)ptr = res; 
break;
 
  171           case OC_VAR_I64:*(int64 *)ptr = res; 
break;
 
  172           case OC_VAR_U64:*(uint64*)ptr = res; 
break;
 
  173           default: NOT_REACHED();
 
  177         if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
 
  195   ls->decoding     = 
false;
 
  199   ls->buffer_count = 0;
 
  200   memset(ls->buffer, 0, BUFFER_SIZE);
 
  202   _bump_assert_value = 0;
 
  217   for (uint i = 0; i < len - 2; i++) {
 
  224   uint16 sum2 = title[len - 2]; 
 
  225   SB(sum2, 8, 8, title[len - 1]);
 
  230 static inline bool CheckOldSavegameType(FILE *f, 
char *temp, 
const char *last, uint len)
 
  232   assert(last - temp + 1 >= (
int)len);
 
  234   if (fread(temp, 1, len, f) != len) {
 
  240   temp[len - 2] = 
'\0'; 
 
  246 static SavegameType DetermineOldSavegameType(FILE *f, 
char *title, 
const char *last)
 
  248   assert_compile(TTD_HEADER_SIZE >= TTO_HEADER_SIZE);
 
  249   char temp[TTD_HEADER_SIZE] = 
"Unknown";
 
  255   if (pos >= 0 && !CheckOldSavegameType(f, temp, 
lastof(temp), TTO_HEADER_SIZE)) {
 
  257     if (fseek(f, pos, SEEK_SET) < 0 || !CheckOldSavegameType(f, temp, 
lastof(temp), TTD_HEADER_SIZE)) {
 
  266       default:      title = 
strecpy(title, 
"(broken) ", last); 
break;
 
  268     title = 
strecpy(title, temp, last);
 
  276 bool LoadOldSaveGame(
const char *file)
 
  280   DEBUG(oldloader, 3, 
"Trying to load a TTD(Patch) savegame");
 
  287   if (ls.file == NULL) {
 
  288     DEBUG(oldloader, 0, 
"Cannot open file '%s'", file);
 
  292   SavegameType type = DetermineOldSavegameType(ls.file, NULL, NULL);
 
  294   LoadOldMainProc *proc = NULL;
 
  297     case SGT_TTO: proc = &LoadTTOMain; 
break;
 
  298     case SGT_TTD: proc = &LoadTTDMain; 
break;
 
  306     game_loaded = proc != NULL && proc(&ls);
 
  322 void GetOldSaveGameName(
const char *file, 
char *title, 
const char *last)
 
  331   DetermineOldSavegameType(f, title, last);