Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,309 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/datapacker.h"
#include "common/stream.h"
#include "common/textconsole.h"
namespace ICB {
// Just initialise the buffer position and the min, max values
// used for packing and error detection
DataPacker::DataPacker() {
readMode = false;
iMode = NO_MODE;
iPackMode = NO_PACKMODE;
pos = 0;
packMin = -(1 << (PACK_BIT_SIZE - 1));
packMax = +((1 << PACK_BIT_SIZE) - 1);
// clear out the data buffer
ClearBuffer();
}
// Could do something here - but not sure what !
// Could error check on pos = 0 : but might lead to trouble
DataPacker::~DataPacker() {}
// Start the bit-packing process : say if we are in READ or WRITE mode
DataPacker::ReturnCodes DataPacker::open(const ModeEnum mode, const PackModeEnum packMode) {
if (pos != 0) {
return BAD_POS;
}
if ((mode != READ) && (mode != WRITE)) {
return BAD_MODE;
}
if ((packMode != PACK) && (packMode != DONT_PACK)) {
return BAD_PACKMODE;
}
if (mode == READ) {
readMode = true;
pos = PACK_CHUNK_SIZE;
}
if (mode == WRITE) {
readMode = false;
pos = 0;
}
// clear out the data buffer
ClearBuffer();
iMode = mode;
iPackMode = packMode;
return OK;
}
// Put a value into the bit-stream
DataPacker::ReturnCodes DataPacker::put(const int32 value, Common::WriteStream *stream) {
if (iMode != WRITE) {
return BAD_MODE;
}
if ((iPackMode != PACK) && (iPackMode != DONT_PACK)) {
return BAD_PACKMODE;
}
if ((pos < 0) || (pos >= PACK_CHUNK_SIZE)) {
return BAD_POS;
}
// For DONT_PACK mode just write the data straight out
if (iPackMode == DONT_PACK) {
// Check it is a legal value : 16-bits
int32 lvarMin = -(1 << 15);
int32 lvarMax = +((1 << 15) - 1);
if ((value < lvarMin) || (value > lvarMax)) {
return BAD_VALUE;
}
int32 nItems = 2;
int16 v16 = (int16)value;
int32 ret = stream->write((const void *)&v16, nItems);
if (ret != nItems) {
return WRITE_ERROR;
}
return OK;
}
// Convert the value to be within limits
int32 v = value - packMin;
// Check the value is within range
if ((v < 0) || (v > packMax)) {
return BAD_VALUE;
}
// Add the value in
if (pos == 0) {
buffer[0] = (uint8)((v >> 6) & 0xFF); // v's top 8-bits
buffer[1] = (uint8)((v & 0x3F) << 2); // v's bottom 6-bits into top 6-bits
} else if (pos == 1) {
buffer[1] |= ((v >> 12) & 0x03); // v's top 2-bits into bottom 2
buffer[2] = (uint8)((v >> 4) & 0xFF); // v's middle 8-bits
buffer[3] = (uint8)((v & 0x0F) << 4); // v's bottom 4-bits into top 4
} else if (pos == 2) {
buffer[3] |= ((v >> 10) & 0x0F); // v's top 4-bits into bottom 4
buffer[4] = (uint8)((v >> 2) & 0xFF); // v's middle 8-bits
buffer[5] = (uint8)((v & 0x03) << 6); // v's bottom 2-bits into top 2
} else if (pos == 3) {
buffer[5] |= ((v >> 8) & 0x3F); // v's top 6-bits into bottom 6
buffer[6] = (uint8)(v & 0xFF); // v's bottom 8-bits
}
// Put data into the next position !
pos++;
// Do we need to output the current buffer ?
if (pos == PACK_CHUNK_SIZE) {
#if 0
printf("WRITE %X %X %X %X %X %X %X",
buffer[0], buffer[1], buffer[2], buffer[3],
buffer[4], buffer[5], buffer[6]);
#endif // #if 0
// Write out the buffer
int32 nItems = BUFFER_BYTE_SIZE;
int32 ret = stream->write((const void *)buffer, nItems);
if (ret != nItems) {
return WRITE_ERROR;
}
pos = 0;
ClearBuffer();
}
return OK;
}
// Get a value from the bit-stream
DataPacker::ReturnCodes DataPacker::Get(int32 &value, Common::SeekableReadStream *stream) {
if (iMode != READ) {
return BAD_MODE;
}
if ((iPackMode != PACK) && (iPackMode != DONT_PACK)) {
return BAD_PACKMODE;
}
if ((pos < 0) || (pos > PACK_CHUNK_SIZE)) {
return BAD_POS;
}
// For DONT_PACK mode just read the data straight in
if (iPackMode == DONT_PACK) {
int32 nItems = 2;
int16 v16;
int32 ret = stream->read((void *)&v16, nItems);
value = v16;
if (ret != nItems) {
return READ_ERROR;
}
return OK;
}
// Do we need to fill up the current buffer ?
if (pos == PACK_CHUNK_SIZE) {
// Read into the buffer
int32 nItems = BUFFER_BYTE_SIZE;
int32 ret = stream->read((void *)buffer, nItems);
if (ret != nItems) {
return READ_ERROR;
}
#if 0
printf("READ %X %X %X %X %X %X %X",
buffer[0], buffer[1], buffer[2], buffer[3],
buffer[4], buffer[5], buffer[6]);
#endif
pos = 0;
}
int32 v = 0;
// Get the value out of the buffer
if (pos == 0) {
v = (buffer[0] << 6); // v's top 8-bits
v |= (buffer[1] >> 2); // v's bottom 6-bits into top 6-bits
} else if (pos == 1) {
v = ((buffer[1] & 0x03) << 12); // v's top 2-bits into bottom 2
v |= (buffer[2] << 4); // v's middle 8-bits
v |= (buffer[3] >> 4); // v's bottom 4-bits into top 4
} else if (pos == 2) {
v = ((buffer[3] & 0x0F) << 10); // v's top 4-bits into bottom 4
v |= (buffer[4] << 2); // v's middle 8-bits
v |= (buffer[5] >> 6); // v's bottom 2-bits into top 2
} else if (pos == 3) {
v = (buffer[5] & 0x3F) << 8; // v's top 6-bits into bottom 6
v |= buffer[6]; // v's bottom 8-bits
}
// Get data from the next position !
pos++;
// Check the value is within range
// This should just not be possible !
if ((v < 0) || (v > packMax)) {
return BAD_VALUE;
}
// Convert the extracted value to be in normal signed/unsigned limits
value = v + packMin;
return OK;
}
// Stop the bit-packing process : will output any remaining data
DataPacker::ReturnCodes DataPacker::close(Common::WriteStream *stream) {
if ((iMode == WRITE) && (pos != 0)) {
// Write out the remaining data items
int32 nItems = BUFFER_BYTE_SIZE;
int32 ret = stream->write((const void *)buffer, nItems);
if (ret != nItems) {
return WRITE_ERROR;
}
} else {
error("Wrong close-function called, passed WriteStream without being in WRITE-mode");
}
iMode = NO_MODE;
iPackMode = NO_PACKMODE;
pos = 0;
ClearBuffer();
return OK;
}
DataPacker::ReturnCodes DataPacker::close(Common::SeekableReadStream *stream) {
// TODO: If write mode.
if ((iMode == WRITE) && (pos != 0)) {
error("Wrong close-function called, passed ReadStream in WRITE-mode");
}
iMode = NO_MODE;
iPackMode = NO_PACKMODE;
pos = 0;
ClearBuffer();
return OK;
}
// Copy constructor
DataPacker::DataPacker(DataPacker &src) { *this = src; }
// Assignment operator
DataPacker &DataPacker::operator=(DataPacker &b) {
readMode = b.readMode;
iMode = b.iMode;
iPackMode = b.iPackMode;
pos = b.pos;
packMin = b.packMin;
packMax = b.packMax;
for (int32 i = 0; i < BUFFER_BYTE_SIZE; i++) {
buffer[i] = b.buffer[i];
}
return *this;
}
// Clear out the data buffer
void DataPacker::ClearBuffer() {
for (int32 i = 0; i < BUFFER_BYTE_SIZE; i++) {
buffer[i] = 0x00;
}
}
} // End of namespace ICB

View File

@@ -0,0 +1,89 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_DATAPACKER_HH
#define ICB_DATAPACKER_HH
#include "common/stream.h"
namespace ICB {
// Pack: 4 values into 4*14 bits = 56-bits = 7 bytes
#define BUFFER_BYTE_SIZE (7)
#define PACK_BIT_SIZE (14)
#define PACK_CHUNK_SIZE (4)
class DataPacker {
public:
DataPacker();
~DataPacker();
// Copy constructor
DataPacker(DataPacker &src);
// Assignment operator
DataPacker &operator=(DataPacker &b);
enum ModeEnum { NO_MODE, READ, WRITE };
enum PackModeEnum { NO_PACKMODE, PACK, DONT_PACK };
enum ReturnCodes { OK, BAD_POS, BAD_MODE, BAD_PACKMODE, READ_ERROR, WRITE_ERROR, BAD_READFUNC, BAD_WRITEFUNC, BAD_VALUE };
// Start the bit-packing process : say if we are in READ or WRITE mode
ReturnCodes open(const ModeEnum mode, const PackModeEnum packMode);
// Put a value into the bit-stream
ReturnCodes put(const int32 value, Common::WriteStream *fh);
// Get a value from the bit-stream
ReturnCodes Get(int32 &value, Common::SeekableReadStream *stream);
// Stop the bit-packing process : will output any remaining data
ReturnCodes close(Common::WriteStream *stream);
ReturnCodes close(Common::SeekableReadStream *stream);
// Simple inspectors
int32 Pos() const { return pos; }
int32 PackMin() const { return packMin; }
int32 PackMax() const { return packMax; }
private:
void ClearBuffer();
bool readMode;
ModeEnum iMode;
PackModeEnum iPackMode;
int32 pos;
int32 packMin;
int32 packMax;
uint8 buffer[BUFFER_BYTE_SIZE];
};
} // End of namespace ICB
#endif // #ifndef DATAPACKER_HH

View File

@@ -0,0 +1,347 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PC_PROPS_H
#define ICB_PC_PROPS_H
#include "engines/icb/common/px_staticlayers.h" // for types + defines
#include "engines/icb/common/px_types.h"
namespace ICB {
#define PCPROP_SCHEMA 3
#define PCPROP_ID MKTAG('p', 'o', 'r', 'P')
#define PCINTERACTIBLE_SCHEMA 2
#define PCINTERACTIBLE_ID MKTAG('k', 'c', 'a', 'T')
#define PCSETFILE_ID_ICB MKTAG('t', 'n', 'i', 'm')
#define PCSETFILE_ID_ELDORADO MKTAG('t', 'n', 'i', 'p')
typedef struct _pcSetHeader {
uint32 id;
uint32 cameraOffset;
uint32 lightOffset;
uint32 propOffset;
uint32 layerOffset;
uint32 backgroundOffset;
uint32 interactiblesOffset;
} _pcSetHeader;
class pcInteractible {
private:
char name[32];
int32 width;
int32 height;
int32 x;
int32 y;
uint8 *mask;
public:
pcInteractible(uint8 *interactiblePtr) {
uint8 *ptr = interactiblePtr;
memcpy(name, ptr, 32);
ptr += 32;
width = (int32)READ_LE_U32(ptr);
ptr += 4;
height = (int32)READ_LE_U32(ptr);
ptr += 4;
x = (int32)READ_LE_U32(ptr);
ptr += 4;
y = (int32)READ_LE_U32(ptr);
ptr += 4;
mask = ptr;
}
};
class pcInteractibleFile {
private:
uint32 id;
uint32 schema;
uint32 mapping;
uint32 quantity;
pcInteractible **interactibles;
public:
pcInteractibleFile() : id(PCINTERACTIBLE_ID), schema(PCINTERACTIBLE_SCHEMA), mapping(0), quantity(0), interactibles(nullptr) {}
pcInteractibleFile(uint8 *interactibleData) {
uint8 *ptr = interactibleData;
id = READ_LE_U32(ptr);
ptr += 4;
schema = READ_LE_U32(ptr);
ptr += 4;
mapping = READ_LE_U32(ptr);
ptr += 4;
quantity = READ_LE_U32(ptr);
ptr += 4;
interactibles = new pcInteractible *[quantity];
for (uint32 i = 0; i < quantity; i++) {
interactibles[i] = new pcInteractible(interactibleData + READ_LE_U32(ptr));
ptr += 4;
}
}
~pcInteractibleFile() {
for (uint32 i = 0; i < quantity; i++) {
delete interactibles[i];
}
delete[] interactibles;
interactibles = 0;
}
uint32 GetID() { return id; }
void SetId(uint32 i) { id = i; }
uint32 GetQty() { return quantity; }
void SetQty(uint32 q) { quantity = q; }
pcInteractible *GetInt(uint32 i) { return interactibles[i]; }
void SetSchema(uint32 s) { schema = s; }
uint32 GetSchema() const {
if (id != PCINTERACTIBLE_ID)
return 0;
else
return schema;
}
};
class pcPropRGBState {
private:
uint16 *zPtrs[TILE_COUNT];
uint16 *semiPtrs[TILE_COUNT];
uint16 nLRBgTiles;
uint16 nLRFgTiles;
uint16 nHRBgTiles;
uint16 nHRFgTiles;
uint32 *palettePtr;
uint16 bgLRSurfaceWidth;
uint16 bgLRSurfaceHeight;
uint16 fgLRSurfaceWidth;
uint16 fgLRSurfaceHeight;
uint16 bgHRSurfaceWidth;
uint16 bgHRSurfaceHeight;
uint16 fgHRSurfaceWidth;
uint16 fgHRSurfaceHeight;
uint8 *bgLRRleDataPtr;
uint8 *fgLRRleDataPtr;
uint8 *bgHRRleDataPtr;
uint8 *fgHRRleDataPtr;
LRECT *tileRects;
public:
pcPropRGBState(uint8 *propBasePtr, uint32 dataOffset) {
uint8 *ptr = propBasePtr + dataOffset;
for (int32 i = 0; i < TILE_COUNT; i++) {
zPtrs[i] = 0;
if (uint32 offset = READ_LE_U32(ptr)) {
zPtrs[i] = (uint16 *)(propBasePtr + offset);
}
ptr += 4;
}
for (int32 i = 0; i < TILE_COUNT; i++) {
semiPtrs[i] = 0;
if (uint32 offset = READ_LE_U32(ptr)) {
semiPtrs[i] = (uint16 *)(propBasePtr + offset);
}
ptr += 4;
}
nLRBgTiles = READ_LE_U16(ptr);
ptr += 2;
nLRFgTiles = READ_LE_U16(ptr);
ptr += 2;
nHRBgTiles = READ_LE_U16(ptr);
ptr += 2;
nHRFgTiles = READ_LE_U16(ptr);
ptr += 2;
palettePtr = (uint32 *)(propBasePtr + READ_LE_U32(ptr));
ptr += 4;
bgLRSurfaceWidth = READ_LE_U16(ptr);
ptr += 2;
bgLRSurfaceHeight = READ_LE_U16(ptr);
ptr += 2;
fgLRSurfaceWidth = READ_LE_U16(ptr);
ptr += 2;
fgLRSurfaceHeight = READ_LE_U16(ptr);
ptr += 2;
bgHRSurfaceWidth = READ_LE_U16(ptr);
ptr += 2;
bgHRSurfaceHeight = READ_LE_U16(ptr);
ptr += 2;
fgHRSurfaceWidth = READ_LE_U16(ptr);
ptr += 2;
fgHRSurfaceHeight = READ_LE_U16(ptr);
ptr += 2;
bgLRRleDataPtr = propBasePtr + READ_LE_U32(ptr);
ptr += 4;
fgLRRleDataPtr = propBasePtr + READ_LE_U32(ptr);
ptr += 4;
bgHRRleDataPtr = propBasePtr + READ_LE_U32(ptr);
ptr += 4;
fgHRRleDataPtr = propBasePtr + READ_LE_U32(ptr);
ptr += 4;
tileRects = (LRECT *)ptr;
}
uint16 *GetZTileTable(int32 t) { return zPtrs[t]; }
uint16 *GetSemiTileTable(int32 t) { return semiPtrs[t]; }
uint16 GetLRBgTileQty() { return nLRBgTiles; }
uint16 GetLRFgTileQty() { return nLRFgTiles; }
uint16 GetHRBgTileQty() { return nHRBgTiles; }
uint16 GetHRFgTileQty() { return nHRFgTiles; }
uint32 *GetPalette() { return palettePtr; }
uint16 GetLRBgSurfaceWidth() { return bgLRSurfaceWidth; }
uint16 GetLRBgSurfaceHeight() { return bgLRSurfaceHeight; }
uint16 GetLRFgSurfaceWidth() { return fgLRSurfaceWidth; }
uint16 GetLRFgSurfaceHeight() { return fgLRSurfaceHeight; }
uint16 GetHRBgSurfaceWidth() { return bgHRSurfaceWidth; }
uint16 GetHRBgSurfaceHeight() { return bgHRSurfaceHeight; }
uint16 GetHRFgSurfaceWidth() { return fgHRSurfaceWidth; }
uint16 GetHRFgSurfaceHeight() { return fgHRSurfaceHeight; }
uint8 *GetLRBgRlePtr() { return bgLRRleDataPtr; }
uint8 *GetLRFgRlePtr() { return fgLRRleDataPtr; }
uint8 *GetHRBgRlePtr() { return bgHRRleDataPtr; }
uint8 *GetHRFgRlePtr() { return fgHRRleDataPtr; }
LRECT *GetTileRects() { return tileRects; }
};
class pcPropRGB {
private:
char name[32];
uint32 stateQty;
pcPropRGBState **states;
public:
pcPropRGB(uint8 *propBasePtr, uint32 dataOffset) {
uint8 *ptr = propBasePtr + dataOffset;
memcpy(name, ptr, 32);
ptr += 32;
stateQty = READ_LE_U32(ptr);
ptr += 4;
states = new pcPropRGBState *[stateQty];
for (uint32 i = 0; i < stateQty; i++) {
states[i] = new pcPropRGBState(propBasePtr, READ_LE_U32(ptr));
ptr += 4;
}
}
~pcPropRGB() {
for (uint32 i = 0; i < stateQty; i++) {
delete states[i];
}
delete[] states;
states = 0;
}
const char *GetName() const { return name; }
uint32 GetStateQty() const { return stateQty; }
pcPropRGBState *GetState(uint32 s) { return states[s]; }
};
class pcPropFile {
private:
uint32 id;
uint32 schema;
uint32 mapping;
uint32 propQty;
pcPropRGB **props;
public:
pcPropFile(uint8 *propData) {
uint8 *ptr = propData;
id = READ_LE_U32(ptr);
ptr += 4;
schema = READ_LE_U32(ptr);
ptr += 4;
mapping = READ_LE_U32(ptr);
ptr += 4;
propQty = READ_LE_U32(ptr);
ptr += 4;
props = new pcPropRGB *[propQty];
for (uint32 i = 0; i < propQty; i++) {
props[i] = new pcPropRGB(propData, READ_LE_U32(ptr));
ptr += 4;
}
}
~pcPropFile() {
for (uint32 i = 0; i < propQty; i++) {
delete props[i];
}
delete[] props;
props = 0;
}
uint32 GetId() const { return id; }
uint32 GetPropQty() const { return propQty; }
pcPropRGB *GetProp(uint32 p) { return props[p]; }
uint32 GetSchema() const {
if (id != PCPROP_ID)
return 0;
else
return schema;
}
};
} // End of namespace ICB
#endif // #ifndef PC_PROPS_H

View File

@@ -0,0 +1,90 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_common.h"
#include "engines/icb/common/ptr_util.h"
#include "common/array.h"
namespace ICB {
Common::Array<PointerReference> *g_ptrArray;
namespace MemoryUtil {
const int32 PTR_ARRAY_MAX(1024);
uint32 encodePtr(uint8 *ptr) {
PointerReference ptrRef;
ptrdiff_t diff = ptr - (uint8 *)nullptr;
ptrRef.ref = (uint32)(diff & 0xFFFFFFFF);
ptrRef.ptr = ptr;
// find free slot
for (Common::Array<PointerReference>::iterator it = g_ptrArray->begin(); it < g_ptrArray->end(); it++) {
if (it->ref == 0) {
*it = ptrRef; // store
return ptrRef.ref;
}
}
// append
g_ptrArray->push_back(ptrRef);
if (g_ptrArray->size() >= (uint)PTR_ARRAY_MAX) {
error("MemoryUtil::encodePtr(): too many pointers (MAX = %u)\n", PTR_ARRAY_MAX);
}
return ptrRef.ref;
}
uint8 *resolvePtr(uint32 ref) {
if (ref == 0)
return nullptr;
// do a linear search
for (Common::Array<PointerReference>::iterator it = g_ptrArray->begin(); it < g_ptrArray->end(); it++) {
if (it->ref == ref) {
uint8 *ptr = it->ptr;
// purge
it->ref = 0;
it->ptr = nullptr;
return ptr;
}
}
error("MemoryUtil::resolvePtr(%08x) COULD NOT RESOLVE POINTER!\n", ref);
return nullptr;
}
void clearAllPtrs(void) { g_ptrArray->clear(); }
}
} // End of namespace ICB

View File

@@ -0,0 +1,53 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PTR_UTIL_H
#define ICB_PTR_UTIL_H
#include "engines/icb/common/px_common.h"
#include "common/array.h"
namespace ICB {
// map pointers to 32-bit references (bottom 32-bits of address)
struct PointerReference {
uint32 ref;
uint8 *ptr;
};
extern Common::Array<PointerReference> *g_ptrArray;
namespace MemoryUtil {
uint32 encodePtr(uint8 *ptr);
uint8 *resolvePtr(uint32 ptrRef);
void clearAllPtrs();
}
#endif // PTR_UTIL_H
} // End of namespace ICB

View File

@@ -0,0 +1,133 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_2drealline.h"
#include "math/utils.h"
namespace ICB {
typedef float PXfloat;
typedef float PXreal;
#define REAL_ZERO 0.0f
#define REAL_TWO 2.0f
#define REAL_MAX FLT_MAX
px2DRealLine::IntersectionLogicVal px2DRealLine::Intersects(const px2DRealLine &oLineB, px2DRealPoint &oIntersection) const {
PXfloat fAX, fBX, fCX, fAY, fBY, fCY;
PXfloat fX1Low, fX1High, fY1Low, fY1High;
PXfloat fD, fE, fF;
// Initialize return value (costs little and tidies up code no end).
oIntersection.SetX(REAL_MAX);
oIntersection.SetY(REAL_MAX);
// Work out some commonly used terms.
fAX = m_fX2 - m_fX1;
fBX = oLineB.m_fX1 - oLineB.m_fX2;
// X bounding box test.
if (fAX < REAL_ZERO) {
fX1Low = m_fX2;
fX1High = m_fX1;
} else {
fX1High = m_fX2;
fX1Low = m_fX1;
}
if (fBX > REAL_ZERO) {
if ((fX1High < oLineB.m_fX2) || oLineB.m_fX1 < fX1Low)
return DONT_INTERSECT;
} else {
if ((fX1High < oLineB.m_fX1) || oLineB.m_fX2 < fX1Low)
return DONT_INTERSECT;
}
// More common terms.
fAY = m_fY2 - m_fY1;
fBY = oLineB.m_fY1 - oLineB.m_fY2;
// Y bounding box test.
if (fAY < REAL_ZERO) {
fY1Low = m_fY2;
fY1High = m_fY1;
} else {
fY1High = m_fY2;
fY1Low = m_fY1;
}
if (fBY > REAL_ZERO) {
if ((fY1High < oLineB.m_fY2) || oLineB.m_fY1 < fY1Low)
return DONT_INTERSECT;
} else {
if ((fY1High < oLineB.m_fY1) || oLineB.m_fY2 < fY1Low)
return DONT_INTERSECT;
}
// Couldn't dismiss the lines on their bounding rectangles, so do a proper intersection.
fCX = m_fX1 - oLineB.m_fX1;
fCY = m_fY1 - oLineB.m_fY1;
fD = (fBY * fCX) - (fBX * fCY);
fF = (fAY * fBX) - (fAX * fBY);
if (fF > REAL_ZERO) {
if ((fD < REAL_ZERO) || (fD > fF))
return DONT_INTERSECT;
} else {
if ((fD > REAL_ZERO) || (fD < fF))
return DONT_INTERSECT;
}
fE = (fAX * fCY) - (fAY * fCX);
if (fF > REAL_ZERO) {
if ((fE < REAL_ZERO) || (fE > fF))
return DONT_INTERSECT;
} else {
if ((fE > REAL_ZERO) || (fE < fF))
return DONT_INTERSECT;
}
// At this point, we can say that the lines do intersect as int32 as they are not
// colinear (colinear is indicated by fF == 0.0).
if (fabs(fF - REAL_ZERO) < (FLT_MIN * 10.0f))
return COLLINEAR;
// Right, lines do intersect, so calculate where.
PXfloat fNum, fOffset;
fNum = fD * fAX;
fOffset = SameSigns(fNum, fF) ? fF / REAL_TWO : -fF / REAL_TWO;
oIntersection.SetX(m_fX1 + (fNum + fOffset) / fF);
fNum = fD * fAY;
fOffset = SameSigns(fNum, fF) ? fF / REAL_TWO : -fF / REAL_TWO;
oIntersection.SetY(m_fY1 + (fNum + fOffset) / fF);
return DO_INTERSECT;
}
} // End of namespace ICB

