PRINCE: script code refactored

This commit is contained in:
Kamil Zbróg 2013-12-10 00:26:42 +00:00
parent 7add223d85
commit 14566d5c27
4 changed files with 627 additions and 577 deletions

View file

@ -74,10 +74,10 @@ void PrinceEngine::debugEngine(const char *s, ...) {
}
PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) :
Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL),
_locationNr(0), _debugger(NULL), _midiPlayer(NULL),
_cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(NULL), _cursor2(NULL), _font(NULL),
_walizkaBmp(NULL), _roomBmp(NULL), _cursorNr(0) {
Engine(syst), _gameDescription(gameDesc), _graph(nullptr), _script(nullptr), _interpreter(nullptr), _flags(nullptr),
_locationNr(0), _debugger(nullptr), _midiPlayer(nullptr),
_cameraX(0), _newCameraX(0), _frameNr(0), _cursor1(nullptr), _cursor2(nullptr), _font(nullptr),
_walizkaBmp(nullptr), _roomBmp(nullptr), _cursorNr(0) {
// Debug/console setup
DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel");
@ -99,6 +99,8 @@ PrinceEngine::~PrinceEngine() {
delete _cursor2;
delete _midiPlayer;
delete _script;
delete _flags;
delete _interpreter;
delete _font;
delete _roomBmp;
delete _walizkaBmp;
@ -153,9 +155,12 @@ void PrinceEngine::init() {
_walizkaBmp = new MhwanhDecoder();
Resource::loadResource(_walizkaBmp, "all/walizka");
_script = new Script(this);
_script = new Script();
Resource::loadResource(_script, "all/skrypt.dat");
_flags = new InterpreterFlags();
_interpreter = new Interpreter(this, _script, _flags);
_variaTxt = new VariaTxt();
Resource::loadResource(_variaTxt, "all/variatxt.dat");
@ -249,8 +254,8 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
_cameraX = 0;
_newCameraX = 0;
_script->setFlagValue(Flags::CURRROOM, _locationNr);
_script->stopBg();
_flags->setFlagValue(Flags::CURRROOM, _locationNr);
_interpreter->stopBg();
changeCursor(0);
@ -290,7 +295,7 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
void PrinceEngine::changeCursor(uint16 curId) {
_debugger->_cursorNr = curId;
const Graphics::Surface *curSurface = NULL;
const Graphics::Surface *curSurface = nullptr;
uint16 hotspotX = 0;
uint16 hotspotY = 0;
@ -353,7 +358,7 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) {
void PrinceEngine::stopSample(uint16 sampleId) {
_mixer->stopID(sampleId);
_voiceStream[sampleId] = NULL;
_voiceStream[sampleId] = nullptr;
}
bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) {
@ -364,12 +369,12 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam
debugEngine("loadSample slot %d, name %s", sampleSlot, normalizedPath.c_str());
_mixer->stopID(sampleSlot);
_voiceStream[sampleSlot] = NULL;
_voiceStream[sampleSlot] = nullptr;
_voiceStream[sampleSlot] = SearchMan.createReadStreamForMember(normalizedPath);
if (_voiceStream[sampleSlot] == NULL) {
if (_voiceStream[sampleSlot] == nullptr) {
error("Can't load sample %s to slot %d", normalizedPath.c_str(), sampleSlot);
}
return _voiceStream[sampleSlot] == NULL;
return _voiceStream[sampleSlot] == nullptr;
}
bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) {
@ -466,7 +471,7 @@ void PrinceEngine::keyHandler(Common::Event event) {
scrollCameraRight(32);
break;
case Common::KEYCODE_ESCAPE:
_script->setFlagValue(Flags::ESCAPED2, 1);
_flags->setFlagValue(Flags::ESCAPED2, 1);
break;
}
}
@ -551,7 +556,7 @@ void PrinceEngine::showTexts() {
--text._time;
if (text._time == 0) {
text._str = NULL;
text._str = nullptr;
}
}
}
@ -587,7 +592,6 @@ void PrinceEngine::drawScreen() {
void PrinceEngine::mainLoop() {
loadLocation(4);
changeCursor(0);
while (!shouldQuit()) {
@ -622,7 +626,7 @@ void PrinceEngine::mainLoop() {
// TODO: Update all structures, animations, naks, heros etc.
_script->step();
_interpreter->step();
drawScreen();

View file

@ -53,6 +53,8 @@ struct PrinceGameDescription;
class PrinceEngine;
class GraphicsMan;
class Script;
class Interpreter;
class InterpreterFlags;
class Debugger;
class MusicPlayer;
class VariaTxt;
@ -162,6 +164,8 @@ private:
Debugger *_debugger;
GraphicsMan *_graph;
Script *_script;
InterpreterFlags *_flags;
Interpreter *_interpreter;
Font *_font;
MusicPlayer *_midiPlayer;

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@
#define PRINCE_SCRIPT_H
#include "common/random.h"
#include "common/endian.h"
#include "audio/mixer.h"
@ -37,25 +38,68 @@ namespace Prince {
class PrinceEngine;
namespace Detail {
template <typename T> T LittleEndianReader(void *data);
template <> inline uint8 LittleEndianReader<uint8>(void *data) { return *(uint8*)(data); }
template <> inline uint16 LittleEndianReader<uint16>(void *data) { return READ_LE_UINT16(data); }
template <> inline uint32 LittleEndianReader<uint32>(void *data) { return READ_LE_UINT32(data); }
}
class Script {
public:
Script(PrinceEngine *vm);
virtual ~Script();
Script();
~Script();
bool loadFromStream(Common::SeekableReadStream &stream);
void step();
template <typename T>
T read(uint32 address) {
assert((_data + address + sizeof(T)) <= (_data + _dataSize));
return Detail::LittleEndianReader<T>(&_data[address]);
}
// Some magic numbers for now, data stored in header
uint32 getRoomTableOffset() { return read<uint32>(0); }
uint32 getStartGameOffset() { return read<uint32>(4); }
const char *getString(uint32 offset) {
return (const char *)(&_data[offset]);
}
private:
uint8 *_data;
uint32 _dataSize;
};
class InterpreterFlags {
public:
InterpreterFlags();
void setFlagValue(Flags::Id flag, uint16 value);
uint16 getFlagValue(Flags::Id flag);
void resetAllFlags();
static const uint16 FLAG_MASK = 0x8000;
private:
static const uint16 MAX_FLAGS = 2000;
int16 _flags[MAX_FLAGS];
};
class Interpreter {
public:
Interpreter(PrinceEngine *vm, Script *script, InterpreterFlags *flags);
void stopBg() { _bgOpcodePC = 0; }
void step();
private:
PrinceEngine *_vm;
Script *_script;
InterpreterFlags *_flags;
byte *_code;
uint32 _codeSize;
uint32 _currentInstruction;
uint32 _bgOpcodePC;
@ -64,13 +108,9 @@ private:
uint16 _lastOpcode;
uint32 _lastInstruction;
byte _result;
static const uint16 MAX_FLAGS = 2000;
static const uint16 FLAG_MASK = 0x8000;
int16 _flags[MAX_FLAGS];
bool _opcodeNF;
bool _opcodeNF; // break interpreter loop
// Stack
static const uint32 _STACK_SIZE = 500;
uint32 _stack[_STACK_SIZE];
uint8 _stacktop;
@ -83,21 +123,19 @@ private:
// Helper functions
uint32 step(uint32 opcodePC);
void checkPC(uint32 address);
uint8 getCodeByte(uint32 address);
uint8 readScript8bits();
uint16 readScript16bits();
uint32 readScript32bits();
uint16 readScript8or16bits();
void checkPC(uint32 address);
uint16 readScriptValue();
Flags::Id readScriptFlagId() { return (Flags::Id)readScript16bits(); }
Flags::Id readScriptFlagId();
void debugScript(const char *s, ...);
// instantiation not needed here
template <typename T> T readScript();
void debugInterpreter(const char *s, ...);
void SetVoice(uint32 slot);
typedef void (Script::*OpcodeFunc)();
typedef void (Interpreter::*OpcodeFunc)();
static OpcodeFunc _opcodes[];
// Keep opcode handlers names as they are in original code
@ -246,6 +284,7 @@ private:
void O_INPUTLINE();
void O_SETVOICED();
void O_BREAK_POINT();
};
}