This commit is contained in:
parent
bf7bd6c3ea
commit
70840d8bc3
2 changed files with 509 additions and 0 deletions
374
source/script/script.cpp
Normal file
374
source/script/script.cpp
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
script.cpp
|
||||||
|
|
||||||
|
Author: PKG
|
||||||
|
Created:
|
||||||
|
Project: Spongebob
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Copyright (c) 2000 Climax Development Ltd
|
||||||
|
|
||||||
|
===========================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Includes
|
||||||
|
-------- */
|
||||||
|
|
||||||
|
#include "paul\script.h"
|
||||||
|
|
||||||
|
#ifndef __SYSTEM_DBG_H__
|
||||||
|
#include "system\dbg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __MEMORY_HEADER__
|
||||||
|
#include "mem\memory.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Std Lib
|
||||||
|
------- */
|
||||||
|
|
||||||
|
/* Data
|
||||||
|
---- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Tyepdefs && Defines
|
||||||
|
------------------- */
|
||||||
|
|
||||||
|
//#define FULL_CODE_OUTPUT
|
||||||
|
//#define SHOW_RUN_COUNT
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Structure defintions
|
||||||
|
-------------------- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function Prototypes
|
||||||
|
------------------- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Vars
|
||||||
|
---- */
|
||||||
|
|
||||||
|
signed short CScript::s_globalVars[NUM_GLOBAL_VARS]=
|
||||||
|
{
|
||||||
|
0, // LIVES
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::initialise(FileEquate _fe)
|
||||||
|
{
|
||||||
|
m_code=(unsigned short*)CFileIO::loadFile(_fe);
|
||||||
|
m_stack=(unsigned short*)MemAlloc(sizeof(unsigned short)*STACK_SIZE,"ScriptStack");
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::run()
|
||||||
|
{
|
||||||
|
#ifdef SHOW_RUN_COUNT
|
||||||
|
int run=0;
|
||||||
|
#endif
|
||||||
|
if(m_state<=RUNNING)
|
||||||
|
{
|
||||||
|
m_state=RUNNING;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
executeNextInstruction();
|
||||||
|
#ifdef SHOW_RUN_COUNT
|
||||||
|
run++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
while(m_state==RUNNING);
|
||||||
|
}
|
||||||
|
#ifdef SHOW_RUN_COUNT
|
||||||
|
if(run)
|
||||||
|
{
|
||||||
|
PAUL_DBGMSG("ran %d instructions",run);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
int testval=2;
|
||||||
|
void CScript::reset()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
m_pc=0;
|
||||||
|
m_sp=0;
|
||||||
|
for(i=0;i<NUM_LOCAL_VARS;i++)
|
||||||
|
{
|
||||||
|
m_localVars[i]=0;
|
||||||
|
}
|
||||||
|
m_localVars[TMP1]=testval;
|
||||||
|
m_state=RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
int CScript::isFinished()
|
||||||
|
{
|
||||||
|
return !(m_state<=RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::executeNextInstruction()
|
||||||
|
{
|
||||||
|
unsigned short instruction;
|
||||||
|
signed short val1,val2,val3;
|
||||||
|
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("pc:0x%04d sp:%03d",m_pc*2,m_sp);
|
||||||
|
#endif
|
||||||
|
instruction=readNextInstruction();
|
||||||
|
switch(instruction)
|
||||||
|
{
|
||||||
|
case OP_NOP:
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("NOP");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_STOP: //
|
||||||
|
PAUL_DBGMSG("STOP");
|
||||||
|
if(m_sp==0)
|
||||||
|
{
|
||||||
|
m_state=STOPPED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PAUL_DBGMSG("!STACK NOT EMPTY!");
|
||||||
|
m_state=STOPPED_STACK_NOT_EMPTY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_PAUSE: //
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("PAUSE");
|
||||||
|
#endif
|
||||||
|
m_state=PAUSED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_PUSHVALUE: // value
|
||||||
|
val1=readNextInstruction();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("PUSHVALUE %d",val1);
|
||||||
|
#endif
|
||||||
|
push(val1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_PUSHVARVALUE: // varidx
|
||||||
|
val1=readNextInstruction();
|
||||||
|
val2=getVar(val1);
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("PUSHVARVALUE $%d ( %d )",val1,val2);
|
||||||
|
#endif
|
||||||
|
push(val2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_JMP: // jump
|
||||||
|
val1=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("JMP %d",val1);
|
||||||
|
#endif
|
||||||
|
jump(val1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_JMPF: // jump, value
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("JMPF %d,%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
if(val2==0)jump(val1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_JMPT: // jump, value
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("JMPT %d,%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
if(val2!=0)jump(val1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_IS_EQUAL_VALUE: // value, value pushes result ( 0 or 1 ) to stack
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("IS_EQUAL_VALUE %d,%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
push(val1==val2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_IS_NOTEQUAL_VALUE: // value, value pushes result ( 0 or 1 ) to stack
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("IS_NOTEQUAL_VALUE %d,%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
push(val1!=val2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_ASSIGN: // varidx, value
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("$%d=%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
setVar(val1,val2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_ADD: // value, value pushes result to stack
|
||||||
|
val1=pop();
|
||||||
|
val2=pop();
|
||||||
|
#ifdef FULL_CODE_OUTPUT
|
||||||
|
PAUL_DBGMSG("ADD %d,%d",val1,val2);
|
||||||
|
#endif
|
||||||
|
push(val1+val2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_PRINT: // value
|
||||||
|
val1=pop();
|
||||||
|
PAUL_DBGMSG("PRINT %d",val1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PAUL_DBGMSG("ILLEGAL OPCODE@%d ( %d )",m_pc,instruction);
|
||||||
|
m_state=CRASHED_ILLEGAL_OPCODE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
unsigned short CScript::readNextInstruction()
|
||||||
|
{
|
||||||
|
return m_code[m_pc++];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::jump(signed short _distance)
|
||||||
|
{
|
||||||
|
m_pc+=_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::push(unsigned short _data)
|
||||||
|
{
|
||||||
|
ASSERT(m_sp<=STACK_SIZE-1); // Stack overflow about to occur :(
|
||||||
|
m_stack[m_sp++]=_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
unsigned short CScript::pop()
|
||||||
|
{
|
||||||
|
ASSERT(m_sp>=1); // Stack underflow about to occur :(
|
||||||
|
return(m_stack[--m_sp]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
void CScript::setVar(int _varIdx,signed short _value)
|
||||||
|
{
|
||||||
|
ASSERT(_varIdx>=0&&_varIdx<=NUM_GLOBAL_VARS+NUM_LOCAL_VARS-1);
|
||||||
|
|
||||||
|
if(_varIdx<NUM_GLOBAL_VARS)
|
||||||
|
{
|
||||||
|
ASSERT(0); // Need to update global vars.. (PKG)
|
||||||
|
s_globalVars[_varIdx]=_value;
|
||||||
|
}
|
||||||
|
else if(_varIdx<NUM_GLOBAL_VARS+NUM_LOCAL_VARS)
|
||||||
|
{
|
||||||
|
m_localVars[_varIdx-NUM_GLOBAL_VARS]=_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Function:
|
||||||
|
Purpose:
|
||||||
|
Params:
|
||||||
|
Returns:
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
|
signed short CScript::getVar(int _varIdx)
|
||||||
|
{
|
||||||
|
ASSERT(_varIdx>=0&&_varIdx<=NUM_GLOBAL_VARS+NUM_LOCAL_VARS-1);
|
||||||
|
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
if(_varIdx<NUM_GLOBAL_VARS)
|
||||||
|
{
|
||||||
|
ASSERT(0); // Need to read global vars.. (PKG)
|
||||||
|
ret=s_globalVars[_varIdx];
|
||||||
|
}
|
||||||
|
else if(_varIdx<NUM_GLOBAL_VARS+NUM_LOCAL_VARS)
|
||||||
|
{
|
||||||
|
ret=m_localVars[_varIdx-NUM_GLOBAL_VARS];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================
|
||||||
|
end */
|
135
source/script/script.h
Normal file
135
source/script/script.h
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
script.h
|
||||||
|
|
||||||
|
Author: PKG
|
||||||
|
Created:
|
||||||
|
Project: Spongebob
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Copyright (c) 2000 Climax Development Ltd
|
||||||
|
|
||||||
|
===========================================================================*/
|
||||||
|
|
||||||
|
#ifndef __PAUL_SCRIPT_H__
|
||||||
|
#define __PAUL_SCRIPT_H__
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Includes
|
||||||
|
-------- */
|
||||||
|
|
||||||
|
#ifndef _FILEIO_HEADER_
|
||||||
|
#include "fileio\fileio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Std Lib
|
||||||
|
------- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Tyepdefs && Defines
|
||||||
|
------------------- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Structure defintions
|
||||||
|
-------------------- */
|
||||||
|
|
||||||
|
class CScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void initialise(FileEquate _fe);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void run();
|
||||||
|
|
||||||
|
int isFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Global vars
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LIVES,
|
||||||
|
NUM_GLOBAL_VARS,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Local vars
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TMP1,
|
||||||
|
TMP2,
|
||||||
|
TMP3,
|
||||||
|
NUM_LOCAL_VARS,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RESET,
|
||||||
|
PAUSED,
|
||||||
|
RUNNING,
|
||||||
|
|
||||||
|
STOPPED,
|
||||||
|
|
||||||
|
STOPPED_STACK_NOT_EMPTY,
|
||||||
|
CRASHED_ILLEGAL_OPCODE,
|
||||||
|
}ScriptState;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STACK_SIZE=20,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// args stack data result
|
||||||
|
OP_NOP=0x1100, //
|
||||||
|
OP_STOP, //
|
||||||
|
OP_PAUSE,
|
||||||
|
OP_PUSHVALUE, // value
|
||||||
|
OP_PUSHVARVALUE, // varidx
|
||||||
|
OP_JMP, // jump
|
||||||
|
OP_JMPF, // jump, value
|
||||||
|
OP_JMPT, // jump, value
|
||||||
|
OP_IS_EQUAL_VALUE, // value, value pushes result ( 0 or 1 ) to stack
|
||||||
|
OP_IS_NOTEQUAL_VALUE, // value, value pushes result ( 0 or 1 ) to stack
|
||||||
|
OP_ASSIGN, // varidx, value
|
||||||
|
OP_ADD, // value, value pushes result to stack
|
||||||
|
OP_PRINT, // value
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void executeNextInstruction();
|
||||||
|
unsigned short readNextInstruction();
|
||||||
|
void jump(signed short _distance);
|
||||||
|
void push(unsigned short _data);
|
||||||
|
unsigned short pop();
|
||||||
|
void setVar(int _varIdx,signed short _value);
|
||||||
|
signed short getVar(int _varIdx);
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short *m_code;
|
||||||
|
int m_pc;
|
||||||
|
|
||||||
|
unsigned short *m_stack;
|
||||||
|
int m_sp;
|
||||||
|
|
||||||
|
static signed short s_globalVars[NUM_GLOBAL_VARS];
|
||||||
|
signed short m_localVars[NUM_LOCAL_VARS];
|
||||||
|
|
||||||
|
ScriptState m_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Globals
|
||||||
|
------- */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
Functions
|
||||||
|
--------- */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#endif /* __PAUL_SCRIPT_H__ */
|
||||||
|
|
||||||
|
/*===========================================================================
|
||||||
|
end */
|
Loading…
Add table
Reference in a new issue