Initial import of the work in progress MADE engine
svn-id: r31599
This commit is contained in:
parent
d484c7ed43
commit
d0590a09ea
20 changed files with 4397 additions and 0 deletions
393
engines/made/database.cpp
Normal file
393
engines/made/database.cpp
Normal file
|
@ -0,0 +1,393 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "made/database.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class types:
|
||||||
|
0x7FFF byte array
|
||||||
|
0x7FFE word array
|
||||||
|
< 0x7FFE object
|
||||||
|
*/
|
||||||
|
|
||||||
|
Object::Object() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Object::~Object() {
|
||||||
|
if (_freeData && _objData)
|
||||||
|
delete[] _objData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::load(Common::SeekableReadStream &source) {
|
||||||
|
|
||||||
|
_freeData = true;
|
||||||
|
|
||||||
|
source.readUint16LE(); // skip flags
|
||||||
|
uint16 type = source.readUint16LE();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (type < 0x7FFE) {
|
||||||
|
byte count1 = source.readByte();
|
||||||
|
byte count2 = source.readByte();
|
||||||
|
_objSize = (count1 + count2) * 2;
|
||||||
|
} else {
|
||||||
|
_objSize = source.readUint16LE();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (type == 0x7FFF) {
|
||||||
|
_objSize = source.readUint16LE();
|
||||||
|
} else if (type == 0x7FFE) {
|
||||||
|
_objSize = source.readUint16LE() * 2;
|
||||||
|
} else if (type < 0x7FFE) {
|
||||||
|
byte count1 = source.readByte();
|
||||||
|
byte count2 = source.readByte();
|
||||||
|
_objSize = (count1 + count2) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
source.seek(-6, SEEK_CUR);
|
||||||
|
|
||||||
|
_objSize += 6;
|
||||||
|
|
||||||
|
_objData = new byte[_objSize];
|
||||||
|
source.read(_objData, _objSize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
debug(2, "Object::load(con): flags = %04X; type = %04X; _objSize = %04X\n", getFlags(), getClass(), _objSize);
|
||||||
|
fflush(stdout);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::load(byte *source) {
|
||||||
|
|
||||||
|
_objData = source;
|
||||||
|
_freeData = false;
|
||||||
|
|
||||||
|
if (getClass() < 0x7FFE) {
|
||||||
|
_objSize = (getCount1() + getCount2()) * 2;
|
||||||
|
} else {
|
||||||
|
_objSize = getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
_objSize += 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
debug(2, "Object::load(var): flags = %04X; type = %04X; _objSize = %04X\n", getFlags(), getClass(), _objSize);
|
||||||
|
fflush(stdout);
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Object::getFlags() const {
|
||||||
|
return READ_LE_UINT16(_objData);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Object::getClass() const {
|
||||||
|
return READ_LE_UINT16(_objData + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Object::getSize() const {
|
||||||
|
return READ_LE_UINT16(_objData + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte Object::getCount1() const {
|
||||||
|
return _objData[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte Object::getCount2() const {
|
||||||
|
return _objData[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *Object::getData() {
|
||||||
|
return _objData + 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Object::getString() {
|
||||||
|
if (getClass() == 0x7FFF)
|
||||||
|
return (const char*)getData();
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::isObject() {
|
||||||
|
return getClass() < 0x7FFE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::isVector() {
|
||||||
|
return getClass() == 0x7FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Object::getVectorSize() {
|
||||||
|
if (getClass() == 0x7FFF || getClass() == 0x7FFE) {
|
||||||
|
return getSize();
|
||||||
|
} else if (getClass() < 0x7FFE) {
|
||||||
|
return getCount1() + getCount2();
|
||||||
|
} else {
|
||||||
|
return 0; // FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Object::getVectorItem(int16 index) {
|
||||||
|
if (getClass() == 0x7FFF) {
|
||||||
|
byte *vector = (byte*)getData();
|
||||||
|
return vector[index];
|
||||||
|
} else if (getClass() == 0x7FFE) {
|
||||||
|
int16 *vector = (int16*)getData();
|
||||||
|
return vector[index];
|
||||||
|
} else if (getClass() < 0x7FFE) {
|
||||||
|
int16 *vector = (int16*)getData();
|
||||||
|
return vector[index];
|
||||||
|
} else {
|
||||||
|
return 0; // FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::setVectorItem(int16 index, int16 value) {
|
||||||
|
if (getClass() == 0x7FFF) {
|
||||||
|
byte *vector = (byte*)getData();
|
||||||
|
vector[index] = value;
|
||||||
|
} else if (getClass() <= 0x7FFE) {
|
||||||
|
int16 *vector = (int16*)getData();
|
||||||
|
vector[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::dump(const char *filename) {
|
||||||
|
/*
|
||||||
|
FILE *o = fopen(filename, "wb");
|
||||||
|
fwrite(_objData, _objSize, 1, o);
|
||||||
|
fclose(o);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
GameDatabase::GameDatabase() {
|
||||||
|
}
|
||||||
|
|
||||||
|
GameDatabase::~GameDatabase() {
|
||||||
|
if (_gameState)
|
||||||
|
delete[] _gameState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameDatabase::open(const char *filename) {
|
||||||
|
_fd.open(filename);
|
||||||
|
|
||||||
|
// TODO: Read/verifiy header
|
||||||
|
|
||||||
|
_fd.seek(0x1E);
|
||||||
|
|
||||||
|
uint32 objectIndexOffs = _fd.readUint32LE();
|
||||||
|
uint16 objectCount = _fd.readUint16LE();
|
||||||
|
uint32 gameStateOffs = _fd.readUint32LE();
|
||||||
|
_gameStateSize = _fd.readUint32LE();
|
||||||
|
uint32 objectsOffs = _fd.readUint32LE();
|
||||||
|
uint32 objectsSize = _fd.readUint32LE();
|
||||||
|
_mainCodeObjectIndex = _fd.readUint16LE();
|
||||||
|
|
||||||
|
debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n",
|
||||||
|
objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
|
||||||
|
|
||||||
|
_gameState = new byte[_gameStateSize];
|
||||||
|
_fd.seek(gameStateOffs);
|
||||||
|
_fd.read(_gameState, _gameStateSize);
|
||||||
|
|
||||||
|
Common::Array<uint32> objectOffsets;
|
||||||
|
_fd.seek(objectIndexOffs);
|
||||||
|
for (uint32 i = 0; i < objectCount; i++)
|
||||||
|
objectOffsets.push_back(_fd.readUint32LE());
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < objectCount; i++) {
|
||||||
|
Object *obj = new Object();
|
||||||
|
// The LSB indicates if it's a constant or variable object
|
||||||
|
|
||||||
|
debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
|
||||||
|
|
||||||
|
if (objectOffsets[i] & 1) {
|
||||||
|
debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
|
||||||
|
_fd.seek(objectsOffs + objectOffsets[i] - 1);
|
||||||
|
obj->load(_fd);
|
||||||
|
} else {
|
||||||
|
debug(2, "-> var\n");
|
||||||
|
obj->load(_gameState + objectOffsets[i]);
|
||||||
|
}
|
||||||
|
_objects.push_back(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 GameDatabase::getVar(int16 index) {
|
||||||
|
return (int16)READ_LE_UINT16(_gameState + index * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameDatabase::setVar(int16 index, int16 value) {
|
||||||
|
WRITE_LE_UINT16(_gameState + index * 2, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
|
||||||
|
Object *obj = getObject(objectIndex);
|
||||||
|
|
||||||
|
//dumpObject(objectIndex);
|
||||||
|
|
||||||
|
int16 *prop = (int16*)obj->getData();
|
||||||
|
byte count1 = obj->getCount1();
|
||||||
|
byte count2 = obj->getCount2();
|
||||||
|
|
||||||
|
int16 *propPtr1 = prop + count1;
|
||||||
|
int16 *propPtr2 = prop + count2;
|
||||||
|
|
||||||
|
debug(2, "# propertyId = %04X\n", propertyId);
|
||||||
|
|
||||||
|
// First see if the property exists in the given object
|
||||||
|
while (count2-- > 0) {
|
||||||
|
if ((*prop & 0x3FFF) == propertyId) {
|
||||||
|
if (*prop & 0x4000) {
|
||||||
|
debug(2, "! L1.1\n");
|
||||||
|
propertyFlag = 1;
|
||||||
|
return (int16*)_gameState + *propPtr1;
|
||||||
|
} else {
|
||||||
|
debug(2, "! L1.2\n");
|
||||||
|
propertyFlag = obj->getFlags() & 1;
|
||||||
|
return propPtr1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop++;
|
||||||
|
propPtr1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check in the object hierarchy of the given object
|
||||||
|
int16 parentObjectIndex = obj->getClass();
|
||||||
|
if (parentObjectIndex == 0) {
|
||||||
|
debug(2, "! NULL(np)\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (parentObjectIndex != 0) {
|
||||||
|
|
||||||
|
debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
|
||||||
|
|
||||||
|
//dumpObject(parentObjectIndex);
|
||||||
|
|
||||||
|
obj = getObject(parentObjectIndex);
|
||||||
|
|
||||||
|
prop = (int16*)obj->getData();
|
||||||
|
count1 = obj->getCount1();
|
||||||
|
count2 = obj->getCount2();
|
||||||
|
|
||||||
|
propPtr1 = propPtr2 + count1 - count2;
|
||||||
|
int16 *propertyPtr = prop + count1;
|
||||||
|
|
||||||
|
while (count2-- > 0) {
|
||||||
|
if (!(*prop & 0x8000)) {
|
||||||
|
if ((*prop & 0x3FFF) == propertyId) {
|
||||||
|
if (*prop & 0x4000) {
|
||||||
|
debug(2, "! L2.1\n");
|
||||||
|
propertyFlag = 1;
|
||||||
|
return (int16*)_gameState + *propPtr1;
|
||||||
|
} else {
|
||||||
|
debug(2, "! L2.2\n");
|
||||||
|
propertyFlag = obj->getFlags() & 1;
|
||||||
|
return propPtr1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
propPtr1++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((*prop & 0x3FFF) == propertyId) {
|
||||||
|
if (*prop & 0x4000) {
|
||||||
|
debug(2, "! L3.1\n");
|
||||||
|
propertyFlag = 1;
|
||||||
|
return (int16*)_gameState + *propertyPtr;
|
||||||
|
} else {
|
||||||
|
debug(2, "! L3.2\n");
|
||||||
|
propertyFlag = obj->getFlags() & 1;
|
||||||
|
return propertyPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prop++;
|
||||||
|
propertyPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentObjectIndex = obj->getClass();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(2, "! NULL(nf)\n");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
|
||||||
|
|
||||||
|
if (objectIndex == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int16 propertyFlag;
|
||||||
|
int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
|
||||||
|
|
||||||
|
if (property) {
|
||||||
|
return *property;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) {
|
||||||
|
|
||||||
|
if (objectIndex == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int16 propertyFlag;
|
||||||
|
int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
|
||||||
|
|
||||||
|
if (property) {
|
||||||
|
if (propertyFlag == 1) {
|
||||||
|
*property = value;
|
||||||
|
} else {
|
||||||
|
debug(2, "GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n",
|
||||||
|
objectIndex, propertyId, value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameDatabase::dumpObject(int16 index) {
|
||||||
|
Object *obj = getObject(index);
|
||||||
|
char fn[512];
|
||||||
|
sprintf(fn, "obj%04X.0", index);
|
||||||
|
obj->dump(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
105
engines/made/database.h
Normal file
105
engines/made/database.h
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_DATABASE_H
|
||||||
|
#define MADE_DATABASE_H
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object();
|
||||||
|
~Object();
|
||||||
|
void load(Common::SeekableReadStream &source);
|
||||||
|
void load(byte *source);
|
||||||
|
|
||||||
|
uint16 getFlags() const;
|
||||||
|
uint16 getClass() const;
|
||||||
|
uint16 getSize() const;
|
||||||
|
|
||||||
|
byte getCount1() const;
|
||||||
|
byte getCount2() const;
|
||||||
|
|
||||||
|
byte *getData();
|
||||||
|
const char *getString();
|
||||||
|
|
||||||
|
bool isObject();
|
||||||
|
bool isVector();
|
||||||
|
bool isConstant() const { return !(getFlags() & 1); }
|
||||||
|
|
||||||
|
int16 getVectorSize();
|
||||||
|
int16 getVectorItem(int16 index);
|
||||||
|
void setVectorItem(int16 index, int16 value);
|
||||||
|
|
||||||
|
void dump(const char *filename);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _freeData;
|
||||||
|
uint16 _objSize;
|
||||||
|
byte *_objData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GameDatabase {
|
||||||
|
public:
|
||||||
|
|
||||||
|
GameDatabase();
|
||||||
|
~GameDatabase();
|
||||||
|
|
||||||
|
void open(const char *filename);
|
||||||
|
|
||||||
|
Object *getObject(int16 index) const {
|
||||||
|
if (index >= 1)
|
||||||
|
return _objects[index - 1];
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 getMainCodeObjectIndex() const { return _mainCodeObjectIndex; }
|
||||||
|
|
||||||
|
int16 getVar(int16 index);
|
||||||
|
void setVar(int16 index, int16 value);
|
||||||
|
|
||||||
|
int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
|
||||||
|
int16 getObjectProperty(int16 objectIndex, int16 propertyId);
|
||||||
|
int16 setObjectProperty(int16 objectIndex, int16 propertyId, int16 value);
|
||||||
|
|
||||||
|
void dumpObject(int16 index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Common::File _fd;
|
||||||
|
Common::Array<Object*> _objects;
|
||||||
|
byte *_gameState;
|
||||||
|
uint32 _gameStateSize;
|
||||||
|
int16 _mainCodeObjectIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
172
engines/made/detection.cpp
Normal file
172
engines/made/detection.cpp
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.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "base/plugins.h"
|
||||||
|
|
||||||
|
#include "common/advancedDetector.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
#include "made/made.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
struct MadeGameDescription {
|
||||||
|
Common::ADGameDescription desc;
|
||||||
|
|
||||||
|
int gameID;
|
||||||
|
int gameType;
|
||||||
|
uint32 features;
|
||||||
|
uint16 version;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 MadeEngine::getGameID() const {
|
||||||
|
return _gameDescription->gameID;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 MadeEngine::getFeatures() const {
|
||||||
|
return _gameDescription->features;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::Platform MadeEngine::getPlatform() const {
|
||||||
|
return _gameDescription->desc.platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 MadeEngine::getVersion() const {
|
||||||
|
return _gameDescription->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const PlainGameDescriptor madeGames[] = {
|
||||||
|
{"made", "Return to Zork"},
|
||||||
|
{0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
static const MadeGameDescription gameDescriptions[] = {
|
||||||
|
|
||||||
|
{
|
||||||
|
// Made English version
|
||||||
|
{
|
||||||
|
"made",
|
||||||
|
"CD",
|
||||||
|
AD_ENTRY1("rtzcd.dat", "a1db8c97a78dae10f91d356f16ad07b8"),
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformPC,
|
||||||
|
Common::ADGF_NO_FLAGS
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
{ AD_TABLE_END_MARKER, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fallback game descriptor used by the Made engine's fallbackDetector.
|
||||||
|
* Contents of this struct are to be overwritten by the fallbackDetector.
|
||||||
|
*/
|
||||||
|
static MadeGameDescription g_fallbackDesc = {
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor
|
||||||
|
Common::UNK_LANG,
|
||||||
|
Common::kPlatformPC,
|
||||||
|
Common::ADGF_NO_FLAGS
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
static const Common::ADParams detectionParams = {
|
||||||
|
// Pointer to ADGameDescription or its superset structure
|
||||||
|
(const byte *)Made::gameDescriptions,
|
||||||
|
// Size of that superset structure
|
||||||
|
sizeof(Made::MadeGameDescription),
|
||||||
|
// Number of bytes to compute MD5 sum for
|
||||||
|
5000,
|
||||||
|
// List of all engine targets
|
||||||
|
madeGames,
|
||||||
|
// Structure for autoupgrading obsolete targets
|
||||||
|
0,
|
||||||
|
// Name of single gameid (optional)
|
||||||
|
"made",
|
||||||
|
// List of files for file-based fallback detection (optional)
|
||||||
|
0,
|
||||||
|
// Flags
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
class MadeMetaEngine : public Common::AdvancedMetaEngine {
|
||||||
|
public:
|
||||||
|
MadeMetaEngine() : Common::AdvancedMetaEngine(detectionParams) {}
|
||||||
|
|
||||||
|
virtual const char *getName() const {
|
||||||
|
return "MADE Engine";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char *getCopyright() const {
|
||||||
|
return "MADE Engine";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
|
||||||
|
|
||||||
|
const Common::ADGameDescription *fallbackDetect(const FSList *fslist) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
bool MadeMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const {
|
||||||
|
const Made::MadeGameDescription *gd = (const Made::MadeGameDescription *)desc;
|
||||||
|
if (gd) {
|
||||||
|
*engine = new Made::MadeEngine(syst, gd);
|
||||||
|
}
|
||||||
|
return gd != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Common::ADGameDescription *MadeMetaEngine::fallbackDetect(const FSList *fslist) const {
|
||||||
|
// Set the default values for the fallback descriptor's ADGameDescription part.
|
||||||
|
Made::g_fallbackDesc.desc.language = Common::UNK_LANG;
|
||||||
|
Made::g_fallbackDesc.desc.platform = Common::kPlatformPC;
|
||||||
|
Made::g_fallbackDesc.desc.flags = Common::ADGF_NO_FLAGS;
|
||||||
|
|
||||||
|
// Set default values for the fallback descriptor's MadeGameDescription part.
|
||||||
|
Made::g_fallbackDesc.gameID = 0;
|
||||||
|
Made::g_fallbackDesc.features = 0;
|
||||||
|
Made::g_fallbackDesc.version = 0;
|
||||||
|
|
||||||
|
return (const Common::ADGameDescription *)&Made::g_fallbackDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_PLUGIN(MADE, PLUGIN_TYPE_ENGINE, MadeMetaEngine);
|
152
engines/made/graphics.cpp
Normal file
152
engines/made/graphics.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
|
||||||
|
#include "made/graphics.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, uint16 pixelOffs, uint16 maskOffs, uint16 lineSize, bool deltaFrame) {
|
||||||
|
|
||||||
|
const int offsets[] = {
|
||||||
|
0, 1, 2, 3,
|
||||||
|
320, 321, 322, 323,
|
||||||
|
640, 641, 642, 643,
|
||||||
|
960, 961, 962, 963
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16 width = surface.w;
|
||||||
|
uint16 height = surface.h;
|
||||||
|
|
||||||
|
byte *cmdBuffer = source + cmdOffs;
|
||||||
|
byte *maskBuffer = source + maskOffs;
|
||||||
|
byte *pixelBuffer = source + pixelOffs;
|
||||||
|
|
||||||
|
byte *destPtr = (byte*)surface.getBasePtr(0, 0);
|
||||||
|
|
||||||
|
//byte lineBuf[320 * 4];
|
||||||
|
byte lineBuf[640 * 4];
|
||||||
|
byte bitBuf[40];
|
||||||
|
|
||||||
|
int bitBufLastOfs = (((lineSize + 1) >> 1) << 1) - 2;
|
||||||
|
int bitBufLastCount = ((width + 3) >> 2) & 7;
|
||||||
|
if (bitBufLastCount == 0)
|
||||||
|
bitBufLastCount = 8;
|
||||||
|
|
||||||
|
while (height > 0) {
|
||||||
|
|
||||||
|
int drawDestOfs = 0;
|
||||||
|
|
||||||
|
memset(lineBuf, 0, sizeof(lineBuf));
|
||||||
|
|
||||||
|
memcpy(bitBuf, cmdBuffer, lineSize);
|
||||||
|
cmdBuffer += lineSize;
|
||||||
|
|
||||||
|
for (uint16 bitBufOfs = 0; bitBufOfs < lineSize; bitBufOfs += 2) {
|
||||||
|
|
||||||
|
uint16 bits = READ_LE_UINT16(&bitBuf[bitBufOfs]);
|
||||||
|
|
||||||
|
int bitCount;
|
||||||
|
if (bitBufOfs == bitBufLastOfs)
|
||||||
|
bitCount = bitBufLastCount;
|
||||||
|
else
|
||||||
|
bitCount = 8;
|
||||||
|
|
||||||
|
for (int curCmd = 0; curCmd < bitCount; curCmd++) {
|
||||||
|
int cmd = bits & 3;
|
||||||
|
bits >>= 2;
|
||||||
|
|
||||||
|
byte pixels[4];
|
||||||
|
uint32 mask;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
pixels[0] = *pixelBuffer++;
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
lineBuf[drawDestOfs + offsets[i]] = pixels[0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
pixels[0] = *pixelBuffer++;
|
||||||
|
pixels[1] = *pixelBuffer++;
|
||||||
|
mask = READ_LE_UINT16(maskBuffer);
|
||||||
|
maskBuffer += 2;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
lineBuf[drawDestOfs + offsets[i]] = pixels[mask & 1];
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
pixels[0] = *pixelBuffer++;
|
||||||
|
pixels[1] = *pixelBuffer++;
|
||||||
|
pixels[2] = *pixelBuffer++;
|
||||||
|
pixels[3] = *pixelBuffer++;
|
||||||
|
mask = READ_LE_UINT32(maskBuffer);
|
||||||
|
maskBuffer += 4;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
lineBuf[drawDestOfs + offsets[i]] = pixels[mask & 3];
|
||||||
|
mask >>= 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (!deltaFrame) {
|
||||||
|
// Yes, it reads from maskBuffer here
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
lineBuf[drawDestOfs + offsets[i]] = *maskBuffer++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drawDestOfs += 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deltaFrame) {
|
||||||
|
for (int y = 0; y < 4 && height > 0; y++, height--) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
if (lineBuf[x + y * 320] != 0)
|
||||||
|
*destPtr = lineBuf[x + y * 320];
|
||||||
|
destPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int y = 0; y < 4 && height > 0; y++, height--) {
|
||||||
|
memcpy(destPtr, &lineBuf[y * 320], width);
|
||||||
|
destPtr += width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
40
engines/made/graphics.h
Normal file
40
engines/made/graphics.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_GRAPHICS_H
|
||||||
|
#define MADE_GRAPHICS_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
void decompressImage(byte *source, Graphics::Surface &surface, uint16 cmdOffs, uint16 pixelOffs, uint16 maskOffs, uint16 lineSize, bool deltaFrame = false);
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
155
engines/made/made.cpp
Normal file
155
engines/made/made.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/events.h"
|
||||||
|
#include "common/keyboard.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/savefile.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
|
||||||
|
#include "graphics/cursorman.h"
|
||||||
|
|
||||||
|
#include "base/plugins.h"
|
||||||
|
#include "base/version.h"
|
||||||
|
|
||||||
|
#include "sound/mixer.h"
|
||||||
|
|
||||||
|
#include "made/made.h"
|
||||||
|
#include "made/database.h"
|
||||||
|
#include "made/pmvplayer.h"
|
||||||
|
#include "made/resource.h"
|
||||||
|
#include "made/screen.h"
|
||||||
|
#include "made/script.h"
|
||||||
|
#include "made/sound.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
struct GameSettings {
|
||||||
|
const char *gameid;
|
||||||
|
const char *description;
|
||||||
|
byte id;
|
||||||
|
uint32 features;
|
||||||
|
const char *detectname;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GameSettings madeSettings[] = {
|
||||||
|
{"made", "Made game", 0, 0, 0},
|
||||||
|
|
||||||
|
{NULL, NULL, 0, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
|
||||||
|
|
||||||
|
// Setup mixer
|
||||||
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
||||||
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
||||||
|
|
||||||
|
const GameSettings *g;
|
||||||
|
|
||||||
|
const char *gameid = ConfMan.get("gameid").c_str();
|
||||||
|
for (g = madeSettings; g->gameid; ++g)
|
||||||
|
if (!scumm_stricmp(g->gameid, gameid))
|
||||||
|
_gameId = g->id;
|
||||||
|
|
||||||
|
_rnd = new Common::RandomSource();
|
||||||
|
syst->getEventManager()->registerRandomSource(*_rnd, "made");
|
||||||
|
|
||||||
|
int cd_num = ConfMan.getInt("cdrom");
|
||||||
|
if (cd_num >= 0)
|
||||||
|
_system->openCD(cd_num);
|
||||||
|
|
||||||
|
_pmvPlayer = new PmvPlayer(_system, _mixer);
|
||||||
|
_res = new ProjectReader();
|
||||||
|
_screen = new Screen(this);
|
||||||
|
_dat = new GameDatabase();
|
||||||
|
_script = new ScriptInterpreter(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MadeEngine::~MadeEngine() {
|
||||||
|
delete _rnd;
|
||||||
|
delete _pmvPlayer;
|
||||||
|
delete _res;
|
||||||
|
delete _screen;
|
||||||
|
delete _dat;
|
||||||
|
delete _script;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MadeEngine::init() {
|
||||||
|
// Initialize backend
|
||||||
|
_system->beginGFXTransaction();
|
||||||
|
initCommonGFX(false);
|
||||||
|
_system->initSize(320, 200);
|
||||||
|
_system->endGFXTransaction();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 MadeEngine::getTimer(int16 timerNum) {
|
||||||
|
return (_system->getMillis() - _timers[timerNum]) / 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MadeEngine::setTimer(int16 timerNum, int16 value) {
|
||||||
|
_timers[timerNum] = value * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MadeEngine::resetTimer(int16 timerNum) {
|
||||||
|
_timers[timerNum] = _system->getMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 MadeEngine::allocTimer() {
|
||||||
|
for (int i = 0; i < ARRAYSIZE(_timers); i++) {
|
||||||
|
if (_timers[i] == -1) {
|
||||||
|
resetTimer(i);
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MadeEngine::freeTimer(int16 timerNum) {
|
||||||
|
_timers[timerNum] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MadeEngine::go() {
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAYSIZE(_timers); i++)
|
||||||
|
_timers[i] = -1;
|
||||||
|
|
||||||
|
_dat->open("rtzcd.dat");
|
||||||
|
_res->open("rtzcd.prj");
|
||||||
|
|
||||||
|
PictureResource *flex1 = _res->getPicture(78);
|
||||||
|
Graphics::Surface *surf = flex1->getPicture();
|
||||||
|
CursorMan.replaceCursor((const byte *)surf->pixels, surf->w, surf->h, 0, 0, 0);
|
||||||
|
CursorMan.showMouse(true);
|
||||||
|
_res->freeResource(flex1);
|
||||||
|
_eventMouseX = _eventMouseY = 0;
|
||||||
|
_script->runScript(_dat->getMainCodeObjectIndex());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
106
engines/made/made.h
Normal file
106
engines/made/made.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_H
|
||||||
|
#define MADE_H
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/savefile.h"
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/hash-str.h"
|
||||||
|
#include "common/events.h"
|
||||||
|
#include "common/keyboard.h"
|
||||||
|
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
#include "sound/audiostream.h"
|
||||||
|
#include "sound/mixer.h"
|
||||||
|
#include "sound/voc.h"
|
||||||
|
#include "sound/audiocd.h"
|
||||||
|
|
||||||
|
#include "engines/engine.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
enum MadeGameFeatures {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MadeGameDescription;
|
||||||
|
|
||||||
|
class ProjectReader;
|
||||||
|
class PmvPlayer;
|
||||||
|
class Screen;
|
||||||
|
class ScriptInterpreter;
|
||||||
|
class GameDatabase;
|
||||||
|
|
||||||
|
class MadeEngine : public ::Engine {
|
||||||
|
int _gameId;
|
||||||
|
Common::KeyState _keyPressed;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int init();
|
||||||
|
int go();
|
||||||
|
|
||||||
|
public:
|
||||||
|
MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc);
|
||||||
|
virtual ~MadeEngine();
|
||||||
|
int getGameId() {
|
||||||
|
return _gameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::RandomSource *_rnd;
|
||||||
|
const MadeGameDescription *_gameDescription;
|
||||||
|
uint32 getGameID() const;
|
||||||
|
uint32 getFeatures() const;
|
||||||
|
uint16 getVersion() const;
|
||||||
|
Common::Platform getPlatform() const;
|
||||||
|
void update_events();
|
||||||
|
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
PmvPlayer *_pmvPlayer;
|
||||||
|
ProjectReader *_res;
|
||||||
|
Screen *_screen;
|
||||||
|
GameDatabase *_dat;
|
||||||
|
ScriptInterpreter *_script;
|
||||||
|
|
||||||
|
int _eventMouseX, _eventMouseY;
|
||||||
|
|
||||||
|
int32 _timers[50];
|
||||||
|
int16 getTimer(int16 timerNum);
|
||||||
|
void setTimer(int16 timerNum, int16 value);
|
||||||
|
void resetTimer(int16 timerNum);
|
||||||
|
int16 allocTimer();
|
||||||
|
void freeTimer(int16 timerNum);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
22
engines/made/module.mk
Normal file
22
engines/made/module.mk
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
MODULE := engines/made
|
||||||
|
|
||||||
|
MODULE_OBJS = \
|
||||||
|
database.o \
|
||||||
|
detection.o \
|
||||||
|
graphics.o \
|
||||||
|
made.o \
|
||||||
|
pmvplayer.o \
|
||||||
|
resource.o \
|
||||||
|
screen.o \
|
||||||
|
script.o \
|
||||||
|
scriptfuncs.o \
|
||||||
|
sound.o
|
||||||
|
|
||||||
|
|
||||||
|
# This module can be built as a plugin
|
||||||
|
ifdef BUILD_PLUGINS
|
||||||
|
PLUGIN := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Include common rules
|
||||||
|
include $(srcdir)/rules.mk
|
152
engines/made/pmvplayer.cpp
Normal file
152
engines/made/pmvplayer.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include "made/pmvplayer.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
PmvPlayer::PmvPlayer(OSystem *system, Audio::Mixer *mixer) : _fd(NULL), _system(system), _mixer(mixer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PmvPlayer::~PmvPlayer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmvPlayer::play(const char *filename) {
|
||||||
|
|
||||||
|
_abort = false;
|
||||||
|
_surface = NULL;
|
||||||
|
|
||||||
|
_fd = new Common::File();
|
||||||
|
_fd->open(filename);
|
||||||
|
|
||||||
|
uint32 chunkType, chunkSize;
|
||||||
|
|
||||||
|
readChunk(chunkType, chunkSize); // "MOVE"
|
||||||
|
readChunk(chunkType, chunkSize); // "MHED"
|
||||||
|
|
||||||
|
// TODO: Evaluate header
|
||||||
|
//_fd->skip(0x3A);
|
||||||
|
|
||||||
|
uint frameDelay = _fd->readUint16LE();
|
||||||
|
_fd->skip(10);
|
||||||
|
uint soundFreq = _fd->readUint16LE();
|
||||||
|
// FIXME: weird frequencies... (11127 or 22254)
|
||||||
|
//if (soundFreq == 11127) soundFreq = 11025;
|
||||||
|
//if (soundFreq == 22254) soundFreq = 22050;
|
||||||
|
|
||||||
|
int unk;
|
||||||
|
|
||||||
|
for (int i = 0; i < 22; i++) {
|
||||||
|
unk = _fd->readUint16LE();
|
||||||
|
debug(2, "%i ", unk);
|
||||||
|
}
|
||||||
|
debug(2, "\n");
|
||||||
|
|
||||||
|
_mixer->stopAll();
|
||||||
|
|
||||||
|
_audioStream = Audio::makeAppendableAudioStream(soundFreq, Audio::Mixer::FLAG_UNSIGNED);
|
||||||
|
_mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
|
||||||
|
|
||||||
|
// Read palette
|
||||||
|
_fd->read(_palette, 768);
|
||||||
|
updatePalette();
|
||||||
|
|
||||||
|
//FILE *raw = fopen("track.raw", "wb");
|
||||||
|
|
||||||
|
while (!_abort && !_fd->eof()) {
|
||||||
|
|
||||||
|
readChunk(chunkType, chunkSize);
|
||||||
|
|
||||||
|
if (_fd->eof())
|
||||||
|
break;
|
||||||
|
|
||||||
|
byte *frameData = new byte[chunkSize];
|
||||||
|
_fd->read(frameData, chunkSize);
|
||||||
|
|
||||||
|
byte *audioData = frameData + READ_LE_UINT32(frameData + 8) - 8;
|
||||||
|
uint16 chunkSize = READ_LE_UINT16(audioData + 4);
|
||||||
|
uint16 chunkCount = READ_LE_UINT16(audioData + 6);
|
||||||
|
|
||||||
|
if (chunkCount > 50) break; // FIXME: this is a hack
|
||||||
|
|
||||||
|
debug(2, "chunkCount = %d; chunkSize = %d\n", chunkCount, chunkSize);
|
||||||
|
|
||||||
|
uint32 soundSize = chunkCount * chunkSize;
|
||||||
|
byte *soundData = new byte[soundSize];
|
||||||
|
decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
|
||||||
|
_audioStream->queueBuffer(soundData, soundSize);
|
||||||
|
|
||||||
|
//fwrite(soundData, soundSize, 1, raw);
|
||||||
|
|
||||||
|
byte *imageData = frameData + READ_LE_UINT32(frameData + 12) - 8;
|
||||||
|
|
||||||
|
uint32 frameNum = READ_LE_UINT32(frameData);
|
||||||
|
uint16 width = READ_LE_UINT16(imageData + 8);
|
||||||
|
uint16 height = READ_LE_UINT16(imageData + 10);
|
||||||
|
uint16 cmdOffs = READ_LE_UINT16(imageData + 12);
|
||||||
|
uint16 pixelOffs = READ_LE_UINT16(imageData + 16);
|
||||||
|
uint16 maskOffs = READ_LE_UINT16(imageData + 20);
|
||||||
|
uint16 lineSize = READ_LE_UINT16(imageData + 24);
|
||||||
|
|
||||||
|
debug(2, "width = %d; height = %d; cmdOffs = %04X; pixelOffs = %04X; maskOffs = %04X; lineSize = %d\n",
|
||||||
|
width, height, cmdOffs, pixelOffs, maskOffs, lineSize);
|
||||||
|
|
||||||
|
if (!_surface) {
|
||||||
|
_surface = new Graphics::Surface();
|
||||||
|
_surface->create(width, height, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
decompressImage(imageData, *_surface, cmdOffs, pixelOffs, maskOffs, lineSize, frameNum > 0);
|
||||||
|
|
||||||
|
handleEvents();
|
||||||
|
updateScreen();
|
||||||
|
|
||||||
|
delete[] frameData;
|
||||||
|
|
||||||
|
_system->delayMillis(frameDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
_audioStream->finish();
|
||||||
|
_mixer->stopAll();
|
||||||
|
|
||||||
|
//delete _audioStream;
|
||||||
|
delete _fd;
|
||||||
|
delete _surface;
|
||||||
|
|
||||||
|
//fclose(raw);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmvPlayer::readChunk(uint32 &chunkType, uint32 &chunkSize) {
|
||||||
|
chunkType = _fd->readUint32BE();
|
||||||
|
chunkSize = _fd->readUint32LE();
|
||||||
|
|
||||||
|
debug(2, "chunkType = %c%c%c%c; chunkSize = %d\n",
|
||||||
|
(chunkType >> 24) & 0xFF, (chunkType >> 16) & 0xFF, (chunkType >> 8) & 0xFF, chunkType & 0xFF,
|
||||||
|
chunkSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmvPlayer::handleEvents() {
|
||||||
|
Common::Event event;
|
||||||
|
while (_system->getEventManager()->pollEvent(event)) {
|
||||||
|
if (event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
||||||
|
_abort = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmvPlayer::updatePalette() {
|
||||||
|
byte colors[1024];
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
colors[i * 4 + 0] = _palette[i * 3 + 0];
|
||||||
|
colors[i * 4 + 1] = _palette[i * 3 + 1];
|
||||||
|
colors[i * 4 + 2] = _palette[i * 3 + 2];
|
||||||
|
colors[i * 4 + 3] = 0;
|
||||||
|
}
|
||||||
|
_system->setPalette(colors, 0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PmvPlayer::updateScreen() {
|
||||||
|
_system->copyRectToScreen((const byte*)_surface->pixels, _surface->pitch, 0, 0, _surface->w, _surface->h);
|
||||||
|
_system->updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
engines/made/pmvplayer.h
Normal file
39
engines/made/pmvplayer.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef MADE_PMVPLAYER_H
|
||||||
|
#define MADE_PMVPLAYER_H
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/events.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
#include "sound/mixer.h"
|
||||||
|
#include "sound/audiostream.h"
|
||||||
|
|
||||||
|
#include "made/graphics.h"
|
||||||
|
#include "made/sound.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
class PmvPlayer {
|
||||||
|
public:
|
||||||
|
PmvPlayer(OSystem *system, Audio::Mixer *mixer);
|
||||||
|
~PmvPlayer();
|
||||||
|
void play(const char *filename);
|
||||||
|
protected:
|
||||||
|
OSystem *_system;
|
||||||
|
Audio::Mixer *_mixer;
|
||||||
|
Common::File *_fd;
|
||||||
|
Audio::AppendableAudioStream *_audioStream;
|
||||||
|
Audio::SoundHandle _audioStreamHandle;
|
||||||
|
byte _palette[768];
|
||||||
|
Graphics::Surface *_surface;
|
||||||
|
bool _abort;
|
||||||
|
void readChunk(uint32 &chunkType, uint32 &chunkSize);
|
||||||
|
void handleEvents();
|
||||||
|
void updatePalette();
|
||||||
|
void updateScreen();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
333
engines/made/resource.cpp
Normal file
333
engines/made/resource.cpp
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
|
||||||
|
#include "made/resource.h"
|
||||||
|
#include "made/graphics.h"
|
||||||
|
#include "made/sound.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
/* Resource */
|
||||||
|
|
||||||
|
Resource::~Resource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PictureResource */
|
||||||
|
|
||||||
|
PictureResource::PictureResource() : _picture(NULL), _palette(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureResource::~PictureResource() {
|
||||||
|
if (_picture)
|
||||||
|
delete _picture;
|
||||||
|
if (_palette)
|
||||||
|
delete[] _palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PictureResource::load(byte *source, int size) {
|
||||||
|
|
||||||
|
Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);
|
||||||
|
|
||||||
|
bool hasPalette = sourceS->readByte() == 1;
|
||||||
|
sourceS->readByte();
|
||||||
|
sourceS->readByte();
|
||||||
|
sourceS->readByte();
|
||||||
|
uint16 cmdOffs = sourceS->readUint16LE();
|
||||||
|
uint16 pixelOffs = sourceS->readUint16LE();
|
||||||
|
uint16 maskOffs = sourceS->readUint16LE();
|
||||||
|
uint16 lineSize = sourceS->readUint16LE();
|
||||||
|
uint16 u = sourceS->readUint16LE();
|
||||||
|
uint16 width = sourceS->readUint16LE();
|
||||||
|
uint16 height = sourceS->readUint16LE();
|
||||||
|
|
||||||
|
debug(2, "width = %d; height = %d\n", width, height);
|
||||||
|
|
||||||
|
if (hasPalette) {
|
||||||
|
_palette = new byte[768];
|
||||||
|
sourceS->read(_palette, 768);
|
||||||
|
}
|
||||||
|
|
||||||
|
_picture = new Graphics::Surface();
|
||||||
|
_picture->create(width, height, 1);
|
||||||
|
|
||||||
|
decompressImage(source, *_picture, cmdOffs, pixelOffs, maskOffs, lineSize);
|
||||||
|
|
||||||
|
delete sourceS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AnimationResource */
|
||||||
|
|
||||||
|
AnimationResource::AnimationResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationResource::~AnimationResource() {
|
||||||
|
// TODO: Free anim frames
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationResource::load(byte *source, int size) {
|
||||||
|
|
||||||
|
Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);
|
||||||
|
|
||||||
|
sourceS->readUint32LE();
|
||||||
|
sourceS->readUint32LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
|
||||||
|
_flags = sourceS->readUint16LE();
|
||||||
|
_width = sourceS->readUint16LE();
|
||||||
|
_height = sourceS->readUint16LE();
|
||||||
|
sourceS->readUint32LE();
|
||||||
|
uint16 frameCount = sourceS->readUint16LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < frameCount; i++) {
|
||||||
|
|
||||||
|
sourceS->seek(26 + i * 4);
|
||||||
|
|
||||||
|
uint32 frameOffs = sourceS->readUint32LE();
|
||||||
|
|
||||||
|
sourceS->seek(frameOffs);
|
||||||
|
sourceS->readUint32LE();
|
||||||
|
sourceS->readUint32LE();
|
||||||
|
|
||||||
|
uint16 frameWidth = sourceS->readUint16LE();
|
||||||
|
uint16 frameHeight = sourceS->readUint16LE();
|
||||||
|
uint16 cmdOffs = sourceS->readUint16LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
uint16 pixelOffs = sourceS->readUint16LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
uint16 maskOffs = sourceS->readUint16LE();
|
||||||
|
sourceS->readUint16LE();
|
||||||
|
uint16 lineSize = sourceS->readUint16LE();
|
||||||
|
|
||||||
|
Graphics::Surface *frame = new Graphics::Surface();
|
||||||
|
frame->create(frameWidth, frameHeight, 1);
|
||||||
|
|
||||||
|
decompressImage(source + frameOffs, *frame, cmdOffs, pixelOffs, maskOffs, lineSize, _flags & 1);
|
||||||
|
|
||||||
|
_frames.push_back(frame);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delete sourceS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SoundResource */
|
||||||
|
|
||||||
|
SoundResource::SoundResource() : _soundSize(0), _soundData(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundResource::~SoundResource() {
|
||||||
|
if (_soundData)
|
||||||
|
delete[] _soundData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundResource::load(byte *source, int size) {
|
||||||
|
|
||||||
|
uint16 chunkCount = READ_LE_UINT16(source + 8);
|
||||||
|
uint16 chunkSize = READ_LE_UINT16(source + 12);
|
||||||
|
|
||||||
|
_soundSize = chunkCount * chunkSize;
|
||||||
|
_soundData = new byte[_soundSize];
|
||||||
|
|
||||||
|
decompressSound(source + 14, _soundData, chunkSize, chunkCount);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::AudioStream *SoundResource::getAudioStream() {
|
||||||
|
return Audio::makeLinearInputStream(_soundData, _soundSize, 22050, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MenuResource */
|
||||||
|
|
||||||
|
MenuResource::MenuResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuResource::~MenuResource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuResource::load(byte *source, int size) {
|
||||||
|
_strings.clear();
|
||||||
|
Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);
|
||||||
|
sourceS->skip(4); // skip "MENU"
|
||||||
|
uint16 count = sourceS->readUint16LE();
|
||||||
|
for (uint16 i = 0; i < count; i++) {
|
||||||
|
uint16 offs = sourceS->readUint16LE();
|
||||||
|
const char *string = (const char*)(source + offs);
|
||||||
|
_strings.push_back(string);
|
||||||
|
debug(2, "%02d: %s\n", i, string);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
delete sourceS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ProjectReader */
|
||||||
|
|
||||||
|
ProjectReader::ProjectReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectReader::~ProjectReader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::open(const char *filename) {
|
||||||
|
|
||||||
|
_fd = new Common::File();
|
||||||
|
_fd->open(filename);
|
||||||
|
|
||||||
|
_fd->skip(0x18); // skip header for now
|
||||||
|
|
||||||
|
uint16 indexCount = _fd->readUint16LE();
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < indexCount; i++) {
|
||||||
|
|
||||||
|
uint32 resType = _fd->readUint32BE();
|
||||||
|
uint32 indexOffs = _fd->readUint32LE();
|
||||||
|
_fd->readUint32LE();
|
||||||
|
_fd->readUint32LE();
|
||||||
|
_fd->readUint32LE();
|
||||||
|
_fd->readUint16LE();
|
||||||
|
_fd->readUint16LE();
|
||||||
|
|
||||||
|
// We don't need ARCH, FREE and OMNI resources
|
||||||
|
if (resType == kResARCH || resType == kResFREE || resType == kResOMNI)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//debug(2, "resType = %08X; indexOffs = %d\n", resType, indexOffs);
|
||||||
|
|
||||||
|
uint32 oldOffs = _fd->pos();
|
||||||
|
|
||||||
|
ResourceSlots *resSlots = new ResourceSlots();
|
||||||
|
_fd->seek(indexOffs);
|
||||||
|
loadIndex(resSlots);
|
||||||
|
_resSlots[resType] = resSlots;
|
||||||
|
|
||||||
|
_fd->seek(oldOffs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_cacheCount = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PictureResource *ProjectReader::getPicture(int index) {
|
||||||
|
return createResource<PictureResource>(kResFLEX, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationResource *ProjectReader::getAnimation(int index) {
|
||||||
|
return createResource<AnimationResource>(kResANIM, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundResource *ProjectReader::getSound(int index) {
|
||||||
|
return createResource<SoundResource>(kResSNDS, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuResource *ProjectReader::getMenu(int index) {
|
||||||
|
return createResource<MenuResource>(kResMENU, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::loadIndex(ResourceSlots *slots) {
|
||||||
|
_fd->readUint32LE(); // skip INDX
|
||||||
|
_fd->readUint32LE(); // skip index size
|
||||||
|
_fd->readUint32LE(); // skip unknown
|
||||||
|
_fd->readUint32LE(); // skip res type
|
||||||
|
uint16 count = _fd->readUint16LE();
|
||||||
|
_fd->readUint16LE(); // skip unknown count
|
||||||
|
_fd->readUint16LE(); // skip unknown count
|
||||||
|
for (uint16 i = 0; i < count; i++) {
|
||||||
|
uint32 offs = _fd->readUint32LE();
|
||||||
|
uint32 size = _fd->readUint32LE();
|
||||||
|
slots->push_back(ResourceSlot(offs, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::freeResource(Resource *resource) {
|
||||||
|
tossResourceFromCache(resource->slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectReader::loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size) {
|
||||||
|
if (slot && slot->size > 0) {
|
||||||
|
size = slot->size - 62;
|
||||||
|
buffer = new byte[size];
|
||||||
|
debug(2, "ProjectReader::loadResource() %08X\n", slot->offs + 62); fflush(stdout);
|
||||||
|
_fd->seek(slot->offs + 62);
|
||||||
|
_fd->read(buffer, size);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceSlot *ProjectReader::getResourceSlot(uint32 resType, uint index) {
|
||||||
|
ResourceSlots *slots = _resSlots[resType];
|
||||||
|
if (index >= 1 && index < slots->size()) {
|
||||||
|
ResourceSlot *slot = &slots->operator[](index);
|
||||||
|
return slot;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource *ProjectReader::getResourceFromCache(ResourceSlot *slot) {
|
||||||
|
if (slot->res)
|
||||||
|
slot->refCount++;
|
||||||
|
return slot->res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::addResourceToCache(ResourceSlot *slot, Resource *res) {
|
||||||
|
if (_cacheCount >= kMaxResourceCacheCount) {
|
||||||
|
purgeCache();
|
||||||
|
}
|
||||||
|
slot->res = res;
|
||||||
|
slot->refCount = 0;
|
||||||
|
_cacheCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::tossResourceFromCache(ResourceSlot *slot) {
|
||||||
|
if (slot->res) {
|
||||||
|
slot->refCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectReader::purgeCache() {
|
||||||
|
printf("ProjectReader::purgeCache()\n");
|
||||||
|
for (ResMap::const_iterator resTypeIter = _resSlots.begin(); resTypeIter != _resSlots.end(); ++resTypeIter) {
|
||||||
|
ResourceSlots *slots = (*resTypeIter)._value;
|
||||||
|
for (ResourceSlots::iterator slotIter = slots->begin(); slotIter != slots->end(); ++slotIter) {
|
||||||
|
ResourceSlot *slot = &(*slotIter);
|
||||||
|
if (slot->refCount <= 0 && slot->res) {
|
||||||
|
delete slot->res;
|
||||||
|
slot->res = NULL;
|
||||||
|
slot->refCount = 0;
|
||||||
|
_cacheCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
178
engines/made/resource.h
Normal file
178
engines/made/resource.h
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_RESOURCE_H
|
||||||
|
#define MADE_RESOURCE_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
#include "common/hashmap.h"
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
#include "sound/audiostream.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
const int kMaxResourceCacheCount = 100;
|
||||||
|
|
||||||
|
enum ResourceType {
|
||||||
|
kResARCH = MKID_BE('ARCH'),
|
||||||
|
kResFREE = MKID_BE('FREE'),
|
||||||
|
kResOMNI = MKID_BE('OMNI'),
|
||||||
|
kResFLEX = MKID_BE('FLEX'),
|
||||||
|
kResSNDS = MKID_BE('SNDS'),
|
||||||
|
kResANIM = MKID_BE('ANIM'),
|
||||||
|
kResMENU = MKID_BE('MENU')
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ResourceSlot;
|
||||||
|
|
||||||
|
class Resource {
|
||||||
|
public:
|
||||||
|
ResourceSlot *slot;
|
||||||
|
virtual ~Resource();
|
||||||
|
virtual void load(byte *buffer, int size) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PictureResource : public Resource {
|
||||||
|
public:
|
||||||
|
PictureResource();
|
||||||
|
~PictureResource();
|
||||||
|
void load(byte *source, int size);
|
||||||
|
Graphics::Surface *getPicture() const { return _picture; }
|
||||||
|
byte *getPalette() const { return _palette; }
|
||||||
|
protected:
|
||||||
|
Graphics::Surface *_picture;
|
||||||
|
byte *_palette;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AnimationResource : public Resource {
|
||||||
|
public:
|
||||||
|
AnimationResource();
|
||||||
|
~AnimationResource();
|
||||||
|
void load(byte *source, int size);
|
||||||
|
int getCount() const { return _frames.size(); }
|
||||||
|
Graphics::Surface *getFrame(int index) const { return _frames[index]; }
|
||||||
|
uint16 getFlags() const { return _flags; }
|
||||||
|
int16 getWidth() const { return _width; }
|
||||||
|
int16 getHeight() const { return _height; }
|
||||||
|
protected:
|
||||||
|
Common::Array<Graphics::Surface*> _frames;
|
||||||
|
uint16 _flags;
|
||||||
|
int16 _width, _height;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundResource : public Resource {
|
||||||
|
public:
|
||||||
|
SoundResource();
|
||||||
|
~SoundResource();
|
||||||
|
void load(byte *source, int size);
|
||||||
|
Audio::AudioStream *getAudioStream();
|
||||||
|
protected:
|
||||||
|
byte *_soundData;
|
||||||
|
int _soundSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MenuResource : public Resource {
|
||||||
|
public:
|
||||||
|
MenuResource();
|
||||||
|
~MenuResource();
|
||||||
|
void load(byte *source, int size);
|
||||||
|
int getCount() const { return _strings.size(); }
|
||||||
|
Common::String getString(int index) const { return _strings[index]; }
|
||||||
|
protected:
|
||||||
|
Common::Array<Common::String> _strings;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ResourceSlot {
|
||||||
|
uint32 offs;
|
||||||
|
uint32 size;
|
||||||
|
Resource *res;
|
||||||
|
int refCount;
|
||||||
|
ResourceSlot() : offs(0), size(0), res(NULL), refCount(0) {
|
||||||
|
}
|
||||||
|
ResourceSlot(uint32 roffs, uint32 rsize) : offs(roffs), size(rsize), res(NULL), refCount(0) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProjectReader {
|
||||||
|
public:
|
||||||
|
|
||||||
|
ProjectReader();
|
||||||
|
~ProjectReader();
|
||||||
|
|
||||||
|
void open(const char *filename);
|
||||||
|
|
||||||
|
PictureResource *getPicture(int index);
|
||||||
|
AnimationResource *getAnimation(int index);
|
||||||
|
SoundResource *getSound(int index);
|
||||||
|
MenuResource *getMenu(int index);
|
||||||
|
|
||||||
|
void freeResource(Resource *resource);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Common::File *_fd;
|
||||||
|
|
||||||
|
typedef Common::Array<ResourceSlot> ResourceSlots;
|
||||||
|
typedef Common::HashMap<uint32, ResourceSlots*> ResMap;
|
||||||
|
|
||||||
|
ResMap _resSlots;
|
||||||
|
int _cacheCount;
|
||||||
|
|
||||||
|
void loadIndex(ResourceSlots *slots);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *createResource(uint32 resType, int index) {
|
||||||
|
ResourceSlot *slot = getResourceSlot(resType, index);
|
||||||
|
if (!slot)
|
||||||
|
return NULL;
|
||||||
|
T *res = (T*)getResourceFromCache(slot);
|
||||||
|
if (!res) {
|
||||||
|
byte *buffer;
|
||||||
|
uint32 size;
|
||||||
|
if (loadResource(slot, buffer, size)) {
|
||||||
|
res = new T();
|
||||||
|
res->slot = slot;
|
||||||
|
res->load(buffer, size);
|
||||||
|
addResourceToCache(slot, res);
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loadResource(ResourceSlot *slot, byte *&buffer, uint32 &size);
|
||||||
|
ResourceSlot *getResourceSlot(uint32 resType, uint index);
|
||||||
|
Resource *getResourceFromCache(ResourceSlot *slot);
|
||||||
|
void addResourceToCache(ResourceSlot *slot, Resource *res);
|
||||||
|
void tossResourceFromCache(ResourceSlot *slot);
|
||||||
|
void purgeCache();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
459
engines/made/screen.cpp
Normal file
459
engines/made/screen.cpp
Normal file
|
@ -0,0 +1,459 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "made/made.h"
|
||||||
|
#include "made/screen.h"
|
||||||
|
#include "made/resource.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
Screen::Screen(MadeEngine *vm) : _vm(vm) {
|
||||||
|
|
||||||
|
_screen1 = new Graphics::Surface();
|
||||||
|
_screen1->create(320, 200, 1);
|
||||||
|
_clipInfo1.x = 0;
|
||||||
|
_clipInfo1.y = 0;
|
||||||
|
_clipInfo1.w = 320;
|
||||||
|
_clipInfo1.h = 200;
|
||||||
|
_clipInfo1.destSurface = _screen1;
|
||||||
|
|
||||||
|
_screen2 = new Graphics::Surface();
|
||||||
|
_screen2->create(320, 200, 1);
|
||||||
|
_clipInfo2.x = 0;
|
||||||
|
_clipInfo2.y = 0;
|
||||||
|
_clipInfo2.w = 320;
|
||||||
|
_clipInfo2.h = 200;
|
||||||
|
_clipInfo2.destSurface = _screen2;
|
||||||
|
|
||||||
|
_clipArea.destSurface = _screen2;
|
||||||
|
|
||||||
|
_excludeClipAreaEnabled[0] = false;
|
||||||
|
_excludeClipAreaEnabled[1] = false;
|
||||||
|
_excludeClipAreaEnabled[2] = false;
|
||||||
|
_excludeClipAreaEnabled[3] = false;
|
||||||
|
|
||||||
|
clearChannels();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen::~Screen() {
|
||||||
|
delete _screen1;
|
||||||
|
delete _screen2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::clearScreen() {
|
||||||
|
_screen1->fillRect(Common::Rect(0, 0, 320, 200), 0);
|
||||||
|
_screen2->fillRect(Common::Rect(0, 0, 320, 200), 0);
|
||||||
|
//_vm->_system->clearScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawSurface(Graphics::Surface *source, int x, int y) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::setPalette(byte *palette, int start, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::updateChannel(uint16 channelIndex) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::deleteChannel(uint16 channelIndex) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100)
|
||||||
|
return;
|
||||||
|
_channels[channelIndex - 1].type = 0;
|
||||||
|
_channels[channelIndex - 1].state = 0;
|
||||||
|
_channels[channelIndex - 1].index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Screen::getChannelType(uint16 channelIndex) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100)
|
||||||
|
return -1;
|
||||||
|
return _channels[channelIndex - 1].type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Screen::getChannelState(uint16 channelIndex) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100)
|
||||||
|
return -1;
|
||||||
|
return _channels[channelIndex - 1].state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::setChannelState(uint16 channelIndex, int16 state) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100 || _channels[channelIndex - 1].type == 0)
|
||||||
|
return;
|
||||||
|
_channels[channelIndex - 1].state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::setChannelLocation(uint16 channelIndex, int16 x, int16 y) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100 || _channels[channelIndex - 1].type == 0)
|
||||||
|
return 0;
|
||||||
|
_channels[channelIndex - 1].x = x;
|
||||||
|
_channels[channelIndex - 1].y = y;
|
||||||
|
return updateChannel(channelIndex - 1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::setChannelContent(uint16 channelIndex, uint16 index) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100 || _channels[channelIndex - 1].type == 0)
|
||||||
|
return 0;
|
||||||
|
//debug(2, "setChannelContent(%d, %04X)\n", channelIndex, index); fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
_channels[channelIndex - 1].index = index;
|
||||||
|
return updateChannel(channelIndex - 1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawSpriteChannels(const ClipInfo &clipInfo, int16 includeStateMask, int16 excludeStateMask) {
|
||||||
|
|
||||||
|
_excludeClipArea[0].destSurface = clipInfo.destSurface;
|
||||||
|
_excludeClipArea[1].destSurface = clipInfo.destSurface;
|
||||||
|
_excludeClipArea[2].destSurface = clipInfo.destSurface;
|
||||||
|
_excludeClipArea[3].destSurface = clipInfo.destSurface;
|
||||||
|
_clipArea.destSurface = clipInfo.destSurface;
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < _channelsUsedCount; i++) {
|
||||||
|
|
||||||
|
debug(2, "drawSpriteChannels() i = %d\n", i);
|
||||||
|
|
||||||
|
if (((_channels[i].state & includeStateMask) == includeStateMask) && (_channels[i].state & excludeStateMask) == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16 flag1 = _channels[i].state & 0x10;
|
||||||
|
uint16 flag2 = _channels[i].state & 0x20;
|
||||||
|
|
||||||
|
debug(2, "drawSpriteChannels() type = %d; index = %04X\n", _channels[i].type, _channels[i].index);
|
||||||
|
|
||||||
|
switch (_channels[i].type) {
|
||||||
|
|
||||||
|
case 1: // drawFlex
|
||||||
|
if (_channels[i].state & 4) {
|
||||||
|
drawFlex(_channels[i].index, _channels[i].x, _channels[i].y, flag1, flag2, _clipArea);
|
||||||
|
} else if (_channels[i].state & 8) {
|
||||||
|
for (int excludeIndex = 0; excludeIndex < 4; excludeIndex++) {
|
||||||
|
if (_excludeClipAreaEnabled[excludeIndex]) {
|
||||||
|
drawFlex(_channels[i].index, _channels[i].x, _channels[i].y, flag1, flag2, _excludeClipArea[excludeIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drawFlex(_channels[i].index, _channels[i].x, _channels[i].y, flag1, flag2, clipInfo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // drawObjectText
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // drawAnimFrame
|
||||||
|
if (_channels[i].state & 4) {
|
||||||
|
drawAnimFrame(_channels[i].index, _channels[i].x, _channels[i].y, _channels[i].frameNum, flag1, flag2, _clipArea);
|
||||||
|
} else if (_channels[i].state & 8) {
|
||||||
|
for (int excludeIndex = 0; excludeIndex < 4; excludeIndex++) {
|
||||||
|
if (_excludeClipAreaEnabled[excludeIndex]) {
|
||||||
|
drawAnimFrame(_channels[i].index, _channels[i].x, _channels[i].y, _channels[i].frameNum, flag1, flag2, _excludeClipArea[excludeIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drawAnimFrame(_channels[i].index, _channels[i].x, _channels[i].y, _channels[i].frameNum, flag1, flag2, clipInfo);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: // drawMenuText
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::updateSprites() {
|
||||||
|
|
||||||
|
// TODO: This needs some more work, I don't use dirty rectangles for now
|
||||||
|
|
||||||
|
memcpy(_screen2->pixels, _screen1->pixels, 64000);
|
||||||
|
|
||||||
|
//drawSpriteChannels(_clipInfo1, 3, 0x40);//CHECKME
|
||||||
|
|
||||||
|
drawSpriteChannels(_clipInfo1, 3, 0);//CHECKME
|
||||||
|
drawSpriteChannels(_clipInfo2, 1, 2);//CHECKME
|
||||||
|
|
||||||
|
_vm->_system->copyRectToScreen((const byte*)_screen2->pixels, _screen2->pitch, 0, 0, _screen2->w, _screen2->h);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::clearChannels() {
|
||||||
|
for (uint16 i = 0; i < ARRAYSIZE(_channels); i++) {
|
||||||
|
_channels[i].type = 0;
|
||||||
|
_channels[i].index = 0;
|
||||||
|
}
|
||||||
|
_channelsUsedCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::drawFlex(uint16 flexIndex, int16 x, int16 y, uint16 flag1, uint16 flag2, const ClipInfo &clipInfo) {
|
||||||
|
|
||||||
|
if (flexIndex == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(flexIndex);
|
||||||
|
Graphics::Surface *sourceSurface = flex->getPicture();
|
||||||
|
byte *source = (byte*)sourceSurface->getBasePtr(0, 0);
|
||||||
|
byte *dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
|
||||||
|
|
||||||
|
|
||||||
|
if (x + sourceSurface->w > clipInfo.destSurface->w || y + sourceSurface->h > clipInfo.destSurface->h) {
|
||||||
|
debug(2, "CLIPPING PROBLEM: x = %d; y = %d; w = %d; h = %d; x+w = %d; y+h = %d\n",
|
||||||
|
x, y, sourceSurface->w, sourceSurface->h, x + sourceSurface->w, y + sourceSurface->h);
|
||||||
|
//fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int16 yc = 0; yc < sourceSurface->h; yc++) {
|
||||||
|
for (int16 xc = 0; xc < sourceSurface->w; xc++) {
|
||||||
|
if (source[xc])
|
||||||
|
dest[xc] = source[xc];
|
||||||
|
}
|
||||||
|
source += sourceSurface->pitch;
|
||||||
|
dest += clipInfo.destSurface->pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Palette stuff; palette should be set in showPage
|
||||||
|
byte *pal = flex->getPalette();
|
||||||
|
if (pal) {
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
_palette[i * 4 + 0] = pal[i * 3 + 0];
|
||||||
|
_palette[i * 4 + 1] = pal[i * 3 + 1];
|
||||||
|
_palette[i * 4 + 2] = pal[i * 3 + 2];
|
||||||
|
}
|
||||||
|
_vm->_system->setPalette(_palette, 0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::drawAnimFrame(uint16 animIndex, int16 x, int16 y, int16 frameNum, uint16 flag1, uint16 flag2, const ClipInfo &clipInfo) {
|
||||||
|
|
||||||
|
AnimationResource *anim = _vm->_res->getAnimation(animIndex);
|
||||||
|
Graphics::Surface *sourceSurface = anim->getFrame(frameNum);
|
||||||
|
byte *source = (byte*)sourceSurface->getBasePtr(0, 0);
|
||||||
|
byte *dest = (byte*)clipInfo.destSurface->getBasePtr(x, y);
|
||||||
|
|
||||||
|
for (int16 yc = 0; yc < sourceSurface->h; yc++) {
|
||||||
|
for (int16 xc = 0; xc < sourceSurface->w; xc++) {
|
||||||
|
if (source[xc])
|
||||||
|
dest[xc] = source[xc];
|
||||||
|
}
|
||||||
|
source += sourceSurface->pitch;
|
||||||
|
dest += clipInfo.destSurface->pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
_vm->_res->freeResource(anim);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::drawPic(uint16 index, int16 x, int16 y, uint16 flag1, uint16 flag2) {
|
||||||
|
|
||||||
|
//DEBUG
|
||||||
|
if (y > 200) y = 0;
|
||||||
|
|
||||||
|
drawFlex(index, x, y, flag1, flag2, _clipInfo1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::drawAnimPic(uint16 animIndex, int16 x, int16 y, int16 frameNum, uint16 flag1, uint16 flag2) {
|
||||||
|
drawAnimFrame(animIndex, x, y, frameNum, flag1, flag2, _clipInfo1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::addSprite(uint16 spriteIndex) {
|
||||||
|
bool oldScreenLock = _screenLock;
|
||||||
|
drawFlex(spriteIndex, 0, 0, 0, 0, _clipInfo1);
|
||||||
|
_screenLock = oldScreenLock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::drawSprite(uint16 flexIndex, int16 x, int16 y) {
|
||||||
|
return placeSprite(_channelsUsedCount + 1, flexIndex, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::placeSprite(uint16 channelIndex, uint16 flexIndex, int16 x, int16 y) {
|
||||||
|
|
||||||
|
debug(2, "placeSprite(%d, %04X, %d, %d)\n", channelIndex, flexIndex, x, y); fflush(stdout);
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
channelIndex--;
|
||||||
|
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(flexIndex);
|
||||||
|
|
||||||
|
if (flex) {
|
||||||
|
Graphics::Surface *surf = flex->getPicture();
|
||||||
|
|
||||||
|
int16 state = 1;
|
||||||
|
int16 x1, y1, x2, y2;
|
||||||
|
|
||||||
|
x1 = x;
|
||||||
|
y1 = y;
|
||||||
|
x2 = x + surf->w + 1;
|
||||||
|
y2 = y + surf->h + 1;
|
||||||
|
//TODO: clipRect(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
if (_ground == 0)
|
||||||
|
state |= 2;
|
||||||
|
if (_clip != 0)
|
||||||
|
state |= 4;
|
||||||
|
if (_exclude != 0)
|
||||||
|
state |= 8;
|
||||||
|
|
||||||
|
_channels[channelIndex].state = state;
|
||||||
|
_channels[channelIndex].type = 1;
|
||||||
|
_channels[channelIndex].index = flexIndex;
|
||||||
|
_channels[channelIndex].x = x;
|
||||||
|
_channels[channelIndex].y = y;
|
||||||
|
_channels[channelIndex].x1 = x1;
|
||||||
|
_channels[channelIndex].y1 = y1;
|
||||||
|
_channels[channelIndex].x2 = x2;
|
||||||
|
_channels[channelIndex].y2 = y2;
|
||||||
|
_channels[channelIndex].area = (x2 - x2) * (y2 - y1);
|
||||||
|
|
||||||
|
if (_channelsUsedCount <= channelIndex)
|
||||||
|
_channelsUsedCount = channelIndex + 1;
|
||||||
|
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
} else {
|
||||||
|
_channels[channelIndex].type = 0;
|
||||||
|
_channels[channelIndex].state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelIndex + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Screen::placeAnim(uint16 channelIndex, uint16 animIndex, int16 x, int16 y, int16 frameNum) {
|
||||||
|
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
channelIndex--;
|
||||||
|
|
||||||
|
AnimationResource *anim = _vm->_res->getAnimation(animIndex);
|
||||||
|
|
||||||
|
if (anim) {
|
||||||
|
|
||||||
|
int16 state = 1;
|
||||||
|
int16 x1, y1, x2, y2;
|
||||||
|
|
||||||
|
x1 = x;
|
||||||
|
y1 = y;
|
||||||
|
x2 = x + anim->getWidth();
|
||||||
|
y2 = y + anim->getHeight();
|
||||||
|
//TODO: clipRect(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
if (anim->getFlags() == 1 || _ground == 0)
|
||||||
|
state |= 2;
|
||||||
|
if (_clip != 0)
|
||||||
|
state |= 4;
|
||||||
|
if (_exclude != 0)
|
||||||
|
state |= 8;
|
||||||
|
|
||||||
|
_channels[channelIndex].state = state;
|
||||||
|
_channels[channelIndex].type = 3;
|
||||||
|
_channels[channelIndex].index = animIndex;
|
||||||
|
_channels[channelIndex].frameNum = frameNum;
|
||||||
|
_channels[channelIndex].needRefresh = 1;
|
||||||
|
_channels[channelIndex].x = x;
|
||||||
|
_channels[channelIndex].y = y;
|
||||||
|
_channels[channelIndex].x1 = x1;
|
||||||
|
_channels[channelIndex].y1 = y1;
|
||||||
|
_channels[channelIndex].x2 = x2;
|
||||||
|
_channels[channelIndex].y2 = y2;
|
||||||
|
_channels[channelIndex].area = (x2 - x2) * (y2 - y1);
|
||||||
|
|
||||||
|
if (_channelsUsedCount <= channelIndex)
|
||||||
|
_channelsUsedCount = channelIndex + 1;
|
||||||
|
|
||||||
|
_vm->_res->freeResource(anim);
|
||||||
|
} else {
|
||||||
|
_channels[channelIndex].type = 0;
|
||||||
|
_channels[channelIndex].state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return channelIndex + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Screen::setAnimFrame(uint16 channelIndex, int16 frameNum) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100 || _channels[channelIndex - 1].type == 0)
|
||||||
|
return 0;
|
||||||
|
channelIndex--;
|
||||||
|
_channels[channelIndex].frameNum = frameNum;
|
||||||
|
_channels[channelIndex].needRefresh = 1;
|
||||||
|
return updateChannel(channelIndex) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Screen::getAnimFrame(uint16 channelIndex) {
|
||||||
|
if (channelIndex < 1 || channelIndex >= 100 || _channels[channelIndex - 1].type == 0)
|
||||||
|
return -1;
|
||||||
|
return _channels[channelIndex - 1].frameNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Screen::getAnimFrameCount(uint16 animIndex) {
|
||||||
|
int16 frameCount = 0;
|
||||||
|
AnimationResource *anim = _vm->_res->getAnimation(animIndex);
|
||||||
|
if (anim) {
|
||||||
|
frameCount = anim->getCount();
|
||||||
|
_vm->_res->freeResource(anim);
|
||||||
|
}
|
||||||
|
return frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16 Screen::placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::show() {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
memcpy(_screen2->pixels, _screen1->pixels, 64000);
|
||||||
|
|
||||||
|
drawSpriteChannels(_clipInfo2, 0, 0);
|
||||||
|
|
||||||
|
//drawSpriteChannels(_clipInfo2, 3, 0);//CHECKME
|
||||||
|
//drawSpriteChannels(_clipInfo2, 1, 2);//CHECKME
|
||||||
|
|
||||||
|
//_vm->_system->copyRectToScreen((const byte*)_screen1->pixels, _screen1->pitch, 0, 0, _screen1->w, _screen1->h);
|
||||||
|
_vm->_system->copyRectToScreen((const byte*)_screen2->pixels, _screen2->pitch, 0, 0, _screen2->w, _screen2->h);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
123
engines/made/screen.h
Normal file
123
engines/made/screen.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_SCREEN_H
|
||||||
|
#define MADE_SCREEN_H
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
struct SpriteChannel {
|
||||||
|
int16 type;
|
||||||
|
int16 state;
|
||||||
|
int16 needRefresh;
|
||||||
|
uint16 index;
|
||||||
|
int16 x, y;
|
||||||
|
int16 x1, y1, x2, y2;
|
||||||
|
uint32 area;
|
||||||
|
uint16 fontNum;
|
||||||
|
int16 textColor, outlineColor;
|
||||||
|
int16 frameNum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ClipInfo {
|
||||||
|
uint16 x, y, w, h;
|
||||||
|
Graphics::Surface *destSurface;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MadeEngine;
|
||||||
|
|
||||||
|
class Screen {
|
||||||
|
public:
|
||||||
|
Screen(MadeEngine *vm);
|
||||||
|
~Screen();
|
||||||
|
|
||||||
|
void clearScreen();
|
||||||
|
|
||||||
|
void drawSurface(Graphics::Surface *source, int x, int y);
|
||||||
|
void setPalette(byte *palette, int start, int count);
|
||||||
|
|
||||||
|
uint16 updateChannel(uint16 channelIndex);
|
||||||
|
void deleteChannel(uint16 channelIndex);
|
||||||
|
int16 getChannelType(uint16 channelIndex);
|
||||||
|
int16 getChannelState(uint16 channelIndex);
|
||||||
|
void setChannelState(uint16 channelIndex, int16 state);
|
||||||
|
uint16 setChannelLocation(uint16 channelIndex, int16 x, int16 y);
|
||||||
|
uint16 setChannelContent(uint16 channelIndex, uint16 index);
|
||||||
|
void drawSpriteChannels(const ClipInfo &clipInfo, int16 includeStateMask, int16 excludeStateMask);
|
||||||
|
void updateSprites();
|
||||||
|
void clearChannels();
|
||||||
|
|
||||||
|
uint16 drawFlex(uint16 flexIndex, int16 x, int16 y, uint16 flag1, uint16 flag2, const ClipInfo &clipInfo);
|
||||||
|
void drawAnimFrame(uint16 animIndex, int16 x, int16 y, int16 frameNum, uint16 flag1, uint16 flag2, const ClipInfo &clipInfo);
|
||||||
|
|
||||||
|
uint16 drawPic(uint16 index, int16 x, int16 y, uint16 flag1, uint16 flag2);
|
||||||
|
uint16 drawAnimPic(uint16 animIndex, int16 x, int16 y, int16 frameNum, uint16 flag1, uint16 flag2);
|
||||||
|
|
||||||
|
uint16 addSprite(uint16 spriteIndex);
|
||||||
|
|
||||||
|
uint16 drawSprite(uint16 flexIndex, int16 x, int16 y);
|
||||||
|
uint16 placeSprite(uint16 channelIndex, uint16 flexIndex, int16 x, int16 y);
|
||||||
|
|
||||||
|
uint16 placeAnim(uint16 channelIndex, uint16 animIndex, int16 x, int16 y, int16 frameNum);
|
||||||
|
int16 setAnimFrame(uint16 channelIndex, int16 frameNum);
|
||||||
|
int16 getAnimFrame(uint16 channelIndex);
|
||||||
|
// TODO: Move to script function
|
||||||
|
int16 getAnimFrameCount(uint16 animIndex);
|
||||||
|
|
||||||
|
uint16 placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor);
|
||||||
|
|
||||||
|
void show();
|
||||||
|
|
||||||
|
void setClip(uint16 clip);
|
||||||
|
void setExclude(uint16 exclude);
|
||||||
|
void setGround(uint16 ground);
|
||||||
|
|
||||||
|
byte _palette[256 * 4];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MadeEngine *_vm;
|
||||||
|
|
||||||
|
bool _screenLock;
|
||||||
|
|
||||||
|
uint16 _clip, _exclude, _ground;
|
||||||
|
|
||||||
|
Graphics::Surface *_screen1, *_screen2;
|
||||||
|
ClipInfo _clipArea, _clipInfo1, _clipInfo2;
|
||||||
|
|
||||||
|
ClipInfo _excludeClipArea[4];
|
||||||
|
bool _excludeClipAreaEnabled[4];
|
||||||
|
|
||||||
|
uint16 _channelsUsedCount;
|
||||||
|
SpriteChannel _channels[100];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
738
engines/made/script.cpp
Normal file
738
engines/made/script.cpp
Normal file
|
@ -0,0 +1,738 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "made/made.h"
|
||||||
|
#include "made/script.h"
|
||||||
|
#include "made/database.h"
|
||||||
|
#include "made/scriptfuncs.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
|
||||||
|
const char *extendFuncNames[] = {
|
||||||
|
"SYSTEM",
|
||||||
|
"INITGRAF",
|
||||||
|
"RESTOREGRAF",
|
||||||
|
"DRAWPIC",
|
||||||
|
"CLS",
|
||||||
|
"SHOWPAGE",
|
||||||
|
"EVENT",
|
||||||
|
"EVENTX",
|
||||||
|
"EVENTY",
|
||||||
|
"EVENTKEY",
|
||||||
|
"VISUALFX",
|
||||||
|
"PLAYSND",
|
||||||
|
"PLAYMUS",
|
||||||
|
"STOPMUS",
|
||||||
|
"ISMUS",
|
||||||
|
"TEXTPOS",
|
||||||
|
"FLASH",
|
||||||
|
"PLAYNOTE",
|
||||||
|
"STOPNOTE",
|
||||||
|
"PLAYTELE",
|
||||||
|
"STOPTELE",
|
||||||
|
"HIDECURS",
|
||||||
|
"SHOWCURS",
|
||||||
|
"MUSICBEAT",
|
||||||
|
"SCREENLOCK",
|
||||||
|
"ADDSPRITE",
|
||||||
|
"FREEANIM",
|
||||||
|
"DRAWSPRITE",
|
||||||
|
"ERASESPRITES",
|
||||||
|
"UPDATESPRITES",
|
||||||
|
"GETTIMER",
|
||||||
|
"SETTIMER",
|
||||||
|
"RESETTIMER",
|
||||||
|
"ALLOCTIMER",
|
||||||
|
"FREETIMER",
|
||||||
|
"PALETTELOCK",
|
||||||
|
"FONT",
|
||||||
|
"DRAWTEXT",
|
||||||
|
"HOMETEXT",
|
||||||
|
"TEXTRECT",
|
||||||
|
"TEXTXY",
|
||||||
|
"DROPSHADOW",
|
||||||
|
"TEXTCOLOR",
|
||||||
|
"OUTLINE",
|
||||||
|
"LOADCURSOR",
|
||||||
|
"SETGROUND",
|
||||||
|
"RESTEXT",
|
||||||
|
"CLIPAREA",
|
||||||
|
"SETCLIP",
|
||||||
|
"ISSND",
|
||||||
|
"STOPSND",
|
||||||
|
"PLAYVOICE",
|
||||||
|
"CDPLAY",
|
||||||
|
"STOPCD",
|
||||||
|
"CDSTATUS",
|
||||||
|
"CDTIME",
|
||||||
|
"CDPLAYSEG",
|
||||||
|
"PRINTF",
|
||||||
|
"MONOCLS",
|
||||||
|
"SNDENERGY",
|
||||||
|
"CLEARTEXT",
|
||||||
|
"ANIMTEXT",
|
||||||
|
"TEXTWIDTH",
|
||||||
|
"PLAYMOVIE",
|
||||||
|
"LOADSND",
|
||||||
|
"LOADMUS",
|
||||||
|
"LOADPIC",
|
||||||
|
"MUSICVOL",
|
||||||
|
"RESTARTEVENTS",
|
||||||
|
"PLACESPRITE",
|
||||||
|
"PLACETEXT",
|
||||||
|
"DELETECHANNEL",
|
||||||
|
"CHANNELTYPE",
|
||||||
|
"SETSTATE",
|
||||||
|
"SETLOCATION",
|
||||||
|
"SETCONTENT",
|
||||||
|
"EXCLUDEAREA",
|
||||||
|
"SETEXCLUDE",
|
||||||
|
"GETSTATE",
|
||||||
|
"PLACEANIM",
|
||||||
|
"SETFRAME",
|
||||||
|
"GETFRAME",
|
||||||
|
"GETFRAMECOUNT",
|
||||||
|
"PICWIDTH",
|
||||||
|
"PICHEIGHT",
|
||||||
|
"SOUNDRATE",
|
||||||
|
"DRAWANIMPIC",
|
||||||
|
"LOADANIM",
|
||||||
|
"READTEXT",
|
||||||
|
"READMENU",
|
||||||
|
"DRAWMENU",
|
||||||
|
"MENUCOUNT",
|
||||||
|
"SAVEGAME",
|
||||||
|
"LOADGAME",
|
||||||
|
"GAMENAME",
|
||||||
|
"SHAKESCREEN",
|
||||||
|
"PLACEMENU",
|
||||||
|
"SETVOLUME",
|
||||||
|
"WHATSYNTH",
|
||||||
|
"SLOWSYSTEM"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ScriptStack */
|
||||||
|
|
||||||
|
ScriptStack::ScriptStack() {
|
||||||
|
for (int16 i = 0; i < kScriptStackSize; i++)
|
||||||
|
_stack[i] = 0;
|
||||||
|
_stackPos = kScriptStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptStack::~ScriptStack() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptStack::top() {
|
||||||
|
return _stack[_stackPos];
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptStack::pop() {
|
||||||
|
if (_stackPos == kScriptStackSize)
|
||||||
|
error("ScriptStack::pop() Stack underflow");
|
||||||
|
return _stack[_stackPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::push(int16 value) {
|
||||||
|
if (_stackPos == 0)
|
||||||
|
error("ScriptStack::push() Stack overflow");
|
||||||
|
_stack[--_stackPos] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::setTop(int16 value) {
|
||||||
|
_stack[_stackPos] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptStack::peek(int16 index) {
|
||||||
|
return _stack[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::poke(int16 index, int16 value) {
|
||||||
|
_stack[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::alloc(int16 count) {
|
||||||
|
_stackPos -= count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::free(int16 count) {
|
||||||
|
_stackPos += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptStack::setStackPos(int16 stackPtr) {
|
||||||
|
_stackPos = stackPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 *ScriptStack::getStackPtr() {
|
||||||
|
return &_stack[_stackPos];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ScriptInterpreter */
|
||||||
|
|
||||||
|
ScriptInterpreter::ScriptInterpreter(MadeEngine *vm) : _vm(vm) {
|
||||||
|
#define COMMAND(x) { &ScriptInterpreter::x, #x }
|
||||||
|
static CommandEntry commandProcs[] = {
|
||||||
|
/* 01 */
|
||||||
|
COMMAND(cmd_branchTrue),
|
||||||
|
COMMAND(cmd_branchFalse),
|
||||||
|
COMMAND(cmd_branch),
|
||||||
|
COMMAND(cmd_true),
|
||||||
|
/* 05 */
|
||||||
|
COMMAND(cmd_false),
|
||||||
|
COMMAND(cmd_push),
|
||||||
|
COMMAND(cmd_not),
|
||||||
|
COMMAND(cmd_add),
|
||||||
|
/* 09 */
|
||||||
|
COMMAND(cmd_sub),
|
||||||
|
COMMAND(cmd_mul),
|
||||||
|
COMMAND(cmd_div),
|
||||||
|
COMMAND(cmd_mod),
|
||||||
|
/* 13 */
|
||||||
|
COMMAND(cmd_band),
|
||||||
|
COMMAND(cmd_bor),
|
||||||
|
COMMAND(cmd_bnot),
|
||||||
|
COMMAND(cmd_lt),
|
||||||
|
/* 17 */
|
||||||
|
COMMAND(cmd_eq),
|
||||||
|
COMMAND(cmd_gt),
|
||||||
|
COMMAND(cmd_loadConstant),
|
||||||
|
COMMAND(cmd_loadVariable),
|
||||||
|
/* 21 */
|
||||||
|
COMMAND(cmd_getObjectProperty),
|
||||||
|
COMMAND(cmd_setObjectProperty),
|
||||||
|
COMMAND(cmd_set),
|
||||||
|
COMMAND(cmd_print),
|
||||||
|
/* 25 */
|
||||||
|
COMMAND(cmd_terpri),
|
||||||
|
COMMAND(cmd_printNumber),
|
||||||
|
COMMAND(cmd_vref),
|
||||||
|
COMMAND(cmd_vset),
|
||||||
|
/* 29 */
|
||||||
|
COMMAND(cmd_vsize),
|
||||||
|
COMMAND(cmd_exit),
|
||||||
|
COMMAND(cmd_return),
|
||||||
|
COMMAND(cmd_call),
|
||||||
|
/* 33 */
|
||||||
|
COMMAND(cmd_svar),
|
||||||
|
COMMAND(cmd_sset),
|
||||||
|
COMMAND(cmd_split),
|
||||||
|
COMMAND(cmd_snlit),
|
||||||
|
/* 37 */
|
||||||
|
COMMAND(cmd_yorn),
|
||||||
|
COMMAND(cmd_save),
|
||||||
|
COMMAND(cmd_restore),
|
||||||
|
COMMAND(cmd_arg),
|
||||||
|
/* 41 */
|
||||||
|
COMMAND(cmd_aset),
|
||||||
|
COMMAND(cmd_tmp),
|
||||||
|
COMMAND(cmd_tset),
|
||||||
|
COMMAND(cmd_tspace),
|
||||||
|
/* 45 */
|
||||||
|
COMMAND(cmd_class),
|
||||||
|
COMMAND(cmd_objectp),
|
||||||
|
COMMAND(cmd_vectorp),
|
||||||
|
COMMAND(cmd_restart),
|
||||||
|
/* 49 */
|
||||||
|
COMMAND(cmd_rand),
|
||||||
|
COMMAND(cmd_randomize),
|
||||||
|
COMMAND(cmd_send),
|
||||||
|
COMMAND(cmd_extend),
|
||||||
|
/* 53 */
|
||||||
|
COMMAND(cmd_catch),
|
||||||
|
COMMAND(cmd_cdone),
|
||||||
|
COMMAND(cmd_throw),
|
||||||
|
COMMAND(cmd_functionp),
|
||||||
|
/* 57 */
|
||||||
|
COMMAND(cmd_le),
|
||||||
|
COMMAND(cmd_ge),
|
||||||
|
COMMAND(cmd_varx),
|
||||||
|
COMMAND(cmd_setx)
|
||||||
|
};
|
||||||
|
_commands = commandProcs;
|
||||||
|
_commandsMax = ARRAYSIZE(commandProcs) + 1;
|
||||||
|
|
||||||
|
_functions = new ScriptFunctionsRtz(_vm);
|
||||||
|
_functions->setupExternalsTable();
|
||||||
|
|
||||||
|
#undef COMMAND
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptInterpreter::~ScriptInterpreter() {
|
||||||
|
delete _functions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::runScript(int16 scriptObjectIndex) {
|
||||||
|
|
||||||
|
_terminated = false;
|
||||||
|
_runningScriptObjectIndex = scriptObjectIndex;
|
||||||
|
|
||||||
|
_localStackPos = _stack.getStackPos();
|
||||||
|
|
||||||
|
_codeBase = _vm->_dat->getObject(_runningScriptObjectIndex)->getData();
|
||||||
|
_codeIp = _codeBase;
|
||||||
|
|
||||||
|
while (!_terminated) {
|
||||||
|
byte opcode = readByte();
|
||||||
|
if (opcode >= 1 && opcode <= _commandsMax) {
|
||||||
|
debug(4, "opcode = %s\n", _commands[opcode - 1].desc);
|
||||||
|
(this->*_commands[opcode - 1].proc)();
|
||||||
|
} else {
|
||||||
|
printf("ScriptInterpreter::runScript(%d) Unknown opcode %02X\n", _runningScriptObjectIndex, opcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
byte ScriptInterpreter::readByte() {
|
||||||
|
return *_codeIp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptInterpreter::readInt16() {
|
||||||
|
int16 temp = (int16)READ_LE_UINT16(_codeIp);
|
||||||
|
_codeIp += 2;
|
||||||
|
debug(4, "readInt16() value = %04X\n", temp);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_branchTrue() {
|
||||||
|
int16 ofs = readInt16();
|
||||||
|
if (_stack.top() != 0)
|
||||||
|
_codeIp = _codeBase + ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_branchFalse() {
|
||||||
|
int16 ofs = readInt16();
|
||||||
|
if (_stack.top() == 0)
|
||||||
|
_codeIp = _codeBase + ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_branch() {
|
||||||
|
int16 ofs = readInt16();
|
||||||
|
_codeIp = _codeBase + ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_true() {
|
||||||
|
_stack.setTop(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_false() {
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_push() {
|
||||||
|
_stack.push();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_not() {
|
||||||
|
if (_stack.top() == 0)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_add() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
_stack.setTop(_stack.top() + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_sub() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
_stack.setTop(_stack.top() - value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_mul() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
_stack.setTop(_stack.top() * value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_div() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (value == 0)
|
||||||
|
_stack.setTop(0);
|
||||||
|
else
|
||||||
|
_stack.setTop(_stack.top() / value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_mod() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (value == 0)
|
||||||
|
_stack.setTop(0);
|
||||||
|
else
|
||||||
|
_stack.setTop(_stack.top() % value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_band() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
_stack.setTop(_stack.top() & value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_bor() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
_stack.setTop(_stack.top() | value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_bnot() {
|
||||||
|
_stack.setTop(~_stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_lt() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (_stack.top() < value)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_eq() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (_stack.top() == value)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_gt() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (_stack.top() > value)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_loadConstant() {
|
||||||
|
int16 value = readInt16();
|
||||||
|
debug(4, "value = %04X (%d)\n", value, value);
|
||||||
|
_stack.setTop(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_loadVariable() {
|
||||||
|
int16 variable = readInt16();
|
||||||
|
int16 value = _vm->_dat->getVar(variable);
|
||||||
|
debug(4, "variable = %d; value = %d (%04X)\n", variable, value, value); fflush(stdout);
|
||||||
|
_stack.setTop(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_getObjectProperty() {
|
||||||
|
int16 propertyId = _stack.pop();
|
||||||
|
int16 objectIndex = _stack.top();
|
||||||
|
int16 value = _vm->_dat->getObjectProperty(objectIndex, propertyId);
|
||||||
|
debug(4, "value = %04X(%d)\n", value, value);
|
||||||
|
//fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
_stack.setTop(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_setObjectProperty() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
int16 propertyId = _stack.pop();
|
||||||
|
int16 objectIndex = _stack.top();
|
||||||
|
value = _vm->_dat->setObjectProperty(objectIndex, propertyId, value);
|
||||||
|
//fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
_stack.setTop(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_set() {
|
||||||
|
int16 variable = readInt16();
|
||||||
|
debug(4, "var(%d) = %04d (%d)\n", variable, _stack.top(), _stack.top());
|
||||||
|
_vm->_dat->setVar(variable, _stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_print() {
|
||||||
|
// TODO: This opcode was used for printing debug messages
|
||||||
|
Object *obj = _vm->_dat->getObject(_stack.top());
|
||||||
|
const char *text = obj->getString();
|
||||||
|
debug(4, "%s", text); fflush(stdout);
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_terpri() {
|
||||||
|
// TODO: This opcode was used for printing debug messages
|
||||||
|
debug(4, "\n");
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_printNumber() {
|
||||||
|
// TODO: This opcode was used for printing debug messages
|
||||||
|
debug(4, "%d", _stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_vref() {
|
||||||
|
int16 index = _stack.pop();
|
||||||
|
int16 objectIndex = _stack.top();
|
||||||
|
int16 value = 0;
|
||||||
|
debug(4, "index = %d; objectIndex = %d\n", index, objectIndex); fflush(stdout);
|
||||||
|
if (objectIndex > 0) {
|
||||||
|
Object *obj = _vm->_dat->getObject(objectIndex);
|
||||||
|
value = obj->getVectorItem(index);
|
||||||
|
}
|
||||||
|
_stack.setTop(value);
|
||||||
|
debug(4, "--> value = %d\n", value); fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_vset() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
int16 index = _stack.pop();
|
||||||
|
int16 objectIndex = _stack.top();
|
||||||
|
debug(4, "index = %d; objectIndex = %d; value = %d\n", index, objectIndex, value); fflush(stdout);
|
||||||
|
if (objectIndex > 0) {
|
||||||
|
Object *obj = _vm->_dat->getObject(objectIndex);
|
||||||
|
obj->setVectorItem(index, value);
|
||||||
|
}
|
||||||
|
_stack.setTop(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_vsize() {
|
||||||
|
int16 objectIndex = _stack.top();
|
||||||
|
if (objectIndex < 1) objectIndex = 1; // HACK
|
||||||
|
Object *obj = _vm->_dat->getObject(objectIndex);
|
||||||
|
int16 size = obj->getVectorSize();
|
||||||
|
_stack.setTop(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_exit() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_return() {
|
||||||
|
// TODO: Check if returning from main function
|
||||||
|
int16 funcResult = _stack.top();
|
||||||
|
_stack.setStackPos(_localStackPos);
|
||||||
|
_localStackPos = kScriptStackLimit - _stack.pop();
|
||||||
|
//_localStackPos = _stack.pop();
|
||||||
|
_runningScriptObjectIndex = _stack.pop();
|
||||||
|
_codeBase = _vm->_dat->getObject(_runningScriptObjectIndex)->getData();
|
||||||
|
_codeIp = _codeBase + _stack.pop();
|
||||||
|
byte argc = _stack.pop();
|
||||||
|
_stack.free(argc);
|
||||||
|
_stack.setTop(funcResult);
|
||||||
|
debug(4, "LEAVE: stackPtr = %d; _localStackPos = %d\n\n\n", _stack.getStackPos(), _localStackPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_call() {
|
||||||
|
debug(4, "\n\n\nENTER: stackPtr = %d; _localStackPos = %d\n", _stack.getStackPos(), _localStackPos);
|
||||||
|
byte argc = readByte();
|
||||||
|
_stack.push(argc);
|
||||||
|
_stack.push(_codeIp - _codeBase);
|
||||||
|
_stack.push(_runningScriptObjectIndex);
|
||||||
|
_stack.push(kScriptStackLimit - _localStackPos);
|
||||||
|
_localStackPos = _stack.getStackPos();
|
||||||
|
_runningScriptObjectIndex = _stack.peek(_localStackPos + argc + 4);
|
||||||
|
debug(4, "argc = %d; _runningScriptObjectIndex = %04X\n", argc, _runningScriptObjectIndex); fflush(stdout);
|
||||||
|
_codeBase = _vm->_dat->getObject(_runningScriptObjectIndex)->getData();
|
||||||
|
_codeIp = _codeBase;
|
||||||
|
//_vm->_dat->dumpObject(_runningScriptObjectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_svar() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_sset() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_split() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_snlit() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_yorn() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_save() {
|
||||||
|
//fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
// TODO
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_restore() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_arg() {
|
||||||
|
int16 argIndex = readByte();
|
||||||
|
debug(4, "argIndex = %d; value = %04X (%d)\n", argIndex, _stack.peek(_localStackPos + 4 + argIndex), _stack.peek(_localStackPos + 4 + argIndex));
|
||||||
|
_stack.setTop(_stack.peek(_localStackPos + 4 + argIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_aset() {
|
||||||
|
int16 argIndex = readByte();
|
||||||
|
debug(4, "argIndex = %d; value = %d\n", argIndex, _stack.peek(_localStackPos + 4 + argIndex));
|
||||||
|
_stack.poke(_localStackPos + 4 + argIndex, _stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_tmp() {
|
||||||
|
int16 tempIndex = readByte();
|
||||||
|
debug(4, "tempIndex = %d; value = %d\n", tempIndex, _stack.peek(_localStackPos - tempIndex - 1));
|
||||||
|
_stack.setTop(_stack.peek(_localStackPos - tempIndex - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_tset() {
|
||||||
|
int16 tempIndex = readByte();
|
||||||
|
debug(4, "tempIndex = %d; value = %d\n", tempIndex, _stack.top());
|
||||||
|
_stack.poke(_localStackPos - tempIndex - 1, _stack.top());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_tspace() {
|
||||||
|
int16 tempCount = readByte();
|
||||||
|
debug(4, "tempCount = %d\n", tempCount);
|
||||||
|
_stack.alloc(tempCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_class() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_objectp() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_vectorp() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_restart() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_rand() {
|
||||||
|
//fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_randomize() {
|
||||||
|
// TODO
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_send() {
|
||||||
|
|
||||||
|
debug(4, "\n\n\nENTER: stackPtr = %d; _localStackPos = %d\n", _stack.getStackPos(), _localStackPos);
|
||||||
|
|
||||||
|
byte argc = readByte();
|
||||||
|
|
||||||
|
debug(4, "argc = %d\n", argc);
|
||||||
|
|
||||||
|
_stack.push(argc);
|
||||||
|
_stack.push(_codeIp - _codeBase);
|
||||||
|
_stack.push(_runningScriptObjectIndex);
|
||||||
|
_stack.push(kScriptStackLimit - _localStackPos);
|
||||||
|
_localStackPos = _stack.getStackPos();
|
||||||
|
|
||||||
|
int16 propertyId = _stack.peek(_localStackPos + argc + 2);
|
||||||
|
int16 objectIndex = _stack.peek(_localStackPos + argc + 4);
|
||||||
|
|
||||||
|
debug(4, "objectIndex = %d (%04X); propertyId = %d(%04X)\n", objectIndex, objectIndex, propertyId, propertyId); fflush(stdout);
|
||||||
|
|
||||||
|
if (objectIndex != 0) {
|
||||||
|
objectIndex = _vm->_dat->getObject(objectIndex)->getClass();
|
||||||
|
} else {
|
||||||
|
objectIndex = _stack.peek(_localStackPos + argc + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(4, "--> objectIndex = %d(%04X)\n", objectIndex, objectIndex); fflush(stdout);
|
||||||
|
|
||||||
|
if (objectIndex != 0) {
|
||||||
|
_runningScriptObjectIndex = _vm->_dat->getObjectProperty(objectIndex, propertyId);
|
||||||
|
if (_runningScriptObjectIndex != 0) {
|
||||||
|
_codeBase = _vm->_dat->getObject(_runningScriptObjectIndex)->getData();
|
||||||
|
_codeIp = _codeBase;
|
||||||
|
} else {
|
||||||
|
_stack.push(0);
|
||||||
|
cmd_return();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_stack.push(0);
|
||||||
|
cmd_return();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_extend() {
|
||||||
|
|
||||||
|
byte func = readByte();
|
||||||
|
|
||||||
|
byte argc = readByte();
|
||||||
|
int16 *argv = _stack.getStackPtr();
|
||||||
|
|
||||||
|
debug(4, "func = %d (%s); argc = %d\n", func, extendFuncNames[func], argc); fflush(stdout);
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
debug(4, "argv[%02d] = %04X (%d)\n", i, argv[i], argv[i]);
|
||||||
|
|
||||||
|
int16 result = _functions->callFunction(func, argc, argv);
|
||||||
|
debug(4, "result = %04X (%d)\n", result, result);
|
||||||
|
|
||||||
|
_stack.free(argc);
|
||||||
|
|
||||||
|
_stack.setTop(result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_catch() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_cdone() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_throw() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_functionp() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_le() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (_stack.top() <= value)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_ge() {
|
||||||
|
int16 value = _stack.pop();
|
||||||
|
if (_stack.top() >= value)
|
||||||
|
_stack.setTop(-1);
|
||||||
|
else
|
||||||
|
_stack.setTop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_varx() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptInterpreter::cmd_setx() {
|
||||||
|
fflush(stdout); g_system->delayMillis(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
154
engines/made/script.h
Normal file
154
engines/made/script.h
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_SCRIPT_H
|
||||||
|
#define MADE_SCRIPT_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
class MadeEngine;
|
||||||
|
class ScriptFunctions;
|
||||||
|
|
||||||
|
const int kScriptStackSize = 1000;
|
||||||
|
const int kScriptStackLimit = kScriptStackSize + 1;
|
||||||
|
|
||||||
|
class ScriptStack {
|
||||||
|
public:
|
||||||
|
ScriptStack();
|
||||||
|
~ScriptStack();
|
||||||
|
int16 top();
|
||||||
|
int16 pop();
|
||||||
|
void push(int16 value = 0);
|
||||||
|
void setTop(int16 value);
|
||||||
|
int16 peek(int16 index);
|
||||||
|
void poke(int16 index, int16 value);
|
||||||
|
void alloc(int16 count);
|
||||||
|
void free(int16 count);
|
||||||
|
int16 getStackPos() const { return _stackPos; }
|
||||||
|
void setStackPos(int16 stackPtr);
|
||||||
|
int16 *getStackPtr();
|
||||||
|
protected:
|
||||||
|
int16 _stack[kScriptStackSize];
|
||||||
|
int16 _stackPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptInterpreter {
|
||||||
|
public:
|
||||||
|
ScriptInterpreter(MadeEngine *vm);
|
||||||
|
~ScriptInterpreter();
|
||||||
|
void runScript(int16 scriptObjectIndex);
|
||||||
|
protected:
|
||||||
|
MadeEngine *_vm;
|
||||||
|
|
||||||
|
ScriptStack _stack;
|
||||||
|
int16 _localStackPos;
|
||||||
|
int16 _runningScriptObjectIndex;
|
||||||
|
byte *_codeBase, *_codeIp;
|
||||||
|
bool _terminated;
|
||||||
|
|
||||||
|
ScriptFunctions *_functions;
|
||||||
|
|
||||||
|
byte readByte();
|
||||||
|
int16 readInt16();
|
||||||
|
|
||||||
|
typedef void (ScriptInterpreter::*CommandProc)();
|
||||||
|
struct CommandEntry {
|
||||||
|
CommandProc proc;
|
||||||
|
const char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CommandEntry *_commands;
|
||||||
|
int16 _commandsMax;
|
||||||
|
|
||||||
|
void cmd_branchTrue();
|
||||||
|
void cmd_branchFalse();
|
||||||
|
void cmd_branch();
|
||||||
|
void cmd_true();
|
||||||
|
void cmd_false();
|
||||||
|
void cmd_push();
|
||||||
|
void cmd_not();
|
||||||
|
void cmd_add();
|
||||||
|
void cmd_sub();
|
||||||
|
void cmd_mul();
|
||||||
|
void cmd_div();
|
||||||
|
void cmd_mod();
|
||||||
|
void cmd_band();
|
||||||
|
void cmd_bor();
|
||||||
|
void cmd_bnot();
|
||||||
|
void cmd_lt();
|
||||||
|
void cmd_eq();
|
||||||
|
void cmd_gt();
|
||||||
|
void cmd_loadConstant();
|
||||||
|
void cmd_loadVariable();
|
||||||
|
void cmd_getObjectProperty();
|
||||||
|
void cmd_setObjectProperty();
|
||||||
|
void cmd_set();
|
||||||
|
void cmd_print();
|
||||||
|
void cmd_terpri();
|
||||||
|
void cmd_printNumber();
|
||||||
|
void cmd_vref();
|
||||||
|
void cmd_vset();
|
||||||
|
void cmd_vsize();
|
||||||
|
void cmd_exit();
|
||||||
|
void cmd_return();
|
||||||
|
void cmd_call();
|
||||||
|
void cmd_svar();
|
||||||
|
void cmd_sset();
|
||||||
|
void cmd_split();
|
||||||
|
void cmd_snlit();
|
||||||
|
void cmd_yorn();
|
||||||
|
void cmd_save();
|
||||||
|
void cmd_restore();
|
||||||
|
void cmd_arg();
|
||||||
|
void cmd_aset();
|
||||||
|
void cmd_tmp();
|
||||||
|
void cmd_tset();
|
||||||
|
void cmd_tspace();
|
||||||
|
void cmd_class();
|
||||||
|
void cmd_objectp();
|
||||||
|
void cmd_vectorp();
|
||||||
|
void cmd_restart();
|
||||||
|
void cmd_rand();
|
||||||
|
void cmd_randomize();
|
||||||
|
void cmd_send();
|
||||||
|
void cmd_extend();
|
||||||
|
void cmd_catch();
|
||||||
|
void cmd_cdone();
|
||||||
|
void cmd_throw();
|
||||||
|
void cmd_functionp();
|
||||||
|
void cmd_le();
|
||||||
|
void cmd_ge();
|
||||||
|
void cmd_varx();
|
||||||
|
void cmd_setx();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
718
engines/made/scriptfuncs.cpp
Normal file
718
engines/made/scriptfuncs.cpp
Normal file
|
@ -0,0 +1,718 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/events.h"
|
||||||
|
|
||||||
|
#include "graphics/cursorman.h"
|
||||||
|
|
||||||
|
#include "made/made.h"
|
||||||
|
#include "made/resource.h"
|
||||||
|
#include "made/database.h"
|
||||||
|
#include "made/screen.h"
|
||||||
|
#include "made/script.h"
|
||||||
|
#include "made/pmvplayer.h"
|
||||||
|
#include "made/scriptfuncs.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
int16 ScriptFunctions::callFunction(uint16 index, int16 argc, int16 *argv) {
|
||||||
|
if (index >= _externalFuncs.size()) {
|
||||||
|
// TODO: ERROR!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
//g_system->delayMillis(2000);
|
||||||
|
|
||||||
|
return (*_externalFuncs[index])(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Functor2Mem<int16, int16*, int16, ScriptFunctionsRtz> ExternalFuncRtz;
|
||||||
|
#define External(x) ExternalFuncRtz(this, &ScriptFunctionsRtz::x)
|
||||||
|
void ScriptFunctionsRtz::setupExternalsTable() {
|
||||||
|
static const ExternalFuncRtz externalsTable[] = {
|
||||||
|
External(o1_SYSTEM),
|
||||||
|
External(o1_INITGRAF),
|
||||||
|
External(o1_RESTOREGRAF),
|
||||||
|
External(o1_DRAWPIC),
|
||||||
|
External(o1_CLS),
|
||||||
|
External(o1_SHOWPAGE),
|
||||||
|
External(o1_EVENT),
|
||||||
|
External(o1_EVENTX),
|
||||||
|
External(o1_EVENTY),
|
||||||
|
External(o1_EVENTKEY),
|
||||||
|
External(o1_VISUALFX),
|
||||||
|
External(o1_PLAYSND),
|
||||||
|
External(o1_PLAYMUS),
|
||||||
|
External(o1_STOPMUS),
|
||||||
|
External(o1_ISMUS),
|
||||||
|
External(o1_TEXTPOS),
|
||||||
|
External(o1_FLASH),
|
||||||
|
External(o1_PLAYNOTE),
|
||||||
|
External(o1_STOPNOTE),
|
||||||
|
External(o1_PLAYTELE),
|
||||||
|
External(o1_STOPTELE),
|
||||||
|
External(o1_HIDECURS),
|
||||||
|
External(o1_SHOWCURS),
|
||||||
|
External(o1_MUSICBEAT),
|
||||||
|
External(o1_SCREENLOCK),
|
||||||
|
External(o1_ADDSPRITE),
|
||||||
|
External(o1_FREEANIM),
|
||||||
|
External(o1_DRAWSPRITE),
|
||||||
|
External(o1_ERASESPRITES),
|
||||||
|
External(o1_UPDATESPRITES),
|
||||||
|
External(o1_GETTIMER),
|
||||||
|
External(o1_SETTIMER),
|
||||||
|
External(o1_RESETTIMER),
|
||||||
|
External(o1_ALLOCTIMER),
|
||||||
|
External(o1_FREETIMER),
|
||||||
|
External(o1_PALETTELOCK),
|
||||||
|
External(o1_FONT),
|
||||||
|
External(o1_DRAWTEXT),
|
||||||
|
External(o1_HOMETEXT),
|
||||||
|
External(o1_TEXTRECT),
|
||||||
|
External(o1_TEXTXY),
|
||||||
|
External(o1_DROPSHADOW),
|
||||||
|
External(o1_TEXTCOLOR),
|
||||||
|
External(o1_OUTLINE),
|
||||||
|
External(o1_LOADCURSOR),
|
||||||
|
External(o1_SETGROUND),
|
||||||
|
External(o1_RESTEXT),
|
||||||
|
External(o1_CLIPAREA),
|
||||||
|
External(o1_SETCLIP),
|
||||||
|
External(o1_ISSND),
|
||||||
|
External(o1_STOPSND),
|
||||||
|
External(o1_PLAYVOICE),
|
||||||
|
External(o1_CDPLAY),
|
||||||
|
External(o1_STOPCD),
|
||||||
|
External(o1_CDSTATUS),
|
||||||
|
External(o1_CDTIME),
|
||||||
|
External(o1_CDPLAYSEG),
|
||||||
|
External(o1_PRINTF),
|
||||||
|
External(o1_MONOCLS),
|
||||||
|
External(o1_SNDENERGY),
|
||||||
|
External(o1_CLEARTEXT),
|
||||||
|
External(o1_ANIMTEXT),
|
||||||
|
External(o1_TEXTWIDTH),
|
||||||
|
External(o1_PLAYMOVIE),
|
||||||
|
External(o1_LOADSND),
|
||||||
|
External(o1_LOADMUS),
|
||||||
|
External(o1_LOADPIC),
|
||||||
|
External(o1_MUSICVOL),
|
||||||
|
External(o1_RESTARTEVENTS),
|
||||||
|
External(o1_PLACESPRITE),
|
||||||
|
External(o1_PLACETEXT),
|
||||||
|
External(o1_DELETECHANNEL),
|
||||||
|
External(o1_CHANNELTYPE),
|
||||||
|
External(o1_SETSTATE),
|
||||||
|
External(o1_SETLOCATION),
|
||||||
|
External(o1_SETCONTENT),
|
||||||
|
External(o1_EXCLUDEAREA),
|
||||||
|
External(o1_SETEXCLUDE),
|
||||||
|
External(o1_GETSTATE),
|
||||||
|
External(o1_PLACEANIM),
|
||||||
|
External(o1_SETFRAME),
|
||||||
|
External(o1_GETFRAME),
|
||||||
|
External(o1_GETFRAMECOUNT),
|
||||||
|
External(o1_PICWIDTH),
|
||||||
|
External(o1_PICHEIGHT),
|
||||||
|
External(o1_SOUNDRATE),
|
||||||
|
External(o1_DRAWANIMPIC),
|
||||||
|
External(o1_LOADANIM),
|
||||||
|
External(o1_READTEXT),
|
||||||
|
External(o1_READMENU),
|
||||||
|
External(o1_DRAWMENU),
|
||||||
|
External(o1_MENUCOUNT),
|
||||||
|
External(o1_SAVEGAME),
|
||||||
|
External(o1_LOADGAME),
|
||||||
|
External(o1_GAMENAME),
|
||||||
|
External(o1_SHAKESCREEN),
|
||||||
|
External(o1_PLACEMENU),
|
||||||
|
External(o1_SETVOLUME),
|
||||||
|
External(o1_WHATSYNTH),
|
||||||
|
External(o1_SLOWSYSTEM)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAYSIZE(externalsTable); ++i)
|
||||||
|
_externalFuncs.push_back(&externalsTable[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
#undef External
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SYSTEM(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_INITGRAF(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_RESTOREGRAF(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DRAWPIC(int16 argc, int16 *argv) {
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
|
||||||
|
int16 channel = _vm->_screen->drawPic(argv[4], argv[3], argv[2], argv[1], argv[0]);
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CLS(int16 argc, int16 *argv) {
|
||||||
|
//_vm->_screen->clearScreen();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SHOWPAGE(int16 argc, int16 *argv) {
|
||||||
|
//_vm->_system->setPalette(_vm->_screen->_palette, 0, 256);
|
||||||
|
_vm->_screen->show();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_EVENT(int16 argc, int16 *argv) {
|
||||||
|
|
||||||
|
Common::Event event;
|
||||||
|
Common::EventManager *eventMan = g_system->getEventManager();
|
||||||
|
|
||||||
|
int16 eventNum = 0;
|
||||||
|
|
||||||
|
if (eventMan->pollEvent(event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
|
||||||
|
case Common::EVENT_MOUSEMOVE:
|
||||||
|
_vm->_eventMouseX = event.mouse.x;
|
||||||
|
_vm->_eventMouseY = event.mouse.y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Common::EVENT_LBUTTONDOWN:
|
||||||
|
eventNum = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Common::EVENT_RBUTTONDOWN:
|
||||||
|
eventNum = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Common::EVENT_KEYDOWN:
|
||||||
|
switch (event.kbd.ascii) {
|
||||||
|
case '1':
|
||||||
|
eventNum = 1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
eventNum = 2;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
eventNum = 3;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
eventNum = 4;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
eventNum = 5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
//g_system->delayMillis(10);
|
||||||
|
|
||||||
|
return eventNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_EVENTX(int16 argc, int16 *argv) {
|
||||||
|
return _vm->_eventMouseX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_EVENTY(int16 argc, int16 *argv) {
|
||||||
|
return _vm->_eventMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_EVENTKEY(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_VISUALFX(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYSND(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_STOPMUS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ISMUS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_FLASH(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYNOTE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_STOPNOTE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYTELE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_STOPTELE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_HIDECURS(int16 argc, int16 *argv) {
|
||||||
|
_vm->_system->showMouse(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SHOWCURS(int16 argc, int16 *argv) {
|
||||||
|
_vm->_system->showMouse(true);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_MUSICBEAT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SCREENLOCK(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ADDSPRITE(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_FREEANIM(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->clearChannels();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DRAWSPRITE(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ERASESPRITES(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->clearChannels();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_UPDATESPRITES(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->updateSprites();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_GETTIMER(int16 argc, int16 *argv) {
|
||||||
|
return _vm->getTimer(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETTIMER(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_RESETTIMER(int16 argc, int16 *argv) {
|
||||||
|
_vm->resetTimer(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ALLOCTIMER(int16 argc, int16 *argv) {
|
||||||
|
int16 timerNum = _vm->allocTimer();
|
||||||
|
return timerNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_FREETIMER(int16 argc, int16 *argv) {
|
||||||
|
_vm->freeTimer(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PALETTELOCK(int16 argc, int16 *argv) {
|
||||||
|
//g_system->delayMillis(1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_FONT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DRAWTEXT(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_HOMETEXT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_TEXTRECT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_TEXTXY(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DROPSHADOW(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_TEXTCOLOR(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_OUTLINE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADCURSOR(int16 argc, int16 *argv) {
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(argv[2]);
|
||||||
|
Graphics::Surface *surf = flex->getPicture();
|
||||||
|
CursorMan.replaceCursor((const byte *)surf->pixels, surf->w, surf->h, argv[1], argv[0], 0);
|
||||||
|
CursorMan.showMouse(true);
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETGROUND(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_RESTEXT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CLIPAREA(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETCLIP(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ISSND(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_STOPSND(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYVOICE(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CDPLAY(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_STOPCD(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CDSTATUS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CDTIME(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CDPLAYSEG(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PRINTF(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_MONOCLS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SNDENERGY(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CLEARTEXT(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_ANIMTEXT(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_TEXTWIDTH(int16 argc, int16 *argv) {
|
||||||
|
Object *obj = _vm->_dat->getObject(argv[1]);
|
||||||
|
const char *text = obj->getString();
|
||||||
|
debug(4, "text = %s\n", text); fflush(stdout);
|
||||||
|
//!!g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLAYMOVIE(int16 argc, int16 *argv) {
|
||||||
|
const char *movieName = _vm->_dat->getObject(argv[1])->getString();
|
||||||
|
printf("movieName = %s\n", movieName); fflush(stdout);
|
||||||
|
_vm->_pmvPlayer->play(movieName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADSND(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADMUS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADPIC(int16 argc, int16 *argv) {
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(argv[0]);
|
||||||
|
if (flex) {
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_MUSICVOL(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_RESTARTEVENTS(int16 argc, int16 *argv) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLACESPRITE(int16 argc, int16 *argv) {
|
||||||
|
return _vm->_screen->placeSprite(argv[3], argv[2], argv[1], argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLACETEXT(int16 argc, int16 *argv) {
|
||||||
|
Object *obj = _vm->_dat->getObject(argv[5]);
|
||||||
|
_vm->_dat->dumpObject(argv[5]);
|
||||||
|
const char *text = obj->getString();
|
||||||
|
debug(4, "text = %s\n", text); fflush(stdout);
|
||||||
|
//!! g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DELETECHANNEL(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->deleteChannel(argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_CHANNELTYPE(int16 argc, int16 *argv) {
|
||||||
|
return _vm->_screen->getChannelType(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETSTATE(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->setChannelState(argv[1], argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETLOCATION(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETCONTENT(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_EXCLUDEAREA(int16 argc, int16 *argv) {
|
||||||
|
//!! g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETEXCLUDE(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_GETSTATE(int16 argc, int16 *argv) {
|
||||||
|
//!! g_system->delayMillis(5000);
|
||||||
|
int16 state = _vm->_screen->getChannelState(argv[0]);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLACEANIM(int16 argc, int16 *argv) {
|
||||||
|
printf("anim = %04X\n", argv[3]); fflush(stdout);
|
||||||
|
int16 channel = _vm->_screen->placeAnim(argv[4], argv[3], argv[2], argv[1], argv[0]);
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETFRAME(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->setAnimFrame(argv[1], argv[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_GETFRAME(int16 argc, int16 *argv) {
|
||||||
|
return _vm->_screen->getAnimFrame(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_GETFRAMECOUNT(int16 argc, int16 *argv) {
|
||||||
|
debug(4, "anim = %04X\n", argv[0]);
|
||||||
|
int16 frameCount = _vm->_screen->getAnimFrameCount(argv[0]);
|
||||||
|
debug(4, "frameCount = %04X\n", frameCount);
|
||||||
|
//fflush(stdout);
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PICWIDTH(int16 argc, int16 *argv) {
|
||||||
|
int16 width = 0;
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(argv[0]);
|
||||||
|
if (flex) {
|
||||||
|
width = flex->getPicture()->w;
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PICHEIGHT(int16 argc, int16 *argv) {
|
||||||
|
int16 height = 0;
|
||||||
|
PictureResource *flex = _vm->_res->getPicture(argv[0]);
|
||||||
|
if (flex) {
|
||||||
|
height = flex->getPicture()->h;
|
||||||
|
_vm->_res->freeResource(flex);
|
||||||
|
}
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SOUNDRATE(int16 argc, int16 *argv) {
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DRAWANIMPIC(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADANIM(int16 argc, int16 *argv) {
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_READTEXT(int16 argc, int16 *argv) {
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_READMENU(int16 argc, int16 *argv) {
|
||||||
|
/*
|
||||||
|
int16 objectIndex = argv[2];
|
||||||
|
int16 menuIndex = argv[1];
|
||||||
|
int16 textIndex = argv[0];
|
||||||
|
MenuResource *menu = _vm->_res->getMenu(menuIndex);
|
||||||
|
if (menu) {
|
||||||
|
const char *text = menu->getString(textIndex).c_str();
|
||||||
|
debug(4, "text = %s\n", text); fflush(stdout);
|
||||||
|
_vm->_res->freeResource(menu);
|
||||||
|
}
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_DRAWMENU(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_MENUCOUNT(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SAVEGAME(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_LOADGAME(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_GAMENAME(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SHAKESCREEN(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_PLACEMENU(int16 argc, int16 *argv) {
|
||||||
|
g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SETVOLUME(int16 argc, int16 *argv) {
|
||||||
|
//!! g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_WHATSYNTH(int16 argc, int16 *argv) {
|
||||||
|
//g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 ScriptFunctionsRtz::o1_SLOWSYSTEM(int16 argc, int16 *argv) {
|
||||||
|
//!! g_system->delayMillis(5000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
188
engines/made/scriptfuncs.h
Normal file
188
engines/made/scriptfuncs.h
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_SCRIPTFUNCS_H
|
||||||
|
#define MADE_SCRIPTFUNCS_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
class MadeEngine;
|
||||||
|
|
||||||
|
template<class Arg1, class Arg2, class Res>
|
||||||
|
struct Functor2 : public Common::BinaryFunction<Arg1, Arg2, Res> {
|
||||||
|
virtual ~Functor2() {}
|
||||||
|
|
||||||
|
virtual bool isValid() const = 0;
|
||||||
|
virtual Res operator()(Arg1, Arg2) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Arg1, class Arg2, class Res, class T>
|
||||||
|
class Functor2Mem : public Functor2<Arg1, Arg2, Res> {
|
||||||
|
public:
|
||||||
|
typedef Res (T::*FuncType)(Arg1, Arg2);
|
||||||
|
|
||||||
|
Functor2Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
|
||||||
|
|
||||||
|
bool isValid() const { return _func != 0; }
|
||||||
|
Res operator()(Arg1 v1, Arg2 v2) const {
|
||||||
|
return (_t->*_func)(v1, v2);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
mutable T *_t;
|
||||||
|
Res (T::*_func)(Arg1, Arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Functor2<int16, int16*, int16> ExternalFunc;
|
||||||
|
|
||||||
|
class ScriptFunctions {
|
||||||
|
public:
|
||||||
|
ScriptFunctions(MadeEngine *vm) : _vm(vm) {}
|
||||||
|
virtual ~ScriptFunctions() {}
|
||||||
|
int16 callFunction(uint16 index, int16 argc, int16 *argv);
|
||||||
|
virtual void setupExternalsTable() = 0;
|
||||||
|
protected:
|
||||||
|
MadeEngine *_vm;
|
||||||
|
|
||||||
|
Common::Array<const ExternalFunc*> _externalFuncs;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptFunctionsRtz : public ScriptFunctions {
|
||||||
|
public:
|
||||||
|
ScriptFunctionsRtz(MadeEngine *vm) : ScriptFunctions(vm) {}
|
||||||
|
~ScriptFunctionsRtz() {}
|
||||||
|
void setupExternalsTable();
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int16 o1_SYSTEM(int16 argc, int16 *argv);
|
||||||
|
int16 o1_INITGRAF(int16 argc, int16 *argv);
|
||||||
|
int16 o1_RESTOREGRAF(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DRAWPIC(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CLS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SHOWPAGE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_EVENT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_EVENTX(int16 argc, int16 *argv);
|
||||||
|
int16 o1_EVENTY(int16 argc, int16 *argv);
|
||||||
|
int16 o1_EVENTKEY(int16 argc, int16 *argv);
|
||||||
|
int16 o1_VISUALFX(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYSND(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYMUS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_STOPMUS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ISMUS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_TEXTPOS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_FLASH(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYNOTE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_STOPNOTE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYTELE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_STOPTELE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_HIDECURS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SHOWCURS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_MUSICBEAT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SCREENLOCK(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ADDSPRITE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_FREEANIM(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DRAWSPRITE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ERASESPRITES(int16 argc, int16 *argv);
|
||||||
|
int16 o1_UPDATESPRITES(int16 argc, int16 *argv);
|
||||||
|
int16 o1_GETTIMER(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETTIMER(int16 argc, int16 *argv);
|
||||||
|
int16 o1_RESETTIMER(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ALLOCTIMER(int16 argc, int16 *argv);
|
||||||
|
int16 o1_FREETIMER(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PALETTELOCK(int16 argc, int16 *argv);
|
||||||
|
int16 o1_FONT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DRAWTEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_HOMETEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_TEXTRECT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_TEXTXY(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DROPSHADOW(int16 argc, int16 *argv);
|
||||||
|
int16 o1_TEXTCOLOR(int16 argc, int16 *argv);
|
||||||
|
int16 o1_OUTLINE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADCURSOR(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETGROUND(int16 argc, int16 *argv);
|
||||||
|
int16 o1_RESTEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CLIPAREA(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETCLIP(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ISSND(int16 argc, int16 *argv);
|
||||||
|
int16 o1_STOPSND(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYVOICE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CDPLAY(int16 argc, int16 *argv);
|
||||||
|
int16 o1_STOPCD(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CDSTATUS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CDTIME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CDPLAYSEG(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PRINTF(int16 argc, int16 *argv);
|
||||||
|
int16 o1_MONOCLS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SNDENERGY(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CLEARTEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_ANIMTEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_TEXTWIDTH(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLAYMOVIE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADSND(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADMUS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADPIC(int16 argc, int16 *argv);
|
||||||
|
int16 o1_MUSICVOL(int16 argc, int16 *argv);
|
||||||
|
int16 o1_RESTARTEVENTS(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLACESPRITE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLACETEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DELETECHANNEL(int16 argc, int16 *argv);
|
||||||
|
int16 o1_CHANNELTYPE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETSTATE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETLOCATION(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETCONTENT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_EXCLUDEAREA(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETEXCLUDE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_GETSTATE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLACEANIM(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETFRAME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_GETFRAME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_GETFRAMECOUNT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PICWIDTH(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PICHEIGHT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SOUNDRATE(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DRAWANIMPIC(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADANIM(int16 argc, int16 *argv);
|
||||||
|
int16 o1_READTEXT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_READMENU(int16 argc, int16 *argv);
|
||||||
|
int16 o1_DRAWMENU(int16 argc, int16 *argv);
|
||||||
|
int16 o1_MENUCOUNT(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SAVEGAME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_LOADGAME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_GAMENAME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SHAKESCREEN(int16 argc, int16 *argv);
|
||||||
|
int16 o1_PLACEMENU(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SETVOLUME(int16 argc, int16 *argv);
|
||||||
|
int16 o1_WHATSYNTH(int16 argc, int16 *argv);
|
||||||
|
int16 o1_SLOWSYSTEM(int16 argc, int16 *argv);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
131
engines/made/sound.cpp
Normal file
131
engines/made/sound.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "made/sound.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount) {
|
||||||
|
|
||||||
|
int16 prevSample = 0;
|
||||||
|
byte soundBuffer[1025];
|
||||||
|
byte soundBuffer3[1024];
|
||||||
|
int16 soundBuffer2[16];
|
||||||
|
|
||||||
|
while (chunkCount--) {
|
||||||
|
|
||||||
|
byte deltaType = (*source) >> 6;
|
||||||
|
|
||||||
|
uint16 workChunkSize = chunkSize;
|
||||||
|
if (deltaType == 1)
|
||||||
|
workChunkSize /= 2;
|
||||||
|
else if (deltaType == 2)
|
||||||
|
workChunkSize /= 4;
|
||||||
|
|
||||||
|
byte type = (*source++) & 0x0F;
|
||||||
|
|
||||||
|
int16 workSample = prevSample;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
memset(soundBuffer, 0x80, workChunkSize);
|
||||||
|
workSample = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
|
||||||
|
const int modeValues[3][4] = {
|
||||||
|
{ 2, 8, 0x01, 1},
|
||||||
|
{ 4, 4, 0x03, 2},
|
||||||
|
{16, 2, 0x0F, 4}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16 byteCount = modeValues[type - 2][0];
|
||||||
|
uint16 bitCount = modeValues[type - 2][1];
|
||||||
|
byte bitMask = modeValues[type - 2][2];
|
||||||
|
byte bitShift = modeValues[type - 2][3];
|
||||||
|
|
||||||
|
uint16 ofs = 0;
|
||||||
|
|
||||||
|
for (uint16 i = 0; i < byteCount; i++)
|
||||||
|
soundBuffer2[i] = (*source++) * 2 - 128;
|
||||||
|
|
||||||
|
while (ofs < workChunkSize) {
|
||||||
|
byte val = *source++;
|
||||||
|
for (uint i = 0; i < bitCount; i++) {
|
||||||
|
workSample = CLIP<int16>(workSample + soundBuffer2[val & bitMask], -127, 127);
|
||||||
|
val >>= bitShift;
|
||||||
|
soundBuffer[ofs++] = workSample + 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
for (uint16 i = 0; i < workChunkSize; i++)
|
||||||
|
soundBuffer[i] = *source++;
|
||||||
|
workSample = soundBuffer[workChunkSize - 1] - 128;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deltaType == 1) {
|
||||||
|
for (uint16 i = 0; i < chunkSize - 1; i += 2) {
|
||||||
|
uint16 l = i / 2;
|
||||||
|
soundBuffer3[i] = soundBuffer[l];
|
||||||
|
soundBuffer3[i + 1] = (soundBuffer[l + 1] + soundBuffer[l]) / 2;
|
||||||
|
}
|
||||||
|
for (uint16 i = 0; i < chunkSize; i++) {
|
||||||
|
soundBuffer[i] = soundBuffer3[i];
|
||||||
|
}
|
||||||
|
} else if (deltaType == 2) {
|
||||||
|
debug(2, "****************************************");
|
||||||
|
}
|
||||||
|
|
||||||
|
prevSample = workSample;
|
||||||
|
memcpy(dest, soundBuffer, chunkSize);
|
||||||
|
dest += chunkSize;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
39
engines/made/sound.h
Normal file
39
engines/made/sound.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MADE_SOUND_H
|
||||||
|
#define MADE_SOUND_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount);
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif /* MADE_H */
|
Loading…
Add table
Add a link
Reference in a new issue