View File

@@ -0,0 +1,97 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX2DLINE_H_INCLUDED
#define ICB_PX2DLINE_H_INCLUDED
#include "engines/icb/common/px_array.h"
#include "engines/icb/common/px_2drealpoint.h"
namespace ICB {
// Note, this header file needs somethings :
// e.g. PXreal, REAL_ZERO
#ifndef REAL_ZERO
#error "REAL_ZERO not defined in px2drealline.h"
#endif // #ifndef REAL_ZERO
// Here I define an array type for the class. This neatens syntax and also allows pxArrays of pxArrays to be declared.
class px2DRealLine;
typedef rcActArray<px2DRealLine> px2DRealLineArray;
// Holds a line on a plane as a pair of integer endpoints, and provides functions for working with them.
class px2DRealLine {
public:
// Definitions for this class.
enum IntersectionLogicVal { DONT_INTERSECT, DO_INTERSECT, COLLINEAR };
// Default constructor and destructor.
inline px2DRealLine() {
m_fX1 = REAL_ZERO;
m_fY1 = REAL_ZERO;
m_fX2 = REAL_ZERO;
m_fY2 = REAL_ZERO;
}
inline ~px2DRealLine() { ; }
// Gets and sets.
PXreal GetX1() const { return m_fX1; }
PXreal GetY1() const { return m_fY1; }
PXreal GetX2() const { return m_fX2; }
PXreal GetY2() const { return m_fY2; }
void SetX1(PXreal fX1) { m_fX1 = fX1; }
void SetY1(PXreal fY1) { m_fY1 = fY1; }
void SetX2(PXreal fX2) { m_fX2 = fX2; }
void SetY2(PXreal fY2) { m_fY2 = fY2; }
// This determines whether this-> line intersects another.
IntersectionLogicVal Intersects(const px2DRealLine &oLineB, px2DRealPoint &oIntersection) const;
private:
PXreal m_fX1, m_fY1, m_fX2, m_fY2; // The line's endpoints.
// Functions used only by this class.
inline bool8 SameSigns(PXreal dA, PXreal dB) const;
};
inline bool8 px2DRealLine::SameSigns(PXreal fA, PXreal fB) const {
if (fA < REAL_ZERO) {
if (fB < REAL_ZERO)
return TRUE8;
else
return FALSE8;
} else {
if (fB < REAL_ZERO)
return FALSE8;
else
return TRUE8;
}
}
} // End of namespace ICB
#endif // #ifndef PX2DLINE_H_INCLUDED

View File

@@ -0,0 +1,69 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_2DREALPOINT_H_INCLUDED
#define ICB_PX_2DREALPOINT_H_INCLUDED
#include "engines/icb/common/px_rcutypes.h"
#include "engines/icb/common/px_common.h"
namespace ICB {
// A 2D point on a plane with endpoints stored as floating point.
class px2DRealPoint {
public:
// Default constructor and destructor.
px2DRealPoint() {
m_fX = REAL_ZERO;
m_fY = REAL_ZERO;
}
~px2DRealPoint() { ; }
// Alternative constructor that allows the point to be initialized.
px2DRealPoint(PXreal fX, PXreal fY) {
m_fX = fX;
m_fY = fY;
}
// Gets and sets.
void SetX(PXreal fX) { m_fX = fX; }
void SetY(PXreal fY) { m_fY = fY; }
PXreal GetX() const { return m_fX; }
PXreal GetY() const { return m_fY; }
// This allows the values of a point to be set after it has been created.
void Set(PXreal fX, PXreal fY) {
m_fX = fX;
m_fY = fY;
}
private:
PXreal m_fX, m_fY; // The point.
};
} // End of namespace ICB
#endif // #ifndef PX_2DREALPOINT_H_INCLUDED

View File

@@ -0,0 +1,95 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_3DREALPOINT_H_INCLUDED
#define ICB_PX_3DREALPOINT_H_INCLUDED
// Include the header files needed by this class.
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
// Note, this needs pre-definitions / typedef's of :
// PXreal, REAL_ZERO
// For PC PXreal = float, REAL_ZERO = 0.0f
// For PSX PXreal = int, REAL_ZERO = 0
#ifndef REAL_ZERO
#error "REAL_ZERO not defined"
#endif // #ifndef REAL_ZERO
// A 2D point on a plane with endpoints stored as floating point.
class px3DRealPoint {
public:
// Default constructor and destructor.
px3DRealPoint() {
m_fX = REAL_ZERO;
m_fY = REAL_ZERO;
m_fZ = REAL_ZERO;
}
~px3DRealPoint() { ; }
// Alternative constructor that allows the point to be initialized.
px3DRealPoint(PXreal fX, PXreal fY, PXreal fZ) {
m_fX = fX;
m_fY = fY;
m_fZ = fZ;
}
// Gets and sets.
void SetX(PXreal fX) { m_fX = fX; }
void SetY(PXreal fY) { m_fY = fY; }
void SetZ(PXreal fZ) { m_fZ = fZ; }
PXreal GetX() const { return m_fX; }
PXreal GetY() const { return m_fY; }
PXreal GetZ() const { return m_fZ; }
// This allows the values of a point to be set after it has been created.
void Set(PXreal fX, PXreal fY, PXreal fZ) {
m_fX = fX;
m_fY = fY;
m_fZ = fZ;
}
private:
PXreal m_fX, m_fY, m_fZ; // The point.
};
#if 0
inline bool8 px3DRealPoint::operator == (const px3DRealPoint &obOpB) const {
if ((PXfabs(m_fX - obOpB.m_fX) < (FLT_MIN * 5.0f)) &&
(PXfabs(m_fY - obOpB.m_fY) < (FLT_MIN * 5.0f)) &&
(PXfabs(m_fZ - obOpB.m_fZ) < (FLT_MIN * 5.0f)))
return TRUE8;
else
return FALSE8;
}
#endif
} // End of namespace ICB
#endif // #ifndef PX_3DREALPOINT_H_INCLUDED

View File

@@ -0,0 +1,172 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_ANIMS_H_
#define ICB_PX_ANIMS_H_
#include "engines/icb/common/px_common.h"
#include "common/endian.h"
namespace ICB {
#define PXANIM_SCHEMA 5
#define PXANIM_TAG "Peas"
#define ORG_POS 0
#define ORG_STRING "ORG"
#define INT_POS 1
#define INT_STRING "INT"
#define OBJ_STRING "OBJ"
#define ORG_TYPE 0
#define INT_TYPE 1
#define INT0_TYPE 2 // Forced export of INT marker on frame 0 of anim
#define TRI_TYPE 3
#define OBJ_TYPE 4
// PXmarker_PC : the PC version
typedef struct {
uint32 m_type;
float m_x, m_y, m_z;
float m_pan;
} PXmarker_PC;
// PXmarker_PC : the PC version
class PXmarker_PC_Object {
public:
static uint32 GetType(PXmarker_PC *marker) { return FROM_LE_32(marker->m_type); }
static void GetPan(PXmarker_PC *marker, float *pan) { *pan = FROM_LE_32(marker->m_pan); }
static void GetXYZ(PXmarker_PC *marker, float *x, float *y, float *z);
};
// PXframe_PC : the PC version //
typedef struct {
int16 left_foot_distance;
int16 right_foot_distance;
uint8 marker_qty;
uint8 leftFootStep;
uint8 rightFootStep;
uint8 pad3;
PXmarker_PC markers[1];
} PXframe_PC;
// PXmarker_PSX : the PSX version
typedef struct {
uint8 m_type;
uint8 x8;
uint16 x7y9;
uint32 y6z15pan11;
} PXmarker_PSX;
// PXmarker_PSX : the PSX version
class PXmarker_PSX_Object {
public:
static uint8 GetType(PXmarker_PSX *marker) { return marker->m_type; }
static void GetPan(PXmarker_PSX *marker, float *pan);
static void GetXYZ(PXmarker_PSX *marker, float *x, float *y, float *z);
};
inline void PXmarker_PSX_Object::GetPan(PXmarker_PSX *marker, float *pan) {
*pan = (float)(((FROM_LE_32(marker->y6z15pan11) & 0x7FF) << 1)) / 4096.0f;
}
inline void PXmarker_PSX_Object::GetXYZ(PXmarker_PSX *marker, float *x, float *y, float *z) {
int32 ix, iy, iz;
ix = ((marker->x8 << 7) | (FROM_LE_16(marker->x7y9) >> 9));
if (ix >= 16384)
ix = ix - 32768;
iy = (((FROM_LE_16(marker->x7y9) & 0x1FF) << 6) | (FROM_LE_32(marker->y6z15pan11) >> 26));
if (iy >= 16384)
iy = iy - 32768;
iz = ((FROM_LE_32(marker->y6z15pan11) >> 11) & 0x7FFF);
if (iz >= 16384)
iz = iz - 32768;
*x = (float)ix;
*y = (float)iy;
*z = (float)iz;
}
// PXframe_PSX : the PSX version //
typedef struct {
int16 left_foot_distance;
int16 right_foot_distance;
uint8 marker_qty;
uint8 leftFootStep;
uint8 rightFootStep;
uint8 pad3;
PXmarker_PSX markers[1];
} PXframe_PSX;
// PXanim //
typedef struct {
char tag[4];
int32 schema;
uint8 frame_qty;
uint8 speed;
uint16 offsets[1];
} PXanim_PSX;
typedef struct {
char tag[4];
int32 schema;
uint8 frame_qty;
uint8 speed;
uint16 offsets[1];
} PXanim_PC;
inline void ConvertPXanim(PXanim_PSX *anim) {
// Support old schema type files
if (FROM_LE_32(anim->schema) == PXANIM_SCHEMA - 1) {
int32 nFrames = anim->frame_qty;
anim->frame_qty = (uint8)nFrames;
anim->speed = 1;
anim->schema = TO_LE_32(PXANIM_SCHEMA);
}
}
inline void ConvertPXanim(PXanim_PC *anim) {
// Support old schema type files
if (FROM_LE_32(anim->schema) == PXANIM_SCHEMA - 1) {
int32 nFrames = anim->frame_qty;
anim->frame_qty = (uint8)nFrames;
anim->speed = 1;
anim->schema = TO_LE_32(PXANIM_SCHEMA);
}
}
// The animation, frame, marker
typedef PXframe_PSX PXframe;
typedef PXmarker_PSX PXmarker;
} // End of namespace ICB
#endif // _library__PX_ANIMS_H_

View File

@@ -0,0 +1,367 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_LIBRARY_CMYACTARRAY
#define ICB_LIBRARY_CMYACTARRAY
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
#define MY_TEMPLATE template <class Type>
#define T_MYACTARRAY rcActArray<Type>
#define T_MYPTRARRAY rcAutoPtrArray<Type>
MY_TEMPLATE class rcActArray {
public:
rcActArray() { // Construct an empty array
m_userPosition = m_allocatedSize = 0;
}
rcActArray(rcActArray &a) {
m_userPosition = m_allocatedSize = 0;
(*this) = a;
}
~rcActArray(); // Destruct the array
void operator=(const rcActArray &);
// Member access functions
uint32 GetNoItems() const { return (m_userPosition); }
uint32 Add(const Type &f); // Add an item.
Type &operator[](uint32); // Give access to an entry
const Type &operator[](uint32 i) const;
void SetSize(uint32 n) { ResizeArray(n); }
void Reset();
private:
uint32 m_userPosition; // Next place to add an item to
uint32 m_allocatedSize; // How many items have been allocated
Type **m_contents; // A pointer to pointers to the objects
void ResizeArray(uint32); // Change the size of the array
};
MY_TEMPLATE
void T_MYACTARRAY::operator=(const rcActArray &a) {
if (m_allocatedSize)
delete[] m_contents;
m_userPosition = a.m_userPosition;
m_allocatedSize = a.m_allocatedSize;
if (m_allocatedSize)
{
m_contents = new Type *[m_allocatedSize];
for (uint32 count = 0; count < m_allocatedSize; count++)
m_contents[count] = new Type(*(a.m_contents[count]));
}
}
MY_TEMPLATE
Type &T_MYACTARRAY::operator[](uint32 n) {
if (n >= m_userPosition) {
ResizeArray(n);
m_userPosition = n + 1;
}
return (*(m_contents[n]));
}
MY_TEMPLATE
const Type &T_MYACTARRAY::operator[](uint32 n) const {
// It is permissible to look at an element that has not been defined, as the constructor assures
// that the contents are valid
if (n >= m_userPosition) {
// Remove any 'constness' for a resize
(const_cast<rcActArray<Type> *>(this))->ResizeArray(n);
(const_cast<rcActArray<Type> *>(this))->m_userPosition = n + 1;
}
return (*(m_contents[n]));
}
MY_TEMPLATE T_MYACTARRAY::~rcActArray() { Reset(); }
MY_TEMPLATE void T_MYACTARRAY::Reset() {
for (uint32 count = 0; count < m_allocatedSize; count++)
delete m_contents[count];
if (m_allocatedSize)
delete[] m_contents;
m_allocatedSize = 0;
m_userPosition = 0;
}
MY_TEMPLATE void T_MYACTARRAY::ResizeArray(uint32 n2) {
// if n is still within the allocated area then just set the last position
if (n2 >= m_allocatedSize) {
// Make sure we are going to make the thing big enough
uint32 nextSize = m_allocatedSize ? m_allocatedSize + m_allocatedSize : 1; // Double, or 1 if now 0
while (nextSize <= n2)
nextSize += nextSize;
// Get a New pointer array of the correct size
Type **newArray = new Type *[nextSize];
if (m_allocatedSize > 0) {
// Copy in the old stuff
memcpy((unsigned char *)newArray, (unsigned char *)m_contents, m_allocatedSize * sizeof(Type *));
}
// Put empty objects in the newly allocated space
for (uint32 newObjects = m_allocatedSize; newObjects < nextSize; newObjects++)
newArray[newObjects] = new Type;
// Remove any old stuff
if (m_allocatedSize)
delete[] m_contents;
m_contents = newArray;
m_allocatedSize = nextSize;
}
}
MY_TEMPLATE uint32 T_MYACTARRAY::Add(const Type &f) {
operator[](m_userPosition) = f;
return (m_userPosition - 1);
}
MY_TEMPLATE class rcAutoPtrArray {
uint32 m_noContents; // How many entries have been allocated
uint32 m_userPosition; // Next position for the Add command
Type **m_contents; // A pointer to pointers to the objects
void ResizeArray(uint32); // Change the size of the array
public:
explicit rcAutoPtrArray() { // Construct an empty array
m_noContents = m_userPosition = 0;
}
~rcAutoPtrArray(); // Destruct the array
// Member access functions
uint32 GetNoItems() const { return (m_userPosition); }
uint32 Add(Type *f) {
operator[](m_userPosition) = f;
return (m_userPosition - 1);
}
Type *&operator[](uint32); // Give access to an entry
const Type *&operator[](uint32) const; // Give access to an entry
void Reset();
void RemoveAndShuffle(uint32); // Remove an object from the array
void SetSize(uint32 n) { ResizeArray(n); }
// Super dangerous, but faster, access to the array
Type *GetRawArray() { return (*m_contents); }
private: // Prevent use of the PtrArray copy constructor
// The default copy constructor should never be called
rcAutoPtrArray(const rcAutoPtrArray &) {}
void operator=(const rcAutoPtrArray &) {}
};
MY_TEMPLATE
Type *&T_MYPTRARRAY::operator[](uint32 n) {
if (n >= m_userPosition) {
ResizeArray(n);
m_userPosition = n + 1;
}
return (m_contents[n]);
}
MY_TEMPLATE
const Type *&T_MYPTRARRAY::operator[](uint32 n) const {
// It is permissible to look at an element that has not been defined, as it will be defined as NULL
if (n >= m_userPosition) {
(const_cast<rcAutoPtrArray<Type> *>(this))->ResizeArray(n);
(const_cast<rcAutoPtrArray<Type> *>(this))->m_userPosition = n + 1;
}
return const_cast<const Type *&>(m_contents[n]);
}
MY_TEMPLATE T_MYPTRARRAY::~rcAutoPtrArray() { Reset(); }
MY_TEMPLATE void T_MYPTRARRAY::Reset() {
// The pointer array maintains responsibility for deleting any contents
for (uint32 count = 0; count < m_userPosition; count++)
if (m_contents[count])
delete m_contents[count];
if (m_noContents)
delete[] m_contents;
m_noContents = m_userPosition = 0;
}
MY_TEMPLATE void T_MYPTRARRAY::ResizeArray(uint32 n2) {
if (n2 >= m_noContents) {
// Double the allocation value
uint32 nextSize = m_noContents > 0 ? m_noContents + m_noContents : 1;
while (n2 >= nextSize)
nextSize = nextSize + nextSize;
// Get a New pointer array of the correct size
Type **newArray = new Type *[nextSize];
// Copy in the old stuff, if there is any
if (m_noContents > 0)
memcpy((unsigned char *)newArray, (unsigned char *)m_contents, m_noContents * sizeof(Type *));
// Reset the New entries
memset((unsigned char *)(newArray + m_noContents), 0, (nextSize - m_noContents) * sizeof(Type *));
// Remove any old stuff
if (m_noContents)
delete[] m_contents;
m_contents = newArray;
m_noContents = nextSize;
}
}
MY_TEMPLATE void T_MYPTRARRAY::RemoveAndShuffle(uint32 n) {
// Remove an object from the array
// First delete it
if (m_contents[n])
delete m_contents[n];
// and shuffle the array
memcpy(m_contents + n, m_contents + n + 1, (m_noContents - n - 1) * sizeof(Type *));
}
template <class Type> class rcIntArray {
uint32 m_noContents; // How many entries there are
uint32 m_userPosition; // Where the next add position goes
Type *m_contents;
void ResizeArray(uint32); // Change the size of the array
public:
explicit rcIntArray() { // Construct an empty array
m_noContents = m_userPosition = 0;
}
~rcIntArray() { // Destruct the array
if (m_noContents)
delete[] m_contents;
}
// Copy constructor
rcIntArray(const rcIntArray &a) {
m_noContents = m_userPosition = 0;
(*this) = a;
}
// Constructor with an initial size
rcIntArray(uint32 initialSize) { ResizeArray(initialSize); }
const rcIntArray &operator=(const rcIntArray &);
// Member access functions
uint32 GetNoItems() const { return (m_userPosition); }
uint32 Add(Type f); // Add an integer. Only makes sense if the resize step is one
Type &operator[](uint32); // Give access to an entry
const Type operator[](uint32) const; // Give access to an entry
void Reset();
void SetSize(uint32 n) { ResizeArray(n); }
Type *GetRawArray() { return (m_contents); }
};
template <class Type> Type &rcIntArray<Type>::operator[](uint32 index) {
if (index >= m_userPosition) {
ResizeArray(index);
m_userPosition = index + 1;
}
return m_contents[index];
}
// This version of [] allows the array to be part of a const function
template <class Type> const Type rcIntArray<Type>::operator[](uint32 index) const {
// It is permissible to look at an element that has not been defined, as it will have been set to 0
if (index >= m_userPosition) {
// Remove any 'constness' for a resize
(const_cast<rcIntArray<Type> *>(this))->ResizeArray(index);
(const_cast<rcIntArray<Type> *>(this))->m_userPosition = index + 1;
}
return m_contents[index];
}
template <class IntType> void rcIntArray<IntType>::ResizeArray(uint32 accessedSize) {
// Check if we need to do any reallocating
if (accessedSize >= m_noContents) {
uint32 newSize = m_noContents > 0 ? m_noContents * 2 : 1;
while (newSize <= accessedSize)
newSize = newSize + newSize;
IntType *newArray = new IntType[newSize];
if (m_noContents)
memcpy(newArray, m_contents, m_noContents * sizeof(IntType));
// Call me a fool, but I like my integers initialised to 0
memset(newArray + m_noContents, 0, (newSize - m_noContents) * sizeof(IntType));
if (m_noContents)
delete[] m_contents;
m_contents = newArray;
m_noContents = newSize;
}
}
template <class IntType> const rcIntArray<IntType> &rcIntArray<IntType>::operator=(const rcIntArray<IntType> &obOpB) {
uint32 nCount;
if (m_noContents)
delete[] m_contents;
m_userPosition = obOpB.m_userPosition;
m_noContents = obOpB.m_noContents;
if (m_noContents) {
m_contents = new IntType[m_noContents];
for (nCount = 0; nCount < m_noContents; nCount++)
m_contents[nCount] = obOpB.m_contents[nCount];
}
return *this;
}
template <class Type> void rcIntArray<Type>::Reset() {
// CLear out the array
if (m_noContents) {
delete[] m_contents;
m_noContents = m_userPosition = 0;
}
}
template <class Type> uint32 rcIntArray<Type>::Add(Type f) {
// Add an integer. Only makes sense if the resize step is one
operator[](m_userPosition) = f;
return (m_userPosition - 1);
}
} // End of namespace ICB
#endif // ndef _LIBRARY_CMYACTARRAY

View File

@@ -0,0 +1,42 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_BITMAP_H_INCLUDED
#define ICB_PX_BITMAP_H_INCLUDED
#include "engines/icb/common/px_bitmap_pc.h"
namespace ICB {
typedef _pxPCBitmap _pxBitmap;
typedef _pxPCSprite _pxSprite;
#define PX_BITMAP_EXT PX_BITMAP_PC_EXT
#define PX_BITMAP_SCHEMA PC_BITMAP_SCHEMA
#define PX_BITMAP_ID PC_BITMAP_ID
} // End of namespace ICB
#endif // #ifndef _PX_BITMAP_H_INCLUDED

View File

@@ -0,0 +1,63 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_BITMAP_PC_H_INCLUDED
#define ICB_PX_BITMAP_PC_H_INCLUDED
#include "engines/icb/common/px_common.h"
namespace ICB {
// These define the extension for the finding the bitmap files
#ifndef PX_BITMAP_PC_EXT
#define PX_BITMAP_PC_EXT "bitmap_pc"
#endif
// Replaced pxHeader with id and added schema control to datafiles
#define PC_BITMAP_SCHEMA 1
#define PC_BITMAP_ID "PCB"
// Data structure to overlay the sprite data.
typedef struct {
uint32 x, y; // X and Y position of sprite.
uint32 width, height; // Width and height of the sprite in pixels.
uint8 data[1]; // Sprite data.
} _pxPCSprite;
typedef struct _pxPCBitmap {
char id[4]; // "PCB" Pc bitmap
uint32 schema; // The current schema number
uint8 palette[4 * 256]; // RGB but padded with 0 to 32-bits.
uint32 num_sprites; // Number of sprites in this file.
uint32 sprite_offsets[1]; // Offsets to sprite data for each sprite.
} _pxPCBitmap;
} // End of namespace ICB
#endif // #ifndef _PX_BITMAP_PC_H_INCLUDED

View File

@@ -0,0 +1,53 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/gfx/psx_pcdefines.h"
#include "engines/icb/common/px_common.h"
#include "engines/icb/common/px_bones.h"
namespace ICB {
void BoneDeformation::UpdateBoneValue(short &v, short t) {
if (v < t) {
v = (int16)(v + boneSpeed);
if (v > t)
v = t;
} else if (v > t) {
v = (int16)(v - boneSpeed);
if (v < t)
v = t;
}
}
void BoneDeformation::Target0() { boneTarget.vx = boneTarget.vy = boneTarget.vz = 0; }
void BoneDeformation::Update() {
UpdateBoneValue(boneValue.vx, boneTarget.vx);
UpdateBoneValue(boneValue.vy, boneTarget.vy);
UpdateBoneValue(boneValue.vz, boneTarget.vz);
}
} // End of namespace ICB

View File

@@ -0,0 +1,62 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_BONES_H
#define ICB_PX_BONES_H
#include "engines/icb/common/px_common.h"
namespace ICB {
// maximum number of deformations
#define MAX_DEFORMABLE_BONES 4
// the deformations being used (so standard across tools/engine...
#define JAW_DEFORMATION 0
#define NECK_DEFORMATION 1
#define LOOK_DEFORMATION 2
#define SPARE_DEFORMATION 3
class BoneDeformation {
public:
BoneDeformation() {
boneTarget.vx = boneTarget.vy = boneTarget.vz = boneValue.vx = boneValue.vy = boneValue.vz = 0;
boneNumber = -1;
}
int16 boneNumber;
int16 boneSpeed;
SVECTOR boneValue;
SVECTOR boneTarget;
void UpdateBoneValue(int16 &v, int16 t);
void Target0();
void Update();
};
} // End of namespace ICB
#endif // _PX_BONES_H

View File

