Update to 1.11.0-beta1

This commit is contained in:
dP
2021-01-23 17:31:11 +03:00
parent d3c06c25c8
commit 5e4506f493
1045 changed files with 23534 additions and 60345 deletions
+93 -62
View File
@@ -44,6 +44,10 @@
#include "../fios.h"
#include "../error.h"
#include <atomic>
#include <string>
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
#include "table/strings.h"
@@ -166,7 +170,7 @@ struct MemoryDumper {
size_t t = this->GetSize();
while (t > 0) {
size_t to_write = min(MEMORY_CHUNK_SIZE, t);
size_t to_write = std::min(MEMORY_CHUNK_SIZE, t);
writer->Write(this->blocks[i++], to_write);
t -= to_write;
@@ -301,17 +305,13 @@ static void SlNullPointers()
* pointers from other pools. */
_sl_version = SAVEGAME_VERSION;
DEBUG(sl, 1, "Nulling pointers");
FOR_ALL_CHUNK_HANDLERS(ch) {
if (ch->ptrs_proc != nullptr) {
DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
ch->ptrs_proc();
}
}
DEBUG(sl, 1, "All pointers nulled");
assert(_sl.action == SLA_NULL);
}
@@ -466,16 +466,6 @@ static inline void SlWriteUint64(uint64 x)
SlWriteUint32((uint32)x);
}
/**
* Read in bytes from the file/data structure but don't do
* anything with them, discarding them in effect
* @param length The amount of bytes that is being treated this way
*/
static inline void SlSkipBytes(size_t length)
{
for (; length != 0; length--) SlReadByte();
}
/**
* Read in the header descriptor of an object or an array.
* If the highest bit is set (7), then the index is bigger than 127
@@ -792,7 +782,7 @@ void WriteValue(void *ptr, VarType conv, int64 val)
case SLE_VAR_U32: *(uint32*)ptr = val; break;
case SLE_VAR_I64: *(int64 *)ptr = val; break;
case SLE_VAR_U64: *(uint64*)ptr = val; break;
case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
case SLE_VAR_NAME: *reinterpret_cast<std::string *>(ptr) = CopyFromOldName(val); break;
case SLE_VAR_NULL: break;
default: NOT_REACHED();
}
@@ -866,7 +856,7 @@ static void SlSaveLoadConv(void *ptr, VarType conv)
static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
{
if (ptr == nullptr) return 0;
return min(strlen(ptr), length - 1);
return std::min(strlen(ptr), length - 1);
}
/**
@@ -901,6 +891,21 @@ static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType con
return len + SlGetArrayLength(len); // also include the length of the index
}
/**
* Calculate the gross length of the string that it
* will occupy in the savegame. This includes the real length, returned
* by SlCalcNetStringLen and the length that the index will occupy.
* @param ptr Pointer to the \c std::string.
* @return The gross length of the string.
*/
static inline size_t SlCalcStdStringLen(const void *ptr)
{
const std::string *str = reinterpret_cast<const std::string *>(ptr);
size_t len = str->length();
return len + SlGetArrayLength(len); // also include the length of the index
}
/**
* Save/Load a string.
* @param ptr the string being manipulated
@@ -980,6 +985,53 @@ static void SlString(void *ptr, size_t length, VarType conv)
}
}
/**
* Save/Load a \c std::string.
* @param ptr the string being manipulated
* @param conv must be SLE_FILE_STRING
*/
static void SlStdString(void *ptr, VarType conv)
{
std::string *str = reinterpret_cast<std::string *>(ptr);
switch (_sl.action) {
case SLA_SAVE: {
size_t len = str->length();
SlWriteArrayLength(len);
SlCopyBytes(const_cast<void *>(static_cast<const void *>(str->c_str())), len);
break;
}
case SLA_LOAD_CHECK:
case SLA_LOAD: {
size_t len = SlReadArrayLength();
char *buf = AllocaM(char, len + 1);
SlCopyBytes(buf, len);
buf[len] = '\0'; // properly terminate the string
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
if ((conv & SLF_ALLOW_CONTROL) != 0) {
settings = settings | SVS_ALLOW_CONTROL_CODE;
if (IsSavegameVersionBefore(SLV_169)) {
str_fix_scc_encoded(buf, buf + len);
}
}
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE;
}
str_validate(buf, buf + len, settings);
// Store sanitized string.
str->assign(buf);
}
case SLA_PTRS: break;
case SLA_NULL: break;
default: NOT_REACHED();
}
}
/**
* Return the size in bytes of a certain type of atomic array
* @param length The length of the array counted in elements
@@ -1086,7 +1138,7 @@ static size_t ReferenceToInt(const void *obj, SLRefType rt)
*/
static void *IntToReference(size_t index, SLRefType rt)
{
assert_compile(sizeof(size_t) <= sizeof(void *));
static_assert(sizeof(size_t) <= sizeof(void *));
assert(_sl.action == SLA_PTRS);
@@ -1403,6 +1455,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
case SL_STR:
case SL_LST:
case SL_DEQUE:
case SL_STDSTR:
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) break;
@@ -1413,6 +1466,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld->conv);
case SL_STDSTR: return SlCalcStdStringLen(GetVariableAddress(object, sld));
default: NOT_REACHED();
}
break;
@@ -1450,6 +1504,8 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
case SLE_VAR_I64:
case SLE_VAR_U64:
return sld->size == sizeof(int64);
case SLE_VAR_NAME:
return sld->size == sizeof(std::string);
default:
return sld->size == sizeof(void *);
}
@@ -1461,6 +1517,10 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
/* These should be pointer sized, or fixed array. */
return sld->size == sizeof(void *) || sld->size == sld->length;
case SL_STDSTR:
/* These should be all pointers to std::string. */
return sld->size == sizeof(std::string);
default:
return true;
}
@@ -1482,6 +1542,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
case SL_STR:
case SL_LST:
case SL_DEQUE:
case SL_STDSTR:
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) return false;
if (SlSkipVariableOnLoad(sld)) return false;
@@ -1510,6 +1571,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
case SL_STR: SlString(ptr, sld->length, sld->conv); break;
case SL_LST: SlList(ptr, (SLRefType)conv); break;
case SL_DEQUE: SlDeque(ptr, conv); break;
case SL_STDSTR: SlStdString(ptr, sld->conv); break;
default: NOT_REACHED();
}
break;
@@ -1556,7 +1618,7 @@ void SlObject(void *object, const SaveLoad *sld)
}
for (; sld->cmd != SL_END; sld++) {
void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld);
}
}
@@ -1687,32 +1749,6 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
}
}
/**
* Stub Chunk handlers to only calculate length and do nothing else.
* The intended chunk handler that should be called.
*/
static ChunkSaveLoadProc *_stub_save_proc;
/**
* Stub Chunk handlers to only calculate length and do nothing else.
* Actually call the intended chunk handler.
* @param arg ignored parameter.
*/
static inline void SlStubSaveProc2(void *arg)
{
_stub_save_proc();
}
/**
* Stub Chunk handlers to only calculate length and do nothing else.
* Call SlAutoLenth with our stub save proc that will eventually
* call the intended chunk handler.
*/
static void SlStubSaveProc()
{
SlAutolength(SlStubSaveProc2, nullptr);
}
/**
* Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
* prefixed by an ID identifying it, followed by data, and terminator where appropriate
@@ -1728,12 +1764,6 @@ static void SlSaveChunk(const ChunkHandler *ch)
SlWriteUint32(ch->id);
DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
if (ch->flags & CH_AUTO_LENGTH) {
/* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
_stub_save_proc = proc;
proc = SlStubSaveProc;
}
_sl.block_mode = ch->flags & CH_TYPE_MASK;
switch (ch->flags & CH_TYPE_MASK) {
case CH_RIFF:
@@ -1813,17 +1843,13 @@ static void SlFixPointers()
{
_sl.action = SLA_PTRS;
DEBUG(sl, 1, "Fixing pointers");
FOR_ALL_CHUNK_HANDLERS(ch) {
if (ch->ptrs_proc != nullptr) {
DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
ch->ptrs_proc();
}
}
DEBUG(sl, 1, "All pointers fixed");
assert(_sl.action == SLA_PTRS);
}
@@ -2379,7 +2405,7 @@ static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
/* actual loader/saver function */
void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
extern bool AfterLoadGame();
extern bool LoadOldSaveGame(const char *file);
extern bool LoadOldSaveGame(const std::string &file);
/**
* Clear temporary data that is passed between various saveload phases.
@@ -2432,6 +2458,10 @@ static void SaveFileDone()
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
_sl.saveinprogress = false;
#ifdef __EMSCRIPTEN__
EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs());
#endif
}
/** Set the error message from outside of the actual loading/saving of the game (AfterLoadGame and friends) */
@@ -2619,6 +2649,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
/* Is the version higher than the current? */
if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
if (_sl_version >= SLV_START_PATCHPACKS && _sl_version <= SLV_END_PATCHPACKS) SlError(STR_GAME_SAVELOAD_ERROR_PATCHPACK);
break;
}
@@ -2730,7 +2761,7 @@ SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
* @param threaded True when threaded saving is allowed
* @return Return the result of the action. #SL_OK, #SL_ERROR, or #SL_REINIT ("unload" the game)
*/
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
{
/* An instance of saving is already active, so don't go saving again */
if (_sl.saveinprogress && fop == SLO_SAVE && dft == DFT_GAME_FILE && threaded) {
@@ -2794,7 +2825,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, Detaile
}
if (fop == SLO_SAVE) { // SAVE game
DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename.c_str());
if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
return DoSave(new FileWriter(fh), threaded);
@@ -2802,7 +2833,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, Detaile
/* LOAD game */
assert(fop == SLO_LOAD || fop == SLO_CHECK);
DEBUG(desync, 1, "load: %s", filename);
DEBUG(desync, 1, "load: %s", filename.c_str());
return DoLoad(new FileReader(fh), fop == SLO_CHECK);
} catch (...) {
/* This code may be executed both for old and new save games. */
@@ -2891,7 +2922,7 @@ void FileToSaveLoad::SetMode(SaveLoadOperation fop, AbstractFileType aft, Detail
*/
void FileToSaveLoad::SetName(const char *name)
{
strecpy(this->name, name, lastof(this->name));
this->name = name;
}
/**