2007-05-30 21:56:52 +00:00
|
|
|
/* 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.
|
2004-10-15 06:06:47 +00:00
|
|
|
*
|
|
|
|
* 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
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2004-10-15 06:06:47 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2007-02-20 17:33:54 +00:00
|
|
|
#ifndef KYRA_SCRIPT_H
|
|
|
|
#define KYRA_SCRIPT_H
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2008-02-07 23:13:13 +00:00
|
|
|
#include "common/stream.h"
|
2008-05-11 23:16:50 +00:00
|
|
|
#include "common/array.h"
|
2008-04-20 15:47:11 +00:00
|
|
|
#include "common/func.h"
|
2009-05-12 14:18:08 +00:00
|
|
|
#include "common/iff_container.h"
|
2007-05-05 12:18:02 +00:00
|
|
|
|
2007-07-29 16:33:11 +00:00
|
|
|
namespace Kyra {
|
2007-05-05 12:18:02 +00:00
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
struct EMCState;
|
2010-05-17 23:29:44 +00:00
|
|
|
typedef Common::Functor1<EMCState *, int> Opcode;
|
2008-04-20 15:47:11 +00:00
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
struct EMCData {
|
2008-07-10 12:05:38 +00:00
|
|
|
char filename[13];
|
|
|
|
|
2005-10-13 18:05:04 +00:00
|
|
|
byte *text;
|
2007-04-15 14:38:02 +00:00
|
|
|
uint16 *data;
|
|
|
|
uint16 *ordr;
|
2005-10-13 18:05:04 +00:00
|
|
|
uint16 dataSize;
|
2007-05-05 12:18:02 +00:00
|
|
|
|
2010-05-17 23:29:44 +00:00
|
|
|
const Common::Array<const Opcode *> *sysFuncs;
|
2004-11-14 20:11:22 +00:00
|
|
|
};
|
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
struct EMCState {
|
2009-01-18 17:24:47 +00:00
|
|
|
enum {
|
|
|
|
kStackSize = 100,
|
|
|
|
kStackLastEntry = kStackSize - 1
|
|
|
|
};
|
|
|
|
|
2008-09-10 18:01:02 +00:00
|
|
|
const uint16 *ip;
|
2008-04-29 15:12:09 +00:00
|
|
|
const EMCData *dataPtr;
|
2005-10-13 18:05:04 +00:00
|
|
|
int16 retValue;
|
|
|
|
uint16 bp;
|
|
|
|
uint16 sp;
|
2009-10-04 17:54:08 +00:00
|
|
|
int16 regs[30]; // VM registers
|
|
|
|
int16 stack[kStackSize]; // VM stack
|
2004-11-14 20:11:22 +00:00
|
|
|
};
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2007-10-09 08:44:45 +00:00
|
|
|
#define stackPos(x) (script->stack[script->sp+x])
|
2009-05-29 12:52:03 +00:00
|
|
|
#define stackPosString(x) ((const char *)&script->dataPtr->text[READ_BE_UINT16(&script->dataPtr->text[stackPos(x)<<1])])
|
2007-07-29 16:33:11 +00:00
|
|
|
|
2008-04-20 15:47:11 +00:00
|
|
|
class Resource;
|
2008-05-11 23:16:50 +00:00
|
|
|
class KyraEngine_v1;
|
2008-04-20 15:47:11 +00:00
|
|
|
|
2009-05-12 14:18:08 +00:00
|
|
|
class IFFParser : public Common::IFFParser {
|
2007-07-29 16:33:11 +00:00
|
|
|
public:
|
2009-06-12 09:49:38 +00:00
|
|
|
IFFParser(Common::ReadStream &input) : Common::IFFParser(&input) {
|
2009-05-12 14:18:08 +00:00
|
|
|
// It seems Westwood missunderstood the 'size' field of the FORM chunk.
|
|
|
|
//
|
|
|
|
// For EMC scripts (type EMC2) it's filesize instead of filesize - 8,
|
|
|
|
// means accidently including the 8 bytes used by the chunk header for the FORM
|
|
|
|
// chunk.
|
|
|
|
//
|
|
|
|
// For TIM scripts (type AVFS) it's filesize - 12 instead of filesize - 8,
|
|
|
|
// means it will not include the size of the 'type' field in the FORM chunk,
|
|
|
|
// instead of only not including the chunk header size.
|
|
|
|
//
|
|
|
|
// Both lead to some problems in our IFF parser, either reading after the end
|
|
|
|
// of file or producing a "Chunk overread" error message. To work around this
|
|
|
|
// we need to adjust the size field properly.
|
2011-04-12 14:53:15 +00:00
|
|
|
if (_formType == MKTAG('E','M','C','2'))
|
2009-05-17 14:22:05 +00:00
|
|
|
_formChunk.size -= 8;
|
2011-04-12 14:53:15 +00:00
|
|
|
else if (_formType == MKTAG('A','V','F','S'))
|
2009-05-17 15:59:04 +00:00
|
|
|
_formChunk.size += 4;
|
2009-05-12 14:18:08 +00:00
|
|
|
}
|
2007-07-29 16:33:11 +00:00
|
|
|
};
|
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
class EMCInterpreter {
|
2004-11-14 20:11:22 +00:00
|
|
|
public:
|
2008-05-11 23:16:50 +00:00
|
|
|
EMCInterpreter(KyraEngine_v1 *vm);
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2009-05-12 12:30:59 +00:00
|
|
|
bool load(const char *filename, EMCData *data, const Common::Array<const Opcode *> *opcodes);
|
2008-04-29 15:12:09 +00:00
|
|
|
void unload(EMCData *data);
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
void init(EMCState *scriptState, const EMCData *data);
|
|
|
|
bool start(EMCState *script, int function);
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
bool isValid(EMCState *script);
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2008-04-29 15:12:09 +00:00
|
|
|
bool run(EMCState *script);
|
2004-11-14 20:11:22 +00:00
|
|
|
protected:
|
2008-05-11 23:16:50 +00:00
|
|
|
KyraEngine_v1 *_vm;
|
2005-11-13 19:35:01 +00:00
|
|
|
int16 _parameter;
|
2005-10-13 18:05:04 +00:00
|
|
|
|
2009-06-12 09:49:38 +00:00
|
|
|
const char *_filename;
|
|
|
|
EMCData *_scriptData;
|
|
|
|
|
2009-06-12 09:56:07 +00:00
|
|
|
bool callback(Common::IFFChunk &chunk);
|
2009-06-12 09:49:38 +00:00
|
|
|
|
2009-05-12 12:30:59 +00:00
|
|
|
typedef void (EMCInterpreter::*OpcodeProc)(EMCState *);
|
|
|
|
struct OpcodeEntry {
|
|
|
|
OpcodeProc proc;
|
2007-07-08 12:50:24 +00:00
|
|
|
const char *desc;
|
2004-11-14 20:11:22 +00:00
|
|
|
};
|
2008-01-27 19:47:41 +00:00
|
|
|
|
2009-05-12 12:30:59 +00:00
|
|
|
const OpcodeEntry *_opcodes;
|
2005-10-13 18:05:04 +00:00
|
|
|
private:
|
2009-05-29 12:52:03 +00:00
|
|
|
void op_jmp(EMCState *);
|
|
|
|
void op_setRetValue(EMCState *);
|
|
|
|
void op_pushRetOrPos(EMCState *);
|
|
|
|
void op_push(EMCState *);
|
|
|
|
void op_pushReg(EMCState *);
|
|
|
|
void op_pushBPNeg(EMCState *);
|
|
|
|
void op_pushBPAdd(EMCState *);
|
|
|
|
void op_popRetOrPos(EMCState *);
|
|
|
|
void op_popReg(EMCState *);
|
|
|
|
void op_popBPNeg(EMCState *);
|
|
|
|
void op_popBPAdd(EMCState *);
|
|
|
|
void op_addSP(EMCState *);
|
|
|
|
void op_subSP(EMCState *);
|
|
|
|
void op_sysCall(EMCState *);
|
|
|
|
void op_ifNotJmp(EMCState *);
|
|
|
|
void op_negate(EMCState *);
|
|
|
|
void op_eval(EMCState *);
|
|
|
|
void op_setRetAndJmp(EMCState *);
|
2004-11-14 20:11:22 +00:00
|
|
|
};
|
2009-10-04 21:26:33 +00:00
|
|
|
} // End of namespace Kyra
|
2004-10-15 06:06:47 +00:00
|
|
|
|
|
|
|
#endif
|