Initial commit
This commit is contained in:
302
engines/chamber/resdata.cpp
Normal file
302
engines/chamber/resdata.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/* 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/file.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/decompr.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern void askDisk2(void);
|
||||
extern int16 loadSplash(const char *filename);
|
||||
|
||||
/*
|
||||
Get bank entry
|
||||
TODO: port SeekToString to this routine
|
||||
*/
|
||||
byte *seekToEntry(byte *bank, uint16 num, byte **end) {
|
||||
byte len;
|
||||
byte *p = bank;
|
||||
|
||||
while (num--) {
|
||||
len = *p;
|
||||
p += len;
|
||||
}
|
||||
len = *p;
|
||||
*end = p + len;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
byte *seekToEntryW(byte *bank, uint16 num, byte **end) {
|
||||
uint16 len;
|
||||
byte *p = bank;
|
||||
|
||||
while (num--) {
|
||||
len = p[0] | (p[1] << 8);
|
||||
p += len;
|
||||
}
|
||||
len = p[0] | (p[1] << 8);
|
||||
*end = p + len;
|
||||
return p + 2;
|
||||
}
|
||||
|
||||
uint16 loadFile(const char *filename, byte *buffer) {
|
||||
Common::File in;
|
||||
|
||||
in.open(filename);
|
||||
|
||||
if (!in.isOpen())
|
||||
return 0;
|
||||
|
||||
return in.read(buffer, 0xFFFF0);
|
||||
}
|
||||
|
||||
uint16 saveFile(char *filename, byte *buffer, uint16 size) {
|
||||
warning("STUB: SaveFile(%s, buffer, %d)", filename, size);
|
||||
return 0;
|
||||
#if 0
|
||||
int16 f;
|
||||
int16 wlen;
|
||||
f = open(filename, O_RDONLY | O_BINARY);
|
||||
if (f == -1)
|
||||
return 0;
|
||||
wlen = write(f, buffer, size);
|
||||
close(f);
|
||||
if (wlen == -1)
|
||||
return 0;
|
||||
return (uint16)wlen;
|
||||
#endif
|
||||
}
|
||||
|
||||
int16 loadFilesList(ResEntry_t *entries) {
|
||||
int16 i;
|
||||
for (i = 0; entries[i].name[0] != '$'; i++) {
|
||||
if (!loadFile(entries[i].name, (byte *)entries[i].buffer))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
byte *arpla_data = NULL;
|
||||
byte *aleat_data = NULL;
|
||||
byte *icone_data = NULL;
|
||||
byte *souco_data = NULL;
|
||||
byte *carpc_data = NULL;
|
||||
byte *souri_data = NULL;
|
||||
byte *templ_data = NULL;
|
||||
byte *mursm_data = NULL;
|
||||
byte *gauss_data = NULL;
|
||||
byte *lutin_data = NULL;
|
||||
byte *anima_data = NULL;
|
||||
byte *anico_data = NULL;
|
||||
byte *zones_data = NULL;
|
||||
|
||||
ResEntry_tp res_static[] = {
|
||||
{"ARPLA.BIN", &arpla_data},
|
||||
{"ALEAT.BIN", &aleat_data},
|
||||
{"ICONE.BIN", &icone_data},
|
||||
{"SOUCO.BIN", &souco_data},
|
||||
{"CARPC.BIN", &carpc_data},
|
||||
{"SOURI.BIN", &souri_data},
|
||||
{"TEMPL.BIN", &templ_data},
|
||||
{"MURSM.BIN", &mursm_data},
|
||||
{"GAUSS.BIN", &gauss_data},
|
||||
{"LUTIN.BIN", &lutin_data},
|
||||
{"ANIMA.BIN", &anima_data},
|
||||
{"ANICO.BIN", &anico_data},
|
||||
{"ZONES.BIN", &zones_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load resident data files. Original game has all these data files embedded in the executable.
|
||||
NB! Static data includes the font file, don't use any text print routines before it's loaded.
|
||||
*/
|
||||
int16 loadStaticData() {
|
||||
Common::File pxi;
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA)
|
||||
pxi.open("kult1.pxi");
|
||||
else
|
||||
pxi.open("ere.pxi");
|
||||
|
||||
uint numMods = pxi.readUint16BE();
|
||||
uint modBase = 2 + numMods * 4;
|
||||
|
||||
uint32 *modOffs = new uint32[numMods];
|
||||
|
||||
for (uint i = 0; i < numMods; i++)
|
||||
modOffs[i] = modBase + pxi.readUint32BE();
|
||||
|
||||
// So far, take only resource 0. Additional selection is required
|
||||
uint32 modOfs = modOffs[0];
|
||||
pxi.seek(modOfs);
|
||||
|
||||
uint32 modPsize = pxi.readUint32BE();
|
||||
uint32 modUsize = pxi.readUint32BE();
|
||||
|
||||
byte *modData = new byte[modPsize];
|
||||
|
||||
pxi.read(modData, modPsize);
|
||||
|
||||
warning("Module %d : at 0x%6X, psize = %6d, usize = %6d", 0, modOfs, modPsize, modUsize);
|
||||
|
||||
byte *rawData = new byte[modUsize];
|
||||
g_vm->_pxiData = rawData;
|
||||
|
||||
uint32 rawSize = decompress(modData, rawData);
|
||||
warning("decoded to %d bytes", rawSize);
|
||||
|
||||
delete[] modData;
|
||||
|
||||
if (rawData[0] != 'M' || rawData[1] != 'Z')
|
||||
error("Module decompressed, but is not an EXE file");
|
||||
|
||||
uint16 hdrparas = READ_LE_UINT16(rawData + 8);
|
||||
uint32 off = hdrparas * 16;
|
||||
|
||||
warning("hdrparas: 0x%x, off: 0x%x", hdrparas, off);
|
||||
|
||||
const char *firstRes = "ARPLA.";
|
||||
int32 resOffs = -1;
|
||||
|
||||
for (uint i = off; i < rawSize; i++)
|
||||
if (!strncmp((char *)rawData + i, firstRes, strlen(firstRes))) {
|
||||
resOffs = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (resOffs == -1)
|
||||
error("No internal resources table found");
|
||||
|
||||
warning("Found resources table at 0x%X", resOffs - off);
|
||||
|
||||
while (rawData[resOffs] != '$') {
|
||||
Common::String resName((char *)rawData + resOffs);
|
||||
|
||||
resOffs += MAX(resName.size() + 1, 10U); // work around malformed resource entry in the US release
|
||||
|
||||
uint16 reso = READ_LE_UINT16(rawData + resOffs);
|
||||
resOffs += 2;
|
||||
uint16 ress = READ_LE_UINT16(rawData + resOffs);
|
||||
resOffs += 2;
|
||||
|
||||
warning("%s : %X", resName.c_str(), ress * 16 + reso);
|
||||
|
||||
int i;
|
||||
for (i = 0; res_static[i].name[0] != '$'; i++) { // Yeah, linear search
|
||||
if (!strcmp(res_static[i].name, resName.c_str())) {
|
||||
*res_static[i].buffer = rawData + off + ress * 16 + reso;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res_static[i].name[0] == '$')
|
||||
warning("loadStaticData(): Extra resource %s", resName.c_str());
|
||||
}
|
||||
|
||||
// And now check that everything was loaded
|
||||
bool missing = false;
|
||||
for (int i = 0; res_static[i].name[0] != '$'; i++) {
|
||||
if (*res_static[i].buffer == NULL) {
|
||||
warning("loadStaticData(): Resource %s is not present", res_static[i].name);
|
||||
missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] modOffs;
|
||||
|
||||
return !missing;
|
||||
}
|
||||
|
||||
ResEntry_t res_texts[] = {
|
||||
{"VEPCI.BIN", vepci_data},
|
||||
{"MOTSI.BIN", motsi_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (commands/names)
|
||||
*/
|
||||
int16 loadVepciData() {
|
||||
return loadFilesList(res_texts);
|
||||
}
|
||||
|
||||
int16 loadFond(void) {
|
||||
return loadSplash("FOND.BIN");
|
||||
}
|
||||
|
||||
ResEntry_t res_sprites[] = {
|
||||
{"PUZZL.BIN", puzzl_data},
|
||||
{"SPRIT.BIN", sprit_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
int16 loadSpritesData(void) {
|
||||
return loadFilesList(res_sprites);
|
||||
}
|
||||
|
||||
ResEntry_t res_person[] = {
|
||||
{"PERS1.BIN", pers1_data},
|
||||
{"PERS2.BIN", pers2_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
int16 loadPersData(void) {
|
||||
/*Originally it tries to load pers1 + pers2 as a single contiguos resource, if have enough memory*/
|
||||
/*If memory is low, necessary file is loaded on demand, according to requested bank resource index*/
|
||||
/*Here we load both parts to their own memory buffers then select one in LoadPersSprit()*/
|
||||
return loadFilesList(res_person);
|
||||
}
|
||||
|
||||
ResEntry_t res_desci[] = {
|
||||
{"DESCI.BIN", desci_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (obj. descriptions)
|
||||
*/
|
||||
int16 loadDesciData(void) {
|
||||
while (!loadFilesList(res_desci))
|
||||
askDisk2();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ResEntry_t res_diali[] = {
|
||||
{"DIALI.BIN", diali_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (dialogs)
|
||||
*/
|
||||
int16 loadDialiData(void) {
|
||||
while (!loadFilesList(res_diali))
|
||||
askDisk2();
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
Reference in New Issue
Block a user