@@ -0,0 +1,49 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_CAMERA_H
#define ICB_PX_CAMERA_H
#include "engines/icb/common/px_common.h"
namespace ICB {
typedef struct PXmatrix_PC {
PXreal m[3][3]; /* 3x3 rotation matrix */
PXreal t[3]; /* transfer vector */
} PXmatrix_PC;
struct PCcamera {
char id[4];
int32 schema;
PXmatrix_PC view;
float pan;
float focLen;
};
} // End of namespace ICB
#endif // __px_camera_h__included__

View File

@@ -0,0 +1,63 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_CAMERA_CUBE
#define ICB_PX_CAMERA_CUBE
#include "engines/icb/common/px_common.h"
namespace ICB {
typedef struct {
/*
(y)height
|
|
|
|
|
x1,y1,z1 |----------| y
\ \ |
\ \ |
\___________ (x)width \---x
(z)depth \ parallel to max model axis
z
*/
PXreal x1;
PXreal y1;
PXreal z1; // top left bottom corner point
PXreal width;
PXreal depth;
PXreal height;
uint32 script_name_offset; // IF this is set then we call a script
uint32 camera_name_offset; // ELSE offset from start of this file to ascii
// name of camera - and therefore set
} _camera_cube;
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,44 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/psx_config.h"
#include "engines/icb/gfx/psx_pcdefines.h"
#if _PSX_ON_PC == 1
#include "engines/icb/common/px_capri_maths.h"
#endif
namespace ICB {
MATRIX *gterot;
MATRIX *gtetrans;
MATRIX *gtecolour;
MATRIX *gtelight;
short gteback[3];
int32 gtegeomscrn;
uint8 dcache[1024];
} // End of namespace ICB

View File

@@ -0,0 +1,408 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PC_CAPRI_MATHS_H
#define ICB_PC_CAPRI_MATHS_H
#include "engines/icb/psx_config.h"
#include "engines/icb/common/px_capri_maths_pc.h"
namespace ICB {
#if (_PSX_ON_PC == 0) && !defined ICB_PSX_PCDEFINES_H
// make our own equivalents
typedef struct MATRIX {
int16 m[3][3]; /* 3x3 rotation matrix */
int16 pad;
int32 t[3]; /* transfer vector */
MATRIX() { pad = 0; }
} MATRIX;
/* int32 word type 3D vector */
typedef struct VECTOR {
int32 vx, vy;
int32 vz, pad;
VECTOR() { pad = 0; }
} VECTOR;
/* short word type 3D vector */
typedef struct SVECTOR {
int16 vx, vy;
int16 vz, pad;
SVECTOR() { pad = 0; }
bool operator==(const SVECTOR &v) { return ((v.vx == vx) && (v.vy == vy) && (v.vz == vz)); }
} SVECTOR;
/* short word type 3D vector */
typedef struct CVECTOR {
uint8 r, g;
int16 b, pad;
CVECTOR() { pad = 0; }
bool operator==(const CVECTOR &v) { return ((v.r == r) && (v.g == g) && (v.b == b)); }
} CVECTOR;
#endif // #if (_PSX_ON_PC==0)
#define ONE 4096
#define myPI (3.141592654f)
inline int32 myNINT(float f) {
if (f >= 0.0f)
return int(f + 0.5f);
else
return int(f - 0.5f);
}
#define VectorNormal myVectorNormal
#define ApplyMatrixLV myApplyMatrixLV
#define ApplyMatrixSV myApplyMatrixSV
#define RotMatrix_gte myRotMatrix_gte
#define gte_MulMatrix0 mygte_MulMatrix0
#define gte_RotTrans mygte_RotTrans
#define gte_RotTransPers mygte_RotTransPers
#define gte_RotTransPers3 mygte_RotTransPers3
#define gte_SetRotMatrix mygte_SetRotMatrix
#define gte_SetTransMatrix mygte_SetTransMatrix
#define gte_ApplyRotMatrix mygte_ApplyRotMatrix
#define gte_SetGeomScreen mygte_SetGeomScreen
#define gte_SetBackColor mygte_SetBackColor
#define gte_SetColorMatrix mygte_SetColorMatrix
#define gte_SetLightMatrix mygte_SetLightMatrix
#define gte_NormalColorCol mygte_NormalColorCol
#define gte_NormalColorCol3 mygte_NormalColorCol3
#define gte_NormalClip mygte_NormalClip
#define gte_AverageZ3 mygte_AverageZ3
extern MATRIX *gterot;
extern MATRIX *gtetrans;
extern MATRIX *gtecolour;
extern MATRIX *gtelight;
extern int16 gteback[3];
extern int32 gtegeomscrn;
extern uint8 dcache[1024];
#define getScratchAddr(x) ((uint32 *)(dcache + x))
inline void myApplyMatrixLV(MATRIX *m, VECTOR *invec, VECTOR *outvec);
inline void myApplyMatrixSV(MATRIX *m, SVECTOR *invec, SVECTOR *outvec);
inline int32 myVectorNormal(VECTOR *in0, VECTOR *out0);
inline void mygte_MulMatrix0(MATRIX *m1, MATRIX *m2, MATRIX *out);
inline void mygte_RotTrans(SVECTOR *in0, VECTOR *out0, int32 *flag);
inline void mygte_RotTransPers(SVECTOR *in0, int32 *sxy0, int32 *p, int32 *flag, int32 *z);
inline void mygte_RotTransPers3(SVECTOR *in0, SVECTOR *in1, SVECTOR *in2, int32 *sxy0, int32 *sxy1, int32 *sxy2, int32 *p, int32 *flag, int32 *z);
inline void mygte_SetRotMatrix(MATRIX *m);
inline void mygte_SetTransMatrix(MATRIX *m);
inline void mygte_ApplyRotMatrix(SVECTOR *invec, VECTOR *outvec);
inline void myRotMatrix_gte(SVECTOR *rot, MATRIX *m);
inline void mygte_SetColorMatrix(MATRIX *m);
inline void mygte_SetLightMatrix(MATRIX *m);
inline void mygte_SetGeomScreen(int32 h);
inline void mygte_SetBackColor(int32 r, int32 g, int32 b);
inline void mygte_NormalColorCol(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0);
inline void mygte_NormalColorCol3(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2);
inline void mygte_NormalClip(int32 sxy0, int32 sxy1, int32 sxy2, int32 *flag);
inline void mygte_AverageZ3(int32 z0, int32 z1, int32 z2, int32 *sz);
inline void myApplyMatrixLV(MATRIX *m, VECTOR *invec, VECTOR *outvec) {
outvec->vx = ((int)m->m[0][0] * invec->vx + (int)m->m[0][1] * invec->vy + (int)m->m[0][2] * invec->vz) / 4096;
outvec->vy = ((int)m->m[1][0] * invec->vx + (int)m->m[1][1] * invec->vy + (int)m->m[1][2] * invec->vz) / 4096;
outvec->vz = ((int)m->m[2][0] * invec->vx + (int)m->m[2][1] * invec->vy + (int)m->m[2][2] * invec->vz) / 4096;
}
inline void myApplyMatrixSV(MATRIX *m, SVECTOR *invec, SVECTOR *outvec) {
outvec->vx = (int16)(((int)m->m[0][0] * invec->vx + (int)m->m[0][1] * invec->vy + (int)m->m[0][2] * invec->vz) / 4096);
outvec->vy = (int16)(((int)m->m[1][0] * invec->vx + (int)m->m[1][1] * invec->vy + (int)m->m[1][2] * invec->vz) / 4096);
outvec->vz = (int16)(((int)m->m[2][0] * invec->vx + (int)m->m[2][1] * invec->vy + (int)m->m[2][2] * invec->vz) / 4096);
}
inline void mygte_MulMatrix0(MATRIX *m1, MATRIX *m2, MATRIX *out) {
MATRIX local;
MATRIX *work;
if ((out == m1) || (out == m2))
work = &local;
else
work = out;
work->m[0][0] = (int16)(((int)m1->m[0][0] * (int)m2->m[0][0] + (int)m1->m[0][1] * (int)m2->m[1][0] + (int)m1->m[0][2] * (int)m2->m[2][0]) / 4096);
work->m[0][1] = (int16)(((int)m1->m[0][0] * (int)m2->m[0][1] + (int)m1->m[0][1] * (int)m2->m[1][1] + (int)m1->m[0][2] * (int)m2->m[2][1]) / 4096);
work->m[0][2] = (int16)(((int)m1->m[0][0] * (int)m2->m[0][2] + (int)m1->m[0][1] * (int)m2->m[1][2] + (int)m1->m[0][2] * (int)m2->m[2][2]) / 4096);
work->m[1][0] = (int16)(((int)m1->m[1][0] * (int)m2->m[0][0] + (int)m1->m[1][1] * (int)m2->m[1][0] + (int)m1->m[1][2] * (int)m2->m[2][0]) / 4096);
work->m[1][1] = (int16)(((int)m1->m[1][0] * (int)m2->m[0][1] + (int)m1->m[1][1] * (int)m2->m[1][1] + (int)m1->m[1][2] * (int)m2->m[2][1]) / 4096);
work->m[1][2] = (int16)(((int)m1->m[1][0] * (int)m2->m[0][2] + (int)m1->m[1][1] * (int)m2->m[1][2] + (int)m1->m[1][2] * (int)m2->m[2][2]) / 4096);
work->m[2][0] = (int16)(((int)m1->m[2][0] * (int)m2->m[0][0] + (int)m1->m[2][1] * (int)m2->m[1][0] + (int)m1->m[2][2] * (int)m2->m[2][0]) / 4096);
work->m[2][1] = (int16)(((int)m1->m[2][0] * (int)m2->m[0][1] + (int)m1->m[2][1] * (int)m2->m[1][1] + (int)m1->m[2][2] * (int)m2->m[2][1]) / 4096);
work->m[2][2] = (int16)(((int)m1->m[2][0] * (int)m2->m[0][2] + (int)m1->m[2][1] * (int)m2->m[1][2] + (int)m1->m[2][2] * (int)m2->m[2][2]) / 4096);
if (work != out) {
out->m[0][0] = work->m[0][0];
out->m[0][1] = work->m[0][1];
out->m[0][2] = work->m[0][2];
out->m[1][0] = work->m[1][0];
out->m[1][1] = work->m[1][1];
out->m[1][2] = work->m[1][2];
out->m[2][0] = work->m[2][0];
out->m[2][1] = work->m[2][1];
out->m[2][2] = work->m[2][2];
}
}
inline void mygte_SetRotMatrix(MATRIX *m) { *gterot = *m; }
inline void mygte_SetTransMatrix(MATRIX *m) { *gtetrans = *m; }
inline void mygte_ApplyRotMatrix(SVECTOR *invec, VECTOR *outvec) {
outvec->vx = (((int)gterot->m[0][0] * (int)invec->vx + (int)gterot->m[0][1] * (int)invec->vy + (int)gterot->m[0][2] * (int)invec->vz) / 4096);
outvec->vy = (((int)gterot->m[1][0] * (int)invec->vx + (int)gterot->m[1][1] * (int)invec->vy + (int)gterot->m[1][2] * (int)invec->vz) / 4096);
outvec->vz = (((int)gterot->m[2][0] * (int)invec->vx + (int)gterot->m[2][1] * (int)invec->vy + (int)gterot->m[2][2] * (int)invec->vz) / 4096);
}
inline void mygte_RotTrans(SVECTOR *in0, VECTOR *out0, int32 *flag) {
mygte_ApplyRotMatrix(in0, out0);
out0->vx += gtetrans->t[0];
out0->vy += gtetrans->t[1];
out0->vz += gtetrans->t[2];
// What GTE flags should we set ?
*flag = 0;
}
inline void mygte_RotTransPers(SVECTOR *in0, int32 *sxy0, int32 * /* p */, int32 *flag, int32 *z) {
VECTOR cam;
SVECTOR *scrn = (SVECTOR *)sxy0;
gte_RotTrans(in0, &cam, flag);
*flag = 0;
if (cam.vz != 0) {
scrn->vx = (int16)((cam.vx * gtegeomscrn) / cam.vz);
scrn->vy = (int16)((cam.vy * gtegeomscrn) / cam.vz);
} else {
// To force an error and hence an illegal polygon
scrn->vx = 2048;
scrn->vy = 2048;
}
*z = cam.vz / 4;
if (abs(scrn->vx) > 1024)
*flag |= 0x80000000;
if (abs(scrn->vy) > 1024)
*flag |= 0x80000000;
// set the value of flag : closer than h/2
if (cam.vz < 0)
*flag |= 0x80000000;
}
inline void mygte_RotTransPers3(SVECTOR *in0, SVECTOR *in1, SVECTOR *in2, int32 *sxy0, int32 *sxy1, int32 *sxy2, int32 *p, int32 *flag, int32 *z) {
int32 z0, z1, z2;
int32 p0, p1, p2;
int32 flag0, flag1, flag2;
mygte_RotTransPers(in0, sxy0, &p0, &flag0, &z0);
mygte_RotTransPers(in1, sxy1, &p1, &flag1, &z1);
mygte_RotTransPers(in2, sxy2, &p2, &flag2, &z2);
// What GTE flags should we set ?
*flag = flag0 | flag1 | flag2;
*p = p2;
*z = z2;
}
inline void myRotMatrix_gte(SVECTOR *rot, MATRIX *m) {
const int32 one = (1 << 12);
float ang0 = (float)rot->vx * 2.0f * myPI / one;
MATRIX m0;
int32 c0 = myNINT(one * (float)cos(ang0));
int32 s0 = myNINT(one * (float)sin(ang0));
m0.m[0][0] = one;
m0.m[0][1] = 0;
m0.m[0][2] = 0;
m0.m[1][0] = 0;
m0.m[1][1] = (int16)c0;
m0.m[1][2] = (int16)-s0;
m0.m[2][0] = 0;
m0.m[2][1] = (int16)s0;
m0.m[2][2] = (int16)c0;
float ang1 = (float)rot->vy * 2.0f * myPI / one;
int32 c1 = myNINT(one * (float)cos(ang1));
int32 s1 = myNINT(one * (float)sin(ang1));
MATRIX m1;
m1.m[0][0] = (int16)c1;
m1.m[0][1] = 0;
m1.m[0][2] = (int16)s1;
m1.m[1][0] = 0;
m1.m[1][1] = one;
m1.m[1][2] = 0;
m1.m[2][0] = (int16)-s1;
m1.m[2][1] = 0;
m1.m[2][2] = (int16)c1;
float ang2 = (float)rot->vz * 2.0f * myPI / one;
int32 c2 = myNINT(one * (float)cos(ang2));
int32 s2 = myNINT(one * (float)sin(ang2));
MATRIX m2;
m2.m[0][0] = (int16)c2;
m2.m[0][1] = (int16)-s2;
m2.m[0][2] = 0;
m2.m[1][0] = (int16)s2;
m2.m[1][1] = (int16)c2;
m2.m[1][2] = 0;
m2.m[2][0] = 0;
m2.m[2][1] = 0;
m2.m[2][2] = one;
mygte_MulMatrix0(&m0, &m1, m);
mygte_MulMatrix0(m, &m2, m);
}
inline void mygte_SetBackColor(int32 r, int32 g, int32 b) {
gteback[0] = (int16)r;
gteback[1] = (int16)g;
gteback[2] = (int16)b;
}
inline void mygte_SetColorMatrix(MATRIX *m) { *gtecolour = *m; }
inline void mygte_SetLightMatrix(MATRIX *m) { *gtelight = *m; }
inline void mygte_SetGeomScreen(int32 h) { gtegeomscrn = h; }
inline void mygte_NormalColorCol(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0) {
SVECTOR lightEffect;
// Normal line vector(local) -> light source effect
ApplyMatrixSV(gtelight, v0, &lightEffect);
if (lightEffect.vx < 0)
lightEffect.vx = 0;
if (lightEffect.vy < 0)
lightEffect.vy = 0;
if (lightEffect.vz < 0)
lightEffect.vz = 0;
// Light source effect -> Colour effect(local colour matrix+back colour)
SVECTOR colourEffect;
ApplyMatrixSV(gtecolour, &lightEffect, &colourEffect);
if (colourEffect.vx < 0)
colourEffect.vx = 0;
if (colourEffect.vy < 0)
colourEffect.vy = 0;
if (colourEffect.vz < 0)
colourEffect.vz = 0;
// colourEffect is 0-4095 (2^12)
// gteback is 0-255 (2^8)
colourEffect.vx = (int16)((colourEffect.vx >> 4) + gteback[0]);
colourEffect.vy = (int16)((colourEffect.vy >> 4) + gteback[1]);
colourEffect.vz = (int16)((colourEffect.vz >> 4) + gteback[2]);
// 256 = 1.0 in colourEffect
// 128 = 1.0 in in0
int32 red = ((in0->r * colourEffect.vx) >> 8);
int32 green = ((in0->g * colourEffect.vy) >> 8);
int32 blue = ((in0->b * colourEffect.vz) >> 8);
if (red > 255)
red = 255;
if (green > 255)
green = 255;
if (blue > 255)
blue = 255;
out0->r = (uint8)(red);
out0->g = (uint8)(green);
out0->b = (uint8)(blue);
}
inline void mygte_NormalColorCol3(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2) {
gte_NormalColorCol(v0, in0, out0);
gte_NormalColorCol(v1, in0, out1);
gte_NormalColorCol(v2, in0, out2);
}
inline int32 myVectorNormal(VECTOR *in0, VECTOR *out0) {
int32 r2 = (in0->vx * in0->vx + in0->vy * in0->vy + in0->vz * in0->vz);
float r = (float)sqrt((float)r2) / 4096.0f;
if (fabs(r) < 1.0e-6)
return 0;
out0->vx = (int32)((float)in0->vx / r);
out0->vy = (int32)((float)in0->vy / r);
out0->vz = (int32)((float)in0->vz / r);
return r2;
}
inline void mygte_NormalClip(int32 sxy0, int32 sxy1, int32 sxy2, int32 *flag) {
SVECTOR *v0 = (SVECTOR *)&sxy0;
SVECTOR *v1 = (SVECTOR *)&sxy1;
SVECTOR *v2 = (SVECTOR *)&sxy2;
// compute the cross-product of (v1-v0) x (v2-v0)
int32 l0x = v1->vx - v0->vx;
int32 l0y = v1->vy - v0->vy;
int32 l1x = v2->vx - v0->vx;
int32 l1y = v2->vy - v0->vy;
*flag = ((l0x * l1y) - (l0y * l1x));
}
inline void mygte_AverageZ3(int32 z0, int32 z1, int32 z2, int32 *sz) {
*sz = (z0 + z1 + z2) / 3;
*sz /= 4;
}
} // End of namespace ICB
#endif // #ifndef __PC_CAPRI_MATHS_H

View File

@@ -0,0 +1,44 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/psx_config.h"
#include "engines/icb/gfx/psx_pcdefines.h"
#if _PSX_ON_PC == 1
#include "engines/icb/common/px_capri_maths_pc.h"
#endif
namespace ICB {
MATRIXPC *gterot_pc;
MATRIXPC *gtetrans_pc;
MATRIXPC *gtecolour_pc;
MATRIXPC *gtelight_pc;
int32 gteback_pc[3];
int32 gtegeomscrn_pc;
int32 gtescreenscaleshift_pc = 0;
} // End of namespace ICB

View File

@@ -0,0 +1,537 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_CAPRI_MATHS_PC_H
#define ICB_PX_CAPRI_MATHS_PC_H
#include "common/util.h"
namespace ICB {
#if (_PSX_ON_PC == 0) && !defined ICB_PX_CAPRI_MATHS_PC_H
// make our own equivalents
typedef struct MATRIXPC {
int32 m[3][3]; /* 3x3 rotation matrix */
int32 pad;
int32 t[3]; /* transfer vector */
MATRIXPC() { pad = 0; }
} MATRIXPC;
/* int32 word type 3D vector */
typedef struct VECTOR {
int32 vx, vy;
int32 vz, pad;
VECTOR() { pad = 0; }
} VECTOR;
/* short word type 3D vector */
typedef struct SVECTORPC {
int32 vx, vy;
int32 vz, pad;
SVECTORPC() { pad = 0; }
bool operator==(const SVECTORPC &v) { return ((v.vx == vx) && (v.vy == vy) && (v.vz == vz)); }
} SVECTORPC;
/* short word type 3D vector */
typedef struct CVECTOR {
uint8 r, g;
int16 b, pad;
CVECTOR() { pad = 0; }
bool operator==(const CVECTOR &v) { return ((v.r == r) && (v.g == g) && (v.b == b)); }
} CVECTOR;
#endif // #if (_PSX_ON_PC==0)
//-=- Definitions -=-//
const int32 ONE_PC_SCALE = 12;
const int32 ONE_PC = 1 << ONE_PC_SCALE;
const float myPI_PC = 3.141592654f;
const int32 ZSCALE = 1;
inline int32 myNINT_PC(float f) {
if (f >= 0.0f)
return int(f + 0.5f);
else
return int(f - 0.5f);
}
//------------------------------------------------------------------------
#define VectorNormal_pc myVectorNormal_pc
#define ApplyMatrixLV_pc myApplyMatrixLV_pc
#define ApplyMatrixSV_pc myApplyMatrixSV_pc
#define RotMatrix_gte_pc myRotMatrix_gte_pc
#define gte_MulMatrix0_pc mygte_MulMatrix0_pc
#define gte_RotTrans_pc mygte_RotTrans_pc
#define gte_RotTransPers_pc mygte_RotTransPers_pc
#define gte_RotTransPers3_pc mygte_RotTransPers3_pc
#define gte_SetRotMatrix_pc mygte_SetRotMatrix_pc
#define gte_SetTransMatrix_pc mygte_SetTransMatrix_pc
#define gte_ApplyRotMatrix_pc mygte_ApplyRotMatrix_pc
#define gte_SetGeomScreen_pc mygte_SetGeomScreen_pc
#define gte_SetBackColor_pc mygte_SetBackColor_pc
#define gte_SetColorMatrix_pc mygte_SetColorMatrix_pc
#define gte_SetLightMatrix_pc mygte_SetLightMatrix_pc
#define gte_NormalColorCol_pc mygte_NormalColorCol_pc
#define gte_NormalColorCol3_pc mygte_NormalColorCol3_pc
#define gte_NormalClip_pc mygte_NormalClip_pc
#define gte_AverageZ3_pc mygte_AverageZ3_pc
#define gte_SetScreenScaleShift_pc mygte_SetScreenScaleShift_pc
//------------------------------------------------------------------------
extern MATRIXPC *gterot_pc;
extern MATRIXPC *gtetrans_pc;
extern MATRIXPC *gtecolour_pc;
extern MATRIXPC *gtelight_pc;
extern int32 gteback_pc[3];
extern int32 gtegeomscrn_pc;
extern int32 gtescreenscaleshift_pc;
//------------------------------------------------------------------------
inline void myApplyMatrixLV_pc(MATRIXPC *m, VECTOR *invec, VECTOR *outvec);
inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTORPC *invec, SVECTORPC *outvec);
inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTOR *invec, SVECTORPC *outvec);
inline int32 myVectorNormal_pc(VECTOR *in0, VECTOR *out0);
inline void mygte_MulMatrix0_pc(MATRIXPC *m1, MATRIXPC *m2, MATRIXPC *out);
inline void mygte_RotTrans_pc(SVECTORPC *in0, VECTOR *out0, int32 *flag);
inline void mygte_RotTrans_pc(SVECTOR *in0, VECTOR *out0, int32 *flag);
inline void mygte_RotTransPers_pc(SVECTORPC *in0, SVECTORPC *sxy0, int32 *p, int32 *flag, int32 *z);
inline void mygte_RotTransPers_pc(SVECTOR *in0, SVECTORPC *sxy0, int32 *p, int32 *flag, int32 *z);
inline void mygte_RotTransPers3_pc(SVECTORPC *in0, SVECTORPC *in1, SVECTORPC *in2, SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *p, int32 *flag, int32 *z);
inline void mygte_SetRotMatrix_pc(MATRIXPC *m);
inline void mygte_SetTransMatrix_pc(MATRIXPC *m);
inline void mygte_ApplyRotMatrix_pc(SVECTORPC *invec, VECTOR *outvec);
inline void myRotMatrix_gte_pc(SVECTOR *rot, MATRIXPC *m);
inline void mygte_SetColorMatrix_pc(MATRIXPC *m);
inline void mygte_SetLightMatrix_pc(MATRIXPC *m);
inline void mygte_SetGeomScreen_pc(int32 h);
inline void mygte_SetBackColor_pc(int32 r, int32 g, int32 b);
inline void mygte_SetScreenScaleShift_pc(int32 shift);
inline void mygte_NormalColorCol_pc(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0);
inline void mygte_NormalColorCol3_pc(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2);
inline void mygte_NormalClip_pc(SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *flag);
inline void mygte_NormalClip_pc(SVECTOR *sxy0, SVECTOR *sxy1, SVECTOR *sxy2, int32 *flag);
inline void mygte_AverageZ3_pc(int32 z0, int32 z1, int32 z2, int32 *sz);
//------------------------------------------------------------------------
inline void myApplyMatrixLV_pc(MATRIXPC *m, VECTOR *invec, VECTOR *outvec) {
outvec->vx = (m->m[0][0] * invec->vx + m->m[0][1] * invec->vy + m->m[0][2] * invec->vz) / ONE_PC;
outvec->vy = (m->m[1][0] * invec->vx + m->m[1][1] * invec->vy + m->m[1][2] * invec->vz) / ONE_PC;
outvec->vz = (m->m[2][0] * invec->vx + m->m[2][1] * invec->vy + m->m[2][2] * invec->vz) / ONE_PC;
}
//------------------------------------------------------------------------
inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTORPC *invec, SVECTORPC *outvec) {
outvec->vx = (int)((m->m[0][0] * invec->vx + m->m[0][1] * invec->vy + m->m[0][2] * invec->vz) / ONE_PC);
outvec->vy = (int)((m->m[1][0] * invec->vx + m->m[1][1] * invec->vy + m->m[1][2] * invec->vz) / ONE_PC);
outvec->vz = (int)((m->m[2][0] * invec->vx + m->m[2][1] * invec->vy + m->m[2][2] * invec->vz) / ONE_PC);
}
//------------------------------------------------------------------------
inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTOR *invec, SVECTORPC *outvec) {
outvec->vx = (int)((m->m[0][0] * (int)invec->vx + m->m[0][1] * (int)invec->vy + m->m[0][2] * (int)invec->vz) / ONE_PC);
outvec->vy = (int)((m->m[1][0] * (int)invec->vx + m->m[1][1] * (int)invec->vy + m->m[1][2] * (int)invec->vz) / ONE_PC);
outvec->vz = (int)((m->m[2][0] * (int)invec->vx + m->m[2][1] * (int)invec->vy + m->m[2][2] * (int)invec->vz) / ONE_PC);
}
//------------------------------------------------------------------------
inline void mygte_MulMatrix0_pc(MATRIXPC *m1, MATRIXPC *m2, MATRIXPC *out) {
MATRIXPC local;
MATRIXPC *work;
if ((out == m1) || (out == m2))
work = &local;
else
work = out;
work->m[0][0] = (int)((m1->m[0][0] * m2->m[0][0] + m1->m[0][1] * m2->m[1][0] + m1->m[0][2] * m2->m[2][0]) / ONE_PC);
work->m[0][1] = (int)((m1->m[0][0] * m2->m[0][1] + m1->m[0][1] * m2->m[1][1] + m1->m[0][2] * m2->m[2][1]) / ONE_PC);
work->m[0][2] = (int)((m1->m[0][0] * m2->m[0][2] + m1->m[0][1] * m2->m[1][2] + m1->m[0][2] * m2->m[2][2]) / ONE_PC);
work->m[1][0] = (int)((m1->m[1][0] * m2->m[0][0] + m1->m[1][1] * m2->m[1][0] + m1->m[1][2] * m2->m[2][0]) / ONE_PC);
work->m[1][1] = (int)((m1->m[1][0] * m2->m[0][1] + m1->m[1][1] * m2->m[1][1] + m1->m[1][2] * m2->m[2][1]) / ONE_PC);
work->m[1][2] = (int)((m1->m[1][0] * m2->m[0][2] + m1->m[1][1] * m2->m[1][2] + m1->m[1][2] * m2->m[2][2]) / ONE_PC);
work->m[2][0] = (int)((m1->m[2][0] * m2->m[0][0] + m1->m[2][1] * m2->m[1][0] + m1->m[2][2] * m2->m[2][0]) / ONE_PC);
work->m[2][1] = (int)((m1->m[2][0] * m2->m[0][1] + m1->m[2][1] * m2->m[1][1] + m1->m[2][2] * m2->m[2][1]) / ONE_PC);
work->m[2][2] = (int)((m1->m[2][0] * m2->m[0][2] + m1->m[2][1] * m2->m[1][2] + m1->m[2][2] * m2->m[2][2]) / ONE_PC);
if (work != out) {
out->m[0][0] = work->m[0][0];
out->m[0][1] = work->m[0][1];
out->m[0][2] = work->m[0][2];
out->m[1][0] = work->m[1][0];
out->m[1][1] = work->m[1][1];
out->m[1][2] = work->m[1][2];
out->m[2][0] = work->m[2][0];
out->m[2][1] = work->m[2][1];
out->m[2][2] = work->m[2][2];
}
}
//------------------------------------------------------------------------
inline void mygte_SetRotMatrix_pc(MATRIXPC *m) { *gterot_pc = *m; }
//------------------------------------------------------------------------
inline void mygte_SetTransMatrix_pc(MATRIXPC *m) { *gtetrans_pc = *m; }
//------------------------------------------------------------------------
inline void mygte_ApplyRotMatrix_pc(SVECTORPC *invec, VECTOR *outvec) {
outvec->vx = ((gterot_pc->m[0][0] * invec->vx + gterot_pc->m[0][1] * invec->vy + gterot_pc->m[0][2] * invec->vz) / ONE_PC);
outvec->vy = ((gterot_pc->m[1][0] * invec->vx + gterot_pc->m[1][1] * invec->vy + gterot_pc->m[1][2] * invec->vz) / ONE_PC);
outvec->vz = ((gterot_pc->m[2][0] * invec->vx + gterot_pc->m[2][1] * invec->vy + gterot_pc->m[2][2] * invec->vz) / ONE_PC);
}
//------------------------------------------------------------------------
inline void mygte_RotTrans_pc(SVECTORPC *in0, VECTOR *out0, int32 *flag) {
mygte_ApplyRotMatrix_pc(in0, out0);
out0->vx += gtetrans_pc->t[0];
out0->vy += gtetrans_pc->t[1];
out0->vz += gtetrans_pc->t[2];
// What GTE flags should we set ?
*flag = 0;
}
//------------------------------------------------------------------------
inline void mygte_RotTrans_pc(SVECTOR *in0, VECTOR *out0, int32 *flag) {
SVECTORPC sv_pc;
sv_pc.vx = in0->vx;
sv_pc.vy = in0->vy;
sv_pc.vz = in0->vz;
mygte_ApplyRotMatrix_pc(&sv_pc, out0);
out0->vx += gtetrans_pc->t[0];
out0->vy += gtetrans_pc->t[1];
out0->vz += gtetrans_pc->t[2];
// What GTE flags should we set ?
*flag = 0;
}
//------------------------------------------------------------------------
inline void mygte_RotTransPers_pc(SVECTORPC *in0, SVECTORPC *sxy0, int32 * /* p */, int32 *flag, int32 *z) {
VECTOR cam;
cam.vx = ((gterot_pc->m[0][0] * in0->vx + gterot_pc->m[0][1] * in0->vy + gterot_pc->m[0][2] * in0->vz) / ONE_PC);
cam.vy = ((gterot_pc->m[1][0] * in0->vx + gterot_pc->m[1][1] * in0->vy + gterot_pc->m[1][2] * in0->vz) / ONE_PC);
cam.vz = ((gterot_pc->m[2][0] * in0->vx + gterot_pc->m[2][1] * in0->vy + gterot_pc->m[2][2] * in0->vz) / ONE_PC);
cam.vx += (gtetrans_pc->t[0] << gtescreenscaleshift_pc);
cam.vy += (gtetrans_pc->t[1] << gtescreenscaleshift_pc);
cam.vz += (gtetrans_pc->t[2] << gtescreenscaleshift_pc);
*flag = 0;
if (cam.vz != 0) {
sxy0->vx = (int)((cam.vx * gtegeomscrn_pc) / cam.vz);
sxy0->vy = (int)((cam.vy * gtegeomscrn_pc) / cam.vz);
} else {
// To force an error and hence an illegal polygon
sxy0->vx = 2048;
sxy0->vy = 2048;
}
cam.vz >>= gtescreenscaleshift_pc;
*z = cam.vz / 4;
if (abs(sxy0->vx) > 1024)
*flag |= 0x80000000;
if (abs(sxy0->vy) > 1024)
*flag |= 0x80000000;
// set the value of flag : closer than h/2
if (cam.vz < 0)
*flag |= 0x80000000;
}
//------------------------------------------------------------------------
inline void mygte_RotTransPers_pc(SVECTOR *in0, SVECTORPC *sxy0, int32 * /* p */, int32 *flag, int32 *z) {
VECTOR cam;
cam.vx = ((gterot_pc->m[0][0] * (int)in0->vx + gterot_pc->m[0][1] * (int)in0->vy + gterot_pc->m[0][2] * (int)in0->vz) / ONE_PC);
cam.vy = ((gterot_pc->m[1][0] * (int)in0->vx + gterot_pc->m[1][1] * (int)in0->vy + gterot_pc->m[1][2] * (int)in0->vz) / ONE_PC);
cam.vz = ((gterot_pc->m[2][0] * (int)in0->vx + gterot_pc->m[2][1] * (int)in0->vy + gterot_pc->m[2][2] * (int)in0->vz) / ONE_PC);
cam.vx += (gtetrans_pc->t[0] << gtescreenscaleshift_pc);
cam.vy += (gtetrans_pc->t[1] << gtescreenscaleshift_pc);
cam.vz += (gtetrans_pc->t[2] << gtescreenscaleshift_pc);
*flag = 0;
if (cam.vz != 0) {
sxy0->vx = (int)((cam.vx * gtegeomscrn_pc) / cam.vz);
sxy0->vy = (int)((cam.vy * gtegeomscrn_pc) / cam.vz);
} else {
// To force an error and hence an illegal polygon
sxy0->vx = 2048;
sxy0->vy = 2048;
}
cam.vz >>= gtescreenscaleshift_pc;
*z = cam.vz / 4;
if (abs(sxy0->vx) > 1024)
*flag |= 0x80000000;
if (abs(sxy0->vy) > 1024)
*flag |= 0x80000000;
// set the value of flag : closer than h/2
if (cam.vz < 0)
*flag |= 0x80000000;
}
//------------------------------------------------------------------------
inline void mygte_RotTransPers3_pc(SVECTORPC *in0, SVECTORPC *in1, SVECTORPC *in2, SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *p, int32 *flag, int32 *z) {
int32 z0, z1, z2;
int32 p0, p1, p2;
int32 flag0, flag1, flag2;
mygte_RotTransPers_pc(in0, sxy0, &p0, &flag0, &z0);
mygte_RotTransPers_pc(in1, sxy1, &p1, &flag1, &z1);
mygte_RotTransPers_pc(in2, sxy2, &p2, &flag2, &z2);
// What GTE flags should we set ?
*flag = flag0 | flag1 | flag2;
*p = p2;
*z = z2;
}
//------------------------------------------------------------------------
inline void myRotMatrix_gte_pc(SVECTOR *rot, MATRIXPC *m) {
float ang0 = (float)rot->vx * 2.0f * myPI_PC / 4096;
MATRIXPC m0;
int32 c0 = myNINT_PC(ONE_PC * (float)cos(ang0));
int32 s0 = myNINT_PC(ONE_PC * (float)sin(ang0));
m0.m[0][0] = ONE_PC;
m0.m[0][1] = 0;
m0.m[0][2] = 0;
m0.m[1][0] = 0;
m0.m[1][1] = c0;
m0.m[1][2] = -s0;
m0.m[2][0] = 0;
m0.m[2][1] = s0;
m0.m[2][2] = c0;
float ang1 = (float)rot->vy * 2.0f * myPI_PC / 4096;
int32 c1 = myNINT_PC(ONE_PC * (float)cos(ang1));
int32 s1 = myNINT_PC(ONE_PC * (float)sin(ang1));
MATRIXPC m1;
m1.m[0][0] = c1;
m1.m[0][1] = 0;
m1.m[0][2] = s1;
m1.m[1][0] = 0;
m1.m[1][1] = ONE_PC;
m1.m[1][2] = 0;
m1.m[2][0] = -s1;
m1.m[2][1] = 0;
m1.m[2][2] = c1;
float ang2 = (float)rot->vz * 2.0f * myPI_PC / 4096;
int32 c2 = myNINT_PC(ONE_PC * (float)cos(ang2));
int32 s2 = myNINT_PC(ONE_PC * (float)sin(ang2));
MATRIXPC m2;
m2.m[0][0] = c2;
m2.m[0][1] = -s2;
m2.m[0][2] = 0;
m2.m[1][0] = s2;
m2.m[1][1] = c2;
m2.m[1][2] = 0;
m2.m[2][0] = 0;
m2.m[2][1] = 0;
m2.m[2][2] = ONE_PC;
mygte_MulMatrix0_pc(&m0, &m1, m);
mygte_MulMatrix0_pc(m, &m2, m);
}
//------------------------------------------------------------------------
inline void mygte_SetBackColor_pc(int32 r, int32 g, int32 b) {
gteback_pc[0] = r;
gteback_pc[1] = g;
gteback_pc[2] = b;
}
//------------------------------------------------------------------------
inline void mygte_SetColorMatrix_pc(MATRIXPC *m) { *gtecolour_pc = *m; }
//------------------------------------------------------------------------
inline void mygte_SetLightMatrix_pc(MATRIXPC *m) { *gtelight_pc = *m; }
//------------------------------------------------------------------------
inline void mygte_SetGeomScreen_pc(int32 h) { gtegeomscrn_pc = h; }
//------------------------------------------------------------------------
inline void mygte_NormalColorCol_pc(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0) {
SVECTORPC lightEffect;
// Normal line vector(local) -> light source effect
ApplyMatrixSV_pc(gtelight_pc, v0, &lightEffect);
if (lightEffect.vx < 0)
lightEffect.vx = 0;
if (lightEffect.vy < 0)
lightEffect.vy = 0;
if (lightEffect.vz < 0)
lightEffect.vz = 0;
// Light source effect -> Colour effect(local colour matrix+back colour)
SVECTORPC colourEffect;
ApplyMatrixSV_pc(gtecolour_pc, &lightEffect, &colourEffect);
if (colourEffect.vx < 0)
colourEffect.vx = 0;
if (colourEffect.vy < 0)
colourEffect.vy = 0;
if (colourEffect.vz < 0)
colourEffect.vz = 0;
// colourEffect is 0-ONE_PC (2^ONE_PC_SCALE)
// gteback is 0-255 (2^8)
colourEffect.vx = ((colourEffect.vx >> (ONE_PC_SCALE - 8)) + gteback_pc[0]);
colourEffect.vy = ((colourEffect.vy >> (ONE_PC_SCALE - 8)) + gteback_pc[1]);
colourEffect.vz = ((colourEffect.vz >> (ONE_PC_SCALE - 8)) + gteback_pc[2]);
// 256 = 1.0 in colourEffect
// 128 = 1.0 in in0
int32 red = ((in0->r * colourEffect.vx) >> 8);
int32 green = ((in0->g * colourEffect.vy) >> 8);
int32 blue = ((in0->b * colourEffect.vz) >> 8);
if (red > 255)
red = 255;
if (green > 255)
green = 255;
if (blue > 255)
blue = 255;
out0->r = (uint8)(red);
out0->g = (uint8)(green);
out0->b = (uint8)(blue);
}
//------------------------------------------------------------------------
inline void mygte_NormalColorCol3_pc(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2) {
gte_NormalColorCol_pc(v0, in0, out0);
gte_NormalColorCol_pc(v1, in0, out1);
gte_NormalColorCol_pc(v2, in0, out2);
}
//------------------------------------------------------------------------
inline int32 myVectorNormal_pc(VECTOR *in0, VECTOR *out0) {
int32 r2 = (in0->vx * in0->vx + in0->vy * in0->vy + in0->vz * in0->vz);
float r = (float)sqrt((float)r2) / (float)ONE_PC;
if (fabs(r) < 1.0e-6)
return 0;
out0->vx = (int32)((float)in0->vx / r);
out0->vy = (int32)((float)in0->vy / r);
out0->vz = (int32)((float)in0->vz / r);
return r2;
}
//////////////////////////////////////////////////////////////////////
inline void mygte_NormalClip_pc(SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *flag) {
// compute the cross-product of (v1-v0) x (v2-v0)
int32 l0x = sxy1->vx - sxy0->vx;
int32 l0y = sxy1->vy - sxy0->vy;
int32 l1x = sxy2->vx - sxy0->vx;
int32 l1y = sxy2->vy - sxy0->vy;
*flag = ((l0x * l1y) - (l0y * l1x));
}
//------------------------------------------------------------------------
inline void mygte_NormalClip_pc(SVECTOR *sxy0, SVECTOR *sxy1, SVECTOR *sxy2, int32 *flag) {
// compute the cross-product of (v1-v0) x (v2-v0)
int32 l0x = sxy1->vx - sxy0->vx;
int32 l0y = sxy1->vy - sxy0->vy;
int32 l1x = sxy2->vx - sxy0->vx;
int32 l1y = sxy2->vy - sxy0->vy;
*flag = ((l0x * l1y) - (l0y * l1x));
}
//------------------------------------------------------------------------
inline void mygte_AverageZ3_pc(int32 z0, int32 z1, int32 z2, int32 *sz) {
*sz = (z0 + z1 + z2) / 3;
*sz /= 4;
}
//------------------------------------------------------------------------
inline void mygte_SetScreenScaleShift_pc(int32 shift) { gtescreenscaleshift_pc = shift; }
//------------------------------------------------------------------------
} // End of namespace ICB
#endif // #ifndef __PC_CAPRI_MATHS_PC_H

