This commit is contained in:
Paul 2000-12-12 20:55:10 +00:00
parent bf7bd6c3ea
commit 70840d8bc3
2 changed files with 509 additions and 0 deletions

374
source/script/script.cpp Normal file
View 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
View 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 */