mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 04:28:37 +00:00
270 lines
6.6 KiB
C++
270 lines
6.6 KiB
C++
/* 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 "common/endian.h"
|
|
#include "cruise/cruise_main.h"
|
|
|
|
namespace Cruise {
|
|
|
|
exportEntryStruct *parseExport(int *out1, int *pExportedFuncionIdx, char *buffer) {
|
|
char localBuffer[256];
|
|
char functionName[256];
|
|
char overlayName[256];
|
|
char *dotPtr;
|
|
char *ptr2;
|
|
int idx;
|
|
int numSymbGlob;
|
|
exportEntryStruct *currentExportEntry;
|
|
char *entity1Name;
|
|
|
|
*out1 = 0;
|
|
*pExportedFuncionIdx = 0;
|
|
|
|
Common::strlcpy(localBuffer, buffer, sizeof(localBuffer));
|
|
dotPtr = strchr(localBuffer, '.');
|
|
|
|
if (dotPtr) {
|
|
Common::strlcpy(functionName, dotPtr + 1, sizeof(functionName));
|
|
*dotPtr = 0;
|
|
|
|
Common::strcpy_s(overlayName, localBuffer);
|
|
} else {
|
|
overlayName[0] = 0;
|
|
|
|
Common::strlcpy(functionName, buffer, sizeof(functionName));
|
|
}
|
|
|
|
ptr2 = strchr((char *)functionName, ':');
|
|
|
|
if (ptr2) {
|
|
*ptr2 = 0;
|
|
|
|
*out1 = 1;
|
|
}
|
|
|
|
strToUpper(overlayName);
|
|
strToUpper(functionName);
|
|
if (strlen((char *)overlayName) == 0)
|
|
return nullptr;
|
|
|
|
idx = findOverlayByName2(overlayName);
|
|
|
|
if (idx == -4)
|
|
return (nullptr);
|
|
|
|
if (overlayTable[idx].alreadyLoaded == 0)
|
|
return (nullptr);
|
|
|
|
if (!overlayTable[idx].ovlData)
|
|
return (nullptr);
|
|
|
|
numSymbGlob = overlayTable[idx].ovlData->numSymbGlob;
|
|
currentExportEntry = overlayTable[idx].ovlData->arraySymbGlob;
|
|
entity1Name = overlayTable[idx].ovlData->arrayNameSymbGlob;
|
|
|
|
if (!entity1Name)
|
|
return (nullptr);
|
|
|
|
for (int i = 0; i < numSymbGlob; i++) {
|
|
char exportedName[256];
|
|
char *name = entity1Name + currentExportEntry->offsetToName;
|
|
|
|
Common::strlcpy(exportedName, name, sizeof(exportedName));
|
|
strToUpper(exportedName);
|
|
|
|
if (!strcmp(functionName, exportedName)) {
|
|
*pExportedFuncionIdx = idx;
|
|
|
|
return (currentExportEntry);
|
|
}
|
|
|
|
currentExportEntry++;
|
|
}
|
|
|
|
return (nullptr);
|
|
}
|
|
|
|
int updateScriptImport(int ovlIdx) {
|
|
char buffer[256];
|
|
ovlDataStruct *ovlData;
|
|
int numData3;
|
|
int size5;
|
|
int numRelocGlob;
|
|
int param;
|
|
int var_32;
|
|
ovlData3Struct *pScript;
|
|
// char* arrayRelocGlob;
|
|
// char* namePtr;
|
|
// char* arrayMsgRelHeader;
|
|
|
|
if (!overlayTable[ovlIdx].ovlData)
|
|
return (-4);
|
|
|
|
ovlData = overlayTable[ovlIdx].ovlData;
|
|
|
|
numData3 = ovlData->numProc;
|
|
size5 = ovlData->numRel;
|
|
numRelocGlob = ovlData->numRelocGlob;
|
|
param = 0;
|
|
|
|
// do it for the 2 first string types
|
|
do {
|
|
|
|
if (param == 0) {
|
|
var_32 = numData3;
|
|
} else {
|
|
var_32 = size5;
|
|
}
|
|
|
|
if (var_32) {
|
|
int i = 0;
|
|
do {
|
|
importScriptStruct *ptrImportData;
|
|
const char *ptrImportName;
|
|
uint8 *ptrData;
|
|
|
|
if (param == 0)
|
|
pScript = getOvlData3Entry(ovlIdx, i);
|
|
else
|
|
pScript = scriptFunc1Sub2(ovlIdx, i);
|
|
|
|
ptrImportData = (importScriptStruct *)(pScript->dataPtr + pScript->offsetToImportData); // import data
|
|
ptrImportName = (const char*)(pScript->dataPtr + pScript->offsetToImportName); // import name
|
|
ptrData = pScript->dataPtr;
|
|
|
|
if (pScript->numRelocGlob > 0) {
|
|
int counter = pScript->numRelocGlob;
|
|
|
|
do {
|
|
int param2 = ptrImportData->type;
|
|
|
|
if (param2 != 70) {
|
|
exportEntryStruct * ptrDest2;
|
|
int out1;
|
|
int out2;
|
|
|
|
Common::strlcpy(buffer, ptrImportName + ptrImportData->offsetToName, sizeof(buffer));
|
|
ptrDest2 = parseExport(&out1, &out2, buffer);
|
|
|
|
if (ptrDest2 && out2) {
|
|
int temp =
|
|
ptrImportData->
|
|
offset;
|
|
if (out1) { //is sub function... (ie 'invent.livre:s')
|
|
uint8 *ptr = ptrData + temp;
|
|
|
|
*(ptr + 1) = out2;
|
|
WRITE_BE_UINT16(ptr + 2, ptrDest2->idx);
|
|
} else {
|
|
if (param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50) { // this patch a double push
|
|
uint8 *ptr = ptrData + temp;
|
|
|
|
*(ptr + 1) = 0;
|
|
*(ptr + 2) = out2; // update the overlay number
|
|
|
|
WRITE_BE_UINT16(ptr + 4, ptrDest2->idx);
|
|
} else {
|
|
int var_4 = ptrDest2->var4;
|
|
|
|
if (var_4 & 1) {
|
|
param2 = 8;
|
|
} else {
|
|
param2 = 16;
|
|
}
|
|
|
|
if (var_4 >= 0 && var_4 <= 3) {
|
|
param2 |= 5;
|
|
} else {
|
|
param2 |= 6;
|
|
}
|
|
|
|
*(ptrData + temp) = param2;
|
|
*(ptrData + temp + 1) = out2;
|
|
|
|
WRITE_BE_UINT16(ptrData + temp + 2, ptrDest2->idx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ptrImportData++;
|
|
} while (--counter);
|
|
}
|
|
|
|
} while (++i < var_32);
|
|
|
|
}
|
|
|
|
} while (++param < 2);
|
|
|
|
if (ovlData->arrayRelocGlob && ovlData->arrayNameRelocGlob && numRelocGlob) {
|
|
int numImport2 = numRelocGlob;
|
|
for (int i = 0; i < numImport2; i++) {
|
|
int out1;
|
|
int foundExportIdx;
|
|
exportEntryStruct *pFoundExport;
|
|
int linkType;
|
|
int linkEntryIdx;
|
|
|
|
Common::strlcpy(buffer, ovlData->arrayNameRelocGlob + ovlData->arrayRelocGlob[i].nameOffset, sizeof(buffer));
|
|
|
|
pFoundExport = parseExport(&out1, &foundExportIdx, buffer);
|
|
|
|
linkType = ovlData->arrayRelocGlob[i].linkType;
|
|
linkEntryIdx = ovlData->arrayRelocGlob[i].linkIdx;
|
|
|
|
if (pFoundExport && foundExportIdx) {
|
|
switch (linkType) {
|
|
case 0: { // verb
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].verbOverlay = foundExportIdx;
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].verbNumber = pFoundExport->idx;
|
|
break;
|
|
}
|
|
case 1: { // obj1
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].obj1Overlay = foundExportIdx;
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].obj1Number = pFoundExport->idx;
|
|
break;
|
|
}
|
|
case 2: { // obj2
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].obj2Overlay = foundExportIdx;
|
|
ovlData->arrayMsgRelHeader[linkEntryIdx].obj2Number = pFoundExport->idx;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
// check that the newly loaded isn't used by the already loaded overlays
|
|
void updateAllScriptsImports() {
|
|
for (int i = 0; i < 90; i++) {
|
|
if (overlayTable[i].ovlData && overlayTable[i].alreadyLoaded)
|
|
updateScriptImport(i);
|
|
}
|
|
}
|
|
|
|
} // End of namespace Cruise
|