|
|
@ -343,17 +343,6 @@ void *ScriptInstance::GetLogPointer()
|
|
|
|
* - null: No data.
|
|
|
|
* - null: No data.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/** The type of the data that follows in the savegame. */
|
|
|
|
|
|
|
|
enum SQSaveLoadType {
|
|
|
|
|
|
|
|
SQSL_INT = 0x00, ///< The following data is an integer.
|
|
|
|
|
|
|
|
SQSL_STRING = 0x01, ///< The following data is an string.
|
|
|
|
|
|
|
|
SQSL_ARRAY = 0x02, ///< The following data is an array.
|
|
|
|
|
|
|
|
SQSL_TABLE = 0x03, ///< The following data is an table.
|
|
|
|
|
|
|
|
SQSL_BOOL = 0x04, ///< The following data is a boolean.
|
|
|
|
|
|
|
|
SQSL_NULL = 0x05, ///< A null variable.
|
|
|
|
|
|
|
|
SQSL_ARRAY_TABLE_END = 0xFF, ///< Marks the end of an array or table, no data follows.
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static byte _script_sl_byte; ///< Used as source/target by the script saveload code to store/load a single byte.
|
|
|
|
static byte _script_sl_byte; ///< Used as source/target by the script saveload code to store/load a single byte.
|
|
|
|
|
|
|
|
|
|
|
|
/** SaveLoad array that saves/loads exactly one byte. */
|
|
|
|
/** SaveLoad array that saves/loads exactly one byte. */
|
|
|
@ -572,14 +561,14 @@ bool ScriptInstance::IsPaused()
|
|
|
|
return this->is_paused;
|
|
|
|
return this->is_paused;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm)
|
|
|
|
/* static */ bool ScriptInstance::LoadObjects(ScriptData *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
switch (_script_sl_byte) {
|
|
|
|
switch (_script_sl_byte) {
|
|
|
|
case SQSL_INT: {
|
|
|
|
case SQSL_INT: {
|
|
|
|
int64 value;
|
|
|
|
int64 value;
|
|
|
|
SlCopy(&value, 1, IsSavegameVersionBefore(SLV_SCRIPT_INT64) ? SLE_FILE_I32 | SLE_VAR_I64 : SLE_INT64);
|
|
|
|
SlCopy(&value, 1, IsSavegameVersionBefore(SLV_SCRIPT_INT64) ? SLE_FILE_I32 | SLE_VAR_I64 : SLE_INT64);
|
|
|
|
if (vm != nullptr) sq_pushinteger(vm, (SQInteger)value);
|
|
|
|
if (data != nullptr) data->push_back((SQInteger)value);
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -588,37 +577,79 @@ bool ScriptInstance::IsPaused()
|
|
|
|
static char buf[std::numeric_limits<decltype(_script_sl_byte)>::max()];
|
|
|
|
static char buf[std::numeric_limits<decltype(_script_sl_byte)>::max()];
|
|
|
|
SlCopy(buf, _script_sl_byte, SLE_CHAR);
|
|
|
|
SlCopy(buf, _script_sl_byte, SLE_CHAR);
|
|
|
|
StrMakeValidInPlace(buf, buf + _script_sl_byte);
|
|
|
|
StrMakeValidInPlace(buf, buf + _script_sl_byte);
|
|
|
|
if (vm != nullptr) sq_pushstring(vm, buf, -1);
|
|
|
|
if (data != nullptr) data->push_back(std::string(buf));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_ARRAY:
|
|
|
|
|
|
|
|
case SQSL_TABLE: {
|
|
|
|
|
|
|
|
if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte);
|
|
|
|
|
|
|
|
while (LoadObjects(data));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_BOOL: {
|
|
|
|
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
|
|
|
|
if (data != nullptr) data->push_back((SQBool)(_script_sl_byte != 0));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_NULL: {
|
|
|
|
|
|
|
|
if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_ARRAY_TABLE_END: {
|
|
|
|
|
|
|
|
if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: SlErrorCorrupt("Invalid script data type");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm, ScriptData *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ScriptDataVariant value = data->front();
|
|
|
|
|
|
|
|
data->pop_front();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (std::holds_alternative<SQInteger>(value)) {
|
|
|
|
|
|
|
|
sq_pushinteger(vm, std::get<SQInteger>(value));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (std::holds_alternative<std::string>(value)) {
|
|
|
|
|
|
|
|
sq_pushstring(vm, std::get<std::string>(value).c_str(), -1);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (std::holds_alternative<SQBool>(value)) {
|
|
|
|
|
|
|
|
sq_pushbool(vm, std::get<SQBool>(value));
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (std::get<SQSaveLoadType>(value)) {
|
|
|
|
case SQSL_ARRAY: {
|
|
|
|
case SQSL_ARRAY: {
|
|
|
|
if (vm != nullptr) sq_newarray(vm, 0);
|
|
|
|
sq_newarray(vm, 0);
|
|
|
|
while (LoadObjects(vm)) {
|
|
|
|
while (LoadObjects(vm, data)) {
|
|
|
|
if (vm != nullptr) sq_arrayappend(vm, -2);
|
|
|
|
sq_arrayappend(vm, -2);
|
|
|
|
/* The value is popped from the stack by squirrel. */
|
|
|
|
/* The value is popped from the stack by squirrel. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_TABLE: {
|
|
|
|
case SQSL_TABLE: {
|
|
|
|
if (vm != nullptr) sq_newtable(vm);
|
|
|
|
sq_newtable(vm);
|
|
|
|
while (LoadObjects(vm)) {
|
|
|
|
while (LoadObjects(vm, data)) {
|
|
|
|
LoadObjects(vm);
|
|
|
|
LoadObjects(vm, data);
|
|
|
|
if (vm != nullptr) sq_rawset(vm, -3);
|
|
|
|
sq_rawset(vm, -3);
|
|
|
|
/* The key (-2) and value (-1) are popped from the stack by squirrel. */
|
|
|
|
/* The key (-2) and value (-1) are popped from the stack by squirrel. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_BOOL: {
|
|
|
|
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
|
|
|
|
if (vm != nullptr) sq_pushbool(vm, (SQBool)(_script_sl_byte != 0));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case SQSL_NULL: {
|
|
|
|
case SQSL_NULL: {
|
|
|
|
if (vm != nullptr) sq_pushnull(vm);
|
|
|
|
sq_pushnull(vm);
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -639,22 +670,35 @@ bool ScriptInstance::IsPaused()
|
|
|
|
LoadObjects(nullptr);
|
|
|
|
LoadObjects(nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ScriptInstance::Load(int version)
|
|
|
|
/* static */ ScriptInstance::ScriptData *ScriptInstance::Load(int version)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ScriptObject::ActiveInstance active(this);
|
|
|
|
if (version == -1) {
|
|
|
|
|
|
|
|
|
|
|
|
if (this->engine == nullptr || version == -1) {
|
|
|
|
|
|
|
|
LoadEmpty();
|
|
|
|
LoadEmpty();
|
|
|
|
return;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
HSQUIRRELVM vm = this->engine->GetVM();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
SlObject(nullptr, _script_byte);
|
|
|
|
/* Check if there was anything saved at all. */
|
|
|
|
/* Check if there was anything saved at all. */
|
|
|
|
if (_script_sl_byte == 0) return;
|
|
|
|
if (_script_sl_byte == 0) return nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ScriptData *data = new ScriptData();
|
|
|
|
|
|
|
|
data->push_back((SQInteger)version);
|
|
|
|
|
|
|
|
LoadObjects(data);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ScriptInstance::LoadOnStack(ScriptData *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ScriptObject::ActiveInstance active(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data == nullptr) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HSQUIRRELVM vm = this->engine->GetVM();
|
|
|
|
|
|
|
|
|
|
|
|
sq_pushinteger(vm, version);
|
|
|
|
ScriptDataVariant version = data->front();
|
|
|
|
LoadObjects(vm);
|
|
|
|
data->pop_front();
|
|
|
|
|
|
|
|
sq_pushinteger(vm, std::get<SQInteger>(version));
|
|
|
|
|
|
|
|
LoadObjects(vm, data);
|
|
|
|
this->is_save_data_on_stack = true;
|
|
|
|
this->is_save_data_on_stack = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|