Initial commit
This commit is contained in:
309
engines/icb/common/datapacker.cpp
Normal file
309
engines/icb/common/datapacker.cpp
Normal 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
|
||||
89
engines/icb/common/datapacker.h
Normal file
89
engines/icb/common/datapacker.h
Normal 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
|
||||
347
engines/icb/common/pc_props.h
Normal file
347
engines/icb/common/pc_props.h
Normal 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
|
||||
90
engines/icb/common/ptr_util.cpp
Normal file
90
engines/icb/common/ptr_util.cpp
Normal 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
|
||||
53
engines/icb/common/ptr_util.h
Normal file
53
engines/icb/common/ptr_util.h
Normal 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
|
||||
133
engines/icb/common/px_2drealline.cpp
Normal file
133
engines/icb/common/px_2drealline.cpp
Normal 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
|
||||
97
engines/icb/common/px_2drealline.h
Normal file
97
engines/icb/common/px_2drealline.h
Normal 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
|
||||
69
engines/icb/common/px_2drealpoint.h
Normal file
69
engines/icb/common/px_2drealpoint.h
Normal 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
|
||||
95
engines/icb/common/px_3drealpoint.h
Normal file
95
engines/icb/common/px_3drealpoint.h
Normal 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
|
||||
172
engines/icb/common/px_anims.h
Normal file
172
engines/icb/common/px_anims.h
Normal 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_
|
||||
367
engines/icb/common/px_array.h
Normal file
367
engines/icb/common/px_array.h
Normal 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
|
||||
42
engines/icb/common/px_bitmap.h
Normal file
42
engines/icb/common/px_bitmap.h
Normal 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
|
||||
63
engines/icb/common/px_bitmap_pc.h
Normal file
63
engines/icb/common/px_bitmap_pc.h
Normal 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
|
||||
53
engines/icb/common/px_bones.cpp
Normal file
53
engines/icb/common/px_bones.cpp
Normal 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
|
||||
62
engines/icb/common/px_bones.h
Normal file
62
engines/icb/common/px_bones.h
Normal 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
|
||||
49
engines/icb/common/px_camera.h
Normal file
49
engines/icb/common/px_camera.h
Normal 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__
|
||||
63
engines/icb/common/px_camera_cube.h
Normal file
63
engines/icb/common/px_camera_cube.h
Normal 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
|
||||
44
engines/icb/common/px_capri_maths.cpp
Normal file
44
engines/icb/common/px_capri_maths.cpp
Normal 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
|
||||
408
engines/icb/common/px_capri_maths.h
Normal file
408
engines/icb/common/px_capri_maths.h
Normal 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
|
||||
44
engines/icb/common/px_capri_maths_pc.cpp
Normal file
44
engines/icb/common/px_capri_maths_pc.cpp
Normal 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
|
||||
537
engines/icb/common/px_capri_maths_pc.h
Normal file
537
engines/icb/common/px_capri_maths_pc.h
Normal 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
|
||||
82
engines/icb/common/px_clu_api.cpp
Normal file
82
engines/icb/common/px_clu_api.cpp
Normal 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
|
||||
99
engines/icb/common/px_clu_api.h
Normal file
99
engines/icb/common/px_clu_api.h
Normal 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
|
||||
237
engines/icb/common/px_common.h
Normal file
237
engines/icb/common/px_common.h
Normal 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
|
||||
49
engines/icb/common/px_definitions.h
Normal file
49
engines/icb/common/px_definitions.h
Normal 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
|
||||
63
engines/icb/common/px_features.h
Normal file
63
engines/icb/common/px_features.h
Normal 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
|
||||
97
engines/icb/common/px_floor_map.h
Normal file
97
engines/icb/common/px_floor_map.h
Normal 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
|
||||
211
engines/icb/common/px_game_object.h
Normal file
211
engines/icb/common/px_game_object.h
Normal 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
|
||||
202
engines/icb/common/px_globalvariables.cpp
Normal file
202
engines/icb/common/px_globalvariables.cpp
Normal 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
|
||||
88
engines/icb/common/px_globalvariables.h
Normal file
88
engines/icb/common/px_globalvariables.h
Normal 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
|
||||
88
engines/icb/common/px_lights.h
Normal file
88
engines/icb/common/px_lights.h
Normal 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
|
||||
63
engines/icb/common/px_linkeddatafile.cpp
Normal file
63
engines/icb/common/px_linkeddatafile.cpp
Normal 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
|
||||
180
engines/icb/common/px_linkeddatafile.h
Normal file
180
engines/icb/common/px_linkeddatafile.h
Normal 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
|
||||
184
engines/icb/common/px_list.h
Normal file
184
engines/icb/common/px_list.h
Normal 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
|
||||
163
engines/icb/common/px_mapfile.h
Normal file
163
engines/icb/common/px_mapfile.h
Normal 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)
|
||||
74
engines/icb/common/px_prop_anims.h
Normal file
74
engines/icb/common/px_prop_anims.h
Normal 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
|
||||
45
engines/icb/common/px_rcutypes.h
Normal file
45
engines/icb/common/px_rcutypes.h
Normal 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
|
||||
215
engines/icb/common/px_route_barriers.h
Normal file
215
engines/icb/common/px_route_barriers.h
Normal 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
|
||||
534
engines/icb/common/px_scriptengine.cpp
Normal file
534
engines/icb/common/px_scriptengine.cpp
Normal 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
|
||||
143
engines/icb/common/px_scriptengine.h
Normal file
143
engines/icb/common/px_scriptengine.h
Normal 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
|
||||
97
engines/icb/common/px_sfx_description.h
Normal file
97
engines/icb/common/px_sfx_description.h
Normal 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
|
||||
58
engines/icb/common/px_sound_constants.h
Normal file
58
engines/icb/common/px_sound_constants.h
Normal 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
|
||||
71
engines/icb/common/px_staticlayers.h
Normal file
71
engines/icb/common/px_staticlayers.h
Normal 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
|
||||
336
engines/icb/common/px_string.cpp
Normal file
336
engines/icb/common/px_string.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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
|
||||
195
engines/icb/common/px_string.h
Normal file
195
engines/icb/common/px_string.h
Normal 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
|
||||
41
engines/icb/common/px_types.h
Normal file
41
engines/icb/common/px_types.h
Normal 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
|
||||
150
engines/icb/common/px_walkarea_integer.h
Normal file
150
engines/icb/common/px_walkarea_integer.h
Normal 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
|
||||
73
engines/icb/common/revtex_api.h
Normal file
73
engines/icb/common/revtex_api.h
Normal 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
|
||||
Reference in New Issue
Block a user