View File

@@ -0,0 +1,82 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_common.h"
#include "common/system.h"
namespace ICB {
const char *hashTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
uint32 EngineHashString(const char *fn) {
if (fn == nullptr)
return 0;
char *f;
char c;
uint32 n;
n = 0;
f = const_cast<char *>(fn);
while ((c = *f) != 0) {
n = (n << 7) + (n << 1) + n + c; // n=128n+2n+n+c -> n=131n+c
// n=131*n+c; // n=131n+c
f++;
}
return n;
}
// Take a filename, path whatever,
// convert to hash value, then convert that hash value to
// 7 character filename
uint32 EngineHashFile(const char *fn, char *output) {
uint32 hash = EngineHashString(fn);
output[0] = hashTable[(hash >> 27) & 0x1F];
output[1] = hashTable[(hash >> 22) & 0x1F];
output[2] = hashTable[(hash >> 17) & 0x1F];
output[3] = hashTable[(hash >> 12) & 0x1F];
output[4] = hashTable[(hash >> 7) & 0x1F];
output[5] = hashTable[(hash >> 2) & 0x1F];
output[6] = hashTable[hash & 0x3];
output[7] = '\0';
return hash;
}
// Take a hash
// convert that hash value to
// 7 character filename
uint32 EngineHashToFile(uint32 hash, char *output) {
output[0] = hashTable[(hash >> 27) & 0x1F];
output[1] = hashTable[(hash >> 22) & 0x1F];
output[2] = hashTable[(hash >> 17) & 0x1F];
output[3] = hashTable[(hash >> 12) & 0x1F];
output[4] = hashTable[(hash >> 7) & 0x1F];
output[5] = hashTable[(hash >> 2) & 0x1F];
output[6] = hashTable[hash & 0x3];
output[7] = '\0';
return hash;
}
} // End of namespace ICB

View File

@@ -0,0 +1,99 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_CLU_API_H
#define ICB_CLU_API_H
namespace ICB {
#define MAX_DESCRIPTION_SIZE 60
#define MAX_FILENAME_SIZE 128
#define NON_KOSHA_FILE "ZZT_666_BUGGERED_666_ZZT"
#define NON_KOSHA_HASH 0xFFFFFFFF
#define CLUSTER_API_SCHEMA 2
#define CLUSTER_API_ID "CLU"
#define NULL_HASH 0x0
#define FOLDER_FILE_ID "ZZT"
// moved actual function to clu_api.cpp to save some memory maybe (testing)
uint32 EngineHashString(const char *fn);
uint32 EngineHashFile(const char *fn, char *output);
uint32 EngineHashToFile(uint32 hash, char *output); // Take a hash convert that hash value to 7 character filename
// To let the engine use the old version of HashString & HashFile
#define HashString EngineHashString
#define HashFile EngineHashFile
// File Layout is:
// HEADER_OPEN
// HEADER_NORMAL[n]
// filename1
// filename2
// ...
// filenamen
// file1
// file2
// ...
// filen
//
// The filenames are padded to multiple of 4 bytes
// The files are padded to multiple of 8 bytes
typedef struct HEADER_OPEN {
uint32 header_size;
uint32 noFiles;
uint32 cluster_hash;
int32 cdpos;
char description[MAX_DESCRIPTION_SIZE];
} HEADER_OPEN;
typedef struct HEADER_NORMAL {
uint32 fnOffset; // WAS: char* fn;
uint32 size;
uint32 offset;
uint32 hash;
} HEADER_NORMAL;
typedef struct Cluster_API {
char ID[4];
uint32 schema;
HEADER_OPEN ho;
HEADER_NORMAL hn[1]; // hn[n]
// string data
// file data
} Cluster_API;
#define FILE_NAME(a) (sizeof(uint) + sizeof(uint32) + sizeof(HEADER_OPEN) + (sizeof(HEADER_NORMAL) * (a)))
#define FILE_SIZE(a) (FILE_NAME(a) + sizeof(uint32))
#define FILE_OFFSET(a) (FILE_SIZE(a) + sizeof(uint32))
#define FILE_HASH(a) (FILE_OFFSET(a) + sizeof(uint32))
} // End of namespace ICB
#endif // #ifndef CLU_API_H

View File

