31 #include <boost/make_shared.hpp> 106 if ((pos > -4) || ((pos % 4) != 0))
117 if ((pos > -4) || ((pos % 4) != 0))
128 if ((pos > -4) || ((pos % 4) != 0))
139 if ((pos > -4) || ((pos % 4) != 0))
154 if ((pos > 0) || ((pos % 4) != 0))
168 if ((pos > 0) || ((pos % 4) != 0))
191 #define OPCODE(x) { &NCSFile::x, #x } 192 #define OPCODE0() { 0, "" } 195 static const Opcode opcodes[] = {
324 if (lengthOpcode != 0x42)
331 warning(
"TODO: NCSFile::load(): Script size %u < stream size %u", length, (
uint)
_script->size());
371 std::vector<class Variable>::const_reverse_iterator var;
372 for (var = state.
globals.rbegin(); var != state.
globals.rend(); ++var)
378 for (var = state.
locals.rbegin(); var != state.
locals.rend(); ++var)
381 return execute(owner, triggerer);
415 throw Common::Exception(
"NCSFile::executeStep(): Illegal instruction 0x%02x", opcode);
533 throw Common::Exception(
"NCSFile::callEngine(): Argument count mismatch (%u vs %u - %u)",
542 for (
uint8 i = 0; i < argCount; i++) {
637 e.
add(
"Failed running engine function \"%s\" (%d)",
700 const size_t size =
_script->readUint16BE();
708 std::vector<Variable> args1, args2;
713 for (
size_t i = 0; i < n; i++)
716 for (
size_t i = 0; i < n; i++)
729 const size_t size =
_script->readUint16BE();
737 std::vector<Variable> args1, args2;
742 for (
size_t i = 0; i < n; i++)
745 for (
size_t i = 0; i < n; i++)
903 else if (arg1 < 0 || arg2 < 0)
904 throw Common::Exception(
"NCSFile::o_mod(): Modulus by negative number (%d %% %d)", arg2, arg1);
1056 if ((size % 4) != 0)
1059 int32 startPos = -size;
1077 if ((size % 4) != 0)
1358 warning(
"TODO: NCSFile::o_storestateall(): %d", offset);
1394 if ((stackSize % 4) != 0)
1395 throw Common::Exception(
"NCSFile::o_destruct(): Illegal stack size %d", stackSize);
1396 if ((dontRemoveOffset % 4) != 0)
1397 throw Common::Exception(
"NCSFile::o_destruct(): Illegal offset %d", dontRemoveOffset);
1398 if ((dontRemoveSize % 4) != 0)
1399 throw Common::Exception(
"NCSFile::o_destruct(): Illegal size %d", dontRemoveSize);
1401 std::vector<Variable> tmp;
1402 tmp.reserve(dontRemoveSize / 4);
1404 while (stackSize > 0) {
1406 if ((stackSize <= (dontRemoveOffset + dontRemoveSize)) &&
1407 (stackSize > dontRemoveOffset))
1415 for (std::vector<Variable>::reverse_iterator t = tmp.rbegin(); t != tmp.rend(); ++t)
1430 if ((size % 4) != 0)
1433 int32 startPos = -size;
1454 if ((size % 4) != 0)
1475 if ((sizeBP % 4) != 0)
1477 if ((sizeSP % 4) != 0)
1488 for (
int32 posBP = -4; sizeBP > 0; sizeBP--, posBP -= 4)
1491 for (
int32 posSP = -4; sizeSP > 0; sizeSP--, posSP -= 4)
1526 arrayVar.
getArray()[index] = boost::make_shared<Variable>(
Variable(valueVar));
1556 if ((index < 0) || ((
uint)index >= array.size()))
1558 index, (
uint) array.size());
1619 if ((index < 0) || ((
uint)index >= array.size()))
1620 throw Common::Exception(
"NCSFile::o_getrefarray(): Index out of range (%d, %u)",
1621 index, (
uint) array.size());
VariableContainer & getEnvironment()
Return the script's environment variables.
#define ResMan
Shortcut for accessing the sound manager.
void o_retn(InstructionType type)
RETN: return from a subroutine call.
ObjectReference _triggerer
void setReference(Variable *reference)
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like 'DATA', to ensure portability.
std::vector< boost::shared_ptr< Variable > > Array
static const uint32 kVersion10
void formatVariable(Common::UString &str, const Variable &var)
Print a description of this variable into that string.
void add(const char *s,...) GCC_PRINTF(2
void o_ushright(InstructionType type)
USHRIGHT: shift the top-most stack element to the right (>>).
void o_writearray(InstructionType type)
WRITEARRAY: write the value of an array element on the stack.
void o_leq(InstructionType type)
LEQ: compare the top-most stack elements, less-or-equal (<=).
void debugC(Common::DebugChannel channel, uint32 level, const char *s,...)
void reset()
Reset the script for another execution.
void o_destruct(InstructionType type)
DESTRUCT: remove elements from the stack.
A class holding an UTF-8 string.
void o_getref(InstructionType type)
GETREF: push the reference to a stack element onto the stack.
void setTriggerer(Object *obj)
void reset(PointerType o=0)
Resets the pointer with the new value.
Utility functions for debug output.
void o_incsp(InstructionType type)
INCSP: increment the value of a stack element (++).
void o_decsp(InstructionType type)
DECSP: decrement the value of a stack element (–).
static const uint32 kScriptObjectTypeInvalid
void setBasePtr(int32 pos)
Variable & getRelSP(int32 pos)
void o_movsp(InstructionType type)
MOVSP: pop elements off the stack.
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
void o_comp(InstructionType type)
COMP: calculate the 1-complement of the top-most stack element (~).
bool executeStep()
Execute one script step.
static const uint32 kVersion10
void o_lt(InstructionType type)
LT: compare the top-most stack elements, less (<).
void o_rsadd(InstructionType type)
RSADD: push an empty variable onto the stack.
void growArray(Type type, size_t size)
void setParamsSpecified(size_t params)
void o_jsr(InstructionType type)
JSR: call a subroutine.
size_t getParamMin() const
void setCaller(Object *obj)
The NWScript function manager.
Exception that provides a stack of explanations.
static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le)
Read the header out of a stream.
const Variable & execute(const ObjectReference owner=ObjectReference(), const ObjectReference triggerer=ObjectReference())
void o_excor(InstructionType type)
EXCOR: perform a bit-wise exclusive OR (^).
void getVector(float &x, float &y, float &z) const
void o_cptopbp(InstructionType type)
CPTOPBP: push a copy of a base-pointer stack element on top of the stack.
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Variable & getRelBP(int32 pos)
size_t getParamMax() const
Common::ScopedPtr< Common::SeekableReadStream > _script
const Variable & run(Object *owner=0, Object *triggerer=0)
Run the current script, from start to finish.
Utility templates and functions.
void o_savebp(InstructionType type)
SAVEBP: set the value of the base-pointer.
void o_restorebp(InstructionType type)
RESTOREBP: restore the value of the base-pointer to a prior value.
void o_storestate(InstructionType type)
STORESTATE: create a functor of a subroutine with the current stack.
void setVector(float x, float y, float z)
void o_eq(InstructionType type)
EQ: compare the top-most stack elements for equality (==).
void o_add(InstructionType type)
ADD: add the top-most stack elements (+).
void o_jnz(InstructionType type)
JNZ: jump conditionally if the top-most stack element is not 0.
void o_neq(InstructionType type)
NEQ: compare the top-most stack elements for inequality (!=).
Utility functions for working with differing string encodings.
A reference/pointer to another variable.
"GScripts", global, non-engine scripts.
void o_sub(InstructionType type)
SUB: subtract the top-most stack elements (-).
const Common::UString & getName() const
void o_storestateall(InstructionType type)
STORESTATEALL: unused, obsolete opcode.
void o_readarray(InstructionType type)
READARRAY: push the value of an array element onto of the stack.
uint32 _id
The file's ID.
uint32 _version
The file's version.
void o_const(InstructionType type)
CONST: push a constant (predetermined value) variable onto the stack.
ScriptState & getScriptState()
void setCurrentScript(NCSFile *script=0)
std::stack< uint32 > _returnOffsets
void setStackPtr(int32 pos)
void warning(const char *s,...)
void setRelSP(int32 pos, const Variable &obj)
void o_logor(InstructionType type)
LOGOR: perform a logical boolean OR (||).
void o_mul(InstructionType type)
MUL: multiply the top-most stack elements (*).
void o_getrefarray(InstructionType type)
GETREFARRAY: push the reference to an array element onto the stack.
Basic reading stream interfaces.
#define DebugMan
Shortcut for accessing the debug manager.
void o_neg(InstructionType type)
NEQ: negate the top-most stack element (unary -).
static ScriptState getEmptyState()
void o_cpdownsp(InstructionType type)
CPDOWNSP: copy a value into an existing stack element.
Handling BioWare's NWN Compiled Scripts.
void callEngine(Aurora::NWScript::FunctionContext &ctx, uint32 function, uint8 argCount)
Helper function for o_action(), doing the actual engine function calling.
Plain, unextended ASCII (7bit clean).
void o_div(InstructionType type)
DIV: divide the top-most stack elements (/).
void push(const Variable &obj)
void o_action(InstructionType type)
ACTION: call a game-specific engine function.
"effect", "event", "location", "talent"...
void o_nop(InstructionType type)
NOP: no operation.
std::vector< class Variable > locals
void o_cptopsp(InstructionType type)
CPTOPSP: push a copy of a stack element on top of the stack.
Script, NWScript bytecode.
void o_logand(InstructionType type)
LOGAND: perform a logical boolean AND (&&).
void o_mod(InstructionType type)
MOD: calculate the remainder (modulo) of an integer division (%).
static const uint32 kScriptObjectInvalid2
const Array & getArray() const
Common::UString & getString()
static const uint32 kScriptObjectInvalid
NCSFile(Common::SeekableReadStream *ncs)
void o_jz(InstructionType type)
JZ: jump conditionally if the top-most stack element is 0.
void o_cpdownbp(InstructionType type)
CPDOWNBP: copy a value into an existing base-pointer stack element.
void o_not(InstructionType type)
NOT: boolean-negate the top-most stack element (!).
void setRelBP(int32 pos, const Variable &obj)
void o_incbp(InstructionType type)
INCBP: increment the value of a base-pointer stack element (++).
const Common::UString & getName() const
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
void o_gt(InstructionType type)
GT: compare the top-most stack elements, greater (>).
void o_shright(InstructionType type)
SHRIGHT: signed-shift the top-most stack element to the right (>>>).
void o_decbp(InstructionType type)
DECBP: decrement the value of a base-pointer stack element (–).
void o_booland(InstructionType type)
BOOLAND: perform a bit-wise AND (&).
static const uint32 kNCSTag
void o_jmp(InstructionType type)
JMP: jump directly to a different script offset.
std::vector< class Variable > globals
void o_incor(InstructionType type)
INCOR: perform a bit-wise inclusive OR (|).
Interface for a seekable & readable data stream.
static const uint32 kScriptObjectSelf
void o_geq(InstructionType type)
GEQ: compare the top-most stack elements, greater-or-equal (>=).
void o_shleft(InstructionType type)
SHLEFT: shift the top-most stack element to the left (<<).
The global resource manager for Aurora resources.
void setEnvironment(const VariableContainer &env)
Overwrite the environment.