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