@@ -0,0 +1,237 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_COMMON_H
#define ICB_PX_COMMON_H
#include "common/scummsys.h"
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
#define PXNULL (0xffffffff)
// This defines the scale value for converting PC floats to PSX fixed-point representation. Not
// sure if this is the right place for this.
#define PSX_FIXED_POINT_SCALE 4096
#define PSX_FLOAT_POINT_SHIFT 12
#define PSX_FLOAT_POINT_SCALE (1 << PSX_FLOAT_POINT_SHIFT)
#define PSX_ANGLE_POINT_SCALE 4096
#define PSX_DOUBLE_POINT_SCALE 4096
// Rather than using integer values beginning at 0 it would be more descriptive to use
// four ascii characters, so the type can be guessed from a hex dump.
// Use the FT macro to turn four characters into an enum _file_type
#define FT_MACRO(a, b, c, d) (a | (b << 8) | (c << 16) | (d << 24))
enum _file_type {
FT_UNDEFINED,
unusedFT_COMPILED_GAME_OBJECT, // A compiled game object
FT_FONT, // debug console & head-up font
FT_VOX_ANIM, // voxel anim file (see voxel anim file format doc)
FT_GAME_OBJECT, // A game engine game object
FT_BITMAP_ANIM, // 2D anim file (from bitmap converter) (see 2D bitmaps doc)
FT_BITMAP_FONT, // font file (from bitmap converter) (see 2D bitmaps doc)
unusedFT_FN_ROUTINES_DAT, // fn routine data for the script compiler
unusedFT_OBJECTS_SCRIPTS_DAT, // Compiled scripts for a single object
unusedFT_LINKED_SCRIPTS, // File containing scripts linked together
unusedFT_LINKED_OBJECTS, // File containing objects in session linked together
FT_PROP_LIST, // File containing a list of prop names and there program counters
FT_PROP_ANIM_LIST, // File containing prop animation lists
FT_FLOOR_MAP, // File containing the floors for a session [PS 06/04/98].
FT_BARRIERS, // File containing the index into the barriers file for the line-of-sight stuff [PS 06/04/98].
FT_CAMERAS, // File containing the camera 'cubes' for a session [PS 06/04/98].
FT_BARRIERLIST, // File containing the actual raw walkgrid barriers for a session [PS 01/06/98].
FT_OBJECT_POSITIONS, // File listing props occurring on a given floor [PS 06/04/98].
FT_PROP_ANIMATIONS, // File containing information about prop animations [PS 11/08/98].
FT_VOICE_OVER_TEXT, // Compiled voice-over text file (for Remora etc.).
// add more here!
/***IMPORTANT***
DO NOT DELETE ENTRIES FROM THIS LIST OR SUBSEQUENT RESOURCE TYPES WILL BE RENUMBERED
RENAME ENTRIES NO LONGER IN USE AND REUSE THEM LATER
*/
// The following entries can go in any order, but should not be changed
FT_COMPILED_SCRIPTS = FT_MACRO('C', 'S', 'C', 'R'), // Compiled script object format (.scrobj)
FT_LINKED_SCRIPTS = FT_MACRO('L', 'S', 'C', 'R'), // File containing scripts linked together
FT_LINKED_OBJECTS = FT_MACRO('L', 'O', 'B', 'J'), // File containing objects in session linked together
FT_COMPILED_GAME_OBJECT = FT_MACRO('C', 'O', 'B', 'J'), // A compiled game object
FT_FN_ROUTINES_DAT = FT_MACRO('F', 'N', 'D', 'T'), // fn routine data for the script compiler
FT_COMBINED_OBJECT = FT_MACRO('C', 'M', 'B', 'O'), // Combined object and script data
FT_COMPILED_TEXT = FT_MACRO('C', 'M', 'P', 'T'), // Compressed text
FT_LINKED_TEXT = FT_MACRO('L', 'N', 'K', 'T'), // Linked text
FT_COMPILED_SFX = FT_MACRO('S', 'F', 'X', ' '), // compiled SFX file
FT_LINKED_SFX = FT_MACRO('S', 'F', 'X', 'L'), // linked SFX files file
FT_REMORA_MAP = FT_MACRO('R', 'M', 'A', 'P') // Remora map file.
};
#define STANDARD_HEADER_NAME_LENGTH 32 // Max length of the header name
typedef struct {
int32 version; // This is incremented every time the object is updated
_file_type type; // enumerated value for every type of object in the game
int32 owner; // Who is responsible for producing this object
int32 unused; // For future expansion
int32 unused2; // For future expansion
char name[STANDARD_HEADER_NAME_LENGTH]; // 32 bytes worth of ascii name information
} px_standard_header;
typedef struct {
uint8 red;
uint8 green;
uint8 blue;
uint8 alpha;
} _rgb;
typedef float PXreal;
typedef float PXfloat;
typedef double PXdouble;
#define REAL_ZERO 0.0f
#define REAL_ONE 1.0f
#define REAL_TWO 2.0f
#define REAL_MIN FLT_MIN
#define REAL_MAX FLT_MAX
#define REAL_LARGE 100000.0f
#define FLOAT_ZERO 0.0f
#define FLOAT_QUARTER 0.25f
#define FLOAT_HALF 0.5f
#define FLOAT_ONE 1.0f
#define FLOAT_TWO 2.0f
#define FLOAT_MIN FLT_MIN
#define FLOAT_MAX FLT_MAX
#define FLOAT_LARGE 100000.0f
#define ZERO_TURN 0.0f
#define QUARTER_TURN 0.25f
#define HALF_TURN 0.5f
#define FULL_TURN 1.0f
#define TWO_PI (2.0f * M_PI)
// For converting pan values when the game is saved/loaded
// For PC this is equal to the PSX fixed point scaling used to represent angles
#define PAN_SCALE_FACTOR PSX_ANGLE_POINT_SCALE
// #define DEGREES_TO_RADIANS 0.01745329f
#define DEGREES_TO_RADIANS(x) ((x * TWO_PI) / 360.0f)
#define RADIANS_TO_DEGREES(x) (x * (180.0f / PI))
// How to make a PXdouble from a PXreal
#define PXreal2PXdouble(x) (double)(x)
// How to make a PXreal from a PXdouble
#define PXdouble2PXreal(x) (float)(x)
// How to make a PXfloat from a PXreal
#define PXreal2PXfloat(x) (x)
// How to make a PXreal from a PXfloat
#define PXfloat2PXreal(x) (x)
typedef struct PXsvector_PC {
float x;
float y;
float z;
} PXsvector_PC;
typedef struct PXvector_PC {
float x;
float y;
float z;
} PXvector_PC;
typedef struct PXsvector_PSX {
int16 x;
int16 y;
int16 z;
int16 pad;
} PXsvector_PSX;
typedef struct PXvector_PSX {
int32 x;
int32 y;
int32 z;
} PXvector_PSX;
#ifdef _PSX_VECTOR
typedef PXvector_PSX PXvector;
typedef PXsvector_PSX PXsvector;
#else
typedef PXvector_PC PXvector;
typedef PXsvector_PC PXsvector;
#endif
typedef struct PXorient_PSX {
int16 pan;
int16 tilt;
int16 cant;
int16 pad;
} PXorient_PSX;
typedef struct PXorient_PC {
float pan;
float tilt;
float cant;
} PXorient_PC;
#ifdef _PSX_ORIENT
typedef PXorient_PSX PXorient;
#else
typedef PXorient_PC PXorient;
#endif
// Endian safe read functions
inline uint16 READ_LE_U16(const void *p) {
const uint8 *data = (const uint8 *)p;
return (uint16)((data[1] << 8) | data[0]);
}
inline uint32 READ_LE_U32(const void *p) {
const uint8 *data = (const uint8 *)p;
return (uint32)(((uint32)data[3] << 24) | ((uint32)data[2] << 16) | ((uint32)data[1] << 8) | (uint32)data[0]);
}
#if defined(SCUMM_LITTLE_ENDIAN)
#define FROM_LE_FLOAT32(a) ((float)(a))
#else
#define FROM_LE_FLOAT32(a) ((float)(SWAP_BYTES_32(a)))
#endif
#define MKTAG(a0, a1, a2, a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
} // End of namespace ICB
#endif // #ifndef _PX_INC_PROJECT_X_COMMON_H

View File

@@ -0,0 +1,49 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
namespace ICB {
#define BUILD_OUTPUT_EXTENSION "build" // Extension for the file containing the build results
#define OBJECT_DEFINITION_EXTENSION "objdef" // Extension for an object definition
#define COMPILED_OBJECT_EXTENSION "compobj" // Extension for a compiled object
#define COMPILED_SCRIPT_EXTENSION "scrobj" // Extension for a compiled script
#define COMBINED_OBJECT_EXTENSION "cbdobj" // Extension for a combined object
#define COMPILED_FN_ROUTINES_EXTENSION "fn_dat" // Extension for the compiled fn routine data
#define COMPILED_SPEECH_SCRIPT_EXTENSION "spchscrobj" // Compiled speech script
// Makefile macro names
#define NMAKE_LOCAL_ROOT_MACRO "$(LOCALROOT)"
#define NMAKE_COMMON_ROOT_MACRO "$(COMMONROOT)"
// Resource gauge definitions
#define RESOURCE_VARIABLE_SEARCH_PATTERN "Resource Value:"
#define RESOURCE_VARIABLE_SEARCH_PATTERN_LEN 15
// Converter program versions
#define PXVER_FN_ROUTINES 1 // fn_routines converter version.
#define PXVER_SCRIPTCOMPILER 1 // fn_routines converter version.
} // End of namespace ICB

View File

@@ -0,0 +1,63 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_FEATURES_H_INCLUDED
#define ICB_PX_FEATURES_H_INCLUDED
#include "engines/icb/common/px_common.h"
namespace ICB {
// These define the filenames for files containing floor maps.
#define PX_FILENAME_FEATURES_INFO "pxwgfeatures"
#ifndef PX_EXT_LINKED
#define PX_EXT_LINKED "linked"
#endif
#ifndef PSX_EXT_LINKED
#define PSX_EXT_LINKED "PSXlinked"
#endif
// This is the version for these files. The engine checks this runtime to know that it is running with
// the correct version of file.
#define VERSION_PXWGFEATURES 200
// enum _feature_type
// Not entirely sure what these will be yet. But here are a couple of suggestions.
enum _feature_type { ANIMATING = 0, FEATURE, OTHER };
// struct _feature_info
// This holds information about one prop.
typedef struct {
PXreal x, y, z; // Reference point for the prop.
PXreal floor_y; // Y projected down to the floor the prop is on.
_feature_type type; // The type of the prop.
PXfloat direction; // 0 - 99 (maybe use -1 to indicate no direction).
} _feature_info;
} // End of namespace ICB
#endif // #ifndef _PX_FEATURES_H_INCLUDED

View File

@@ -0,0 +1,97 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_FLOOR_MAP_H_INCLUDED
#define ICB_PX_FLOOR_MAP_H_INCLUDED
#include "engines/icb/common/px_common.h"
namespace ICB {
// Should put this in a nice header file somewhere
typedef float PXreal;
typedef float PXfloat;
// This defines the length of the hashed camera name on the PSX.
#define HASH_CAMERA_LEN 8
// These define the filenames for files containing floor maps.
#define PX_FILENAME_FLOOR_MAP "pxwgfloors"
#ifndef PC_EXT_LINKED
#define PC_EXT_LINKED "linked"
#endif
#ifndef PSX_EXT_LINKED
#define PSX_EXT_LINKED "PSXlinked"
#endif
// Update this whenever the format of the data changes, so engine can check it is in sync with data.
#define VERSION_PXWGFLOORS 300
// This holds one of the rectangles making up the floor. The coordinates are held looking DOWN on the floor, and the
// coordinate system used is our system (y is up/down, x and z axes are in the horizontal plane).
typedef struct {
PXreal x1, z1; // X, Z of top-left of the floor rectangle (looking DOWN on the floor).
PXreal x2, z2; // Ditto for bottom-right corner.
} _rect;
// struct _neighbour_map_entry
// This holds one of the entries in the exit map.
typedef struct {
uint32 neighbour; // Index of neighbour (can be passed directly into _linked_data_file.Fetch_item_by_number()).
uint32 offset_exit_descriptor; // File position of the exit descriptor for this.
} _neighbour_map_entry;
// struct _floor
// This is the top structure in a floor entry. All the other structures hang off this one.
typedef struct {
PXreal base_height;
_rect rect;
char camera_cluster[HASH_CAMERA_LEN];
uint32 camera_name_offset;
uint32 map_location_hash;
uint32 num_neighbours;
_neighbour_map_entry neighbour_map[1];
} _floor;
// struct _exit_descriptor
// This holds an exit descriptor would you believe?
typedef struct {
uint32 num_waypoints; // Number of waypoints for the exit.
uint32 offset_waypoints; // File offset of the list of waypoints for this exit.
uint32 offset_propname; // File offset of the ASCII name of a prop associated with this exit.
} _exit_descriptor;
// struct _floor_waypoint
// This holds a waypoint for an exit.
typedef struct {
PXreal x, z; // Physical position of waypoint on floor.
PXfloat direction; // A direction (0-360?) for the waypoint. Might be used to face a mega a certain way.
} _floor_waypoint;
} // End of namespace ICB
#endif // #ifndef _PX_FLOOR_MAP_H_INCLUDED

View File

@@ -0,0 +1,211 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_GAME_OBJECT_H
#define ICB_GAME_OBJECT_H
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
// object run-time status values
enum _object_status { // possible values of object status field
OB_STATUS_NOT_HELD, // 0
OB_STATUS_HELD // 1 (when an object is held it does not get processed or drawn - it is excluded from the game)
};
#define OB_INIT_SCRIPT 0
#define OB_LOGIC_CONTEXT 1
#define OB_ACTION_CONTEXT 2
typedef struct {
uint32 m_size; // The size of the total data structure
uint32 m_var_table_offset;
uint32 ob_status; // low level internal stuff - see enum _object_status
// The offsets to the blocks of data. All offsets
// are from the start of the object
uint32 m_script_name_hash_table_offset; // Offset to the script name table
uint32 m_lvars_offset; // Offset to the local variable data
uint32 m_name_offset; // Offset to the object name
// Variable and script count
uint32 m_noLvars; // How many lvars this object has
uint32 m_noScripts; // The number of scripts associated with this object
/* This data is then followed by:
Null terminated object name
Object variable information block
Script names information block
*/
} CGame;
class CGameObject {
// Only ob_status is made public. To access the other elements use
// the access functions. This is so that further changes to the structure
// can be catered for through the access functions, and not needed where
// any element is specifically referenced
public:
// Main access functions
static const char *GetName(CGame *game); // Get a pointer to the object name
static uint32 GetNoLvars(CGame *game) ; // Get the number of local variables
static uint32 GetNoScripts(CGame *game); // Get the number of scripts
static uint32 GetSize(CGame *game) { return FROM_LE_32(game->m_size); }
// Using the hash system you cannot get names, only hashes
static uint32 GetScriptNameFullHash(CGame *game, uint32);
static uint32 GetScriptNamePartHash(CGame *game, uint32);
static const char *GetScriptVariableName(CGame *game, uint32); // gets name
static int32 GetVariable(CGame *game, const char *name); // get's number of named variable
static int32 IsVariableString(CGame *game, uint32); // is variable a string (1=string, 0=int)
static void SetIntegerVariable(CGame *game, uint32, int32); // Sets the value of an integer variable
static int32 GetIntegerVariable(CGame *game, uint32); // Get the value of an integer variable
static int32 *GetIntegerVariablePtr(CGame *game, uint32); // Get the value of an integer variable
static const char *GetStringVariable(CGame *game, uint32); // Get the value of a string variable
static const char *GetStringValueOrDefault(CGame *game, const char *varName, const char *defaultStr) {
int32 var;
var = GetVariable(game, varName);
if (var == -1)
return defaultStr;
else
return GetStringVariable(game, var);
}
static int32 GetIntegerValueOrDefault(CGame *game, const char *varName, int32 defaultInt) {
int32 var;
var = GetVariable(game, varName);
if (var == -1)
return defaultInt;
else
return GetIntegerVariable(game, var);
}
};
inline const char *CGameObject::GetName(CGame *game) {
// Get a pointer to the object name
return ((const char *)(((const char *)game) + game->m_name_offset));
}
inline uint32 CGameObject::GetNoLvars(CGame *game) {
// Get the number of local variables
return FROM_LE_32(game->m_noLvars);
}
inline uint32 CGameObject::GetNoScripts(CGame *game) {
// Get the number of scripts
return FROM_LE_32(game->m_noScripts);
}
inline uint32 CGameObject::GetScriptNameFullHash(CGame *game, uint32 scriptNo) {
assert(scriptNo < FROM_LE_32(game->m_noScripts));
return FROM_LE_32(((const int32 *)(((const char *)game) + FROM_LE_32(game->m_script_name_hash_table_offset)))[scriptNo * 2]);
}
inline uint32 CGameObject::GetScriptNamePartHash(CGame *game, uint32 scriptNo) {
assert(scriptNo < FROM_LE_32(game->m_noScripts));
return FROM_LE_32(((const int32 *)(((const char *)game) + FROM_LE_32(game->m_script_name_hash_table_offset)))[scriptNo * 2 + 1]);
}
inline const char *CGameObject::GetScriptVariableName(CGame *game, uint32 varNo) {
const char *currentPos;
const uint32 *table;
currentPos = (((const char *)game) + FROM_LE_32(game->m_var_table_offset));
table = (const uint32 *)currentPos;
return ((const char *)game) + FROM_LE_32(table[varNo * 2]);
}
inline int32 CGameObject::IsVariableString(CGame *game, uint32 varNo) {
const char *currentPos;
const uint32 *table;
currentPos = (((const char *)game) + FROM_LE_32(game->m_var_table_offset));
table = (const uint32 *)currentPos;
return FROM_LE_32(table[varNo * 2 + 1]);
}
inline int32 CGameObject::GetVariable(CGame *game, const char *name) {
const char *currentPos;
const uint32 *table;
int32 retValue;
uint32 whichVar;
currentPos = (((const char *)game) + FROM_LE_32(game->m_var_table_offset));
table = (const uint32 *)currentPos;
retValue = -1;
for (whichVar = 0; whichVar < FROM_LE_32(game->m_noLvars); whichVar++) {
if (strcmp(name, ((const char *)game) + FROM_LE_32(table[whichVar * 2])) == 0) {
retValue = whichVar;
whichVar = (int32)FROM_LE_32(game->m_noLvars);
}
}
return retValue;
}
inline void CGameObject::SetIntegerVariable(CGame *game, uint32 lvar, int32 val) {
assert(lvar < FROM_LE_32(game->m_noLvars));
uint32 *lvars = (uint32 *)((byte *)game + FROM_LE_32(game->m_lvars_offset));
WRITE_LE_UINT32(lvars + lvar, (uint32)val);
}
inline int32 CGameObject::GetIntegerVariable(CGame *game, uint32 lvar) {
// Get an lvar value
assert(lvar < FROM_LE_32(game->m_noLvars));
uint32 *lvars = (uint32 *)((byte *)game + FROM_LE_32(game->m_lvars_offset));
return (int32)READ_LE_UINT32(lvars + lvar);
}
inline int32 *CGameObject::GetIntegerVariablePtr(CGame *game, uint32 lvar) {
// Get an lvar value
assert(lvar < FROM_LE_32(game->m_noLvars));
uint32 *lvars = (uint32 *)((byte *)game + FROM_LE_32(game->m_lvars_offset));
return (int32 *)(lvars + lvar);
}
inline const char *CGameObject::GetStringVariable(CGame *game, uint32 lvar) {
// Get an lvar value
assert(lvar < FROM_LE_32(game->m_noLvars));
uint32 *lvars = (uint32 *)((byte *)game + FROM_LE_32(game->m_lvars_offset));
return (const char *)game + (int32)READ_LE_UINT32(lvars + lvar);
}
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,202 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/p4.h"
#include "engines/icb/debug_pc.h"
#include "engines/icb/common/px_globalvariables.h"
namespace ICB {
CpxGlobalScriptVariables::CpxGlobalScriptVariables() {
m_no_vars = 0;
m_sorted = 0;
int32 i;
for (i = 0; i < MAX_global_vars; i++) {
m_vars[i].hash = 666;
m_vars[i].value = 666;
m_varInit[i] = GLOBAL_VAR_NOT_SET;
}
}
int32 CpxGlobalScriptVariables::FindVariable(uint32 hash) {
int32 index = -1;
if (m_sorted == 0) {
SortVariables();
} else {
// Use binary search system to find the variables
// The variables are stored in ascending hash sorted order
int32 min = 0;
int32 max = m_no_vars;
index = ((max - min) >> 1);
CpxVariable *pvar = m_vars + index;
// Start at the middle of the list
while (pvar->hash != hash) {
// Not found
if ((index == min) || (index == max)) {
index = -1;
break;
}
// Is it further up the table ?
if (hash > pvar->hash) {
min = index;
// Go down from min so we creep towards maximum
index = max - ((max - min) >> 1);
} else {
max = index;
// Go up from min so we creep towards minimum
index = min + ((max - min) >> 1);
}
pvar = m_vars + index;
if (max == min)
Fatal_error("GlobalVars Binary search failed max==min %d number %d", max, m_no_vars);
}
//#define CHECK_BINARY_SEARCH
#ifdef CHECK_BINARY_SEARCH
uint32 i;
int32 oldi = 0;
// Check the binarry search worked
for (i = 0; i < m_no_vars; i++) {
if (m_vars[i].hash == hash) {
oldi = i;
break;
}
}
if (oldi != index) {
Fatal_error("Binary search failed");
}
#endif
}
return index;
}
void CpxGlobalScriptVariables::InitVariable(uint32 hash, int32 value, const char *name) {
// If the variable exists then it has already been initialised
int32 i = FindVariable(hash);
if (i == -1) {
m_vars[m_no_vars].hash = hash;
m_vars[m_no_vars].value = value;
if (name) {
Tdebug("gtable.txt", "%s , %d , 0x%X", name, value, hash);
}
m_no_vars++;
// The list is no int32er sorted !
m_sorted = 0;
} else {
// The variable has been set, so initing it is an error
// Fatal_error( "Global variable with hash 0x%08x has already been initialised",hash); // Game engine error
m_vars[i].value = value;
}
}
void CpxGlobalScriptVariables::SetVariable(uint32 hash, int32 value) {
// Set a variable
// You can't set a variable that has not been initialised
// Has the variable been defined already
int32 i = FindVariable(hash);
if (i != -1) {
// Once a variable is set then flag it as such
m_varInit[i] = GLOBAL_VAR_SET;
// Ok, just return the value
m_vars[i].value = value;
} else {
// The variable hasn't been set, so accessing it is an error
Fatal_error("SetVariable::Global variable with hash 0x%08x has been accessed before it was initialised", hash); // Game engine error
}
}
// warn = 1
// Give a warning if someone Get's the value before Setting it
// i.e. they are relying on the initialisation code which is bad
// warn = 0
// Don't give the warning - this is needed for save games which Get all global's !
int32 CpxGlobalScriptVariables::GetVariable(uint32 hash, const char *name, int32 warn) {
// Has the variable been defined already
int32 i = FindVariable(hash);
if (i != -1) {
if (warn == 1) {
// Give a warning if someone Get's the value before Setting it
// i.e. they are relying on the initialisation code which is bad
// Once a variable is set then flag it as such
if (m_varInit[i] == GLOBAL_VAR_NOT_SET) {
// Only give the warning once
m_varInit[i] = GLOBAL_VAR_SET;
if (name) {
{ Message_box("GetVariable::Global variable '%s' hash 0x%08X value %d accessed before it was set", name, hash, m_vars[i].value); }
} else {
{ Message_box("GetVariable::Global variable hash 0x%08X value %d accessed before it was set", hash, m_vars[i].value); }
}
}
}
// Ok, just return the value
return m_vars[i].value;
} else {
// The variable hasn't been set, so accessing it is an error
Fatal_error("GetVariable::Global variable with hash 0x%08X has been accessed before it was initialised", hash); // Game engine error
return 0;
}
}
//
// Sort the variables so searching for them is quicker !
// The search method can then use a binary chop system
//
void CpxGlobalScriptVariables::SortVariables() {
uint32 i;
uint32 j;
CpxVariable temp;
uint8 temp8;
// Sort the variable in ascending order
// e.g. lowest -> highest
for (i = 0; i < m_no_vars; i++) {
for (j = i + 1; j < m_no_vars; j++) {
if (m_vars[i].hash > m_vars[j].hash) {
temp = m_vars[i];
m_vars[i] = m_vars[j];
m_vars[j] = temp;
temp8 = m_varInit[i];
m_varInit[i] = m_varInit[j];
m_varInit[j] = temp8;
}
}
}
// The list is now sorted
m_sorted = 1;
}
} // End of namespace ICB

View File

