Initial commit
This commit is contained in:
336
engines/ags/shared/script/cc_script.cpp
Normal file
336
engines/ags/shared/script/cc_script.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ags/shared/script/cc_common.h"
|
||||
#include "ags/shared/script/cc_script.h"
|
||||
#include "ags/shared/script/cc_internal.h"
|
||||
#include "ags/shared/util/stream.h"
|
||||
#include "ags/shared/util/string_compat.h"
|
||||
#include "ags/shared/util/string_utils.h"
|
||||
#include "ags/globals.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
using namespace AGS::Shared;
|
||||
|
||||
ccScript *ccScript::CreateFromStream(Stream *in) {
|
||||
ccScript *scri = new ccScript();
|
||||
if (!scri->Read(in)) {
|
||||
delete scri;
|
||||
return nullptr;
|
||||
}
|
||||
return scri;
|
||||
}
|
||||
|
||||
ccScript::ccScript() {
|
||||
globaldata = nullptr;
|
||||
globaldatasize = 0;
|
||||
code = nullptr;
|
||||
codesize = 0;
|
||||
strings = nullptr;
|
||||
stringssize = 0;
|
||||
fixuptypes = nullptr;
|
||||
fixups = nullptr;
|
||||
numfixups = 0;
|
||||
importsCapacity = 0;
|
||||
imports = nullptr;
|
||||
numimports = 0;
|
||||
exportsCapacity = 0;
|
||||
exports = nullptr;
|
||||
export_addr = nullptr;
|
||||
numexports = 0;
|
||||
instances = 0;
|
||||
sectionNames = nullptr;
|
||||
sectionOffsets = nullptr;
|
||||
numSections = 0;
|
||||
capacitySections = 0;
|
||||
}
|
||||
|
||||
ccScript::ccScript(const ccScript &src) {
|
||||
globaldatasize = src.globaldatasize;
|
||||
if (globaldatasize > 0) {
|
||||
globaldata = (char *)malloc(globaldatasize);
|
||||
memcpy(globaldata, src.globaldata, globaldatasize);
|
||||
} else {
|
||||
globaldata = nullptr;
|
||||
}
|
||||
|
||||
codesize = src.codesize;
|
||||
if (codesize > 0) {
|
||||
code = (int32_t *)malloc(codesize * sizeof(int32_t));
|
||||
memcpy(code, src.code, sizeof(int32_t) * codesize);
|
||||
} else {
|
||||
code = nullptr;
|
||||
}
|
||||
|
||||
stringssize = src.stringssize;
|
||||
if (stringssize > 0) {
|
||||
strings = (char *)malloc(stringssize);
|
||||
memcpy(strings, src.strings, stringssize);
|
||||
} else {
|
||||
strings = nullptr;
|
||||
}
|
||||
|
||||
numfixups = src.numfixups;
|
||||
if (numfixups > 0) {
|
||||
fixuptypes = (char *)malloc(numfixups);
|
||||
fixups = (int32_t *)malloc(numfixups * sizeof(int32_t));
|
||||
memcpy(fixuptypes, src.fixuptypes, numfixups);
|
||||
memcpy(fixups, src.fixups, numfixups * sizeof(int32_t));
|
||||
} else {
|
||||
fixups = nullptr;
|
||||
fixuptypes = nullptr;
|
||||
}
|
||||
|
||||
importsCapacity = src.numimports;
|
||||
numimports = src.numimports;
|
||||
if (numimports > 0) {
|
||||
imports = (char **)malloc(sizeof(char *) * numimports);
|
||||
for (int i = 0; i < numimports; ++i)
|
||||
imports[i] = ags_strdup(src.imports[i]);
|
||||
} else {
|
||||
imports = nullptr;
|
||||
}
|
||||
|
||||
exportsCapacity = src.numexports;
|
||||
numexports = src.numexports;
|
||||
if (numexports > 0) {
|
||||
exports = (char **)malloc(sizeof(char *) * numexports);
|
||||
export_addr = (int32_t *)malloc(sizeof(int32_t) * numexports);
|
||||
for (int i = 0; i < numexports; ++i) {
|
||||
exports[i] = ags_strdup(src.exports[i]);
|
||||
export_addr[i] = src.export_addr[i];
|
||||
}
|
||||
} else {
|
||||
exports = nullptr;
|
||||
export_addr = nullptr;
|
||||
}
|
||||
|
||||
capacitySections = src.numSections;
|
||||
numSections = src.numSections;
|
||||
if (numSections > 0) {
|
||||
sectionNames = (char **)malloc(numSections * sizeof(char *));
|
||||
sectionOffsets = (int32_t *)malloc(numSections * sizeof(int32_t));
|
||||
for (int i = 0; i < numSections; ++i) {
|
||||
sectionNames[i] = ags_strdup(src.sectionNames[i]);
|
||||
sectionOffsets[i] = src.sectionOffsets[i];
|
||||
}
|
||||
} else {
|
||||
numSections = 0;
|
||||
sectionNames = nullptr;
|
||||
sectionOffsets = nullptr;
|
||||
}
|
||||
|
||||
instances = 0;
|
||||
}
|
||||
|
||||
ccScript::~ccScript() {
|
||||
Free();
|
||||
}
|
||||
|
||||
void ccScript::Write(Stream *out) {
|
||||
int n;
|
||||
out->Write(_G(scfilesig), 4);
|
||||
out->WriteInt32(SCOM_VERSION);
|
||||
out->WriteInt32(globaldatasize);
|
||||
out->WriteInt32(codesize);
|
||||
out->WriteInt32(stringssize);
|
||||
if (globaldatasize > 0)
|
||||
out->WriteArray(globaldata, globaldatasize, 1);
|
||||
if (codesize > 0)
|
||||
out->WriteArrayOfInt32(code, codesize);
|
||||
if (stringssize > 0)
|
||||
out->WriteArray(strings, stringssize, 1);
|
||||
out->WriteInt32(numfixups);
|
||||
if (numfixups > 0) {
|
||||
out->WriteArray(fixuptypes, numfixups, 1);
|
||||
out->WriteArrayOfInt32(fixups, numfixups);
|
||||
}
|
||||
out->WriteInt32(numimports);
|
||||
for (n = 0; n < numimports; n++)
|
||||
StrUtil::WriteCStr(imports[n], out);
|
||||
out->WriteInt32(numexports);
|
||||
for (n = 0; n < numexports; n++) {
|
||||
StrUtil::WriteCStr(exports[n], out);
|
||||
out->WriteInt32(export_addr[n]);
|
||||
}
|
||||
out->WriteInt32(numSections);
|
||||
for (n = 0; n < numSections; n++) {
|
||||
StrUtil::WriteCStr(sectionNames[n], out);
|
||||
out->WriteInt32(sectionOffsets[n]);
|
||||
}
|
||||
out->WriteInt32(ENDFILESIG);
|
||||
}
|
||||
|
||||
bool ccScript::Read(Stream *in) {
|
||||
instances = 0;
|
||||
int n;
|
||||
char gotsig[5];
|
||||
_G(currentline) = -1;
|
||||
in->Read(gotsig, 4);
|
||||
gotsig[4] = 0;
|
||||
|
||||
int fileVer = in->ReadInt32();
|
||||
|
||||
if ((strcmp(gotsig, _G(scfilesig)) != 0) || (fileVer > SCOM_VERSION)) {
|
||||
cc_error("file was not written by ccScript::Write or seek position is incorrect");
|
||||
return false;
|
||||
}
|
||||
|
||||
globaldatasize = in->ReadInt32();
|
||||
codesize = in->ReadInt32();
|
||||
stringssize = in->ReadInt32();
|
||||
|
||||
if (globaldatasize > 0) {
|
||||
globaldata = (char *)malloc(globaldatasize);
|
||||
in->Read(globaldata, globaldatasize);
|
||||
} else
|
||||
globaldata = nullptr;
|
||||
|
||||
if (codesize > 0) {
|
||||
code = (int32_t *)malloc(codesize * sizeof(int32_t));
|
||||
in->ReadArrayOfInt32(code, codesize);
|
||||
} else
|
||||
code = nullptr;
|
||||
|
||||
if (stringssize > 0) {
|
||||
strings = (char *)malloc(stringssize);
|
||||
in->Read(strings, stringssize);
|
||||
} else
|
||||
strings = nullptr;
|
||||
|
||||
numfixups = in->ReadInt32();
|
||||
if (numfixups > 0) {
|
||||
fixuptypes = (char *)malloc(numfixups);
|
||||
fixups = (int32_t *)malloc(numfixups * sizeof(int32_t));
|
||||
in->Read(fixuptypes, numfixups);
|
||||
in->ReadArrayOfInt32(fixups, numfixups);
|
||||
} else {
|
||||
fixups = nullptr;
|
||||
fixuptypes = nullptr;
|
||||
}
|
||||
|
||||
numimports = in->ReadInt32();
|
||||
|
||||
imports = (char **)malloc(sizeof(char *) * numimports);
|
||||
for (n = 0; n < numimports; n++)
|
||||
imports[n] = StrUtil::ReadMallocCStrOrNull(in);
|
||||
|
||||
numexports = in->ReadInt32();
|
||||
exports = (char **)malloc(sizeof(char *) * numexports);
|
||||
export_addr = (int32_t *)malloc(sizeof(int32_t) * numexports);
|
||||
for (n = 0; n < numexports; n++) {
|
||||
exports[n] = StrUtil::ReadMallocCStrOrNull(in);
|
||||
export_addr[n] = in->ReadInt32();
|
||||
}
|
||||
|
||||
if (fileVer >= 83) {
|
||||
// read in the Sections
|
||||
numSections = in->ReadInt32();
|
||||
sectionNames = (char **)malloc(numSections * sizeof(char *));
|
||||
sectionOffsets = (int32_t *)malloc(numSections * sizeof(int32_t));
|
||||
for (n = 0; n < numSections; n++) {
|
||||
sectionNames[n] = StrUtil::ReadMallocCStrOrNull(in);
|
||||
sectionOffsets[n] = in->ReadInt32();
|
||||
}
|
||||
} else {
|
||||
numSections = 0;
|
||||
sectionNames = nullptr;
|
||||
sectionOffsets = nullptr;
|
||||
}
|
||||
|
||||
if (static_cast<uint32_t>(in->ReadInt32()) != ENDFILESIG) {
|
||||
cc_error("internal error rebuilding script");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ccScript::Free() {
|
||||
if (globaldata != nullptr)
|
||||
free(globaldata);
|
||||
|
||||
if (code != nullptr)
|
||||
free(code);
|
||||
|
||||
if (strings != nullptr)
|
||||
free(strings);
|
||||
|
||||
if (fixups != nullptr && numfixups > 0)
|
||||
free(fixups);
|
||||
|
||||
if (fixuptypes != nullptr && numfixups > 0)
|
||||
free(fixuptypes);
|
||||
|
||||
globaldata = nullptr;
|
||||
code = nullptr;
|
||||
strings = nullptr;
|
||||
fixups = nullptr;
|
||||
fixuptypes = nullptr;
|
||||
|
||||
int aa;
|
||||
for (aa = 0; aa < numimports; aa++) {
|
||||
if (imports[aa] != nullptr)
|
||||
free(imports[aa]);
|
||||
}
|
||||
|
||||
for (aa = 0; aa < numexports; aa++)
|
||||
free(exports[aa]);
|
||||
|
||||
for (aa = 0; aa < numSections; aa++)
|
||||
free(sectionNames[aa]);
|
||||
|
||||
if (sectionNames != nullptr) {
|
||||
free(sectionNames);
|
||||
free(sectionOffsets);
|
||||
sectionNames = nullptr;
|
||||
sectionOffsets = nullptr;
|
||||
}
|
||||
|
||||
if (imports != nullptr) {
|
||||
free(imports);
|
||||
free(exports);
|
||||
free(export_addr);
|
||||
imports = nullptr;
|
||||
exports = nullptr;
|
||||
export_addr = nullptr;
|
||||
}
|
||||
numimports = 0;
|
||||
numexports = 0;
|
||||
numSections = 0;
|
||||
}
|
||||
|
||||
const char *ccScript::GetSectionName(int32_t offs) const {
|
||||
int i;
|
||||
for (i = 0; i < numSections; i++) {
|
||||
if (sectionOffsets[i] < offs)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
// if no sections in script, return unknown
|
||||
if (i == 0)
|
||||
return "(unknown section)";
|
||||
|
||||
return sectionNames[i - 1];
|
||||
}
|
||||
|
||||
} // namespace AGS3
|
||||
Reference in New Issue
Block a user