Merge in some of LordHotos kyra code, with some changes.
It's still non-functional, but once I merge in some more of my local changes things should actually be moving a long a bit. svn-id: r15554
This commit is contained in:
parent
9e40ef7d29
commit
8f65711a28
15 changed files with 2645 additions and 27 deletions
506
kyra/script.cpp
Normal file
506
kyra/script.cpp
Normal file
|
@ -0,0 +1,506 @@
|
|||
/* ScummVM - Kyrandia Interpreter
|
||||
* Copyright (C) 2003-2004 The ScummVM project
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "kyra.h"
|
||||
#include "script.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#define COMMAND(x) { &VMContext::x, #x }
|
||||
#define OPCODE(x) { &VMContext::x, #x }
|
||||
|
||||
namespace Kyra {
|
||||
VMContext::VMContext(KyraEngine* engine) {
|
||||
_engine = engine;
|
||||
|
||||
// now we create a list of all Command/Opcode procs and so
|
||||
static CommandEntry commandProcs[] = {
|
||||
// 0
|
||||
COMMAND(c1_goToLine),
|
||||
COMMAND(c1_setReturn),
|
||||
COMMAND(c1_pushRetRec),
|
||||
COMMAND(c1_push),
|
||||
COMMAND(c1_push),
|
||||
COMMAND(c1_pushVar),
|
||||
COMMAND(c1_pushFrameNeg),
|
||||
COMMAND(c1_pushFramePos),
|
||||
COMMAND(c1_popRetRec),
|
||||
COMMAND(c1_popVar),
|
||||
|
||||
// 10
|
||||
COMMAND(c1_popFrameNeg),
|
||||
COMMAND(c1_popFramePos),
|
||||
COMMAND(c1_addToSP),
|
||||
COMMAND(c1_subFromSP),
|
||||
COMMAND(c1_execOpcode),
|
||||
COMMAND(c1_ifNotGoTo),
|
||||
COMMAND(c1_negate),
|
||||
COMMAND(c1_evaluate),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 20
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 30
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 40
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 50
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 60
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 70
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 80
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 90
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 100
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 110
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 120
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 130
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 140
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 150
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 160
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 170
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 180
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 190
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 200
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 210
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 220
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 230
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 240
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
|
||||
// 250
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
COMMAND(c1_unknownCommand),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
_scriptFile = NULL;
|
||||
_scriptFileSize = 0;
|
||||
}
|
||||
|
||||
void VMContext::loadScript(const char* file) {
|
||||
printf("a\n");
|
||||
if (_scriptFile) {
|
||||
delete [] _scriptFile;
|
||||
_scriptFileSize = 0;
|
||||
}
|
||||
|
||||
debug("--------------");
|
||||
|
||||
// loads the new file
|
||||
_scriptFile = _engine->resManager()->fileData(file, &_scriptFileSize);
|
||||
printf("c\n");
|
||||
|
||||
if (!_scriptFileSize || !_scriptFile) {
|
||||
error("couldn't load script file '%s'", file);
|
||||
}
|
||||
|
||||
Common::MemoryReadStream script(_scriptFile, _scriptFileSize);
|
||||
memset(_chunks, 0, sizeof(ScriptChunk) * kCountChunkTypes);
|
||||
uint8 chunkName[sizeof("EMC2ORDR") + 1];
|
||||
|
||||
// so lets look for our chunks :)
|
||||
while(true) {
|
||||
if (script.eof()) {
|
||||
break;
|
||||
}
|
||||
// lets read only the first 4 chars
|
||||
script.read(chunkName, sizeof(uint8) * 4);
|
||||
chunkName[4] = '\0';
|
||||
debug("chunk name(4 chars): '%s'", chunkName);
|
||||
|
||||
// check name of chunk
|
||||
if (!scumm_stricmp((char*)chunkName, "FORM")) {
|
||||
// FreeKyra swaps the size I only read it in BigEndian :)
|
||||
_chunks[kForm]._size = script.readUint32BE();
|
||||
debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);
|
||||
} else if (!scumm_stricmp((char*)chunkName, "TEXT")) {
|
||||
uint32 text_size = script.readUint32BE();
|
||||
text_size += text_size % 2 != 0 ? 1 : 0;
|
||||
|
||||
_chunks[kText]._data = _scriptFile + script.pos();
|
||||
_chunks[kText]._size = READ_BE_UINT16(_chunks[kText]._data) >> 1;
|
||||
_chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);
|
||||
debug("_chunks[kText]._size = %d, real chunk size = %d", _chunks[kText]._size, text_size);
|
||||
|
||||
script.seek(script.pos() + text_size);
|
||||
} else if (!scumm_stricmp((char*)chunkName, "DATA")) {
|
||||
_chunks[kData]._size = script.readUint32BE();
|
||||
_chunks[kData]._data = _scriptFile + script.pos();
|
||||
debug("_chunks[kData]._size = %d", _chunks[kData]._size);
|
||||
|
||||
// mostly it will be the end of the file because all files should end with a 'DATA' chunk
|
||||
script.seek(script.pos() + _chunks[kData]._size);
|
||||
} else {
|
||||
// read next 4 chars
|
||||
script.read(&chunkName[4], sizeof(uint8) * 4);
|
||||
chunkName[8] = '\0';
|
||||
debug("chunk name(8 chars): '%s'", chunkName);
|
||||
|
||||
if (!scumm_stricmp((char*)chunkName, "EMC2ORDR")) {
|
||||
_chunks[kEmc2Ordr]._size = script.readUint32BE() >> 1;
|
||||
_chunks[kEmc2Ordr]._data = _scriptFile + script.pos();
|
||||
debug("_chunks[kEmc2Ordr]._size = %d, real chunk size = %d", _chunks[kEmc2Ordr]._size, _chunks[kEmc2Ordr]._size * 2);
|
||||
|
||||
script.seek(script.pos() + _chunks[kEmc2Ordr]._size * 2);
|
||||
} else {
|
||||
// any unkown chunk or problems with seeking through the file
|
||||
error("unknown chunk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// so file loaded
|
||||
debug("--------------");
|
||||
}
|
||||
|
||||
int32 VMContext::param(int32 index) {
|
||||
if (_stackPos - index + 1 >= 16 || _stackPos - index + 1 < 0)
|
||||
return -0xFFFF;
|
||||
return _stack[_stackPos - index + 1];
|
||||
}
|
||||
|
||||
const char* VMContext::stringAtIndex(int32 index) {
|
||||
if (index < 0 || (uint32)index >= _chunks[kText]._size)
|
||||
return 0;
|
||||
|
||||
return (char*)(_chunks[kText]._additional + _chunks[kText]._data[index]);
|
||||
}
|
||||
|
||||
bool VMContext::startScript(int32 func) {
|
||||
if ((uint32)func >= _chunks[kEmc2Ordr]._size || func < 0) {
|
||||
debug("script doesn't support function %d", func);
|
||||
return false;
|
||||
}
|
||||
|
||||
_instructionPos = (READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1) + 2;
|
||||
_stackPos = 0;
|
||||
_tempPos = 0;
|
||||
_delay = 0;
|
||||
_scriptState = kScriptRunning;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 VMContext::contScript(void) {
|
||||
uint8* script_start = _chunks[kData]._data;
|
||||
assert(script_start);
|
||||
|
||||
uint32 scriptStateAtStart = _scriptState;
|
||||
|
||||
// runs the script
|
||||
while(true) {
|
||||
if ((uint32)_instructionPos > _chunks[kData]._size) {
|
||||
debug("_instructionPos( = %d) > _chunks[kData]._size( = %d)", _instructionPos, _chunks[kData]._size);
|
||||
_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
_currentCommand = *(script_start + _instructionPos++);
|
||||
|
||||
// gets out
|
||||
if (_currentCommand & 0x80) {
|
||||
_argument = ((_currentCommand & 0x0F) << 8) | *(script_start + _instructionPos++);
|
||||
_currentCommand &= 0xF0;
|
||||
} else if (_currentCommand & 0x40) {
|
||||
_argument = *(script_start + _instructionPos++);
|
||||
} else if (_currentCommand & 0x20) {
|
||||
_instructionPos++;
|
||||
|
||||
uint16 tmp = *(uint16*)(script_start + _instructionPos);
|
||||
tmp &= 0xFF7F;
|
||||
|
||||
_argument = READ_BE_UINT16(&tmp);
|
||||
_instructionPos += 2;
|
||||
} else {
|
||||
debug("unknown way of getting the command");
|
||||
}
|
||||
|
||||
_currentCommand &= 0x1f;
|
||||
|
||||
CommandProc currentProc = _commands[_currentCommand].proc;
|
||||
(this->*currentProc)();
|
||||
|
||||
if (_error) {
|
||||
_scriptState = kScriptError;
|
||||
break;
|
||||
}
|
||||
|
||||
if (scriptStateAtStart != _scriptState) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _scriptState;
|
||||
}
|
||||
} // end of namespace Kyra
|
Loading…
Add table
Add a link
Reference in a new issue