@@ -0,0 +1,88 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PXGLOBALVARIABLES
#define ICB_PXGLOBALVARIABLES
#include "common/noncopyable.h"
#include "engines/icb/common/px_common.h"
#include "engines/icb/common/px_clu_api.h"
namespace ICB {
#define MAX_global_vars 256
#define GLOBAL_VAR_NOT_SET (0)
#define GLOBAL_VAR_SET (1)
class CpxVariable {
public:
uint32 hash;
int32 value;
};
class CpxGlobalScriptVariables : Common::NonCopyable {
private:
CpxVariable m_vars[MAX_global_vars];
// This is not part of the CpxVariable class - because of memory packing reasons
uint8 m_varInit[MAX_global_vars];
uint32 m_no_vars;
uint32 m_sorted;
public:
CpxGlobalScriptVariables();
void SortVariables();
int32 GetVariable(uint32 hash, const char *name = NULL, int32 warn = 1); // Get a variable by hash
int32 GetVariable(const char *n) { // Get a variable
return GetVariable(EngineHashString(n), n);
}
void SetVariable(uint32, int32); // Set a variable by hash
void SetVariable(const char *n, int32 i) { // Set a variable
SetVariable(EngineHashString(n), i);
}
void InitVariable(uint32, int32, const char *name = NULL); // First time initialise a variable by hash
void InitVariable(const char *n, int32 i) { // First time initialise a variable
InitVariable(EngineHashString(n), i, n);
}
int32 FindVariable(uint32); // is this variable taken
int32 FindVariable(const char *n) { // is this variable taken
return FindVariable(EngineHashString(n));
}
uint32 GetNoItems() { return (m_no_vars); }
const CpxVariable &operator[](uint32 n) { return (m_vars[n]); } // Return reference to variable itself (const)
};
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,88 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_common.h"
#include "engines/icb/gfx/psx_pcdefines.h"
namespace ICB {
enum pxLightType { OMNI_PX_LIGHT, FREE_SPOT_PX_LIGHT, TARGET_SPOT_PX_LIGHT, FREE_DIRECT_PX_LIGHT, TARGET_DIRECT_PX_LIGHT, GLOBAL_PX_LIGHT };
typedef struct {
char name[16]; // String for user's name
uint32 type; // 0-5 enumerated, see above
MATRIX PSX_matrix; // Standard PSX type, 32 bytes
SVECTOR direction; // Standard PSX type, 8 bytes
int32 pan; // Fixed point angle
int32 cant; // Fixed point angle
int32 tilt; // Fixed point angle
uint32 red; // Fixed point integer
uint32 green; // Fixed point integer
uint32 blue; // Fixed point integer
uint32 intensity; // Fixed point integer
uint32 hspot_size; // Fixed point angle
uint32 falloff_size; // Fixed point angle
uint32 use_nearAtten; // 0 false, 1 true
uint32 nearAtten_start; // Nearest integer
uint32 nearAtten_end; // Nearest integer
uint32 use_farAtten; // 0 false, 1 true
uint32 farAtten_start; // Nearest integer
uint32 farAtten_end; // Nearest integer
uint32 shape; // 0 rectangular, 1 circlular
uint32 aspect; // Fixed point integer
uint32 overshoot; // 0 false, 1 true
uint32 shadow; // 0 false, 1 true
uint32 affect_diffuse; // 0 false, 1 true
uint32 affect_specular; // 0 false, 1 true
} _pxLightState; // Size 144 bytes in total
class _pxLights {
public:
_pxLights() { ; }
~_pxLights() { ; }
uint32 Fetch_number_of_items() const { return num_of_lights; }
inline const _pxLightState *Fetch_item_by_number(uint32 number) const;
private:
uint32 num_of_lights;
};
// All lights are of the same size to skip to the start of whichever is wanted
inline const _pxLightState *_pxLights::Fetch_item_by_number(uint32 number) const {
if (number < num_of_lights) {
return ((_pxLightState *)(((char *)this) + (4 + (number * 144))));
} else
return NULL;
}
} // End of namespace ICB

View File

@@ -0,0 +1,63 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_rcutypes.h"
#include "engines/icb/common/px_string.h"
#include "engines/icb/common/px_common.h"
#include "engines/icb/common/px_clu_api.h"
#include "engines/icb/common/px_linkeddatafile.h"
namespace ICB {
// get NUMBER given HASH (does the search) - hashs must be ordered for this binary search to succeed.
uint32 LinkedDataObject::Fetch_item_number_by_hash(LinkedDataFile *file, const uint32 hash) {
int32 top, bottom;
int32 i;
uint32 current;
if (!FROM_LE_32(file->number_of_items))
return PX_LINKED_DATA_FILE_ERROR;
top = FROM_LE_32(file->number_of_items) - 1;
i = top >> 1;
bottom = 0;
for (;;) {
current = FROM_LE_32(file->list[i].name_hash_value);
if (hash == current)
return i;
else if (top == bottom)
return PX_LINKED_DATA_FILE_ERROR;
else if (hash > current) {
bottom = i + 1;
i = (top + bottom) >> 1;
} else {
top = i;
i = (top + bottom) >> 1;
}
}
}
} // End of namespace ICB

View File

@@ -0,0 +1,180 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_LINKED_DATA_FILE_H
#define ICB_PX_LINKED_DATA_FILE_H
#include "engines/icb/common/px_rcutypes.h"
#include "engines/icb/common/px_common.h"
#include "engines/icb/common/px_clu_api.h"
#include "engines/icb/debug.h"
#include "common/endian.h"
namespace ICB {
// This value is returned as an error condition.
#define PX_LINKED_DATA_FILE_ERROR (0xffffffff)
#define ORDER_PRESERVED_FLAG 1
#define NO_NAMES_FLAG 2
#define SUPPRESS_OUTPUT 4 // Suppress printing of output
typedef struct {
int32 name_offset; // offset to Null terminated name of the item
int32 data_offset; // Offset to the item
int32 data_size; // Size of the items data
uint32 name_hash_value; // hash value of name item...
} LinkedDataFileEntry;
typedef struct {
px_standard_header header;
uint32 number_of_items;
uint32 flags;
LinkedDataFileEntry list[1]; // 1 used to prevent 0 sized array warnings
// This structure is a variable size and so should never
// be a parameter to sizeof anyway
} LinkedDataFile;
class LinkedDataObject { // Should be CObjectFile
public:
static inline uint32 Fetch_number_of_items(LinkedDataFile *file) { // how many
return (FROM_LE_32(file->number_of_items));
}
static inline uint32 GetHeaderVersion(LinkedDataFile *file) { return (FROM_LE_32(file->header.version)); }
static inline int32 OrderPreserved(LinkedDataFile *file) { return (FROM_LE_32(file->flags) & (ORDER_PRESERVED_FLAG)); }
static inline int32 NameSearchable(LinkedDataFile *file) { return (!OrderPreserved(file)); }
static uint32 Fetch_item_number_by_hash(LinkedDataFile *file, const uint32 hash);
static uint32 Fetch_item_number_by_name(LinkedDataFile *file, const char *name); // reference a number by its ascii name
static void *Fetch_item_by_number(LinkedDataFile *file, uint32 number); // reference a resource by number
static void *Fetch_item_by_name(LinkedDataFile *file, const char *name); // reference a resource by its ascii name
static void *Fetch_items_name_by_number(LinkedDataFile *file, uint32 number); // return pointer to name of item number n
static void *Try_fetch_item_by_name(LinkedDataFile *file, const char *); // reference a resource by name
static void *Try_fetch_item_by_hash(LinkedDataFile *file, uint32); // reference a resource by hash
static void *Try_fetch_item_by_script_name(LinkedDataFile *file, const char *name);
};
// get DATA given NUMBER
inline void *LinkedDataObject::Fetch_item_by_number(LinkedDataFile *file, uint32 number) {
// illegal reference number
assert(number < FROM_LE_32(file->number_of_items));
// return address of resource
return (((uint8 *)&file->header) + FROM_LE_32(file->list[number].data_offset));
}
// get NAME given NUMBER
inline void *LinkedDataObject::Fetch_items_name_by_number(LinkedDataFile *file, uint32 number) {
// illegal reference number
assert(number < FROM_LE_32(file->number_of_items));
// return name
return (((uint8 *)&file->header) + FROM_LE_32(file->list[number].name_offset));
}
// this is the one that does the search...
// get NUMBER given NAME (does search)
inline uint32 LinkedDataObject::Fetch_item_number_by_name(LinkedDataFile *file, const char *name) {
uint32 hash;
if (!NameSearchable(file)) {
Fatal_error("This file is not searchable by name and was created as such (name %s)", name);
}
hash = EngineHashString(name);
return Fetch_item_number_by_hash(file, hash);
}
// get ITEM given NAME (uses Try_fetch_item_by_name, fatal error if can't find)
inline void *LinkedDataObject::Fetch_item_by_name(LinkedDataFile *file, const char *name) {
void *search;
search = Try_fetch_item_by_name(file, name);
if (search == 0) {
Fatal_error("pxLinked_data_file::Fetch_item_by_name Object %s not found", name);
// Note, for not the engine then the error is not caught which is a bad thing
// but we need a generic Fatal_error type thing that converters & the engine can call
// i.e. the converters need a Fatal_error function
return (NULL);
} else
return search;
}
// get DATA given NAME (uses get NUMBER given NAME and returns 0 if not found or uses get DATA given NUMBER to return DATA)
inline void *LinkedDataObject::Try_fetch_item_by_name(LinkedDataFile *file, const char *name) {
// as Fetch_item_with_name but will return 0 if entry could not be found as opposed to an assert
uint32 search = 0;
search = Fetch_item_number_by_name(file, name);
if (search == PX_LINKED_DATA_FILE_ERROR)
return 0; // not found (legal)
else
return Fetch_item_by_number(file, search);
}
// get DATA given HASH (uses get NUMBER given HASH and returns 0 if not found or uses get DATA given NUMBER to return DATA)
inline void *LinkedDataObject::Try_fetch_item_by_hash(LinkedDataFile *file, uint32 hash) {
// as Fetch_item_with_name but will return 0 if entry could not be found as opposed to an assert
uint32 search = 0;
search = Fetch_item_number_by_hash(file, hash);
if (search == PX_LINKED_DATA_FILE_ERROR)
return 0; // not found (legal)
else
return Fetch_item_by_number(file, search);
}
inline void *LinkedDataObject::Try_fetch_item_by_script_name(LinkedDataFile *file, const char *name) {
uint32 search = 0;
do {
if (strstr((const char *)((uint8 *)&file->header) + FROM_LE_32(file->list[search].name_offset), (const char *)name))
return (((uint8 *)&file->header) + FROM_LE_32(file->list[search].data_offset));
search++;
} while (search < FROM_LE_32(file->number_of_items));
// not found at all
return (0);
}
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,184 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_LIBRARY_LIST_TEMPLATE
#define ICB_PX_LIBRARY_LIST_TEMPLATE
namespace ICB {
template <class Type> class pxList {
protected:
Type m_item; // The item at this node
pxList<Type> *m_tail; // The tail of the list
public:
pxList() {
m_tail = NULL; // Construct an empty list
}
~pxList() {
if (!IsEmpty())
delete Tail(); // Destruct the array
}
Type &Head() {
return m_item; // The lists' head
}
pxList<Type> *Tail() {
return m_tail; // The lists' tail
}
bool IsEmpty() {
return (m_tail == NULL); // Is the list empty ?
}
void Append(const Type &); // Append item to the end of the list
void Insert(const Type &); // Inserts an item after the current item
pxList<Type> *Find(const Type &); // Returns the list whose head == entry (NULL if not found)
int32 Length(); // Returns the length of the list
};
template <class Type> class rcSortedList {
protected:
Type m_item; // The item at this node
rcSortedList<Type> *m_tail; // The tail of the list
public:
rcSortedList() {
m_tail = NULL; // Construct an empty list
}
~rcSortedList() {
if (!IsEmpty())
delete Tail(); // Destruct the array
}
public:
Type &Head(); // The lists' head
rcSortedList<Type> *Tail(); // The lists' tail
bool IsEmpty(); // Is the list empty ?
int32 Length(); // Returns the length of the list
public:
rcSortedList<Type> *Insert(const Type &); // Inserts an item in the correct place
rcSortedList<Type> *Find(const Type &); // Returns the list whose head == entry (NULL if not found)
};
template <class Type> void pxList<Type>::Append(const Type &entry) {
if (IsEmpty()) {
m_item = entry;
m_tail = new pxList<Type>;
} else {
Tail()->Append(entry);
}
}
template <class Type> void pxList<Type>::Insert(const Type &entry) {
pxList<Type> *newNode = new pxList<Type>;
if (IsEmpty()) { // Is the list is empty, insert the item at the start of the list
m_item = entry;
} else { // Else put the item before this node
newNode->m_item = m_item;
m_item = entry;
newNode->m_tail = Tail();
}
m_tail = newNode;
}
template <class Type> pxList<Type> *pxList<Type>::Find(const Type &entry) {
// If this is the end of list marker we haven't found it
if (IsEmpty())
return NULL;
if (Head() == entry)
return this;
return (Tail()->Find(entry));
}
template <class Type> int32 pxList<Type>::Length() {
if (IsEmpty())
return 0;
return (1 + Tail()->Length());
}
template <class Type> Type &rcSortedList<Type>::Head() { // The lists' head
return m_item;
}
template <class Type> rcSortedList<Type> *rcSortedList<Type>::Tail() { // The lists' tail
return m_tail;
}
template <class Type> bool rcSortedList<Type>::IsEmpty() { // Is the list empty ?
return (m_tail == NULL);
}
template <class Type> rcSortedList<Type> *rcSortedList<Type>::Insert(const Type &entry) {
if (IsEmpty()) {
// End of the list so add the entry here
m_item = entry;
m_tail = new rcSortedList<Type>;
return this;
}
// The class being listed must have a '>' Operator defined
else if (m_item > entry) {
// The new item comes before the current one
rcSortedList<Type> *newNode = new rcSortedList<Type>;
newNode->m_tail = m_tail;
newNode->m_item = m_item;
m_item = entry;
m_tail = newNode;
return this;
} else {
// Keep going
return Tail()->Insert(entry);
}
}
template <class Type> rcSortedList<Type> *rcSortedList<Type>::Find(const Type &entry) {
// If this is the end of list marker we haven't found it
if (IsEmpty())
return NULL;
// this list is sorted, so we can stop when we have a higher value than entry
if (Head() > entry)
return NULL;
if (Head() == entry)
return this;
return (Tail()->Find(entry));
}
template <class Type> int32 rcSortedList<Type>::Length() {
if (IsEmpty())
return 0;
return (1 + Tail()->Length());
}
} // End of namespace ICB
#endif // #ifndef _PX_LIBRARY_LIST_TEMPLATE

View File

@@ -0,0 +1,163 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
// NOTES
// 1. A session has a number of maps. These maps may, though don't have to, correspond to the
// slices in the walkgrid data. Each map is one item in a px_linkeddatafile. The data structures
// below describe the internal structure of this.
// 2. Each entry in the px_linkeddatafile is simply a uint32 count of the number of objects in
// this level, followed by the objects themselves, which are all one of the types listed below.
// 3. All x,y,z coordinates are divided by two before storage, so we can fit them in a byte. Thus
// the map is stored half-scale.
// Make sure this header gets included only once.
#ifndef ICB_PX_MAPFILE_H_INCLUDED
#define ICB_PX_MAPFILE_H_INCLUDED
// Include headers needed by this file.
#include "engines/icb/common/px_common.h"
namespace ICB {
// This defines a schema version number for the data. If the format is changed then this number should
// be changed to prevent the engine running with out-of-date data.
#define REMORA_MAP_FILE_VERSION 100
// These define extensions and names for these files.
#if !defined(REMORA_MAP_FILENAME)
#define REMORA_MAP_FILENAME "remora_map"
#endif
#if !defined(REMORA_MAP_PC_EXT)
#define REMORA_MAP_PC_EXT "rmf_pc"
#endif
#if !defined(REMORA_MAP_PSX_EXT)
#define REMORA_MAP_PSX_EXT "rmf_psx"
#endif
#if !defined(PX_MAP_EXT)
#if defined(_PSX)
#define PX_MAP_EXT REMORA_MAP_PSX_EXT
#else
#define PX_MAP_EXT REMORA_MAP_PC_EXT
#endif
#endif
// This defines the 'knowledge levels' that items can have. Basically, the idea is that an object
// will only get drawn in the game if the knowledge level for the player is greater than or equal
// to the level stored for the object.
#define REMORA_MAP_MAX_KNOWLEDGE_LEVEL 3
// These are definitions for the object types. These are packed in with the 'level' indicator. So
// if you had a line that should be displayed only when the player's knowledge is at level 4 (i.e. the
// player is currently in a location), then it would have the following code:
// 0x40 | 0x02 = 0x42.
enum MapObjectType { REMORA_MAP_RECTANGLE = 0, REMORA_MAP_FILLED_RECTANGLE, REMORA_MAP_LINE, REMORA_MAP_TEXT, REMORA_MAP_POLYGON, REMORA_MAP_NUM_OBJECTS };
// These macros allow access to the two halves of the packed field mentioned previously.
#define GET_KNOWLEDGE_LEVEL(x) ((uint32)((x & 0xf0) >> 4))
#define GET_OBJECT_TYPE(x) ((MapObjectType)(x & 0x0f))
// type _map_colour_point
// This holds a point with a colour. This is not used in the objects that have a fixed number
// of points because we lose 3 padding bytes per point.
typedef struct {
uint8 nX, nY;
uint8 nR, nG, nB;
uint8 nPad1;
uint8 nPad2;
uint8 nPad3;
} _map_colour_point;
// type _map_rectangle
// An outline rectangle - object type 0.
typedef struct {
uint32 nLocationNameHash; // Hash of the location this object is part of.
uint8 nLevelAndType; // See note above for how to construct this field.
uint8 nX1, nY1; // Top-left corner of the rectangle.
uint8 nR1, nG1, nB1; // Colour for top-left corner.
uint8 nX2, nY2; // Bottom-right corner of the rectangle.
uint8 nR2, nG2, nB2; // Colour for bottom-right corner.
uint8 nWidth; // Width to draw rectangle line.
} _map_rectangle;
// type _map_filled_rectangle
// A filled rectangle - object type 1.
typedef struct {
uint32 nLocationNameHash; // Hash of the location this object is part of.
uint8 nLevelAndType; // See note above for how to construct this field.
uint8 nX1, nY1; // Top-left corner of the rectangle.
uint8 nR1, nG1, nB1; // Colour for top-left corner.
uint8 nX2, nY2; // Bottom-right corner of the rectangle.
uint8 nR2, nG2, nB2; // Colour for bottom-right corner.
uint8 nPad1;
} _map_filled_rectangle;
// type _map_line
// A line - object type 2.
typedef struct {
uint32 nLocationNameHash; // Hash of the location this object is part of.
uint8 nLevelAndType; // See note above for how to construct this field.
uint8 nX1, nY1; // Top-left corner of the rectangle.
uint8 nR1, nG1, nB1; // Colour for top-left corner.
uint8 nX2, nY2; // Bottom-right corner of the rectangle.
uint8 nR2, nG2, nB2; // Colour for bottom-right corner.
uint8 nWidth; // Width to draw rectangle line.
} _map_line;
// type _map_text
// Some text to be displayed - object type 3.
typedef struct {
uint32 nLocationNameHash; // Hash of the location this object is part of.
uint8 nLevelAndType; // See note above for how to construct this field.
uint8 nX, nY; // Bottom-left point to start drawing text.
uint8 nR, nG, nB; // Colour.
uint8 nPad1;
uint8 nPad2;
uint32 nTextHash; // Hash of the text.
} _map_text;
// type _map_polygon
// A filled rectangle - object type 4.
typedef struct {
uint32 nLocationNameHash; // Hash of the location this object is part of.
uint8 nLevelAndType; // See note above for how to construct this field.
uint8 nNumPoints; // How many points it has.
uint8 m_nPad1;
uint8 m_nPad2;
_map_colour_point pPoints[1]; // The points for the polygon.
} _map_polygon;
// This function works out the size of a polygon structure in the file because there are variable.
inline uint32 _map_polygon_sizeof(const _map_polygon *pPoly) { return (sizeof(_map_polygon) + (pPoly->nNumPoints - 1) * sizeof(_map_colour_point)); }
} // End of namespace ICB
#endif // #if !defined(_PX_MAPFILE_H_INCLUDED)

View File

@@ -0,0 +1,74 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_PROP_ANIMS_H_INCLUDED
#define ICB_PX_PROP_ANIMS_H_INCLUDED
// Include headers needed by this file.
#include "engines/icb/common/px_common.h"
namespace ICB {
// These define the filenames for files containing prop animations.
// The PSX definition is in engine\p4_psx.h
#define PX_FILENAME_PROPANIMS "pxwgpropanims"
#ifndef PC_EXT_LINKED
#define PC_EXT_LINKED "linked"
#endif
#ifndef PSX_EXT_LINKED
#define PSX_EXT_LINKED "PSXlinked"
#endif
#ifdef PX_EXT_LINKED
#undef PX_EXT_LINKED
#endif
#define PX_EXT_LINKED PC_EXT_LINKED
#define VERSION_PXWGPROPANIMS 300
// This the animations for one prop.
typedef struct {
uint16 num_anims; // The number of animations this prop has.
uint16 anims[1]; // Array of file offsets to the entries for the animations.
} _animating_prop;
// This holds one animation and any associated barriers. Note that the offsets are relative to the
// start of this _animation_entry.
typedef struct {
uint16 name; // File offset of the name of the animation.
uint16 offset_barriers; // Offset to an array of barrier indices (NULL if none).
uint16 offset_heights; // Offset to an array of PxReal height values (0 means there isn't one).
uint8 num_frames; // Number of frames in the animation.
uint8 num_barriers_per_frame; // The number of barriers per frame (same for each frame and very often 1).
uint8 frames[1]; // The frames for the animation.
} _animation_entry;
} // End of namespace ICB
#endif // #ifndef _PX_PROP_ANIMS_H_INCLUDED

View File

@@ -0,0 +1,45 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_RCUTYPES_H
#define ICB_RCUTYPES_H
#include "common/scummsys.h"
namespace ICB {
// Definition of a boolean value that can be used across the PC and PSX. I stopped true being 0xff because
// C++ weak typing allows you to assign a bool8 to an int8 without warning, whereupon '==' fails for TRUE8 because
// one is signed and one isn't.
typedef uint8 bool8;
#define TRUE8 ((uint8)0x01)
#define FALSE8 ((uint8)0x00)
// end of file
} // End of namespace ICB
#endif //_px_rcUTYPES_H

View File

@@ -0,0 +1,215 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_ROUTE_BARRIERS_H_INCLUDED
#define ICB_PX_ROUTE_BARRIERS_H_INCLUDED
// Include headers needed by this file.
#include "engines/icb/common/px_common.h"
namespace ICB {
// These define the filenames for files containing barrier maps and routing maps.
#define PX_FILENAME_LINEOFSIGHT "pxwglineofsight"
#define PX_FILENAME_ROUTING "pxwgrouting"
#define PX_FILENAME_BARRIERLIST "pxwgbarrierlist"
#ifndef PC_EXT_LINKED
#define PC_EXT_LINKED "linked"
#endif
#ifndef PSX_EXT_LINKED
#define PSX_EXT_LINKED "PSXlinked"
#endif
#ifdef PX_EXT_LINKED
#undef PX_EXT_LINKED
#endif
#define PX_EXT_LINKED PC_EXT_LINKED
// This is the version for these files. The engine checks this runtime to know that it is running with
// the correct version of file.
#define VERSION_PXWGLINEOFSIGHT 200
#define VERSION_PXWGROUTING 200
#define VERSION_PXWGBARRIERLIST 200
// This is the size of the sides of the cubes that each floor is divided into in centimetres.
#define FLOOR_CUBE_SIZE 1000 // 10-metre sides.
#define ABOVE_ALL_MODELS 10000 // Set this to be higher than any model point ever.
// This is an enumerated type for the barrier (the types listed are just illustrations - they may well be changed).
// BRICK - can't walk through it, see through it or shoot through it.
// GLASS - can't walk through it; can see through it; not sure about shooting (glass would need to break).
// BULLET_PROOF_GLASS - can't walk through it or shoot through it, but can see through it.
// THIN_STEEL - can't see through it or walk through it, but can shoot through it.
// WIRE_FENCE - can't walk through it, but can see through it; can shoot through it with random success.
// UNIT_HEIGHT - special one for stopping characters walking off the edge of ledges etc.
// VIEW_FIELD - stops characters walking out of camera field-of-view.
// LEFT_NUDGE - use to assist player control going through doors.
// RIGHT_NUDGE - ditto last one.
enum eBarrierType { BRICK = 0, GLASS, BULLET_PROOF_GLASS, THIN_STEEL, WIRE_FENCE, UNIT_HEIGHT, VIEW_FIELD, LEFT_NUDGE, RIGHT_NUDGE };
#define BARRIER_TYPE_CARDINALITY 9 // Must match number of enums in previous type (because C++
// doesn't provide a way to get this).
// This is an enumerated type for the things that might try to pass through a barrier. Note: the TEST_RAY
// is blocked by all types of barrier.
enum eBarrierRayType { TEST_RAY, LIGHT, BULLET };
#define RAY_TYPE_CARDINALITY 3
// Defines a multi-state logic value for use with the barriers.
enum eBarrierLogicValue { NO_IMPACT = 0, BLOCKS, ALLOWS, MAYBE, SPECIAL };
// This is the truth table that states what kind of ray passes through what
// type of barrier.
static enum eBarrierLogicValue barrierLogicTable[BARRIER_TYPE_CARDINALITY][RAY_TYPE_CARDINALITY] = {
{BLOCKS, BLOCKS, BLOCKS}, {BLOCKS, ALLOWS, SPECIAL}, {BLOCKS, ALLOWS, BLOCKS}, {BLOCKS, BLOCKS, ALLOWS}, {BLOCKS, ALLOWS, MAYBE},
{BLOCKS, ALLOWS, ALLOWS}, {BLOCKS, ALLOWS, ALLOWS}, {BLOCKS, ALLOWS, ALLOWS}, {BLOCKS, ALLOWS, ALLOWS}};
typedef struct {
// these are in both versions
PXfloat m_linedist, m_alinedist, m_blinedist;
PXfloat m_lpx, m_lpz; // Main barrier
PXfloat m_alpx, m_alpz; // End A.
PXfloat m_blpx, m_blpz; // End B.
} BarrierCollisionMaths;
class BarrierCollisionMathsObject {
public:
static inline PXfloat alpx(BarrierCollisionMaths *bmath) {
// return m_alpx;
return -bmath->m_lpz;
}
static inline PXfloat alpz(BarrierCollisionMaths *bmath) {
// return m_alpz;
return bmath->m_lpx;
}
static inline PXfloat blpx(BarrierCollisionMaths *bmath) {
// return m_blpx;
return bmath->m_lpz;
}
static inline PXfloat blpz(BarrierCollisionMaths *bmath) {
// return m_blpz;
return -bmath->m_lpx;
}
static void Generate(BarrierCollisionMaths *bmath, PXreal x1, PXreal z1, PXreal x2, PXreal z2) {
PXreal dx = x1 - x2;
PXreal dz = z1 - z2;
int32 nLength = (int32)PXsqrt((PXdouble)(dx * dx + dz * dz));
PXfloat xunit = PXreal2PXfloat(dx) / nLength;
PXfloat zunit = PXreal2PXfloat(dz) / nLength;
bmath->m_lpx = -zunit;
bmath->m_lpz = xunit;
bmath->m_linedist = (x1 * bmath->m_lpx) + (z1 * bmath->m_lpz);
bmath->m_alinedist = (x1 * alpx(bmath)) + (z1 * alpz(bmath));
bmath->m_blinedist = (x2 * blpx(bmath)) + (z2 * blpz(bmath));
}
};
typedef struct {
PXreal m_x1, m_z1; // Looking down on the model, the position of the first vertical edge of the barrier.
PXreal m_x2, m_z2; // Looking down on the model, the position of the second vertical edge.
PXreal m_bottom; // The bottom of the barrier.
PXreal m_top; // The top of the barrier.
eBarrierType m_material; // The material the barrier is made of.
PXfloat m_pan; // The barrier's pan value.
BarrierCollisionMaths m_bcm; // Some extra figures to speed up barrier collision detection.
} RouteBarrier;
inline void routeBarrierCreatePan(RouteBarrier *barrier) { barrier->m_pan = PXAngleOfVector(barrier->m_z1 - barrier->m_z2, barrier->m_x1 - barrier->m_x2); }
// This holds several barriers. These barriers all at least partly occupy a given cube in space. If one barrier passes
// through more than one cube, it will have a duplicate entry in each cube.
typedef struct {
int32 num_barriers; // The number of barriers referenced in this cube.
uint32 barriers; // Offset to an array of barrier indices.
} BarrierCube;
// This is a horizontal slice through the Max model, containing all the route barriers that pass through this level. The
// extremeties of the whole cuboid are given first so that a quick initial check can be done to see if there might be
// route barriers in the way.
typedef struct {
PXreal bottom; // The bottom of the slice.
PXreal top; // The top of the slice.
PXreal left_edge; // Leftmost edge of the cube of space occupied by this floor slice.
PXreal right_edge; // Ditto right edge.
PXreal back_edge; // Back edge.
PXreal front_edge; // Ditto front edge.
uint32 num_cubes; // Number of _route_cubes in this floor (could be calculated by dividing overall cube size by FLOOR_CUBE_SIZE).
uint32 row_length; // Size of the rows in the array (eg. 6 cubes could be 1X6, 2X3, 3X2 or 6X1).
uint32 offset_cubes[1]; // An array of offsets to cubes (2D array of size row_length * (num_cubes / row_length) ).
} BarrierSlice;
// This is used in the following definition of _parent_box, and holds one group of barriers.
typedef struct {
PXreal back, left; // Back/left of the bounding box holding this group of barriers (looking down into the model).
PXreal front, right; // Ditto front/right.
uint32 num_barriers; // Number of barriers in this group.
uint32 barriers[1]; // Array of barrier indices.
} ChildGroup;
// This holds one parent box entry.
typedef struct {
PXreal back, left; // Top/left of the parent box (looking down into the model).
PXreal front, right; // Ditto bottom/right.
uint32 num_barriers; // Number of barriers in the parent (not its children).
uint32 barriers; // Offset to an array of barrier indices.
uint32 num_specials; // Number of special barriers (eg. field-of-view).
uint32 specials; // Offset of the array of special barrier indices.
uint32 num_childgroups; // Number of child groups owned by this parent box.
uint32 childgroups[1]; // Array of offsets to the child groups.
} ParentBox;
// This is also a slice through the model, but the data is grouped in a different way which is more suited to routing.
typedef struct {
PXreal bottom; // The bottom of the slice.
PXreal top; // The top of the slice.
uint32 num_parent_boxes; // The number of parent boxes in this slice (same as the number of floor rectangles at this height).
uint32 parent_boxes[1]; // An array of offsets to parent boxes.
} RoutingSlice;
inline eBarrierLogicValue IsBarrierTo(eBarrierType eMaterial, eBarrierRayType eRay) { return barrierLogicTable[eMaterial][eRay]; }
} // End of namespace ICB
#endif // #ifndef _PX_ROUTE_BARRIERS_H_INCLUDED

View File

@@ -0,0 +1,534 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/ptr_util.h"
#include "engines/icb/p4.h"
#include "engines/icb/debug_pc.h"
#include "engines/icb/common/px_scriptengine.h"
#include "engines/icb/common/px_common.h" // common defs for tools & engine
#include "engines/icb/common/px_globalvariables.h" // The global variable class
#include "engines/icb/fn_routines.h"
#include "engines/icb/icb.h"
namespace ICB {
const char *playerString = "player";
CpxGlobalScriptVariables *g_globalScriptVariables;
// Information for the script program stack
#define STACK_SIZE 10 // The size of the stack
int32 stack[STACK_SIZE]; // The current stack
int32 stackPointer = 0; // Position within stack
#define _SCRIPT_ENGINE_ERROR(mess) Fatal_error("Script engine error\nObject %s\nScript %s\nMessage %s", CGameObject::GetName(object), scriptSourceName, mess)
// Check the stack pointer is within bounds
#define CheckStackPointer \
if (!((stackPointer >= 0) && (stackPointer < STACK_SIZE))) \
_SCRIPT_ENGINE_ERROR("Out of stack")
// Push a value on to the stack
#define PushOnStack(x) \
{ \
stack[stackPointer] = (x); \
stackPointer++; \
CheckStackPointer; \
}
// Pop a value from the stack
#define PopOffStack(x) \
{ \
x = stack[stackPointer - 1]; \
stackPointer--; \
CheckStackPointer; \
}
// Do a stack based two operator operation
#define DoBinaryOperation(x) \
{ \
stack[stackPointer - 2] = (x); \
stackPointer--; \
CheckStackPointer; \
}
// Do a stack based single operator operation
#define DoUnaryOperation(x) \
{ stack[stackPointer - 1] = (x); }
// Report an operation to the log file
#define TraceOperation(x, y) ScriptTrace("%d %s %d -> %d", stack[stackPointer - 2], x, stack[stackPointer - 1], stack[stackPointer - 2] y stack[stackPointer - 1]);
#define TraceUnaryOperation(x, y) ScriptTrace("%s %d -> %d", x, stack[stackPointer - 1], y stack[stackPointer - 1]);
// Macros for fetching data from the script file
#define Fetch8(var) \
{ \
var = *((char *)const_cast<char *>(actualScript)); \
actualScript += sizeof(char); \
}
#define Fetch32(param) \
{ \
param = *((int32 *)const_cast<char *>(actualScript)); \
actualScript += sizeof(int32); \
}
#define Read32ipLeaveip(var) \
{ var = *((int32 *)const_cast<char *>(actualScript)); }
#define Fetch16(param) \
{ \
param = *((int16 *)const_cast<char *>(actualScript)); \
actualScript += sizeof(int16); \
}
#define Read16ipLeaveip(var) \
{ var = *((int16 *)const_cast<char *>(actualScript)); }
#define UpdatePC \
{ scriptData = actualScript; }
#define ScriptTrace Zdebug
void SetScriptDebugging(bool8) {}
extern mcodeFunctionReturnCodes fn_context_chosen_logic(int32 &, int32 *);
extern mcodeFunctionReturnCodes fn_start_player_interaction(int32 &, int32 *);
scriptInterpreterReturnCodes RunScript(const char *&scriptData, // A pointer to the script data that can be modified
CGame *object, // A pointer to the object that owns this object
int32 *engineReturnValue2,
const char *scriptSourceName) { // A value to return to the game engine
// Run a script
ScriptTrace("Run script");
// Default return value is 0
if (engineReturnValue2)
*engineReturnValue2 = 0;
// Check if the script data begins with the check text, and skip it if it does
if (strncmp(scriptData, SCRIPT_CHECK_TEXT, SCRIPT_CHECK_TEXT_LEN) == 0)
scriptData += SCRIPT_CHECK_TEXT_LEN;
const char *actualScript = scriptData;
// Some variables to hold parameters and values
int32 parameter1, parameter2, value;
bool8 isInExpression = FALSE8;
// Variable to prevent infinite loops
uint32 infiniteLoopCounter = 0;
while (*actualScript) {
// Quick check for infinite loops
infiniteLoopCounter++;
if (infiniteLoopCounter > 10000) {
// Oh dear, what do we do now.
Fatal_error("Internal script loop in object %s", CGameObject::GetName(object));
}
int32 command = *(actualScript++);
// so that call_mcode and call_mcode_expr can share code...
isInExpression = FALSE8;
switch (command) {
case CP_PUSH_INT32: { // 1: Push a 32 bit integer
Fetch32(parameter1);
ScriptTrace("Push number(32 bit) %d", parameter1);
PushOnStack(parameter1);
} break;
case CP_PUSH_INT16: { // 1: Push a 16 bit integer
int16 sixteenBit;
Fetch16(sixteenBit);
ScriptTrace("Push number(16 bit) %d", sixteenBit);
PushOnStack((int32)sixteenBit);
} break;
case CP_PUSH_INT8: { // 1: Push an 8 bit integer
int8 eightBit;
Fetch8(eightBit);
ScriptTrace("Push number(8 bit) %d", eightBit);
PushOnStack((int32)eightBit);
} break;
case CP_PUSH_ADDRESS_LOCAL_VAR32: {
Fetch8(value); // Get the local variable number
if (!((value >= 0) && (value < (int32)CGameObject::GetNoLvars(object))))
_SCRIPT_ENGINE_ERROR("Local variable out of range");
ScriptTrace("Push address of local integer variable %d = %d", value, CGameObject::GetIntegerVariable(object, value));
PushOnStack(MemoryUtil::encodePtr((uint8 *)CGameObject::GetIntegerVariablePtr(object, value)));
} break;
case CP_SKIPONFALSE: { // 4 : Skip a chunk if a result if false
Read32ipLeaveip(parameter1) PopOffStack(value);
ScriptTrace("Skip %d if %d is false", parameter1, value);
if (value)
actualScript += sizeof(int32);
else
actualScript += parameter1;
} break;
case CP_SKIPALLWAYS: { // 5 : Skip a chunk
Read32ipLeaveip(parameter1) ScriptTrace("Skip %d", parameter1);
actualScript += parameter1;
} break;
case CP_SKIPONTRUE: { // 6 : Skip a chunk if a result if true
Read32ipLeaveip(parameter1) PopOffStack(value);
ScriptTrace("Skip %d if %d is true", parameter1, value);
if (value)
actualScript -= parameter1;
else
actualScript += sizeof(int32);
} break;
case CP_RETURN: { // po value off stack and return it to the game engine
if (!engineReturnValue2)
_SCRIPT_ENGINE_ERROR("No return value");
PopOffStack(*engineReturnValue2);
ScriptTrace("Return %d to game engine", *engineReturnValue2);
return (IR_RET_END_THE_CYCLE);
} break;
case CP_PUSH_GLOBAL_VAR32: {
Fetch32(parameter1); // hash of global
parameter2 = g_globalScriptVariables->GetVariable(parameter1); // value of global
PushOnStack(parameter2); // push on stack
// printf("push global 0x%08x = %d",parameter1,parameter2);
} break;
case CP_POP_GLOBAL_VAR32: {
Fetch32(parameter1); // hash of global
PopOffStack(parameter2); // value from stack
g_globalScriptVariables->SetVariable(parameter1, parameter2); // set value
// printf("pop global 0x%08x = %d",parameter1,parameter2);
} break;
// isInExpression starts off at false as it is set every loop of the while...
case CP_CALL_MCODE_EXPR:
isInExpression = TRUE8; // set to true and carry on running this code...
// falls through
case CP_CALL_MCODE: { // 10: Call an mcode routine
// Get the mcode number
int16 fnNumber;
Fetch16(fnNumber);
const int16 numApiRoutines = (g_icb->getGameType() == GType_ELDORADO) ? NO_API_ROUTINES_ELDORADO : NO_API_ROUTINES_ICB;
if (!((fnNumber >= 0) && (fnNumber < numApiRoutines)))
_SCRIPT_ENGINE_ERROR("fnNumber out of range?");
// Get the number of parameters
Fetch8(value); // amount to adjust stack by (no of parameters)
ScriptTrace("Call mcode %d (%sin expression)", fnNumber, isInExpression ? "" : "not ");
int32 routineReturnParameter = 0; // The value returned by the mcode routine
mcodeFunctionReturnCodes mcodeRetVal;
if (g_icb->getGameType() == GType_ICB) {
mcodeRetVal = McodeTableICB[fnNumber](routineReturnParameter, stack + (stackPointer - value));
} else if (g_icb->getGameType() == GType_ELDORADO) {
mcodeRetVal = McodeTableED[fnNumber](routineReturnParameter, stack + (stackPointer - value));
} else {
error("unknown game type");
}
ScriptTrace("api returned %d(%d)", mcodeRetVal, routineReturnParameter);
// Correct the stack for the parameters pushed on
stackPointer -= value;
// If this is part of an expression then we want to
// push the return value on to the stack
// Otherwise we may want to pause the script here
if (isInExpression) {
// Push the fn_routine return value
PushOnStack(routineReturnParameter);
// save the mcode return value
} else {
// Check return value in case we want to pause the script
switch (mcodeRetVal) {
case IR_STOP:
UpdatePC;
ScriptTrace("Script returns IR_RET_END_THE_CYCLE");
return (IR_RET_END_THE_CYCLE);
case IR_CONT:
// Continue the script
break;
case IR_TERMINATE:
ScriptTrace("Script returns IR_RET_CONT_THIS_CYCLE");
return (IR_RET_CONT_THIS_CYCLE);
case IR_REPEAT:
ScriptTrace("Script returns IR_RET_END_THE_CYCLE");
return (IR_RET_END_THE_CYCLE);
case IR_GOSUB:
UpdatePC;
ScriptTrace("Script returns IR_RET_END_THE_CYCLE");
return (IR_RET_END_THE_CYCLE);
}
}
} break;
case CP_QUIT: {
// Quit for a cycle
UpdatePC;
return (IR_RET_END_THE_CYCLE);
} break;
case CP_PUSH_STRING:
Fetch8(value); // the length of the string
ScriptTrace("Push string \"%s\"", actualScript);
// printf("push \"%s\"\n",actualScript);
PushOnStack(MemoryUtil::encodePtr((uint8 *)const_cast<char *>(actualScript))); // The pointer to the string
actualScript += value;
break;
case CP_PUSH_STRING_REFERENCE:
Fetch32(parameter1); // lookup (backwards)
ScriptTrace("Push string reference \"%s\"", actualScript + parameter1 - 4);
// printf("push reference \"%s\"\n",actualScript+parameter1-4);
PushOnStack(MemoryUtil::encodePtr((uint8 *)const_cast<char *>(actualScript + parameter1 - 4)));
break;
case CP_PUSH_STRING_PLAYER:
ScriptTrace("Push special string \"player\"");
// printf("push special \"player\"\n");
PushOnStack(MemoryUtil::encodePtr((uint8 *)const_cast<char *>(playerString)));
break;
case CP_CALL_VSCRIPT_ON_TRUE: { // 14: Call a virtual script if a result is true
// Get the value to check
PopOffStack(value);
// Get the script index
Fetch32(parameter1);
if (!((parameter1 >= 0) && (parameter1 < (int32)CGameObject::GetNoScripts(object))))
_SCRIPT_ENGINE_ERROR("Virtual script call out of range");
// Get the type
Fetch8(parameter2);
ScriptTrace("if (%d) call virtual script %d (%d)", value, parameter1, CGameObject::GetScriptNameFullHash(object, parameter1));
if (value) {
parameter1 &= 0xffff;
int32 dummyReturnValue;
ScriptTrace("param2 = %d", parameter2);
int32 scriptHash = CGameObject::GetScriptNameFullHash(object, parameter1);
if (parameter2) {
ScriptTrace("interact");
fn_start_player_interaction(dummyReturnValue, &scriptHash);
} else {
ScriptTrace("chosen logic");
fn_context_chosen_logic(dummyReturnValue, &scriptHash);
}
// Update and finish
UpdatePC;
return (IR_RET_CONT_THIS_CYCLE);
}
} break;
case CP_SAVE_MCODE_START: // 15: Update the script pc, usually before doing an mcode routine
UpdatePC;
ScriptTrace("Update pc");
break;
case CP_PUSH_LOCAL_VAR32: // 16: Push a local variable on to the stack
Fetch8(value); // Get the local variable number
if (!((value >= 0) && (value < (int32)CGameObject::GetNoLvars(object))))
_SCRIPT_ENGINE_ERROR("Unknown variable??");
ScriptTrace("Push local integer variable %d = %d", value, CGameObject::GetIntegerVariable(object, value));
PushOnStack(CGameObject::GetIntegerVariable(object, value));
break;
case CP_POP_LOCAL_VAR32: // 17 // Pop a local variable from the stack
Fetch8(value); // Get the local variable number
if (!(value >= 0) && (value < (int32)CGameObject::GetNoLvars(object)))
_SCRIPT_ENGINE_ERROR("Unknown variable??");
ScriptTrace("Pop local variable %d", value);
{
int32 varValue;
PopOffStack(varValue);
CGameObject::SetIntegerVariable(object, value, varValue);
}
break;
case CP_PUSH_LOCAL_VARSTRING: // 18: Push a local string variable on to the stack
Fetch8(value); // Get the local variable number
if (!((value >= 0) && (value < (int32)CGameObject::GetNoLvars(object))))
_SCRIPT_ENGINE_ERROR("Unknown variable (string)??");
ScriptTrace("Push local string variable %d = \"%s\"", value, CGameObject::GetStringVariable(object, value));
PushOnStack(MemoryUtil::encodePtr((uint8 *)const_cast<char *>(CGameObject::GetStringVariable(object, value))));
break;
case CP_DEBUG: { // 19: Debug options
Fetch8(value); // Get the debug type
} break;
case CP_INITIALISEGLOBAL: {
// Initialise a global
_SCRIPT_ENGINE_ERROR("Can't initialise a variable here anymore");
} break;
case CP_SWITCH: {
int32 i, size, found;
PopOffStack(parameter1); // value
Fetch32(parameter2); // 4 byte offset to table
ScriptTrace("Start of switch statement - value: %d", parameter1);
actualScript += parameter2 - sizeof(int32);
Fetch8(size); // 1 byte number of cases
i = 0;
found = 0;
while (!found) {
Fetch32(value); // case value (or offset if default case)
if (i == (size - 1)) { // default case
actualScript += value - sizeof(int32);
found = 1;
} else {
Fetch32(parameter2); // case code offset
if (value == parameter1) { // if switch value = this case value
actualScript += parameter2 - sizeof(int32); // do the jump
found = 1;
}
}
i++;
}
} break;
case CP_PUSH_0: {
ScriptTrace("Push 0");
PushOnStack(0);
} break;
case CP_PUSH_1: {
ScriptTrace("Push 1");
PushOnStack(1);
} break;
case OP_TIMES: { // 32 // '*'
ScriptTrace("*");
TraceOperation("*", *)DoBinaryOperation((stack[stackPointer - 2] * stack[stackPointer - 1]));
} break;
case OP_DIVIDE: { // 34 // '/'
ScriptTrace("/");
TraceOperation("/", / ) DoBinaryOperation((stack[stackPointer - 2] / stack[stackPointer - 1]));
} break;
case OP_PLUS: { // 31 // '+'
ScriptTrace("+");
TraceOperation("+", +) DoBinaryOperation((stack[stackPointer - 2] + stack[stackPointer - 1]));
} break;
case OP_MINUS: { // 33 // '-'
ScriptTrace("-");
TraceOperation("-", -) DoBinaryOperation((stack[stackPointer - 2] - stack[stackPointer - 1]));
} break;
case OP_LSTHAN: { // 35 // '<'
ScriptTrace("<");
TraceOperation("<", < ) DoBinaryOperation((stack[stackPointer - 2] < stack[stackPointer - 1]));
} break;
case OP_GTTHAN: { // 39 // '>'
ScriptTrace(">");
TraceOperation(">", > ) DoBinaryOperation((stack[stackPointer - 2] > stack[stackPointer - 1]));
} break;
case OP_LSTHANE: { // 42 // '<='
ScriptTrace("<=");
TraceOperation("<=", <= ) DoBinaryOperation((stack[stackPointer - 2] <= stack[stackPointer - 1]));
} break;
case OP_GTTHANE: { // 41 // '>='
ScriptTrace(">=");
TraceOperation(">=", >= ) DoBinaryOperation((stack[stackPointer - 2] >= stack[stackPointer - 1]));
} break;
case OP_ISEQUAL: { // 30: '=='
ScriptTrace("==");
TraceOperation("==", == ) DoBinaryOperation((stack[stackPointer - 2] == stack[stackPointer - 1]));
} break;
case OP_NOTEQUAL: { // 36: '!='
ScriptTrace("!=");
TraceOperation("!=", != ) DoBinaryOperation((stack[stackPointer - 2] != stack[stackPointer - 1]));
} break;
case OP_ANDAND: { // 37 // '&&'
ScriptTrace("&&");
TraceOperation("&&", &&) DoBinaryOperation((stack[stackPointer - 2] && stack[stackPointer - 1]));
} break;
case OP_OROR: { // 38 // '||'
ScriptTrace("||");
TraceOperation("||", || ) DoBinaryOperation((stack[stackPointer - 2] || stack[stackPointer - 1]));
} break;
case TK_UNARY_NOT: { // 50 // '!'
// _SCRIPT_ENGINE_ERROR("I aint doing that!");
ScriptTrace("!");
TraceUnaryOperation("!", !) DoUnaryOperation(!stack[stackPointer - 1]);
} break;
case TK_UNARY_MINUS: { // 51 // '-'
ScriptTrace("-");
TraceUnaryOperation("-", -) DoUnaryOperation(-stack[stackPointer - 1]);
} break;
default: { _SCRIPT_ENGINE_ERROR(pxVString("Invalid script token %d", command)); }
}
}
ScriptTrace("Script Done");
return (IR_RET_SCRIPT_FINISHED);
}
} // End of namespace ICB

View File

@@ -0,0 +1,143 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_GAME_ENGINE_SCRIPTENGINE_H
#define ICB_GAME_ENGINE_SCRIPTENGINE_H
#include "engines/icb/common/px_string.h"
#include "engines/icb/common/px_game_object.h"
#include "engines/icb/common/px_globalvariables.h"
namespace ICB {
#define SCRIPT_CHECK_TEXT "SDS>"
#define SCRIPT_CHECK_TEXT_LEN 4
enum scriptInterpreterReturnCodes {
IR_RET_END_THE_CYCLE = 0, // done enough this cycle
IR_RET_SCRIPT_FINISHED = 1, // current script has finished and hit closing brace
IR_RET_CONT_THIS_CYCLE = 2 // FN_ returned an IR_TERMINATE to interpreter so we just go around - new script or gosub
};
scriptInterpreterReturnCodes RunScript(const char *&scriptData, // A pointer to the script data that can be modified
CGame *object, // A pointer to the object that owns this object
int32 *engineReturnValue = NULL,
const char *scriptSourceName = NULL); // A value to return to the game engine
void SetScriptDebugging(bool8 f); // Set script debugging flag
extern CpxGlobalScriptVariables *g_globalScriptVariables;
#define CP_END_SCRIPT 0 // Terminate a script
#define CP_PUSH_INT32 1 // Push a number on to the stack
#define CP_PUSH_ADDRESS_LOCAL_VAR32 2 // Push the address of a local variable
//#define CP_CALL_SCRIPT_ON_TRUE 3 // Call a script if the expression result is true
// Not sure where this is used
#define CP_SKIPONFALSE 4 // Skip if the bottom value on the stack is false
#define CP_SKIPALLWAYS 5 // Skip a block of code
#define CP_SKIPONTRUE 6 // Skip if the bottom value on the stack is true
#define CP_RETURN 7 // return the value on the stack to the game engine
#define CP_PUSH_GLOBAL_VAR32 8 // Set a variable to 1
#define CP_POP_GLOBAL_VAR32 9 // Pop a global variable
#define CP_CALL_MCODE 10 // Call a machine code function
#define CP_QUIT 11 // Quit for a cycle
#define CP_PUSH_STRING 12 // Push a pointer to a string
//#define CP_LINE_NUMBER 13 // Notify a change of script line number
#define CP_CALL_VSCRIPT_ON_TRUE 14 // Call a virtual script if the expression result is true
// The script name is taken from the object virtual
// script table
#define CP_SAVE_MCODE_START 15 // Save the mcode code start for restarting when necessary
#define CP_PUSH_LOCAL_VAR32 16 // Push a local variable on to the stack
#define CP_POP_LOCAL_VAR32 17 // Pop a local variable from the stack
#define CP_PUSH_LOCAL_VARSTRING 18 // Push a local variable on to the stack
#define CP_DEBUG 19 // A debug command
#define CP_INITIALISEGLOBAL 20 // Initialise a global variable
#define CP_SWITCH 21 // takes value of the stack and uses with switch table...
#define CP_PUSH_0 22 // push 0 on the stack (a slight speed advantage and a space saving)
#define CP_PUSH_1 23 // push 1 on the stack (a slight speed advantage and a space saving)
// It was decided that the following fix to the return code of fn routines
// in expressions was not to be applied, but the code has been kept just in
// case
// special push variations to save space
#define CP_PUSH_INT16 26
#define CP_PUSH_INT8 27
#define CP_PUSH_STRING_REFERENCE 28
// An invalid token
#define CP_INVALID_TOKEN 29 // For functions where a token is required, but not appropriate
// Binary Operators
#define OP_ISEQUAL 30 // '=='
#define OP_PLUS 31 // '+'
#define OP_TIMES 32 // '*'
#define OP_MINUS 33 // '-'
#define OP_DIVIDE 34 // '/'
#define OP_LSTHAN 35 // <
#define OP_NOTEQUAL 36 // '!='
#define OP_ANDAND 37 // &&
#define OP_OROR 38 // || or OR
#define OP_GTTHAN 39 // >
#define OP_GTTHANE 41 // >=
#define OP_LSTHANE 42 // <=
// Unary Operators
#define TK_UNARY_NOT 50 // ! Invert a boolean
#define TK_UNARY_MINUS 51 // - Negate a number
// a special op which pushes the string "player" onto the stack
#define CP_PUSH_STRING_PLAYER 52
// a new version of call_mcode which sets inside expression to true (saves 1 byte per fn_call)
#define CP_CALL_MCODE_EXPR 53
// Command tokens, only ever used internally
#define CT_IF 100 // An if statement
#define CT_CLOSEBRACKET 101 // )
#define CT_SEMICOLON 102 // ;
#define CT_ONCE 103 // the 'once' command
#define CT_CLOSEBRACE 104 // }
#define CT_DOUBLECLOSEBRACE 105 // Two tab indent reduction
#define CT_DO 106 // the 'do' command
#define CT_RETURN 107 // return a value to the engine
#define CT_SWITCH 108 // Switch
#define CT_QUIT 109 // Quit for a cycle
#define CT_COMMA 110 // ,
#define CT_OPENBRACE 111 // {
#define CT_DEBUG 112 // Debug commands
#define CT_INITIALISEGLOBAL 113 // Initialise a global variable
#define CT_WHILE 114 // the 'while' command
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,97 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_SFX_DESCRIPTION_H
#define ICB_PX_SFX_DESCRIPTION_H
namespace ICB {
// versions...
// 100 initial
// 101 rearanged
// 105 added also to sfxdesc files to be checked by converter
//
#define SFX_VERSION 105
#define NO_LOOPING 0x00
#define WAV_LOOPING_FLAG 0x01
#define SFX_LOOPING_FLAG 0x02
// this class contains an envelope of the form y=ax^3+bx^2+cx+d
class CEnvelope {
public:
int32 a;
int32 b;
int32 c;
int32 d;
int8 div; // dividing value on the time scale
CEnvelope() { Reset(); }
void Reset() {
a = b = c = d = 0;
div = 1;
}
};
// this class contains a single sfx ready to be saved out. This will go in it's own file eventually...
class CSfx {
public:
CSfx() { Reset(); }
CEnvelope m_volume; // volume where v<=0 => none >=128 => max
CEnvelope m_pitch; // pitch addition to base pitch (in PSX pitch units where 0x1000=44100hz, etc)
int32 m_duration; // duration in 128th of second
int32 m_rand_pitch; // random value to add to pitch at start (in PSX pitch units where 0x1000=44100hz, etc)
int32 m_min_distance; // in cm
int32 m_max_distance; // in cm
int8 m_sampleNameOffset; // offset into structure of sampleName...
int8 m_descOffset; // generally this will be 0 when outputing for the engine since the engine will not need descriptions
int8 m_looping; // BIT 0 is hardware flag, bit 1 is software flag.
int8 m_rand_mode; // mode=0 is normal, choose a random value at startup, mode>0 is some divider of the envelope
void Reset() {
m_volume.Reset();
m_pitch.Reset();
m_duration = 0;
m_looping = 0;
m_rand_pitch = 0;
m_rand_mode = 0;
m_sampleNameOffset = 0;
m_descOffset = 0;
m_min_distance = 0;
m_max_distance = 0;
}
const char *GetSampleName() { return (const char *) this + m_sampleNameOffset; }
};
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,58 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
namespace ICB {
#define PITCH_MULT \
{ \
128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, \
143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155, 156, 156, 157, 157, 158, 158, 159, 160, \
160, 161, 161, 162, 163, 163, 164, 164, 165, 165, 166, 167, 167, 168, 169, 169, 170, 170, 171, 172, 172, 173, 173, 174, 175, 175, 176, 177, 177, 178, 179, \
179, 180, 181, 181, 182, 182, 183, 184, 184, 185, 186, 186, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 198, 198, 199, 200, \
200, 201, 202, 203, 203, 204, 205, 206, 206, 207, 208, 209, 209, 210, 211, 212, 212, 213, 214, 215, 216, 216, 217, 218, 219, 219, 220, 221, 222, 223, 223, \
224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 233, 234, 235, 236, 237, 238, 239, 239, 240, 241, 242, 243, 244, 245, 246, 246, 247, 248, 249, 250, \
251, 252, 253, 254, 255 \
}
#define PITCH_DIV \
{ \
128, 127, 127, 126, 126, 125, 125, 124, 124, 123, 123, 123, 122, 122, 121, 121, 120, 120, 119, 119, 119, 118, 118, 117, 117, 116, 116, 116, 115, 115, 114, 114, \
114, 113, 113, 112, 112, 111, 111, 111, 110, 110, 109, 109, 109, 108, 108, 108, 107, 107, 106, 106, 106, 105, 105, 104, 104, 104, 103, 103, 103, 102, 102, \
101, 101, 101, 100, 100, 100, 99, 99, 99, 98, 98, 97, 97, 97, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, \
88, 88, 88, 87, 87, 87, 86, 86, 86, 86, 85, 85, 85, 84, 84, 84, 83, 83, 83, 82, 82, 82, 82, 81, 81, 81, 80, 80, 80, 80, 79, 79, 79, 78, 78, 78, 78, 77, 77, \
77, 76, 76, 76, 76, 75, 75, 75, 75, 74, 74, 74, 73, 73, 73, 73, 72, 72, 72, 72, 71, 71, 71, 71, 70, 70, 70, 70, 69, 69, 69, 69, 68, 68, 68, 68, 67, 67, 67, \
67, 66, 66, 66, 66, 65, 65, 65, 65, 64, 64, 64, 64 \
}
#define VOL_FUNCTION \
{ \
0, 11, 16, 19, 22, 25, 27, 29, 32, 33, 35, 37, 39, 40, 42, 43, 45, 46, 47, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 64, 65, 66, 67, 68, 69, 70, 71, \
72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 86, 86, 87, 88, 89, 89, 90, 91, 91, 92, 93, 93, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, \
101, 101, 102, 103, 103, 104, 104, 105, 106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 111, 112, 113, 113, 114, 114, 115, 115, 116, 117, 117, 118, 118, \
119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127 \
}
} // End of namespace ICB

View File

@@ -0,0 +1,71 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_STATIC_LAYERS_H
#define ICB_PX_STATIC_LAYERS_H
#include "engines/icb/common/px_common.h"
namespace ICB {
#define PCLAYER_SCHEMA 1
#define PCLAYER_ID MKTAG('r', 'y', 'a', 'L')
#define TILE_WIDTH 64
#define TILE_HEIGHT 48
#define TILES_WIDE (640 / TILE_WIDTH)
#define TILES_HIGH (480 / TILE_HEIGHT)
#define TILE_COUNT (TILES_WIDE * TILES_HIGH)
class pcStaticLayers {
private:
char id[4];
uint32 schema;
uint32 mapping;
uint32 tilePtrs[TILE_COUNT]; // 10 x 10 array of tiles (null means an empty tile)
uint32 semiPtrs[TILE_COUNT]; // 10 x 10 array of tiles (null means an empty tile)
uint8 *DataStart() { return (uint8 *)id; }
public:
uint16 *GetSemiTileTable(int32 idx) { return semiPtrs[idx] ? (uint16 *)(DataStart() + semiPtrs[idx]) : 0; }
uint16 *GetTileTable(int32 idx) { return tilePtrs[idx] ? (uint16 *)(DataStart() + tilePtrs[idx]) : 0; }
uint32 GetSchema() {
if (READ_LE_U32(id) != PCLAYER_ID)
return 0;
else
return schema;
}
pcStaticLayers () {
(void)mapping; // shutup warning
}
};
} // End of namespace ICB
#endif // _PX_STATIC_LAYERS_H

View 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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 "engines/icb/common/px_common.h"
#include "engines/icb/common/px_string.h"
#include "common/textconsole.h"
namespace ICB {
#define SLEN_CHECK (slen < 0)
const char *pxString::operator=(const char *str) {
// Assign a value
// If we are assigning the string to ourself, then no assignment is necessary
if (str == s)
return (s);
if (s)
delete[] s;
if (str) {
// We are not assigning a null string
uint32 len = strlen(const_cast<char *>(str)) + 1;
s = new char[len];
memcpy((unsigned char *)s, (unsigned char *)const_cast<char *>(str), len);
} else
s = nullptr; // Just the null string
return (s);
}
void pxString::operator=(const pxString &str) {
// Assign a value
if (s)
delete[] s;
if (str.s) {
// We are not assigning a null string
uint32 len = strlen((char *)(str.s)) + 1;
s = new char[len];
memcpy((unsigned char *)s, (unsigned char *)str.s, len);
} else
s = nullptr; // Null string
}
const char *pxString::operator+=(const char *adder) {
// Add a string
if (adder) {
uint32 slen = s ? strlen(s) : 0; // Get original string length
uint32 adderlen = strlen(const_cast<char *>(adder)); // Get additional string length
char *buf = new char[slen + adderlen + 1]; // Create a buffer
if (s)
memcpy((unsigned char *)buf, (unsigned char *)s, slen); // Move the original string in
memcpy((unsigned char *)buf + slen, (unsigned char *)const_cast<char *>(adder), adderlen + 1); // And put the additional string in
// Tidy up
delete[] s;
s = buf;
}
return (s);
}
const pxString pxString::operator+(const char *adder) const {
// Produce a string addition without affecting this object
pxString temp(s);
temp += adder;
return (temp);
}
bool pxString::operator==(const char *string) const {
// Do a character by character comparison
if (s == nullptr)
return ((bool)(string == nullptr));
if (string == nullptr)
return (false);
return ((bool)(strcmp(s, const_cast<char *>(string)) == 0));
}
void pxString::SetString(const char *data, uint32 len) {
// Get the first len characters from another string
// Lose any string we currently hold
if (s)
delete[] s;
// If the data is NULL then we become NULL
if (data) {
// Copy in the data
s = new char[len + 1];
memcpy((unsigned char *)s, (unsigned char *)const_cast<char *>(data), len);
// And null terminate it
s[len] = 0;
} else
s = nullptr;
}
void pxString::Substr(pxString &rsStr, uint32 nStart, uint32 nNum) const {
char *pNewString;
uint32 slen = strlen(s); // ds: No need to calculate this several times
// Do some range checking.
if (nStart > (slen - 1)) {
rsStr = "";
return;
}
// If the requested substring goes past the end of the existing string, simply clip it
// after the last character in the existing one.
if (nStart + nNum > slen)
nNum -= (nStart + nNum) - slen;
// Create a buffer the correct size to hold the new substring
pNewString = new char[nNum + 1];
// Copy in the substring.
memcpy((unsigned char *)pNewString, (unsigned char *)&s[nStart], nNum);
// Put the terminator on.
pNewString[nNum] = '\0';
// Make the new pxString from the buffer.
rsStr = pNewString;
// ds: Deallocate the temporary buffer
delete[] pNewString;
}
uint32 pxString::StrChr(char cToFind, uint32 nStartPos) const {
char *pcPositionOfFirst;
uint32 nStringLength = strlen(s);
// Check if the start position is outside the string.
if (nStartPos >= nStringLength)
return nStringLength;
// I use strchr, which relies on the pxString being implemented as a character array,
// but it is OK to do it in here, 'cos if the internal representation changed, presumably
// every function in this class would need looking at anyway.
pcPositionOfFirst = strchr(s + nStartPos, static_cast<uint>(cToFind));
if (pcPositionOfFirst) {
// Character was found. Work out its index from the address.
return (pcPositionOfFirst - s);
} else {
// I use the length of the string as a rogue value to indicate the character wasn't found.
return nStringLength;
}
}
void pxString::ToUpper() {
if (s) {
char *sp = s;
while (*sp) {
*sp = (char)toupper(*sp);
sp++;
}
}
}
void pxString::ToLower() {
if (s) {
char *sp = s;
while (*sp) {
*sp = (char)tolower(*sp);
sp++;
}
}
}
void pxString::ConvertPath() {
if (s) {
char *sp = s;
while (*sp) {
*sp = (*sp == '\\' ? '/' : *sp);
sp++;
}
// trim '/'
if (*s == '/') {
uint32 len = strlen((char *)s);
sp = new char[len];
memcpy((unsigned char *)sp, (unsigned char *)(s + 1), len);
delete[] s;
s = sp;
}
}
}
const pxString &pxString::Format(const char *format, ...) {
if (s)
delete[] s;
s = nullptr;
// Check for a null parameter
if (format == nullptr)
return (*this);
// The data could be any size. Rather than incrementally allocating memory until
// it fits a large buffer multiple is used that should cover 99.9% of all strings
// but will still cope with unfeasably large ones
uint32 startBufferSize = 1024;
// Allocate a start buffer
s = new char[startBufferSize + 2];
if (s == nullptr)
return (*this);
// Process the variable arguments
va_list arglist;
int32 slen;
// Keep doubling the size of the buffer until it fits
while (va_start(arglist, format), slen = vsnprintf(s, startBufferSize, const_cast<char *>(format), arglist), SLEN_CHECK) {
delete[] s;
startBufferSize += startBufferSize;
s = new char[startBufferSize + 2];
// According to VC5 release mode this code is unreachable
// I can't see why, so I shall turn the warning off for this bit of code
// If the sllocation failed return an empty string
if (s == nullptr)
return (*this);
}
// Tidy up and finish
va_end(arglist);
// At this point the buffer in s is much larger than it needs to be
// In the interest of saving space, it will now be reduced
assert(slen == (int32)strlen(s));
char *tempBuffer = new char[slen + 1];
// If this allocation fails leave the string as it is
if (tempBuffer) {
memcpy((unsigned char *)tempBuffer, (unsigned char *)s, slen + 1);
delete[] s;
s = tempBuffer;
}
return (*this);
}
// build a temporary string
const char *pxVString(const char *format, ...) {
#define PXV_BUF_SIZE 1024
static char buf[PXV_BUF_SIZE];
va_list va;
va_start(va, format);
vsnprintf(buf, PXV_BUF_SIZE, format, va);
va_end(va);
#undef PXV_BUF_SIZE
return buf;
}
pxFixedCharBuffer::pxFixedCharBuffer(uint32 len) {
// Construct the object with the appropriate amount of data
m_data = new char[len];
// Check for an error
if (m_data == nullptr) {
error("pxFixedCharBuffer memory allocation error");
}
}
pxFlexiCharBuffer::pxFlexiCharBuffer(uint32 initLen) {
m_bufLen = initLen;
m_buffer = new char[initLen]; // The buffer itself
}
pxFlexiCharBuffer::~pxFlexiCharBuffer() { delete[] m_buffer; }
char &pxFlexiCharBuffer::operator[](uint32 offset) {
CheckSize(offset);
return (m_buffer[offset]);
}
void pxFlexiCharBuffer::CheckSize(uint32 size) {
// Make sure we have enough room
if (size >= m_bufLen) {
uint32 newLen = size + 1;
char *newb = new char[newLen];
assert(newb);
memcpy((unsigned char *)newb, (unsigned char *)m_buffer, m_bufLen);
delete[] m_buffer;
m_buffer = newb;
m_bufLen = newLen;
}
}
void pxFlexiCharBuffer::StrCpy(uint32 offset, const char *string) {
// Add a string
uint32 slen = strlen(const_cast<char *>(string));
CheckSize(offset + slen);
memcpy((unsigned char *)(m_buffer + offset), (unsigned char *)const_cast<char *>(string), slen);
}
void pxFlexiCharBuffer::StrnCpy(uint32 offset, const char *string, uint32 len) {
// Copy a number of characters to the buffer
CheckSize(offset + len);
memcpy((unsigned char *)(m_buffer + offset), (unsigned char *)const_cast<char *>(string), len);
}
} // End of namespace ICB

View File

@@ -0,0 +1,195 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PX_STRING_H
#define ICB_PX_STRING_H
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
class pxString {
protected:
char *s; // The actual string
public:
pxString(); // Empty creator
pxString(const char *); // Copy constructor
pxString(const pxString &); // Copy constructor
~pxString(); // Destructor
operator const char *() const {
return (s); // Return a pointer to the string
}
const char *operator=(const char *); // Assign a value
void operator=(const pxString &); // Assign a value
const char *operator+=(const char *); // Add a string
char &operator[](uint32 n) {
return (s[n]); // Get a character (no reason not to allow it to change)
}
char &operator[](int32 n) {
return (s[n]); // Get a character (no reason not to allow it to change)
}
bool IsNull() const {
return ((bool)(s == NULL)); // Check for a null value
}
bool IsEmpty() const; // Check for an empty string
uint32 GetLen() const; // Returns the length of the string.
void ToUpper(); // Make contents of string uppercase
void ToLower(); // Make contents of string lowercase
void ConvertPath(); // Converts a path to native format
const char *c_str() { return s; }
const pxString &Format(const char *, ...); // Use variable arguments to set the string
const pxString operator+(const char *) const;
inline pxString Substr(uint32 nStart, uint32 nLen) const; // Return a part of this string
void Substr(pxString &rsStr, uint32 nStart, uint32 nLen) const; // A faster substring.
void SetString(const char *data, uint32 len); // Get the first len characters from another string
uint32 StrChr(char cToFind, uint32 nStartPos = 0) const; // Find position of a character in a string [PS 17/08/98]
// char * comparisons
bool operator==(const char *string) const; // Do a character by character comparison
bool operator!=(const char *string) const; // Do a character by character uncomparison
};
inline pxString::pxString(const pxString &str) {
if (str.s) {
// There is some data to copy
uint32 len = strlen((char *)str.s) + 1;
s = new char[len];
memcpy((unsigned char *)s, (unsigned char *)str.s, len);
} else
// No data for this string
s = NULL;
}
inline pxString::~pxString() {
// Destructor
if (s)
delete[] s;
}
const char *pxVString(MSVC_PRINTF const char *format, ...) GCC_PRINTF(1, 2);
class pxFlexiCharBuffer {
char *m_buffer; // The buffer itself
uint32 m_bufLen; // The buffer length
public:
// explicit
pxFlexiCharBuffer(uint32 len = 40);
~pxFlexiCharBuffer();
char &operator[](uint32); // Allow array access
void CheckSize(uint32); // Make sure we have enough room
char *GetBuffer() {
return (m_buffer); // Make it a little more difficult to pass the pointer
}
// Pointer access was originally const char *, but for use as a buffer for reading in from
// files this needs to be changeable, and needs a void * operator
operator char *() {
return (m_buffer); // Treat as a char *
}
operator void *() {
return (m_buffer); // Treat as a void *
}
void StrCpy(uint32 offset, const char *text); // Copy a string to the buffer
void StrnCpy(uint32 offset, const char *text, uint32 len); // Copy a number of characters to the buffer
// Prevent copy or assignment
private:
pxFlexiCharBuffer(const pxFlexiCharBuffer &) {}
void operator=(const pxFlexiCharBuffer &) {}
};
class pxFixedCharBuffer {
char *m_data;
public:
pxFixedCharBuffer(uint32 len);
~pxFixedCharBuffer() { delete[] m_data; }
operator void *() { return (m_data); }
operator char *() { return (m_data); }
// Prevent copy or assignment
private:
pxFixedCharBuffer(const pxFixedCharBuffer &) {}
void operator=(const pxFixedCharBuffer &) {}
};
inline pxString::pxString() {
// Empty creator
s = NULL;
}
inline pxString::pxString(const char *str) {
// Copy constructor
if (str) {
uint32 len = strlen(str) + 1;
s = new char[len];
memcpy(s, str, len);
} else
s = NULL;
}
inline bool pxString::IsEmpty() const {
// Check for an empty string
if ((s == NULL) || (*s == 0))
return (true);
return (false);
}
inline uint32 pxString::GetLen() const {
if ((s == NULL))
return (0);
return (strlen(s));
}
inline pxString pxString::Substr(uint32 nStart, uint32 nNum) const {
pxString rsRetVal;
Substr(rsRetVal, nStart, nNum);
return rsRetVal;
}
inline bool pxString::operator!=(const char *string) const {
// Do a character by character uncomparison
// Simply return the opposit of the == function
return ((bool)!((*this) == string));
}
} // End of namespace ICB
#endif // #ifndef _PX_pxString_H

View File

@@ -0,0 +1,41 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_PXTYPES_H
#define ICB_PXTYPES_H
namespace ICB {
typedef struct {
int32 left;
int32 top;
int32 right;
int32 bottom;
} LRECT;
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,150 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef WALKAREA_H
#define WALKAREA_H
#include "engines/icb/common/px_rcutypes.h"
namespace ICB {
#define INTEGER_WALKAREA_API_SCHEMA 1
struct __point { // 3D integer coordinate representation
__point(void) : x(0), y(0), z(0) { ; }
__point(int32 X, int32 Y, int32 Z) : x(X), y(Y), z(Z) { ; }
int32 x;
int32 y;
int32 z;
};
struct __aWalkArea{
char name[32]; // Name of the walkarea
char cameraCluster[8]; // Hashed cameraName value
// Bounding box dimensions
int32 x; // Top-left corner x coordinate (Revolution space)
int32 y; // Top-left corner y coordinate (Revolution space)
int32 z; // Top-left corner z coordinate (Revolution space)
int32 w; // Width
int32 h; // Height
// THE AREA DEFINITION (All in Revolution space)
uint32 noPoints; // Number of verteces\knots in 2D spline
__point points[1]; // The points themselves (spline is always closed)
char cameraName[1]; // Name of associated camera (DWORD aligned)
};
class INTEGER_WalkAreaFile {
public:
uint32 schema; // The format version
char ID[4]; // ID "WGA"
// Class methods
INTEGER_WalkAreaFile() { ; }
~INTEGER_WalkAreaFile() { ; }
uint32 GetSchema(void) const { return schema; }
uint32 GetNoAreas(void) const { return noAreas; }
// Get pointer to a specific WalkArea
inline const __aWalkArea *GetWalkArea(uint32 number) const;
inline uint32 GetNoPoints(uint32 number) const;
inline int32 GetBox_X(uint32 number) const;
inline int32 GetBox_Y(uint32 number) const;
inline int32 GetBox_Z(uint32 number) const;
inline int32 GetBox_W(uint32 number) const;
inline int32 GetBox_H(uint32 number) const;
bool8 GetAreaName(uint32 number, const char *&name) const;
bool8 GetCluster(uint32 number, const char *&cluster) const;
bool8 GetPoint(uint32 area, uint32 number, __point &point) const;
bool8 GetCameraName(uint32 number, const char *&name) const;
private:
uint32 noAreas;
uint32 offsetTable[1];
};
inline const __aWalkArea *INTEGER_WalkAreaFile::GetWalkArea(uint32 number) const { return ((const __aWalkArea *)(((const char *)this) + offsetTable[number])); }
inline uint32 INTEGER_WalkAreaFile::GetNoPoints(uint32 number) const { return (GetWalkArea(number)->noPoints); }
inline int32 INTEGER_WalkAreaFile::GetBox_X(uint32 number) const { return (GetWalkArea(number)->x); }
inline int32 INTEGER_WalkAreaFile::GetBox_Y(uint32 number) const { return (GetWalkArea(number)->y); }
inline int32 INTEGER_WalkAreaFile::GetBox_Z(uint32 number) const { return (GetWalkArea(number)->z); }
inline int32 INTEGER_WalkAreaFile::GetBox_W(uint32 number) const { return (GetWalkArea(number)->w); }
inline int32 INTEGER_WalkAreaFile::GetBox_H(uint32 number) const { return (GetWalkArea(number)->h); }
inline bool8 INTEGER_WalkAreaFile::GetAreaName(uint32 number, const char *&name) const {
if (number >= noAreas)
return FALSE8;
name = GetWalkArea(number)->name;
return TRUE8;
}
inline bool8 INTEGER_WalkAreaFile::GetCluster(uint32 number, const char *&cluster) const {
if (number >= noAreas)
return FALSE8;
cluster = GetWalkArea(number)->cameraCluster;
return TRUE8;
}
inline bool8 INTEGER_WalkAreaFile::GetPoint(uint32 area, uint32 number, __point &point) const {
if (area >= noAreas)
return FALSE8;
point.x = GetWalkArea(area)->points[number].x;
point.y = GetWalkArea(area)->points[number].y;
point.z = GetWalkArea(area)->points[number].z;
return TRUE8;
}
inline bool8 INTEGER_WalkAreaFile::GetCameraName(uint32 number, const char *&name) const {
if (number >= noAreas)
return FALSE8;
// Get the address of the start of the cameraName (by asking for a point that isn't there
name = (const char *)&GetWalkArea(number)->points[GetNoPoints(number)];
return TRUE8;
}
} // End of namespace ICB
#endif

View File

@@ -0,0 +1,73 @@
/* 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.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* 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/>.
*
*/
#ifndef ICB_REVTEX_API_H
#define ICB_REVTEX_API_H
namespace ICB {
#define REVTEX_API_ID "RTX"
#define REVTEX_API_SCHEMA_ICB 1
#define REVTEX_API_SCHEMA_ELDORADO 2
#define MAX_PAL_ENTRIES (256)
typedef struct revtex_API_header {
char id[4];
uint32 schema;
} revtex_API_header;
// The level pointers within the RevTexture structure in this structure
// are relative addresses which get converted to absolute pointer by
// calling the Map function
typedef struct revtex_API_v1 {
char id[4];
uint32 schema;
// RevTexture revtex;
uint32 palette[256]; // windows 32-bit RGB with 1 byte of padding
uint32 width; // must be power of 2
uint32 height; // must be power of 2
uint32 levelOffset[9]; // width/1 * height/1 -> width/256 * height/256
} revtex_API_v1;
typedef struct revtex_API_v2 {
char id[4];
uint32 schema;
uint32 transparent;
// RevTexture revtex;
uint32 palette[256]; // windows 32-bit RGB with 1 byte of padding
uint32 width; // must be power of 2
uint32 height; // must be power of 2
uint32 levelOffset[9]; // width/1 * height/1 -> width/256 * height/256
} revtex_API_v2;
} // End of namespace ICB
#endif // #ifndef REVTEX_API_H