cleanup
svn-id: r10333
This commit is contained in:
parent
f4861af4d2
commit
6539b8a0e6
11 changed files with 2569 additions and 3121 deletions
|
@ -19,18 +19,16 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#ifndef INSIDE_LINC // Are we running in linc?
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "driver/driver96.h"
|
#include "driver/driver96.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This file serves two purposes. It is compiled as part of the test functions
|
// This file serves two purposes. It is compiled as part of the test functions
|
||||||
// of Linc, and also as part of the game
|
// of Linc, and also as part of the game
|
||||||
|
|
||||||
|
// I assume Linc was the name of some sort of development tool. Anyway, I've
|
||||||
|
// removed the pieces of code that were labelled as INSIDE_LINC, because they
|
||||||
|
// didn't look easily portable.
|
||||||
|
|
||||||
// The machine code table
|
// The machine code table
|
||||||
|
|
||||||
|
@ -156,14 +154,13 @@ int32 FN_change_shadows(int32 *params);
|
||||||
|
|
||||||
extern int32 (*McodeTable[]) (int32 *);
|
extern int32 (*McodeTable[]) (int32 *);
|
||||||
|
|
||||||
#ifndef INSIDE_LINC
|
// Point to the global variable data
|
||||||
int32 * globalInterpreterVariables2 = NULL; // Point to the global varibale data
|
int32 *globalInterpreterVariables2 = NULL;
|
||||||
|
|
||||||
int g_debugFlag = 0; // Set this to turn debugging on
|
int g_debugFlag = 0; // Set this to turn debugging on
|
||||||
#endif
|
|
||||||
|
|
||||||
|
int32 (*McodeTable[MAX_FN_NUMBER + 1]) (int32 *) = {
|
||||||
int32 (*McodeTable[MAX_FN_NUMBER+1])(int32 *) =
|
FN_test_function,
|
||||||
{ FN_test_function,
|
|
||||||
FN_test_flags,
|
FN_test_flags,
|
||||||
FN_register_start_point,
|
FN_register_start_point,
|
||||||
FN_init_background,
|
FN_init_background,
|
||||||
|
@ -283,38 +280,27 @@ int32 (*McodeTable[MAX_FN_NUMBER+1])(int32 *) =
|
||||||
FN_change_shadows,
|
FN_change_shadows,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHECKSTACKPOINTER2 ASSERT((stackPointer2>=0)&&(stackPointer2<STACK_SIZE));
|
#define CHECKSTACKPOINTER2 ASSERT(stackPointer2 >= 0 && stackPointer2 < STACK_SIZE);
|
||||||
#define PUSHONSTACK(x) {stack2[stackPointer2] = (x);stackPointer2++;CHECKSTACKPOINTER2;}
|
#define PUSHONSTACK(x) { stack2[stackPointer2] = (x); stackPointer2++; CHECKSTACKPOINTER2 }
|
||||||
#define POPOFFSTACK(x) {x=stack2[stackPointer2-1];stackPointer2--;CHECKSTACKPOINTER2;}
|
#define POPOFFSTACK(x) { x = stack2[stackPointer2 - 1]; stackPointer2--; CHECKSTACKPOINTER2 }
|
||||||
#define DOOPERATION(x) {stack2[stackPointer2-2] = (x);stackPointer2--;CHECKSTACKPOINTER2;}
|
#define DOOPERATION(x) { stack2[stackPointer2 - 2] = (x); stackPointer2--; CHECKSTACKPOINTER2 }
|
||||||
|
|
||||||
#ifndef INSIDE_LINC
|
void SetGlobalInterpreterVariables(int32 *vars) {
|
||||||
void SetGlobalInterpreterVariables(int32 *vars)
|
|
||||||
{
|
|
||||||
globalInterpreterVariables2 = vars;
|
globalInterpreterVariables2 = vars;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef INSIDE_LINC // Are we running in linc?
|
int RunScript(char *scriptData, char *objectData, uint32 *offset) {
|
||||||
int RunScript ( MCBOVirtualSword &engine , const char * scriptData , char * objectData , uint32 *offset )
|
|
||||||
#else
|
|
||||||
int RunScript ( char * scriptData , char * objectData , uint32 *offset )
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#define STACK_SIZE 10
|
#define STACK_SIZE 10
|
||||||
|
|
||||||
_standardHeader *header = (_standardHeader *) scriptData;
|
_standardHeader *header = (_standardHeader *) scriptData;
|
||||||
scriptData += sizeof(_standardHeader) + sizeof(_object_hub);
|
scriptData += sizeof(_standardHeader) + sizeof(_object_hub);
|
||||||
|
|
||||||
// The script data format:
|
// The script data format:
|
||||||
|
|
||||||
|
|
||||||
// int32_TYPE 1 Size of variable space in bytes
|
// int32_TYPE 1 Size of variable space in bytes
|
||||||
// ... The variable space
|
// ... The variable space
|
||||||
// int32_TYPE 1 numberOfScripts
|
// int32_TYPE 1 numberOfScripts
|
||||||
// int32_TYPE numberOfScripts The offsets for each script
|
// int32_TYPE numberOfScripts The offsets for each script
|
||||||
|
|
||||||
|
|
||||||
// Initialise some stuff
|
// Initialise some stuff
|
||||||
|
|
||||||
int ip = 0; // Code pointer
|
int ip = 0; // Code pointer
|
||||||
|
@ -324,279 +310,246 @@ int RunScript ( char * scriptData , char * objectData , uint32 *offset )
|
||||||
int parameterReturnedFromMcodeFunction = 0; // Allow scripts to return things
|
int parameterReturnedFromMcodeFunction = 0; // Allow scripts to return things
|
||||||
int savedStartOfMcode = 0; // For saving start of mcode commands
|
int savedStartOfMcode = 0; // For saving start of mcode commands
|
||||||
|
|
||||||
|
int count;
|
||||||
|
int retVal;
|
||||||
|
int caseCount, foundCase;
|
||||||
|
int scriptNumber, foundScript;
|
||||||
|
const char *tempScrPtr;
|
||||||
|
|
||||||
// Get the start of variables and start of code
|
// Get the start of variables and start of code
|
||||||
DEBUG3("Enter interpreter data %x, object %x, offset %d",scriptData,objectData,*offset);
|
DEBUG("Enter interpreter data %x, object %x, offset %d", scriptData, objectData, *offset);
|
||||||
|
|
||||||
// FIXME: 'scriptData' and 'variables' used to be const. However,
|
// FIXME: 'scriptData' and 'variables' used to be const. However,
|
||||||
// this code writes into 'variables' so it can not be const.
|
// this code writes into 'variables' so it can not be const.
|
||||||
|
|
||||||
char *variables = scriptData + sizeof(int);
|
char *variables = scriptData + sizeof(int);
|
||||||
const char *code = scriptData + (int32) READ_LE_UINT32(scriptData) + sizeof(int);
|
const char *code = scriptData + (int32) READ_LE_UINT32(scriptData) + sizeof(int);
|
||||||
uint32 noScripts = (int32) READ_LE_UINT32(code);
|
uint32 noScripts = (int32) READ_LE_UINT32(code);
|
||||||
if ( (*offset) < noScripts)
|
|
||||||
{ ip = (int32)READ_LE_UINT32((const int *)code + (*offset) + 1);
|
if (*offset < noScripts) {
|
||||||
DEBUG2("Start script %d with offset %d",*offset,ip);
|
ip = READ_LE_UINT32((const int *) code + *offset + 1);
|
||||||
}
|
DEBUG("Start script %d with offset %d",*offset,ip);
|
||||||
else
|
} else {
|
||||||
{ ip = (*offset);
|
ip = *offset;
|
||||||
DEBUG1("Start script with offset %d",ip);
|
DEBUG("Start script with offset %d",ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
code += noScripts * sizeof(int) + sizeof(int);
|
code += noScripts * sizeof(int) + sizeof(int);
|
||||||
|
|
||||||
/************************************************************************************************/
|
|
||||||
#ifdef DONTPROCESSSCRIPTCHECKSUM
|
#ifdef DONTPROCESSSCRIPTCHECKSUM
|
||||||
|
|
||||||
code += sizeof(int) * 3;
|
code += sizeof(int) * 3;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
// Code should nop be pointing at an identifier and a checksum
|
||||||
// Code should nopw be pointing at an identifier and a checksum
|
|
||||||
const int *checksumBlock = (const int *) code;
|
const int *checksumBlock = (const int *) code;
|
||||||
code += sizeof(int) * 3;
|
code += sizeof(int) * 3;
|
||||||
|
|
||||||
if ((int32)READ_LE_UINT32(checksumBlock) != 12345678)
|
if (READ_LE_UINT32(checksumBlock) != 12345678) {
|
||||||
{
|
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
AfxMessageBox(CVString("Invalid script in object %s",header->name));
|
|
||||||
#else
|
|
||||||
Con_fatal_error("Invalid script in object %s", header->name);
|
Con_fatal_error("Invalid script in object %s", header->name);
|
||||||
#endif
|
return 0;
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
int codeLen = (int32)READ_LE_UINT32(checksumBlock + 1);
|
|
||||||
|
int codeLen = READ_LE_UINT32(checksumBlock + 1);
|
||||||
int checksum = 0;
|
int checksum = 0;
|
||||||
for (int count = 0 ; count < codeLen ; count++)
|
|
||||||
|
for (count = 0; count < codeLen; count++)
|
||||||
checksum += (unsigned char) code[count];
|
checksum += (unsigned char) code[count];
|
||||||
if ( checksum != (int32)READ_LE_UINT32(checksumBlock + 2) )
|
|
||||||
{
|
if (checksum != (int32) READ_LE_UINT32(checksumBlock + 2)) {
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
AfxMessageBox(CVString("Checksum error in script %s",header->name));
|
|
||||||
#else
|
|
||||||
Con_fatal_error("Checksum error in object %s", header->name);
|
Con_fatal_error("Checksum error in object %s", header->name);
|
||||||
#endif
|
return 0;
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif //DONTPROCESSSCRIPTCHECKSUM
|
|
||||||
|
|
||||||
/************************************************************************************************/
|
|
||||||
|
|
||||||
int runningScript = 1;
|
int runningScript = 1;
|
||||||
while ( runningScript )
|
|
||||||
{ curCommand = code[ip++];
|
while (runningScript) {
|
||||||
switch(curCommand)
|
curCommand = code[ip++];
|
||||||
{ case CP_END_SCRIPT: // 0 End the script
|
|
||||||
DEBUG1("End script",0);
|
switch(curCommand) {
|
||||||
|
case CP_END_SCRIPT:
|
||||||
|
// End the script
|
||||||
|
DEBUG("End script",0);
|
||||||
runningScript = 0;
|
runningScript = 0;
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
engine.AddTextLine( "End script" , VS_COL_GREY );
|
|
||||||
engine.AddTextLine( "" , VS_COL_GREY );
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_PUSH_LOCAL_VAR32: // 1 Push the contents of a local variable
|
case CP_PUSH_LOCAL_VAR32:
|
||||||
Read16ip(parameter)
|
// Push the contents of a local variable
|
||||||
DEBUG2("Push local var %d (%d)",parameter,*(int32 *)(variables+parameter));
|
Read16ip(parameter);
|
||||||
|
DEBUG("Push local var %d (%d)", parameter, *(int32 *) (variables + parameter));
|
||||||
PUSHONSTACK(*(int32 *) (variables + parameter));
|
PUSHONSTACK(*(int32 *) (variables + parameter));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CP_PUSH_GLOBAL_VAR32:
|
||||||
case CP_PUSH_GLOBAL_VAR32: // 2 Push a global variable
|
// Push a global variable
|
||||||
Read16ip(parameter)
|
Read16ip(parameter);
|
||||||
#ifdef INSIDE_LINC
|
DEBUG("Push global var %d (%d)", parameter, globalInterpreterVariables2[parameter]);
|
||||||
DEBUG2("Push global var %d (%d)",parameter,g_GlobalVariables.GetLocalByIndex(parameter).GetValue());
|
|
||||||
PUSHONSTACK ( g_GlobalVariables.GetLocalByIndex(parameter).GetValue() );
|
|
||||||
#else
|
|
||||||
DEBUG2("Push global var %d (%d)",parameter,globalInterpreterVariables2[parameter]);
|
|
||||||
ASSERT(globalInterpreterVariables2);
|
ASSERT(globalInterpreterVariables2);
|
||||||
PUSHONSTACK(globalInterpreterVariables2[parameter]);
|
PUSHONSTACK(globalInterpreterVariables2[parameter]);
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_POP_LOCAL_VAR32: // 3 Pop a value into a local word variable
|
case CP_POP_LOCAL_VAR32:
|
||||||
Read16ip(parameter)
|
// Pop a value into a local word variable
|
||||||
|
Read16ip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
DEBUG2("Pop %d into var %d",value,parameter);
|
DEBUG("Pop %d into var %d", value, parameter);
|
||||||
*((int32 *) (variables + parameter)) = value;
|
*((int32 *) (variables + parameter)) = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_CALL_MCODE: // 4 Call an mcode routine
|
case CP_CALL_MCODE:
|
||||||
{
|
// Call an mcode routine
|
||||||
Read16ip(parameter)
|
Read16ip(parameter);
|
||||||
ASSERT(parameter <= MAX_FN_NUMBER);
|
ASSERT(parameter <= MAX_FN_NUMBER);
|
||||||
value = *((const int8 *)(code+ip)); // amount to adjust stack by (no of parameters)
|
// amount to adjust stack by (no of parameters)
|
||||||
ip ++;
|
Read8ip(value);
|
||||||
DEBUG2("Call mcode %d with stack = %x",parameter,stack2+(stackPointer2-value));
|
DEBUG("Call mcode %d with stack = %x", parameter, stack2 + stackPointer2 - value);
|
||||||
#ifdef INSIDE_LINC
|
retVal = McodeTable[parameter](stack2 + stackPointer2 - value);
|
||||||
int retVal = engine.McodeTable(parameter , stack2+(stackPointer2-value));
|
|
||||||
#else
|
|
||||||
int retVal = McodeTable[parameter](stack2+(stackPointer2-value));
|
|
||||||
#endif
|
|
||||||
stackPointer2 -= value;
|
stackPointer2 -= value;
|
||||||
CHECKSTACKPOINTER2
|
CHECKSTACKPOINTER2
|
||||||
switch ( retVal & 7 )
|
|
||||||
{ case IR_STOP: // 0: Quit out for a cycle
|
|
||||||
*offset = ip;
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
case IR_CONT: // 1: // Continue as normal
|
switch (retVal & 7) {
|
||||||
|
case IR_STOP:
|
||||||
|
// Quit out for a cycle
|
||||||
|
*offset = ip;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case IR_CONT:
|
||||||
|
// Continue as normal
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IR_TERMINATE: // 2:
|
case IR_TERMINATE:
|
||||||
// Return without updating the offset
|
// Return without updating the
|
||||||
return(2);
|
// offset
|
||||||
|
return 2;
|
||||||
|
|
||||||
case IR_REPEAT: // 3:
|
case IR_REPEAT:
|
||||||
// Return setting offset to start of this function call
|
// Return setting offset to
|
||||||
|
// start of this function call
|
||||||
*offset = savedStartOfMcode;
|
*offset = savedStartOfMcode;
|
||||||
return(0);
|
return 0;
|
||||||
|
|
||||||
case IR_GOSUB: // 4: //that's really neat
|
case IR_GOSUB:
|
||||||
|
// that's really neat
|
||||||
*offset = ip;
|
*offset = ip;
|
||||||
return(2);
|
return 2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
}
|
}
|
||||||
parameterReturnedFromMcodeFunction = retVal >> 3;
|
parameterReturnedFromMcodeFunction = retVal >> 3;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_PUSH_LOCAL_ADDR: // 5 push the address of a local variable
|
case CP_PUSH_LOCAL_ADDR:
|
||||||
Read16ip(parameter)
|
// push the address of a local variable
|
||||||
DEBUG2("Push address of local variable %d (%x)",parameter,(int32)(variables + parameter));
|
Read16ip(parameter);
|
||||||
|
DEBUG("Push address of local variable %d (%x)", parameter, (int32) (variables + parameter));
|
||||||
PUSHONSTACK((int32) (variables + parameter));
|
PUSHONSTACK((int32) (variables + parameter));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_PUSH_INT32: // 6 Push a long word value on to the stack
|
case CP_PUSH_INT32:
|
||||||
Read32ip(parameter)
|
// Push a long word value on to the stack
|
||||||
DEBUG2("Push int32 %d (%x)",parameter,parameter);
|
Read32ip(parameter);
|
||||||
|
DEBUG("Push int32 %d (%x)", parameter, parameter);
|
||||||
PUSHONSTACK(parameter);
|
PUSHONSTACK(parameter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CP_SKIPONFALSE:
|
||||||
case CP_SKIPONFALSE: // 7 Skip if the value on the stack is false
|
// Skip if the value on the stack is false
|
||||||
Read32ipLeaveip(parameter)
|
Read32ipLeaveip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
DEBUG2("Skip %d if %d is false",parameter,value);
|
DEBUG("Skip %d if %d is false", parameter, value);
|
||||||
if (value)
|
if (value)
|
||||||
ip += sizeof(int32);
|
ip += sizeof(int32);
|
||||||
else
|
else
|
||||||
ip += parameter;
|
ip += parameter;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_SKIPALLWAYS: // 8 skip a block
|
case CP_SKIPALWAYS:
|
||||||
Read32ipLeaveip(parameter)
|
// skip a block
|
||||||
DEBUG1("Skip %d",parameter);
|
Read32ipLeaveip(parameter);
|
||||||
|
DEBUG("Skip %d", parameter);
|
||||||
ip += parameter;
|
ip += parameter;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_SWITCH: // 9 switch
|
case CP_SWITCH:
|
||||||
{ POPOFFSTACK ( value );
|
// 9 switch
|
||||||
int caseCount;
|
POPOFFSTACK(value);
|
||||||
Read32ip(caseCount)
|
Read32ip(caseCount);
|
||||||
|
|
||||||
// Search the cases
|
// Search the cases
|
||||||
int foundCase = 0;
|
foundCase = 0;
|
||||||
for (int count = 0 ; (count < caseCount) && (!foundCase) ; count++)
|
for (count = 0; count < caseCount && !foundCase; count++) {
|
||||||
{
|
if (value == (int32) READ_LE_UINT32(code + ip)) {
|
||||||
if (value == (int32)READ_LE_UINT32(code+ip))
|
// We have found the case, so
|
||||||
{ // We have found the case, so lets jump to it
|
// lets jump to it
|
||||||
foundCase = 1;
|
foundCase = 1;
|
||||||
ip += (int32)READ_LE_UINT32(code+ip+sizeof(int32));
|
ip += READ_LE_UINT32(code + ip + sizeof(int32));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
ip += sizeof(int32) * 2;
|
ip += sizeof(int32) * 2;
|
||||||
}
|
}
|
||||||
// If we found no matching case then use the default
|
|
||||||
|
// If we found no matching case then use the
|
||||||
|
// default
|
||||||
|
|
||||||
if (!foundCase)
|
if (!foundCase)
|
||||||
{
|
ip += READ_LE_UINT32(code + ip);
|
||||||
ip += (int32)READ_LE_UINT32(code+ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_ADDNPOP_LOCAL_VAR32: // 10
|
case CP_ADDNPOP_LOCAL_VAR32:
|
||||||
Read16ip(parameter)
|
Read16ip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
*((int32 *) (variables + parameter)) += value;
|
*((int32 *) (variables + parameter)) += value;
|
||||||
DEBUG3("+= %d into var %d->%d",value,parameter,*(int32 *)(variables+parameter));
|
DEBUG("+= %d into var %d->%d", value, parameter, *(int32 *) (variables + parameter));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_SUBNPOP_LOCAL_VAR32: // 11
|
case CP_SUBNPOP_LOCAL_VAR32:
|
||||||
Read16ip(parameter)
|
Read16ip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
*((int32 *) (variables + parameter)) -= value;
|
*((int32 *) (variables + parameter)) -= value;
|
||||||
DEBUG3("-= %d into var %d->%d",value,parameter,*(int32 *)(variables+parameter));
|
DEBUG("-= %d into var %d->%d", value, parameter, *(int32 *) (variables + parameter));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_SKIPONTRUE: // 12 Skip if the value on the stack is TRUE
|
case CP_SKIPONTRUE:
|
||||||
Read32ipLeaveip(parameter)
|
// Skip if the value on the stack is TRUE
|
||||||
|
Read32ipLeaveip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
DEBUG2("Skip %d if %d is false",parameter,value);
|
DEBUG("Skip %d if %d is false", parameter, value);
|
||||||
if (!value)
|
if (!value)
|
||||||
ip += sizeof(int32);
|
ip += sizeof(int32);
|
||||||
else
|
else
|
||||||
ip += parameter;
|
ip += parameter;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_POP_GLOBAL_VAR32: // 13 // Pop a global variable
|
case CP_POP_GLOBAL_VAR32:
|
||||||
Read16ip(parameter)
|
// Pop a global variable
|
||||||
|
Read16ip(parameter);
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
DEBUG2("Pop %d into global var %d",value,parameter);
|
DEBUG("Pop %d into global var %d", value, parameter);
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
g_GlobalVariables.lclSet(parameter,value);
|
|
||||||
engine.AddTextLine(CVString( "Set variable %s to %d",
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetName(),
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetValue() ),
|
|
||||||
VS_COL_GREY);
|
|
||||||
#else //INSIDE_LINC
|
|
||||||
|
|
||||||
#ifdef TRACEGLOBALVARIABLESET
|
#ifdef TRACEGLOBALVARIABLESET
|
||||||
TRACEGLOBALVARIABLESET(parameter, value);
|
TRACEGLOBALVARIABLESET(parameter, value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
globalInterpreterVariables2[parameter] = value;
|
globalInterpreterVariables2[parameter] = value;
|
||||||
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_ADDNPOP_GLOBAL_VAR32: // 14 Add and pop a global variable
|
case CP_ADDNPOP_GLOBAL_VAR32:
|
||||||
{ Read16ip(parameter)
|
// Add and pop a global variable
|
||||||
|
Read16ip(parameter);
|
||||||
// parameter = *((int16_TYPE *) (code + ip));
|
// parameter = *((int16_TYPE *) (code + ip));
|
||||||
// ip += 2;
|
// ip += 2;
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
int newVal = g_GlobalVariables.GetLocalByIndex(parameter).GetValue() + value ;
|
|
||||||
g_GlobalVariables.lclSet(parameter, newVal );
|
|
||||||
engine.AddTextLine( CVString( "Set variable %s to %d",
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetName(),
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetValue() ),
|
|
||||||
VS_COL_GREY);
|
|
||||||
#else
|
|
||||||
globalInterpreterVariables2[parameter] += value;
|
globalInterpreterVariables2[parameter] += value;
|
||||||
DEBUG3("+= %d into global var %d->%d",value,parameter,*(int32 *)(variables+parameter));
|
DEBUG("+= %d into global var %d->%d", value, parameter, *(int32 *) (variables + parameter));
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case CP_SUBNPOP_GLOBAL_VAR32: // 15 Sub and pop a global variable
|
case CP_SUBNPOP_GLOBAL_VAR32:
|
||||||
{ Read16ip(parameter)
|
// Sub and pop a global variable
|
||||||
// parameter = *((int16_TYPE *)(code+ip));
|
Read16ip(parameter);
|
||||||
// ip += 2;
|
|
||||||
POPOFFSTACK(value);
|
POPOFFSTACK(value);
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
int newVal = g_GlobalVariables.GetLocalByIndex(parameter).GetValue() - value ;
|
|
||||||
g_GlobalVariables.lclSet(parameter, newVal );
|
|
||||||
engine.AddTextLine( CVString( "Set variable %s to %d",
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetName(),
|
|
||||||
g_GlobalVariables.GetLocalByIndex(parameter).GetValue() ),
|
|
||||||
VS_COL_GREY);
|
|
||||||
#else
|
|
||||||
globalInterpreterVariables2[parameter] -= value;
|
globalInterpreterVariables2[parameter] -= value;
|
||||||
DEBUG3("-= %d into global var %d->%d",value,parameter,*(int32 *)(variables+parameter));
|
DEBUG("-= %d into global var %d->%d", value, parameter, *(int32 *) (variables + parameter));
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case CP_DEBUGON:
|
case CP_DEBUGON:
|
||||||
// Turn debugging on
|
// Turn debugging on
|
||||||
|
@ -609,187 +562,195 @@ int RunScript ( char * scriptData , char * objectData , uint32 *offset )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_QUIT:
|
case CP_QUIT:
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
// Quit out for a cycle
|
// Quit out for a cycle
|
||||||
*offset = ip;
|
*offset = ip;
|
||||||
return(0);
|
return 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
case CP_TERMINATE:
|
case CP_TERMINATE:
|
||||||
// Quit out immediately without affecting the offset pointer
|
// Quit out immediately without affecting the
|
||||||
return(3);
|
// offset pointer
|
||||||
|
return 3;
|
||||||
/******************************************************************************************************************
|
|
||||||
******************************************************************************************************************/
|
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
case OP_ISEQUAL: // 20 // '=='
|
case OP_ISEQUAL:
|
||||||
DEBUG3("%d == %d -> %d", stack2[stackPointer2-2],
|
// '=='
|
||||||
|
DEBUG("%d == %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] == stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] == stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] == stack2[stackPointer2-1]) );
|
DOOPERATION (stack2[stackPointer2 - 2] == stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_PLUS: // 21 // '+'
|
case OP_PLUS:
|
||||||
DEBUG3("%d + %d -> %d", stack2[stackPointer2-2],
|
// '+'
|
||||||
|
DEBUG("%d + %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] + stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] + stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] + stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] + stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_MINUS: // 22 // '+'
|
case OP_MINUS:
|
||||||
DEBUG3("%d - %d -> %d", stack2[stackPointer2-2],
|
// '-'
|
||||||
|
DEBUG("%d - %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] - stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] - stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] - stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] - stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_TIMES: // 23 // '+'
|
case OP_TIMES:
|
||||||
DEBUG3("%d * %d -> %d", stack2[stackPointer2-2],
|
// '*'
|
||||||
|
DEBUG("%d * %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] * stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] * stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] * stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] * stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_DEVIDE: // 24 // '+'
|
case OP_DIVIDE:
|
||||||
DEBUG3("%d / %d -> %d", stack2[stackPointer2-2],
|
// '/'
|
||||||
|
DEBUG("%d / %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] / stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] / stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] / stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] / stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_NOTEQUAL: // 25 // '!='
|
case OP_NOTEQUAL:
|
||||||
DEBUG3("%d != %d -> %d", stack2[stackPointer2-2],
|
// '!='
|
||||||
|
DEBUG("%d != %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] != stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] != stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] != stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] != stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_ANDAND: // 26
|
case OP_ANDAND:
|
||||||
DEBUG3("%d != %d -> %d", stack2[stackPointer2-2],
|
// '&&'
|
||||||
|
DEBUG("%d != %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] && stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] && stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] && stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] && stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_GTTHAN: // 27 >
|
case OP_GTTHAN:
|
||||||
DEBUG3("%d > %d -> %d", stack2[stackPointer2-2],
|
// '>'
|
||||||
|
DEBUG("%d > %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] > stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] > stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] > stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] > stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_LSTHAN: // 28 <
|
case OP_LSTHAN:
|
||||||
DEBUG3("%d < %d -> %d", stack2[stackPointer2-2],
|
// '<'
|
||||||
|
DEBUG("%d < %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] < stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] < stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] < stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] < stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_JUMP_ON_RETURNED: // 29
|
case CP_JUMP_ON_RETURNED:
|
||||||
{ // Jump to a part of the script depending on the return value from an mcode routine
|
// Jump to a part of the script depending on
|
||||||
parameter = *((const int8 *)(code+ip)); // Get the maximum value
|
// the return value from an mcode routine
|
||||||
ip++;
|
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
TRACE("ip %d: Parameter %d skip %d\r\n", ip,
|
|
||||||
parameterReturnedFromMcodeFunction,
|
|
||||||
(int32)READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ip += (int32)READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4);
|
// Get the maximum value
|
||||||
}
|
Read8ip(parameter);
|
||||||
|
|
||||||
|
ip += READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_TEMP_TEXT_PROCESS: // 30
|
case CP_TEMP_TEXT_PROCESS:
|
||||||
// Process a text line
|
// Process a text line
|
||||||
Read32ip(parameter)
|
// This was apparently used in Linc
|
||||||
// parameter = *((int32_TYPE *)(code+ip));
|
Read32ip(parameter);
|
||||||
// ip += sizeof(int32_TYPE);;
|
DEBUG("Process text id %d", parameter);
|
||||||
DEBUG1("Process text id %d",parameter);
|
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
// Linc only for the moment
|
|
||||||
engine.ProcessTextLine(parameter);
|
|
||||||
#endif //INSIDE_LINC
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_SAVE_MCODE_START: // 31
|
case CP_SAVE_MCODE_START:
|
||||||
// Save the start position on an mcode instruction in case we need to restart it again
|
// Save the start position on an mcode
|
||||||
|
// instruction in case we need to restart it
|
||||||
|
// again
|
||||||
savedStartOfMcode = ip - 1;
|
savedStartOfMcode = ip - 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CP_RESTART_SCRIPT: // 32
|
case CP_RESTART_SCRIPT:
|
||||||
{ // Start the script again
|
// Start the script again
|
||||||
// Do a ip search to find the script we are running
|
// Do a ip search to find the script we are
|
||||||
const char *tempScrPtr = scriptData + (int32)READ_LE_UINT32(scriptData) + sizeof(int);
|
// running
|
||||||
int scriptNumber = 0;
|
|
||||||
int foundScript = 0;
|
tempScrPtr = scriptData + READ_LE_UINT32(scriptData) + sizeof(int);
|
||||||
uint32 count = 0;
|
scriptNumber = 0;
|
||||||
for (count = 1 ; (count < noScripts) && (!foundScript) ; count++)
|
foundScript = 0;
|
||||||
{ if (ip < ((const int *)tempScrPtr)[count+1])
|
|
||||||
{ scriptNumber = count - 1 ;
|
for (count = 1; count < (int) noScripts && !foundScript; count++) {
|
||||||
|
if (ip < ((const int *) tempScrPtr)[count + 1]) {
|
||||||
|
scriptNumber = count - 1;
|
||||||
foundScript = 1;
|
foundScript = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundScript)
|
if (!foundScript)
|
||||||
scriptNumber = count - 1;
|
scriptNumber = count - 1;
|
||||||
// So we know what script we are running, lets restart it
|
|
||||||
|
// So we know what script we are running,
|
||||||
|
// lets restart it
|
||||||
|
|
||||||
ip = ((const int *) tempScrPtr)[scriptNumber + 1];
|
ip = ((const int *) tempScrPtr)[scriptNumber + 1];
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case CP_PUSH_STRING: // 33
|
case CP_PUSH_STRING:
|
||||||
{ // Push the address of a string on to the stack
|
// Push the address of a string on to the stack
|
||||||
parameter = *((const int8 *)(code+ip)); // Get the string size
|
// Get the string size
|
||||||
ip += 1;
|
Read8ip(parameter);
|
||||||
// ip points to the string
|
// ip points to the string
|
||||||
PUSHONSTACK((int) (code + ip));
|
PUSHONSTACK((int) (code + ip));
|
||||||
ip += (parameter + 1);
|
ip += (parameter + 1);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case CP_PUSH_DEREFERENCED_STRUCTURE: // 34
|
case CP_PUSH_DEREFERENCED_STRUCTURE:
|
||||||
{ // Push the address of a dereferenced structure
|
// Push the address of a dereferenced structure
|
||||||
Read32ip(parameter)
|
Read32ip(parameter);
|
||||||
DEBUG1("Push address of far variable (%x)",(int32)(variables + parameter));
|
DEBUG("Push address of far variable (%x)", (int32) (variables + parameter));
|
||||||
PUSHONSTACK((int) (objectData + sizeof(int) + sizeof(_standardHeader) + sizeof(_object_hub) + parameter));
|
PUSHONSTACK((int) (objectData + sizeof(int) + sizeof(_standardHeader) + sizeof(_object_hub) + parameter));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case OP_GTTHANE: // 35 >=
|
case OP_GTTHANE:
|
||||||
DEBUG3("%d > %d -> %d", stack2[stackPointer2-2],
|
// '>='
|
||||||
|
DEBUG("%d > %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] >= stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] >= stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] >= stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] >= stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_LSTHANE: // 36 <=
|
case OP_LSTHANE:
|
||||||
DEBUG3("%d < %d -> %d", stack2[stackPointer2-2],
|
// '<='
|
||||||
|
DEBUG("%d < %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] <= stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] <= stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] <= stack2[stackPointer2-1]) );
|
DOOPERATION(stack2[stackPointer2 - 2] <= stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_OROR: // 37
|
case OP_OROR:
|
||||||
DEBUG3("%d || %d -> %d", stack2[stackPointer2-2],
|
// '||'
|
||||||
|
DEBUG("%d || %d -> %d",
|
||||||
|
stack2[stackPointer2 - 2],
|
||||||
stack2[stackPointer2 - 1],
|
stack2[stackPointer2 - 1],
|
||||||
stack2[stackPointer2 - 2] || stack2[stackPointer2 - 1]);
|
stack2[stackPointer2 - 2] || stack2[stackPointer2 - 1]);
|
||||||
DOOPERATION ( (stack2[stackPointer2-2] || stack2[stackPointer2-1]) );
|
DOOPERATION (stack2[stackPointer2 - 2] || stack2[stackPointer2 - 1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#ifdef INSIDE_LINC
|
|
||||||
AfxMessageBox(CVString("Invalid interpreter token %d",curCommand));
|
|
||||||
#else
|
|
||||||
Con_fatal_error("Interpreter error: Invalid token %d", curCommand);
|
Con_fatal_error("Interpreter error: Invalid token %d", curCommand);
|
||||||
#endif
|
return 3;
|
||||||
return(3);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,12 @@
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _INTERPRETER
|
||||||
|
#define _INTERPRETER
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
// Interpreter return codes
|
// Interpreter return codes
|
||||||
|
|
||||||
#define IR_STOP 0
|
#define IR_STOP 0
|
||||||
|
@ -25,104 +31,20 @@
|
||||||
#define IR_REPEAT 3
|
#define IR_REPEAT 3
|
||||||
#define IR_GOSUB 4
|
#define IR_GOSUB 4
|
||||||
|
|
||||||
|
#define DEBUG if (g_debugFlag) Zdebug
|
||||||
#ifdef INSIDE_LINC // Are we running in linc?
|
|
||||||
|
|
||||||
extern int g_debugFlag;
|
|
||||||
|
|
||||||
#ifdef _SWORD2_DEBUG
|
|
||||||
|
|
||||||
#define DEBUG1(x,y) if(g_debugFlag){engine.AddTextLine(CVString(x,y),VS_COL_DEBUG);}
|
|
||||||
#define DEBUG2(x,y,z) if(g_debugFlag){engine.AddTextLine(CVString(x,y,z),VS_COL_DEBUG);}
|
|
||||||
#define DEBUG3(x,y,z,a) if(g_debugFlag){engine.AddTextLine(CVString(x,y,z,a),VS_COL_DEBUG);}
|
|
||||||
|
|
||||||
#else //_SWORD2_DEBUG
|
|
||||||
|
|
||||||
#define DEBUG1
|
|
||||||
#define DEBUG2
|
|
||||||
#define DEBUG3
|
|
||||||
|
|
||||||
#endif //_SWORD2_DEBUG
|
|
||||||
|
|
||||||
#else //INSIDE_LINC
|
|
||||||
|
|
||||||
//#include "src\driver96.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "header.h"
|
|
||||||
|
|
||||||
#define DEBUG1 if(g_debugFlag)Zdebug
|
|
||||||
#define DEBUG2 if(g_debugFlag)Zdebug
|
|
||||||
#define DEBUG3 if(g_debugFlag)Zdebug
|
|
||||||
|
|
||||||
#define ASSERT(x) { if (!(x)) { Zdebug("Interpreter ASSERT %s,%d", __FILE__, __LINE__); Con_fatal_error("Assert error in interpreter"); } }
|
#define ASSERT(x) { if (!(x)) { Zdebug("Interpreter ASSERT %s,%d", __FILE__, __LINE__); Con_fatal_error("Assert error in interpreter"); } }
|
||||||
|
|
||||||
|
// Get parameter fix so that the playstation version can handle words not on
|
||||||
|
// word boundaries
|
||||||
|
|
||||||
#endif
|
#define Read8ip(var) { var = *((const int8 *) (code + ip)); ip++; }
|
||||||
|
|
||||||
|
|
||||||
// Get parameter fix so that the playstation version can handle words not on word boundaries
|
|
||||||
#define Read16ip(var) { var = (int16) READ_LE_UINT16(code + ip); ip += sizeof(int16); }
|
#define Read16ip(var) { var = (int16) READ_LE_UINT16(code + ip); ip += sizeof(int16); }
|
||||||
#define Read32ip(var) { var = (int32) READ_LE_UINT32(code + ip); ip += sizeof(int32); }
|
#define Read32ip(var) { var = (int32) READ_LE_UINT32(code + ip); ip += sizeof(int32); }
|
||||||
#define Read32ipLeaveip(var) { var = (int32) READ_LE_UINT32(code + ip); }
|
#define Read32ipLeaveip(var) { var = (int32) READ_LE_UINT32(code + ip); }
|
||||||
|
|
||||||
void SetGlobalInterpreterVariables(int32 *vars);
|
void SetGlobalInterpreterVariables(int32 *vars);
|
||||||
|
int RunScript (char *scriptData, char *objectData, uint32 *offset);
|
||||||
#ifdef INSIDE_LINC // Are we running in linc?
|
|
||||||
int RunScript ( MCBOVirtualSword &engine , const char * scriptData , char * /*objectData*/ , uint32 *offset );
|
|
||||||
#else
|
|
||||||
int RunScript ( char * scriptData , char * /*objectData*/ , uint32 *offset );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Command tokens
|
|
||||||
|
|
||||||
#define CT_COMMENT 1 // A program comment
|
|
||||||
#define CT_IF 2 // An if statement
|
|
||||||
#define CT_OPENBRACKET 3 // (
|
|
||||||
#define CT_CLOSEBRACKET 4 // )
|
|
||||||
#define CT_VAR 5 // Define a variable
|
|
||||||
#define CT_SEMICOLON 6 // ;
|
|
||||||
#define CT_COMMA 7 // ,
|
|
||||||
#define CT_OPENBRACE 8 // {
|
|
||||||
#define CT_CLOSEBRACE 9 // }
|
|
||||||
#define CT_STRUCT 10 // Struct
|
|
||||||
#define CT_SWITCH 11 // Switch
|
|
||||||
#define CT_CASE 12 // Case
|
|
||||||
#define CT_BREAK 13 // break
|
|
||||||
#define CT_DEFAULT 14 // default
|
|
||||||
#define CT_ASSIGN 14 // =
|
|
||||||
#define CT_PLUSEQ 15 // '+='
|
|
||||||
#define CT_MINUSEQ 16 // '-='
|
|
||||||
#define CT_FOR 17 // for
|
|
||||||
#define CT_DO 18 // do
|
|
||||||
#define CT_WHILE 19 // while
|
|
||||||
#define CT_DEBUGON 20 // Turn debugging on
|
|
||||||
#define CT_DEBUGOFF 21 // Turn debugging off
|
|
||||||
#define CT_QUIT 22 // Quit for a cycle
|
|
||||||
#define CT_ENDIF 23 // Endif
|
|
||||||
#define CT_TEXTOBJECT 24 // Speaker: text line
|
|
||||||
#define CT_ANIM 25 // An animation
|
|
||||||
#define CT_ELSE 26 // else to an if
|
|
||||||
#define CT_CHOOSE 27 // Start a chooser
|
|
||||||
#define CT_END 28 // end, usually followed by something else
|
|
||||||
#define CT_END_CHOICE 29 // end choice
|
|
||||||
#define CT_TERMINATE 30 // Terminate
|
|
||||||
#define CT_PAUSE 31 // Pause
|
|
||||||
#define CT_RESTART 32 // Restart script
|
|
||||||
#define CT_START 33 // Start conversation
|
|
||||||
#define CT_CALL 34 // Call a character
|
|
||||||
#define CT_ACTORSCOMMENT 35 // A comment for an actor
|
|
||||||
#define CT_TALKER 36 // A set talker command
|
|
||||||
|
|
||||||
// Special functions
|
|
||||||
|
|
||||||
#define SF_RUNLIST 1
|
|
||||||
#define SF_DOUBLEQUOTE 2
|
|
||||||
#define SF_BACKGROUND 3
|
|
||||||
#define SF_SCALEA 4
|
|
||||||
#define SF_SCALEB 5
|
|
||||||
#define SF_SPEECHSCRIPT 6
|
|
||||||
|
|
||||||
// Compiled tokens
|
// Compiled tokens
|
||||||
|
|
||||||
|
@ -134,7 +56,7 @@ int RunScript ( char * scriptData , char * /*objectData*/ , uint32 *offset );
|
||||||
#define CP_PUSH_LOCAL_ADDR 5 // Push the address of a local variable
|
#define CP_PUSH_LOCAL_ADDR 5 // Push the address of a local variable
|
||||||
#define CP_PUSH_INT32 6 // Adjust the stack after calling an fn function
|
#define CP_PUSH_INT32 6 // Adjust the stack after calling an fn function
|
||||||
#define CP_SKIPONFALSE 7 // Skip if the bottom value on the stack is false
|
#define CP_SKIPONFALSE 7 // Skip if the bottom value on the stack is false
|
||||||
#define CP_SKIPALLWAYS 8 // Skip a block of code
|
#define CP_SKIPALWAYS 8 // Skip a block of code
|
||||||
#define CP_SWITCH 9 // Switch on last stack value
|
#define CP_SWITCH 9 // Switch on last stack value
|
||||||
#define CP_ADDNPOP_LOCAL_VAR32 10 // Add to a local varible
|
#define CP_ADDNPOP_LOCAL_VAR32 10 // Add to a local varible
|
||||||
#define CP_SUBNPOP_LOCAL_VAR32 11 // Subtract to a local variable
|
#define CP_SUBNPOP_LOCAL_VAR32 11 // Subtract to a local variable
|
||||||
|
@ -153,11 +75,11 @@ int RunScript ( char * scriptData , char * /*objectData*/ , uint32 *offset );
|
||||||
#define OP_PLUS 21 // '+'
|
#define OP_PLUS 21 // '+'
|
||||||
#define OP_MINUS 22 // '-'
|
#define OP_MINUS 22 // '-'
|
||||||
#define OP_TIMES 23 // '*'
|
#define OP_TIMES 23 // '*'
|
||||||
#define OP_DEVIDE 24 // '/'
|
#define OP_DIVIDE 24 // '/'
|
||||||
#define OP_NOTEQUAL 25 // '=='
|
#define OP_NOTEQUAL 25 // '=='
|
||||||
#define OP_ANDAND 26 // &&
|
#define OP_ANDAND 26 // '&&'
|
||||||
#define OP_GTTHAN 27 // >
|
#define OP_GTTHAN 27 // '>'
|
||||||
#define OP_LSTHAN 28 // <
|
#define OP_LSTHAN 28 // '<'
|
||||||
|
|
||||||
// More tokens, mixed types
|
// More tokens, mixed types
|
||||||
|
|
||||||
|
@ -171,3 +93,5 @@ int RunScript ( char * scriptData , char * /*objectData*/ , uint32 *offset );
|
||||||
#define OP_GTTHANE 35 // >=
|
#define OP_GTTHANE 35 // >=
|
||||||
#define OP_LSTHANE 36 // <=
|
#define OP_LSTHANE 36 // <=
|
||||||
#define OP_OROR 37 // || or OR
|
#define OP_OROR 37 // || or OR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -23,31 +23,34 @@
|
||||||
#include "driver/driver96.h"
|
#include "driver/driver96.h"
|
||||||
|
|
||||||
// these structures represent the broken up compact components
|
// these structures represent the broken up compact components
|
||||||
// these here declared to the system must be the same as those declared to LINC (or it wont work)
|
// these here declared to the system must be the same as those declared to
|
||||||
|
// LINC (or it wont work)
|
||||||
|
|
||||||
|
// mouse structure - defines mouse detection area, detection priority &
|
||||||
|
// 'type' flag
|
||||||
|
|
||||||
// mouse structure - defines mouse detection area, detection priority & 'type' flag
|
typedef struct {
|
||||||
typedef struct
|
int32 x1; // Top-left and bottom-right of mouse
|
||||||
{
|
int32 y1; // area. (These coords are inclusive.)
|
||||||
int32 x1; // top-left of mouse area is (x1,y1)
|
int32 x2;
|
||||||
int32 y1;
|
|
||||||
int32 x2; // bottom-right of area is (x2,y2) (these coords are inclusive)
|
|
||||||
int32 y2;
|
int32 y2;
|
||||||
int32 priority;
|
int32 priority;
|
||||||
int32 pointer; // type (or resource id?) of pointer used over this area
|
int32 pointer; // type (or resource id?) of pointer used over this area
|
||||||
|
|
||||||
} Object_mouse;
|
} Object_mouse;
|
||||||
|
|
||||||
|
|
||||||
// logic structure - contains fields used in logic script processing
|
// logic structure - contains fields used in logic script processing
|
||||||
typedef struct
|
|
||||||
{
|
typedef struct {
|
||||||
int32 looping; // 0 when first calling FN_<function>; 1 when calling subsequent times in same loop
|
int32 looping; // 0 when first calling FN_<function>;
|
||||||
|
// 1 when calling subsequent times in same loop
|
||||||
int32 pause; // pause count, used by FN_pause()
|
int32 pause; // pause count, used by FN_pause()
|
||||||
} Object_logic;
|
} Object_logic;
|
||||||
|
|
||||||
//------------------------------------------------
|
|
||||||
// status bits for 'type' field of Object_graphic)
|
// status bits for 'type' field of Object_graphic)
|
||||||
|
|
||||||
// in low word:
|
// in low word:
|
||||||
|
|
||||||
#define NO_SPRITE 0x00000000 // don't print
|
#define NO_SPRITE 0x00000000 // don't print
|
||||||
#define BGP0_SPRITE 0x00000001 // fixed to background parallax[0]
|
#define BGP0_SPRITE 0x00000001 // fixed to background parallax[0]
|
||||||
#define BGP1_SPRITE 0x00000002 // fixed to background parallax[1]
|
#define BGP1_SPRITE 0x00000002 // fixed to background parallax[1]
|
||||||
|
@ -58,22 +61,21 @@ typedef struct
|
||||||
#define FGP1_SPRITE 0x00000040 // fixed to foreground parallax[0]
|
#define FGP1_SPRITE 0x00000040 // fixed to foreground parallax[0]
|
||||||
|
|
||||||
// in high word:
|
// in high word:
|
||||||
|
|
||||||
#define UNSHADED_SPRITE 0x00000000 // not to be shaded
|
#define UNSHADED_SPRITE 0x00000000 // not to be shaded
|
||||||
#define SHADED_SPRITE 0x00010000 // to be shaded, based on shading mask
|
#define SHADED_SPRITE 0x00010000 // to be shaded, based on shading mask
|
||||||
//------------------------------------------------
|
|
||||||
|
|
||||||
// graphic structure - contains fields appropriate to sprite output
|
// graphic structure - contains fields appropriate to sprite output
|
||||||
typedef struct
|
|
||||||
{
|
typedef struct {
|
||||||
int32 type; // see above
|
int32 type; // see above
|
||||||
int32 anim_resource; // resource id of animation file
|
int32 anim_resource; // resource id of animation file
|
||||||
int32 anim_pc; // current frame number of animation
|
int32 anim_pc; // current frame number of animation
|
||||||
} Object_graphic;
|
} Object_graphic;
|
||||||
|
|
||||||
|
|
||||||
// speech structure - contains fields used by speech scripts & text output
|
// speech structure - contains fields used by speech scripts & text output
|
||||||
typedef struct
|
|
||||||
{
|
typedef struct {
|
||||||
int32 pen; // colour to use for body of characters
|
int32 pen; // colour to use for body of characters
|
||||||
int32 width; // max width of text sprite
|
int32 width; // max width of text sprite
|
||||||
int32 command; // speech script command id
|
int32 command; // speech script command id
|
||||||
|
@ -82,13 +84,13 @@ typedef struct
|
||||||
int32 ins3;
|
int32 ins3;
|
||||||
int32 ins4;
|
int32 ins4;
|
||||||
int32 ins5;
|
int32 ins5;
|
||||||
int32 wait_state; //0 not waiting 1 waiting for next speech command
|
int32 wait_state; // 0 not waiting, 1 waiting for next speech command
|
||||||
} Object_speech;
|
} Object_speech;
|
||||||
|
|
||||||
|
// mega structure - contains fields used for mega-character & mega-set
|
||||||
|
// processing
|
||||||
|
|
||||||
// mega structure - contains fields used for mega-character & mega-set processing
|
typedef struct {
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int32 NOT_USED_1; // only free roaming megas need to check this before registering their graphics for drawing
|
int32 NOT_USED_1; // only free roaming megas need to check this before registering their graphics for drawing
|
||||||
int32 NOT_USED_2; // id of floor on which we are standing
|
int32 NOT_USED_2; // id of floor on which we are standing
|
||||||
int32 NOT_USED_3; // id of object which we are getting to
|
int32 NOT_USED_3; // id of object which we are getting to
|
||||||
|
@ -100,15 +102,15 @@ typedef struct
|
||||||
int32 feet_x; // mega feet coords - frame-offsets are added to these position mega frames
|
int32 feet_x; // mega feet coords - frame-offsets are added to these position mega frames
|
||||||
int32 feet_y;
|
int32 feet_y;
|
||||||
int32 current_dir; // current dirction faced by mega; used by autorouter to determine turns required
|
int32 current_dir; // current dirction faced by mega; used by autorouter to determine turns required
|
||||||
int32 colliding; // means were currently avoiding a collision (see FN_walk)
|
int32 NOT_USED_5; // means were currently avoiding a collision (see FN_walk)
|
||||||
int32 megaset_res; // resource id of mega-set file
|
int32 megaset_res; // resource id of mega-set file
|
||||||
int32 NOT_USED_5; // NOT USED
|
int32 NOT_USED_6; // NOT USED
|
||||||
} Object_mega;
|
} Object_mega;
|
||||||
|
|
||||||
|
// walk-data structure - contains details of layout of frames in the
|
||||||
|
// mega-set, and how they are to be used
|
||||||
|
|
||||||
// walk-data structure - contains details of layout of frames in the mega-set, and how they are to be used
|
typedef struct {
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int32 nWalkFrames; // no. of frames per walk-cycle
|
int32 nWalkFrames; // no. of frames per walk-cycle
|
||||||
int32 usingStandingTurnFrames; // 0 = no 1 = yes
|
int32 usingStandingTurnFrames; // 0 = no 1 = yes
|
||||||
int32 usingWalkingTurnFrames; // 0 = no 1 = yes
|
int32 usingWalkingTurnFrames; // 0 = no 1 = yes
|
||||||
|
@ -120,5 +122,4 @@ typedef struct
|
||||||
int32 dy[8 * (12 + 1)]; // walk step distances in y direction
|
int32 dy[8 * (12 + 1)]; // walk step distances in y direction
|
||||||
} Object_walkdata;
|
} Object_walkdata;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,34 +17,24 @@
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
//#include "src\driver96.h"
|
|
||||||
#include "build_display.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "layers.h"
|
#include "layers.h"
|
||||||
#include "memory.h"
|
|
||||||
#include "object.h"
|
|
||||||
#include "protocol.h"
|
|
||||||
#include "resman.h"
|
|
||||||
#include "scroll.h"
|
#include "scroll.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
// max no of pixel allowed to scroll per cycle
|
||||||
#define MAX_SCROLL_DISTANCE 8 // max no of pixel allowed to scroll per cycle
|
#define MAX_SCROLL_DISTANCE 8
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
// used to be a define, but now it's flexible (see new functions below)
|
||||||
uint8 scroll_fraction=16; // used to be a define, but now it's flexible (see new functions below)
|
uint8 scroll_fraction = 16;
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
void Set_scrolling(void) //S2.1(2Mar94jel) refurnished Tony25Sept96 :-)
|
void Set_scrolling(void) { // S2.1(2Mar94jel) refurnished Tony25Sept96 :-)
|
||||||
{
|
// normally we aim to get George's feet at (320,250) from top left
|
||||||
// feet_x = 128+320 // normally we aim to get George's feet at (320,250) from top left of screen window
|
// of screen window
|
||||||
|
// feet_x = 128 + 320
|
||||||
// feet_y = 128 + 250
|
// feet_y = 128 + 250
|
||||||
|
|
||||||
// set scroll offsets according to the player's coords
|
// set scroll offsets according to the player's coords
|
||||||
|
@ -55,101 +45,131 @@ void Set_scrolling(void) //S2.1(2Mar94jel) refurnished Tony25Sept96 :-)
|
||||||
uint16 scroll_distance_x; // how much we want to scroll
|
uint16 scroll_distance_x; // how much we want to scroll
|
||||||
uint16 scroll_distance_y;
|
uint16 scroll_distance_y;
|
||||||
|
|
||||||
|
// if the scroll offsets are being forced in script (05feb97 JAMES)
|
||||||
if (SCROLL_X || SCROLL_Y) // if the scroll offsets are being forced in script (05feb97 JAMES)
|
if (SCROLL_X || SCROLL_Y) {
|
||||||
{
|
|
||||||
// ensure not too far right
|
// ensure not too far right
|
||||||
if (SCROLL_X < this_screen.max_scroll_offset_x)
|
if (this_screen.max_scroll_offset_x > SCROLL_X)
|
||||||
this_screen.scroll_offset_x = SCROLL_X;
|
this_screen.scroll_offset_x = SCROLL_X;
|
||||||
else
|
else
|
||||||
this_screen.scroll_offset_x = this_screen.max_scroll_offset_x;
|
this_screen.scroll_offset_x = this_screen.max_scroll_offset_x;
|
||||||
|
|
||||||
// ensure not too far down
|
// ensure not too far down
|
||||||
if (SCROLL_Y < this_screen.max_scroll_offset_y)
|
if (this_screen.max_scroll_offset_y > SCROLL_Y)
|
||||||
this_screen.scroll_offset_y = SCROLL_Y;
|
this_screen.scroll_offset_y = SCROLL_Y;
|
||||||
else
|
else
|
||||||
this_screen.scroll_offset_y = this_screen.max_scroll_offset_y;
|
this_screen.scroll_offset_y = this_screen.max_scroll_offset_y;
|
||||||
}
|
} else {
|
||||||
else
|
// George's offset from the centre - the desired position
|
||||||
{
|
// for him
|
||||||
offset_x = this_screen.player_feet_x-this_screen.feet_x; // George's offset from the centre - the desired position for him
|
|
||||||
|
offset_x = this_screen.player_feet_x - this_screen.feet_x;
|
||||||
offset_y = this_screen.player_feet_y - this_screen.feet_y;
|
offset_y = this_screen.player_feet_y - this_screen.feet_y;
|
||||||
|
|
||||||
|
|
||||||
// prevent scrolling too far left/right/up/down
|
// prevent scrolling too far left/right/up/down
|
||||||
offset_x = offset_x < 0 ? 0 : ( (uint32)offset_x > this_screen.max_scroll_offset_x ? this_screen.max_scroll_offset_x : offset_x );
|
|
||||||
offset_y = offset_y < 0 ? 0 : ( (uint32)offset_y > this_screen.max_scroll_offset_y ? this_screen.max_scroll_offset_y : offset_y );
|
|
||||||
|
|
||||||
if (this_screen.scroll_flag==2) // first time on this screen - need absolute scroll immediately!
|
if (offset_x < 0)
|
||||||
{
|
offset_x = 0;
|
||||||
|
else if ((uint32) offset_x > this_screen.max_scroll_offset_x)
|
||||||
|
offset_x = this_screen.max_scroll_offset_x;
|
||||||
|
|
||||||
|
if (offset_y < 0)
|
||||||
|
offset_y = 0;
|
||||||
|
else if ((uint32) offset_y > this_screen.max_scroll_offset_y)
|
||||||
|
offset_y = this_screen.max_scroll_offset_y;
|
||||||
|
|
||||||
|
// first time on this screen - need absolute scroll
|
||||||
|
// immediately!
|
||||||
|
|
||||||
|
if (this_screen.scroll_flag == 2) {
|
||||||
// Zdebug(42,"init scroll");
|
// Zdebug(42,"init scroll");
|
||||||
this_screen.scroll_offset_x = offset_x;
|
this_screen.scroll_offset_x = offset_x;
|
||||||
this_screen.scroll_offset_y = offset_y;
|
this_screen.scroll_offset_y = offset_y;
|
||||||
this_screen.scroll_flag = 1;
|
this_screen.scroll_flag = 1;
|
||||||
}
|
} else {
|
||||||
else // catch up with required scroll offsets - speed depending on distance to catch up (dx and dy) & 'SCROLL_FRACTION' used
|
// catch up with required scroll offsets - speed
|
||||||
{ // but limit to certain number of pixels per cycle (MAX_SCROLL_DISTANCE)
|
// depending on distance to catch up (dx and dy) &
|
||||||
|
// 'SCROLL_FRACTION' used, but limit to certain
|
||||||
|
// number of pixels per cycle (MAX_SCROLL_DISTANCE)
|
||||||
|
|
||||||
dx = this_screen.scroll_offset_x - offset_x;
|
dx = this_screen.scroll_offset_x - offset_x;
|
||||||
dy = this_screen.scroll_offset_y - offset_y;
|
dy = this_screen.scroll_offset_y - offset_y;
|
||||||
|
|
||||||
if (dx < 0) // current scroll_offset_x is less than the required value
|
// current scroll_offset_x is less than the required
|
||||||
{
|
// value
|
||||||
scroll_distance_x = (1+(-dx)/scroll_fraction); // => inc by (fraction of the differnce) NB. dx is -ve, so we subtract dx/SCROLL_FRACTION
|
|
||||||
this_screen.scroll_offset_x += scroll_distance_x < MAX_SCROLL_DISTANCE ? scroll_distance_x : MAX_SCROLL_DISTANCE;
|
// NB. I'm adding 1 to the result of
|
||||||
}
|
// dx / SCROLL_FRACTION, because it would otherwise
|
||||||
else if (dx > 0) // current scroll_offset_x is greater than the required value
|
|
||||||
{
|
|
||||||
scroll_distance_x = (1+dx/scroll_fraction); // => dec by (fraction of the differnce)
|
|
||||||
this_screen.scroll_offset_x -= scroll_distance_x < MAX_SCROLL_DISTANCE ? scroll_distance_x : MAX_SCROLL_DISTANCE;
|
|
||||||
} // NB. I'm adding 1 to the result of dx/SCROLL_FRACTION, because it would otherwise
|
|
||||||
// not scroll at all when dx < SCROLL_FRACTION
|
// not scroll at all when dx < SCROLL_FRACTION
|
||||||
if (dy < 0)
|
|
||||||
{
|
if (dx < 0) {
|
||||||
scroll_distance_y = (1+(-dy)/scroll_fraction);
|
// => inc by (fraction of the differnce)
|
||||||
this_screen.scroll_offset_y += scroll_distance_y < MAX_SCROLL_DISTANCE ? scroll_distance_y : MAX_SCROLL_DISTANCE;
|
// NB. dx is -ve, so we subtract
|
||||||
|
// dx / SCROLL_FRACTION
|
||||||
|
|
||||||
|
scroll_distance_x = 1 - dx / scroll_fraction;
|
||||||
|
|
||||||
|
if (scroll_distance_x > MAX_SCROLL_DISTANCE)
|
||||||
|
scroll_distance_x = MAX_SCROLL_DISTANCE;
|
||||||
|
|
||||||
|
this_screen.scroll_offset_x += scroll_distance_x; } else if (dx > 0) {
|
||||||
|
// current scroll_offset_x is greater than
|
||||||
|
// the required value
|
||||||
|
// => dec by (fraction of the differnce)
|
||||||
|
|
||||||
|
scroll_distance_x = 1 + dx / scroll_fraction;
|
||||||
|
|
||||||
|
if (scroll_distance_x > MAX_SCROLL_DISTANCE)
|
||||||
|
scroll_distance_x = MAX_SCROLL_DISTANCE;
|
||||||
|
|
||||||
|
this_screen.scroll_offset_x -= scroll_distance_x;
|
||||||
}
|
}
|
||||||
else if (dy > 0)
|
|
||||||
{
|
if (dy < 0) {
|
||||||
scroll_distance_y = (1+dy/scroll_fraction);
|
scroll_distance_y = 1 - dy / scroll_fraction;
|
||||||
this_screen.scroll_offset_y -= scroll_distance_y < MAX_SCROLL_DISTANCE ? scroll_distance_y : MAX_SCROLL_DISTANCE;
|
|
||||||
|
if (scroll_distance_y > MAX_SCROLL_DISTANCE)
|
||||||
|
scroll_distance_y = MAX_SCROLL_DISTANCE;
|
||||||
|
|
||||||
|
this_screen.scroll_offset_y += scroll_distance_y;
|
||||||
|
} else if (dy > 0) {
|
||||||
|
scroll_distance_y = 1 + dy / scroll_fraction;
|
||||||
|
|
||||||
|
if (scroll_distance_y > MAX_SCROLL_DISTANCE)
|
||||||
|
scroll_distance_y = MAX_SCROLL_DISTANCE;
|
||||||
|
|
||||||
|
this_screen.scroll_offset_y -= scroll_distance_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
int32 FN_set_scroll_coordinate(int32 *params) //Tony25Sept96
|
int32 FN_set_scroll_coordinate(int32 *params) { // Tony25Sept96
|
||||||
{
|
|
||||||
// set the special scroll offset variables
|
// set the special scroll offset variables
|
||||||
|
|
||||||
// call when starting screens and to change the camera within screens
|
// call when starting screens and to change the camera within screens
|
||||||
|
|
||||||
// call AFTER FN_init_background() to override the defaults
|
// call AFTER FN_init_background() to override the defaults
|
||||||
// called feet_x and feet_y to retain intelectual compatibility with Sword1 !
|
|
||||||
// feet_x & feet_y refer to the physical screen coords where the system will try to maintain George's feet
|
|
||||||
|
|
||||||
// param 0 feet_x value
|
// called feet_x and feet_y to retain intelectual compatibility with
|
||||||
// param 1 feet_y value
|
// Sword1 !
|
||||||
|
|
||||||
|
// feet_x & feet_y refer to the physical screen coords where the
|
||||||
|
// system will try to maintain George's feet
|
||||||
|
|
||||||
|
// params: 0 feet_x value
|
||||||
|
// 1 feet_y value
|
||||||
|
|
||||||
this_screen.feet_x = params[0];
|
this_screen.feet_x = params[0];
|
||||||
this_screen.feet_y = params[1];
|
this_screen.feet_y = params[1];
|
||||||
|
return IR_CONT;
|
||||||
|
|
||||||
return(IR_CONT);
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
//------------------------------------------------------------------------------------
|
int32 FN_set_scroll_speed_normal(int32 *params) { // James08aug97
|
||||||
int32 FN_set_scroll_speed_normal(int32 *params) // James08aug97
|
|
||||||
{
|
|
||||||
scroll_fraction = 16;
|
scroll_fraction = 16;
|
||||||
|
return IR_CONT;
|
||||||
return(IR_CONT);
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
int32 FN_set_scroll_speed_slow(int32 *params) // James08aug97
|
int32 FN_set_scroll_speed_slow(int32 *params) { // James08aug97
|
||||||
{
|
|
||||||
scroll_fraction = 32;
|
scroll_fraction = 32;
|
||||||
|
return IR_CONT;
|
||||||
return(IR_CONT);
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
#ifndef _SCROLL
|
#ifndef _SCROLL
|
||||||
#define _SCROLL
|
#define _SCROLL
|
||||||
|
|
||||||
//#include "src\driver96.h"
|
|
||||||
|
|
||||||
void Set_scrolling(void);
|
void Set_scrolling(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
384
sword2/sound.cpp
384
sword2/sound.cpp
|
@ -17,7 +17,7 @@
|
||||||
* $Header$
|
* $Header$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// BROKEN SWORD 2
|
// BROKEN SWORD 2
|
||||||
//
|
//
|
||||||
// SOUND.CPP Contains the sound engine, fx & music functions
|
// SOUND.CPP Contains the sound engine, fx & music functions
|
||||||
|
@ -25,12 +25,11 @@
|
||||||
//
|
//
|
||||||
// (16Dec96 JEL)
|
// (16Dec96 JEL)
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
//#include "src\driver96.h"
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "defs.h" // for RESULT
|
#include "defs.h" // for RESULT
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
@ -39,9 +38,7 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "sword2.h"
|
#include "sword2.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
typedef struct {
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32 resource; // resource id of sample
|
uint32 resource; // resource id of sample
|
||||||
uint32 fetchId; // Id of resource in PSX CD queue. :)
|
uint32 fetchId; // Id of resource in PSX CD queue. :)
|
||||||
uint16 delay; // cycles to wait before playing (or 'random chance' if FX_RANDOM)
|
uint16 delay; // cycles to wait before playing (or 'random chance' if FX_RANDOM)
|
||||||
|
@ -50,98 +47,88 @@ typedef struct
|
||||||
uint8 type; // FX_SPOT, FX_RANDOM or FX_LOOP
|
uint8 type; // FX_SPOT, FX_RANDOM or FX_LOOP
|
||||||
} _fxq_entry;
|
} _fxq_entry;
|
||||||
|
|
||||||
#define FXQ_LENGTH 32 // max number of fx in queue at once [DO NOT EXCEED 255]
|
// max number of fx in queue at once [DO NOT EXCEED 255]
|
||||||
|
#define FXQ_LENGTH 32
|
||||||
|
|
||||||
_fxq_entry fxq[FXQ_LENGTH];
|
_fxq_entry fxq[FXQ_LENGTH];
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
// used to store id of tunes that loop, for save & restore
|
||||||
|
uint32 looping_music_id=0;
|
||||||
|
|
||||||
uint32 looping_music_id=0; // used to store id of tunes that loop, for save & restore
|
|
||||||
char musicDirectory[120];
|
char musicDirectory[120];
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// local function prototypes
|
|
||||||
|
|
||||||
void Trigger_fx(uint8 j);
|
void Trigger_fx(uint8 j);
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// initialise the fxq by clearing all the entries
|
// initialise the fxq by clearing all the entries
|
||||||
|
|
||||||
void Init_fx_queue(void)
|
void Init_fx_queue(void) {
|
||||||
{
|
for (int j = 0; j < FXQ_LENGTH; j++) {
|
||||||
uint8 j;
|
|
||||||
|
|
||||||
|
|
||||||
for (j=0; j < FXQ_LENGTH; j++) // scan the queue
|
|
||||||
{
|
|
||||||
fxq[j].resource = 0; // 0 resource means 'empty' slot
|
fxq[j].resource = 0; // 0 resource means 'empty' slot
|
||||||
fxq[j].fetchId = 0; // Not being fetched.
|
fxq[j].fetchId = 0; // Not being fetched.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// process the fxq once every game cycle
|
// process the fxq once every game cycle
|
||||||
|
|
||||||
void Process_fx_queue(void)
|
void Process_fx_queue(void) {
|
||||||
{
|
for (int j = 0; j < FXQ_LENGTH; j++) {
|
||||||
uint8 j; // assuming FXQ_LENGTH is 255 or less
|
if (!fxq[j].resource)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (fxq[j].type) {
|
||||||
|
case FX_RANDOM:
|
||||||
|
// 1 in 'delay' chance of this fx occurring
|
||||||
|
if (rand() % fxq[j].delay == 0)
|
||||||
|
Trigger_fx(j);
|
||||||
|
break;
|
||||||
|
|
||||||
for (j=0; j < FXQ_LENGTH; j++) // scan the queue
|
case FX_SPOT:
|
||||||
{
|
if (fxq[j].delay)
|
||||||
if (fxq[j].resource) // if this entry isn't empty
|
fxq[j].delay--;
|
||||||
{
|
else {
|
||||||
if (fxq[j].type == FX_RANDOM) // if it's type FX_RANDOM
|
Trigger_fx(j);
|
||||||
{
|
|
||||||
if (rand()%(fxq[j].delay)==0) // 1 in 'delay' chance of this fx occurring
|
|
||||||
{
|
|
||||||
Trigger_fx(j); // play it
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(fxq[j].type == FX_SPOT)
|
|
||||||
{
|
|
||||||
if (fxq[j].delay) // if delay is above 0
|
|
||||||
fxq[j].delay--; // decrement delay countdown
|
|
||||||
else // if zero delay remaining
|
|
||||||
{
|
|
||||||
Trigger_fx(j); // play it
|
|
||||||
fxq[j].type = FX_SPOT2;
|
fxq[j].type = FX_SPOT2;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (fxq[j].type == FX_SPOT2)
|
|
||||||
{
|
case FX_SPOT2:
|
||||||
|
// Once the Fx has finished remove it from
|
||||||
|
// the queue.
|
||||||
|
|
||||||
if (g_sound->IsFxOpen(j + 1))
|
if (g_sound->IsFxOpen(j + 1))
|
||||||
fxq[j].resource = 0; // Once the Fx has finished remove it from the queue.
|
fxq[j].resource = 0;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
void Trigger_fx(uint8 j) { // called from Process_fx_queue only
|
||||||
void Trigger_fx(uint8 j) // called from Process_fx_queue only
|
|
||||||
{
|
|
||||||
uint8 *data;
|
uint8 *data;
|
||||||
int32 id;
|
int32 id;
|
||||||
uint32 rv;
|
uint32 rv;
|
||||||
|
|
||||||
id = (uint32) j + 1; // because 0 is not a valid id
|
id = (uint32) j + 1; // because 0 is not a valid id
|
||||||
|
|
||||||
if (fxq[j].type == FX_SPOT)
|
if (fxq[j].type == FX_SPOT) {
|
||||||
{
|
// load in the sample
|
||||||
data = res_man.Res_open(fxq[j].resource); // load in the sample
|
data = res_man.Res_open(fxq[j].resource);
|
||||||
data += sizeof(_standardHeader);
|
data += sizeof(_standardHeader);
|
||||||
rv = g_sound->PlayFx( id, data, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT ); // wav data gets copied to sound memory
|
// wav data gets copied to sound memory
|
||||||
res_man.Res_close(fxq[j].resource); // release the sample
|
rv = g_sound->PlayFx(id, data, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT);
|
||||||
// fxq[j].resource = 0; // clear spot fx from queue
|
// release the sample
|
||||||
}
|
res_man.Res_close(fxq[j].resource);
|
||||||
else // random & looped fx are already loaded into sound memory by FN_play_fx()
|
} else {
|
||||||
{ // - to be referenced by 'j', so pass NULL data
|
// random & looped fx are already loaded into sound memory
|
||||||
|
// by FN_play_fx()
|
||||||
|
// - to be referenced by 'j', so pass NULL data
|
||||||
|
|
||||||
if (fxq[j].type == FX_RANDOM)
|
if (fxq[j].type == FX_RANDOM) {
|
||||||
rv = g_sound->PlayFx( id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT ); // not looped
|
// Not looped
|
||||||
else // FX_LOOP
|
rv = g_sound->PlayFx(id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT);
|
||||||
rv = g_sound->PlayFx( id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXLOOP ); // looped
|
} else {
|
||||||
|
// Looped
|
||||||
|
rv = g_sound->PlayFx(id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXLOOP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
|
@ -150,17 +137,17 @@ void Trigger_fx(uint8 j) // called from Process_fx_queue only
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
int32 FN_play_fx(int32 *params) { // called from script only
|
||||||
int32 FN_play_fx(int32 *params) // called from script only
|
|
||||||
{
|
|
||||||
// params: 0 sample resource id
|
// params: 0 sample resource id
|
||||||
// 1 type (FX_SPOT, FX_RANDOM, FX_LOOP)
|
// 1 type (FX_SPOT, FX_RANDOM, FX_LOOP)
|
||||||
// 2 delay (0..65535)
|
// 2 delay (0..65535)
|
||||||
// 3 volume (0..16)
|
// 3 volume (0..16)
|
||||||
// 4 pan (-16..16)
|
// 4 pan (-16..16)
|
||||||
|
|
||||||
// example script: FN_play_fx (FXWATER, FX_LOOP, 0, 10, 15);
|
// example script:
|
||||||
// fx_water = result; // fx_water is just a local script flag
|
// FN_play_fx (FXWATER, FX_LOOP, 0, 10, 15);
|
||||||
|
// // fx_water is just a local script flag
|
||||||
|
// fx_water = result;
|
||||||
// .
|
// .
|
||||||
// .
|
// .
|
||||||
// .
|
// .
|
||||||
|
@ -171,15 +158,11 @@ int32 FN_play_fx(int32 *params) // called from script only
|
||||||
uint32 id;
|
uint32 id;
|
||||||
uint32 rv;
|
uint32 rv;
|
||||||
|
|
||||||
//----------------------------------
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
|
|
||||||
_standardHeader *header;
|
_standardHeader *header;
|
||||||
char type[10];
|
char type[10];
|
||||||
|
|
||||||
|
if (wantSfxDebug) {
|
||||||
if (wantSfxDebug)
|
|
||||||
{
|
|
||||||
switch (params[1]) // 'type'
|
switch (params[1]) // 'type'
|
||||||
{
|
{
|
||||||
case FX_SPOT:
|
case FX_SPOT:
|
||||||
|
@ -200,49 +183,50 @@ int32 FN_play_fx(int32 *params) // called from script only
|
||||||
|
|
||||||
Zdebug("SFX (sample=\"%s\", vol=%d, pan=%d, delay=%d, type=%s)", FetchObjectName(params[0]), params[3], params[4], params[2], type);
|
Zdebug("SFX (sample=\"%s\", vol=%d, pan=%d, delay=%d, type=%s)", FetchObjectName(params[0]), params[3], params[4], params[2], type);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //_SWORD2_DEBUG
|
while (j < FXQ_LENGTH && fxq[j].resource != 0)
|
||||||
//----------------------------------
|
|
||||||
|
|
||||||
while ((j < FXQ_LENGTH) && (fxq[j].resource != 0))
|
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
if (j == FXQ_LENGTH)
|
if (j == FXQ_LENGTH)
|
||||||
{
|
return IR_CONT;
|
||||||
return (IR_CONT);
|
|
||||||
// Con_fatal_error("ERROR: Sound queue overflow in FN_play_fx() (%s line %u)",__FILE__,__LINE__);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fxq[j].resource = params[0]; // wav resource id
|
fxq[j].resource = params[0]; // wav resource id
|
||||||
fxq[j].type = params[1]; // FX_SPOT, FX_LOOP or FX_RANDOM
|
fxq[j].type = params[1]; // FX_SPOT, FX_LOOP or FX_RANDOM
|
||||||
|
|
||||||
if (fxq[j].type == FX_RANDOM) // FX_RANDOM:
|
if (fxq[j].type == FX_RANDOM) {
|
||||||
fxq[j].delay = params[2] * 12 + 1; // 'delay' param is the intended average no. seconds between playing this effect (+1 to avoid divide-by-zero in Process_fx_queue)
|
// 'delay' param is the intended average no. seconds between
|
||||||
else // FX_SPOT or FX_LOOP:
|
// playing this effect (+1 to avoid divide-by-zero in
|
||||||
fxq[j].delay = params[2]; // 'delay' is no. frames to wait before playing
|
// Process_fx_queue)
|
||||||
|
fxq[j].delay = params[2] * 12 + 1;
|
||||||
|
} else {
|
||||||
|
// FX_SPOT or FX_LOOP:
|
||||||
|
// 'delay' is no. frames to wait before playing
|
||||||
|
fxq[j].delay = params[2];
|
||||||
|
}
|
||||||
|
|
||||||
fxq[j].volume = params[3]; // 0..16
|
fxq[j].volume = params[3]; // 0..16
|
||||||
fxq[j].pan = params[4]; // -16..16
|
fxq[j].pan = params[4]; // -16..16
|
||||||
|
|
||||||
|
if (fxq[j].type == FX_SPOT) {
|
||||||
|
// "pre-load" the sample; this gets it into memory
|
||||||
|
data = res_man.Res_open(fxq[j].resource);
|
||||||
|
|
||||||
if (fxq[j].type == FX_SPOT) // spot fx
|
|
||||||
{
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
data = res_man.Res_open(fxq[j].resource); // "pre-load" the sample; this gets it into memory
|
|
||||||
header = (_standardHeader*) data;
|
header = (_standardHeader*) data;
|
||||||
if (header->fileType != WAV_FILE)
|
if (header->fileType != WAV_FILE)
|
||||||
Con_fatal_error("FN_play_fx given invalid resource (%s line %u)", __FILE__, __LINE__);
|
Con_fatal_error("FN_play_fx given invalid resource (%s line %u)", __FILE__, __LINE__);
|
||||||
#else
|
|
||||||
res_man.Res_open(fxq[j].resource); // "pre-load" the sample; this gets it into memory
|
|
||||||
#endif
|
#endif
|
||||||
res_man.Res_close(fxq[j].resource); // but then releases it to "age" out if the space is needed
|
|
||||||
}
|
// but then releases it to "age" out if the space is needed
|
||||||
else // random & looped fx
|
res_man.Res_close(fxq[j].resource);
|
||||||
{
|
} else {
|
||||||
|
// random & looped fx
|
||||||
|
|
||||||
id = (uint32) j + 1; // because 0 is not a valid id
|
id = (uint32) j + 1; // because 0 is not a valid id
|
||||||
|
|
||||||
data = res_man.Res_open(fxq[j].resource); // load in the sample
|
// load in the sample
|
||||||
|
data = res_man.Res_open(fxq[j].resource);
|
||||||
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
header = (_standardHeader*)data;
|
header = (_standardHeader*)data;
|
||||||
|
@ -251,77 +235,80 @@ int32 FN_play_fx(int32 *params) // called from script only
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data += sizeof(_standardHeader);
|
data += sizeof(_standardHeader);
|
||||||
rv = g_sound->OpenFx(id,data); // copy it to sound memory, using position in queue as 'id'
|
|
||||||
|
// copy it to sound memory, using position in queue as 'id'
|
||||||
|
rv = g_sound->OpenFx(id,data);
|
||||||
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
if (rv)
|
if (rv)
|
||||||
Zdebug("SFX ERROR: OpenFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__);
|
Zdebug("SFX ERROR: OpenFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
res_man.Res_close(fxq[j].resource); // release the sample
|
// release the sample
|
||||||
}
|
res_man.Res_close(fxq[j].resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------
|
|
||||||
// (James07uag97)
|
// (James07uag97)
|
||||||
if (fxq[j].type == FX_LOOP) // looped fx
|
|
||||||
Trigger_fx(j); // play now, rather than in Process_fx_queue where it was getting played again & again!
|
|
||||||
//---------------------------------------------
|
|
||||||
|
|
||||||
|
if (fxq[j].type == FX_LOOP) {
|
||||||
RESULT = j; // in case we want to call FN_stop_fx() later, to kill this fx (mainly for FX_LOOP & FX_RANDOM)
|
// play now, rather than in Process_fx_queue where it was
|
||||||
|
// getting played again & again!
|
||||||
return(IR_CONT); // continue script
|
Trigger_fx(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
// in case we want to call FN_stop_fx() later, to kill this fx
|
||||||
int32 FN_sound_fetch(int32 *params)
|
// (mainly for FX_LOOP & FX_RANDOM)
|
||||||
{
|
|
||||||
|
RESULT = j;
|
||||||
|
return IR_CONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 FN_sound_fetch(int32 *params) {
|
||||||
return (IR_CONT);
|
return (IR_CONT);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// to alter the volume and pan of a currently playing fx
|
// to alter the volume and pan of a currently playing fx
|
||||||
int32 FN_set_fx_vol_and_pan(int32 *params)
|
int32 FN_set_fx_vol_and_pan(int32 *params) {
|
||||||
{
|
// params: 0 id of fx (ie. the id returned in 'result' from
|
||||||
// params 0 id of fx (ie. the id returned in 'result' from FN_play_fx
|
// FN_play_fx
|
||||||
// 1 new volume (0..16)
|
// 1 new volume (0..16)
|
||||||
// 2 new pan (-16..16)
|
// 2 new pan (-16..16)
|
||||||
|
|
||||||
// SetFxVolumePan(int32 id, uint8 vol, uint8 pan);
|
|
||||||
g_sound->SetFxVolumePan(1+params[0], params[1], params[2]); // driver fx_id is 1+<pos in queue>
|
|
||||||
// Zdebug("%d", params[2]);
|
// Zdebug("%d", params[2]);
|
||||||
|
|
||||||
return (IR_CONT);
|
// SetFxVolumePan(int32 id, uint8 vol, uint8 pan);
|
||||||
|
// driver fx_id is 1 + <pos in queue>
|
||||||
|
g_sound->SetFxVolumePan(1 + params[0], params[1], params[2]);
|
||||||
|
return IR_CONT;
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// to alter the volume of a currently playing fx
|
// to alter the volume of a currently playing fx
|
||||||
int32 FN_set_fx_vol(int32 *params)
|
int32 FN_set_fx_vol(int32 *params) {
|
||||||
{
|
// params: 0 id of fx (ie. the id returned in 'result' from
|
||||||
// params 0 id of fx (ie. the id returned in 'result' from FN_play_fx
|
// FN_play_fx
|
||||||
// 1 new volume (0..16)
|
// 1 new volume (0..16)
|
||||||
|
|
||||||
// SetFxIdVolume(int32 id, uint8 vol);
|
// SetFxIdVolume(int32 id, uint8 vol);
|
||||||
g_sound->SetFxIdVolume(1 + params[0], params[1]);
|
g_sound->SetFxIdVolume(1 + params[0], params[1]);
|
||||||
|
return IR_CONT;
|
||||||
return (IR_CONT);
|
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
int32 FN_stop_fx(int32 *params) // called from script only
|
int32 FN_stop_fx(int32 *params) { // called from script only
|
||||||
{
|
|
||||||
// params: 0 position in queue
|
// params: 0 position in queue
|
||||||
|
|
||||||
// This will stop looped & random fx instantly, and remove the fx from the queue.
|
// This will stop looped & random fx instantly, and remove the fx
|
||||||
// So although it doesn't stop spot fx, it will remove them from the queue if they haven't yet played
|
// from the queue. So although it doesn't stop spot fx, it will
|
||||||
|
// remove them from the queue if they haven't yet played
|
||||||
|
|
||||||
uint8 j = (uint8) params[0];
|
uint8 j = (uint8) params[0];
|
||||||
uint32 id;
|
uint32 id;
|
||||||
uint32 rv;
|
uint32 rv;
|
||||||
|
|
||||||
if ((fxq[j].type == FX_RANDOM) || (fxq[j].type == FX_LOOP))
|
if (fxq[j].type == FX_RANDOM || fxq[j].type == FX_LOOP) {
|
||||||
{
|
|
||||||
id = (uint32) j + 1; // because 0 is not a valid id
|
id = (uint32) j + 1; // because 0 is not a valid id
|
||||||
rv = g_sound->CloseFx(id); // stop fx & remove sample from sound memory
|
|
||||||
|
// stop fx & remove sample from sound memory
|
||||||
|
rv = g_sound->CloseFx(id);
|
||||||
|
|
||||||
#ifdef _SWORD2_DEBUG
|
#ifdef _SWORD2_DEBUG
|
||||||
if (rv)
|
if (rv)
|
||||||
|
@ -329,34 +316,31 @@ int32 FN_stop_fx(int32 *params) // called from script only
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fxq[j].resource = 0; // remove from queue
|
// remove from queue
|
||||||
|
fxq[j].resource = 0;
|
||||||
|
|
||||||
|
return IR_CONT;
|
||||||
return(IR_CONT); // continue script
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
int32 FN_stop_all_fx(int32 *params) { // called from script only
|
||||||
int32 FN_stop_all_fx(int32 *params) // called from script only
|
|
||||||
{
|
|
||||||
// Stops all looped & random fx and clears the entire queue
|
// Stops all looped & random fx and clears the entire queue
|
||||||
// NO PARAMS
|
// params: none
|
||||||
|
|
||||||
Clear_fx_queue();
|
Clear_fx_queue();
|
||||||
|
return IR_CONT;
|
||||||
return(IR_CONT); // continue script
|
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// Stops all looped & random fx and clears the entire queue
|
// Stops all looped & random fx and clears the entire queue
|
||||||
|
|
||||||
void Clear_fx_queue(void)
|
void Clear_fx_queue(void) {
|
||||||
{
|
// stop all fx & remove the samples from sound memory
|
||||||
g_sound->ClearAllFx(); // stop all fx & remove the samples from sound memory
|
g_sound->ClearAllFx();
|
||||||
Init_fx_queue(); // clean out the queue
|
|
||||||
|
// clean out the queue
|
||||||
|
Init_fx_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
// ===========================================================================
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// int32 StreamMusic(uint8 *filename, int32 loopFlag)
|
// int32 StreamMusic(uint8 *filename, int32 loopFlag)
|
||||||
//
|
//
|
||||||
// Streams music from the file defined by filename. The loopFlag should
|
// Streams music from the file defined by filename. The loopFlag should
|
||||||
|
@ -364,58 +348,59 @@ void Clear_fx_queue(void)
|
||||||
// Otherwise, it should be RDSE_FXSPOT.
|
// Otherwise, it should be RDSE_FXSPOT.
|
||||||
// The return value must be checked for any problems.
|
// The return value must be checked for any problems.
|
||||||
//
|
//
|
||||||
// --------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// int32 PauseMusic(void)
|
// int32 PauseMusic(void)
|
||||||
//
|
//
|
||||||
// Stops the music dead in it's tracks.
|
// Stops the music dead in it's tracks.
|
||||||
//
|
//
|
||||||
// --------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// int32 UnpauseMusic(void)
|
// int32 UnpauseMusic(void)
|
||||||
//
|
//
|
||||||
// Re-starts the music from where it was stopped.
|
// Re-starts the music from where it was stopped.
|
||||||
//
|
//
|
||||||
//=============================================================================
|
// ===========================================================================
|
||||||
int32 FN_prepare_music(int32 *params)
|
|
||||||
{
|
int32 FN_prepare_music(int32 *params) {
|
||||||
return (IR_CONT);
|
return IR_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
// Start a tune playing, to play once or to loop until stopped or next one
|
||||||
// Start a tune playing, to play once or to loop until stopped or next one played
|
// played
|
||||||
int32 FN_play_music(int32 *params) // updated by James on 10apr97
|
|
||||||
{
|
int32 FN_play_music(int32 *params) { // updated by James on 10apr97
|
||||||
// params 0 tune id
|
// params: 0 tune id
|
||||||
// 1 loop flag (0 or 1)
|
// 1 loop flag (0 or 1)
|
||||||
|
|
||||||
char filename[128];
|
char filename[128];
|
||||||
uint32 loopFlag;
|
uint32 loopFlag;
|
||||||
uint32 rv; // drivers return value
|
uint32 rv;
|
||||||
|
|
||||||
|
|
||||||
// Zdebug("FN_play_music(%d)", params[0]);
|
// Zdebug("FN_play_music(%d)", params[0]);
|
||||||
|
|
||||||
if (params[1]==FX_LOOP) // if it is to loop
|
if (params[1] == FX_LOOP) {
|
||||||
{
|
|
||||||
loopFlag = RDSE_FXLOOP;
|
loopFlag = RDSE_FXLOOP;
|
||||||
looping_music_id = params[0]; // keep a note of the id, for restarting after an interruption to gameplay
|
|
||||||
}
|
|
||||||
else // just play once
|
|
||||||
{
|
|
||||||
loopFlag = RDSE_FXSPOT;
|
|
||||||
looping_music_id = 0; // don't need to restart this tune after control panel or restore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// keep a note of the id, for restarting after an
|
||||||
|
// interruption to gameplay
|
||||||
|
looping_music_id = params[0];
|
||||||
|
} else {
|
||||||
|
loopFlag = RDSE_FXSPOT;
|
||||||
|
|
||||||
|
// don't need to restart this tune after control panel or
|
||||||
|
// restore
|
||||||
|
looping_music_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// add the appropriate file extension & play it
|
// add the appropriate file extension & play it
|
||||||
|
|
||||||
if (g_sword2->_gameId == GID_SWORD2_DEMO)
|
if (g_sword2->_gameId == GID_SWORD2_DEMO) {
|
||||||
// The demo I found didn't come with any music file, but you
|
// The demo I found didn't come with any music file, but you
|
||||||
// could use the music from the first CD of the complete game,
|
// could use the music from the first CD of the complete game,
|
||||||
// I suppose...
|
// I suppose...
|
||||||
strcpy(filename, "music.clu");
|
strcpy(filename, "music.clu");
|
||||||
else {
|
} else {
|
||||||
File f;
|
File f;
|
||||||
|
|
||||||
sprintf(filename, "music%d.clu", res_man.WhichCd());
|
sprintf(filename, "music%d.clu", res_man.WhichCd());
|
||||||
|
@ -434,52 +419,42 @@ int32 FN_play_music(int32 *params) // updated by James on 10apr97
|
||||||
|
|
||||||
// Zdebug("FN_play_music(%d) returning", params[0]);
|
// Zdebug("FN_play_music(%d) returning", params[0]);
|
||||||
|
|
||||||
return(IR_CONT); // continue script
|
return IR_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
int32 FN_stop_music(int32 *params) { // called from script only
|
||||||
int32 FN_stop_music(int32 *params) // called from script only
|
|
||||||
{
|
|
||||||
// params: none
|
// params: none
|
||||||
|
|
||||||
|
|
||||||
looping_music_id = 0; // clear the 'looping' flag
|
looping_music_id = 0; // clear the 'looping' flag
|
||||||
|
|
||||||
g_sound->StopMusic();
|
g_sound->StopMusic();
|
||||||
|
return IR_CONT;
|
||||||
if (params);
|
|
||||||
|
|
||||||
return(IR_CONT); // continue script
|
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
void Kill_music(void) // James22aug97
|
|
||||||
{
|
|
||||||
uint8 count;
|
|
||||||
|
|
||||||
|
void Kill_music(void) { // James22aug97
|
||||||
looping_music_id = 0; // clear the 'looping' flag
|
looping_music_id = 0; // clear the 'looping' flag
|
||||||
g_sound->StopMusic();
|
g_sound->StopMusic();
|
||||||
|
|
||||||
|
/* I don't think this is needed with our music code
|
||||||
// THIS BIT CAUSES THE MUSIC TO STOP INSTANTLY!
|
// THIS BIT CAUSES THE MUSIC TO STOP INSTANTLY!
|
||||||
for(count=0; count<16; count++)
|
for(int count=0; count<16; count++)
|
||||||
g_sound->UpdateCompSampleStreaming();
|
g_sound->UpdateCompSampleStreaming();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
int32 FN_check_music_playing(int32 *params) // James (30july97)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
int32 FN_check_music_playing(int32 *params) { // James (30july97)
|
||||||
// params: none
|
// params: none
|
||||||
|
|
||||||
// sets result to no. of seconds of current tune remaining
|
// sets result to no. of seconds of current tune remaining
|
||||||
// or 0 if no music playing
|
// or 0 if no music playing
|
||||||
|
|
||||||
RESULT = g_sound->MusicTimeRemaining(); // in seconds, rounded up to the nearest second
|
// in seconds, rounded up to the nearest second
|
||||||
|
RESULT = g_sound->MusicTimeRemaining();
|
||||||
|
|
||||||
return(IR_CONT); // continue script
|
return IR_CONT;
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
void PauseAllSound(void) // James25july97
|
void PauseAllSound(void) { // James25july97
|
||||||
{
|
uint32 rv;
|
||||||
uint32 rv; // for drivers return value
|
|
||||||
|
|
||||||
rv = g_sound->PauseMusic();
|
rv = g_sound->PauseMusic();
|
||||||
if (rv != RD_OK)
|
if (rv != RD_OK)
|
||||||
|
@ -493,10 +468,9 @@ void PauseAllSound(void) // James25july97
|
||||||
if (rv != RD_OK)
|
if (rv != RD_OK)
|
||||||
Zdebug("ERROR: PauseFx() returned %.8x in PauseAllSound()", rv);
|
Zdebug("ERROR: PauseFx() returned %.8x in PauseAllSound()", rv);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
void UnpauseAllSound(void) // James25july97
|
void UnpauseAllSound(void) { // James25july97
|
||||||
{
|
uint32 rv;
|
||||||
uint32 rv; // for drivers return value
|
|
||||||
|
|
||||||
rv = g_sound->UnpauseMusic();
|
rv = g_sound->UnpauseMusic();
|
||||||
if (rv != RD_OK)
|
if (rv != RD_OK)
|
||||||
|
@ -510,5 +484,3 @@ void UnpauseAllSound(void) // James25july97
|
||||||
if (rv != RD_OK)
|
if (rv != RD_OK)
|
||||||
Zdebug("ERROR: UnpauseFx() returned %.8x in UnpauseAllSound()", rv);
|
Zdebug("ERROR: UnpauseFx() returned %.8x in UnpauseAllSound()", rv);
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
|
@ -33,23 +33,30 @@
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
|
||||||
// fx types
|
// fx types
|
||||||
|
|
||||||
#define FX_SPOT 0
|
#define FX_SPOT 0
|
||||||
#define FX_LOOP 1
|
#define FX_LOOP 1
|
||||||
#define FX_RANDOM 2
|
#define FX_RANDOM 2
|
||||||
#define FX_SPOT2 3
|
#define FX_SPOT2 3
|
||||||
|
|
||||||
void Init_fx_queue(void); // to be called during system initialisation
|
// to be called during system initialisation
|
||||||
void Process_fx_queue(void); // to be called from the main loop, once per cycle
|
void Init_fx_queue(void);
|
||||||
void Clear_fx_queue(void); // stops all fx & clears the queue - eg. when leaving a location
|
|
||||||
void PauseAllSound(void); // James25july97
|
|
||||||
void UnpauseAllSound(void); // James25july97
|
|
||||||
|
|
||||||
void Kill_music(void); // James22aug97
|
// to be called from the main loop, once per cycle
|
||||||
|
void Process_fx_queue(void);
|
||||||
|
|
||||||
|
// stops all fx & clears the queue - eg. when leaving a location
|
||||||
|
void Clear_fx_queue(void);
|
||||||
|
|
||||||
|
void PauseAllSound(void);
|
||||||
|
void UnpauseAllSound(void);
|
||||||
|
|
||||||
|
void Kill_music(void);
|
||||||
|
|
||||||
int32 FN_play_music(int32 *params); // for save_Rest.cpp
|
int32 FN_play_music(int32 *params); // for save_Rest.cpp
|
||||||
int32 FN_stop_music(int32 *params);
|
int32 FN_stop_music(int32 *params);
|
||||||
|
|
||||||
extern uint32 looping_music_id; // used to store id of tunes that loop, for save & restore
|
// used to store id of tunes that loop, for save & restore
|
||||||
|
extern uint32 looping_music_id;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1942
sword2/speech.cpp
1942
sword2/speech.cpp
File diff suppressed because it is too large
Load diff
|
@ -20,25 +20,26 @@
|
||||||
#ifndef _SPEECH
|
#ifndef _SPEECH
|
||||||
#define _SPEECH
|
#define _SPEECH
|
||||||
|
|
||||||
//#include "src\driver96.h"
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_SUBJECT_LIST 30 // is that enough?
|
#define MAX_SUBJECT_LIST 30 // is that enough?
|
||||||
|
|
||||||
|
// array of these for subject menu build up
|
||||||
|
typedef struct {
|
||||||
typedef struct //array of these for subject menu build up
|
|
||||||
{
|
|
||||||
uint32 res;
|
uint32 res;
|
||||||
uint32 ref;
|
uint32 ref;
|
||||||
} _subject_unit;
|
} _subject_unit;
|
||||||
|
|
||||||
extern uint32 speech_text_bloc_no; // so speech text cleared when running a new start-script
|
// so speech text cleared when running a new start-script
|
||||||
|
extern uint32 speech_text_bloc_no;
|
||||||
|
|
||||||
extern int16 officialTextNumber;
|
extern int16 officialTextNumber;
|
||||||
|
|
||||||
extern int32 speechScriptWaiting;
|
extern int32 speechScriptWaiting;
|
||||||
|
|
||||||
extern int choosing; //could alternately use logic->looping of course
|
//could alternately use logic->looping of course
|
||||||
|
extern int choosing;
|
||||||
|
|
||||||
extern uint32 unpause_zone;
|
extern uint32 unpause_zone;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,15 +20,11 @@
|
||||||
#ifndef _WALKER
|
#ifndef _WALKER
|
||||||
#define _WALKER
|
#define _WALKER
|
||||||
|
|
||||||
//#include "src\driver96.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int32 FN_face_mega(int32 *params);
|
int32 FN_face_mega(int32 *params);
|
||||||
int32 FN_turn(int32 *params);
|
int32 FN_turn(int32 *params);
|
||||||
int32 FN_walk(int32 *params); // James (14nov96)
|
int32 FN_walk(int32 *params);
|
||||||
int32 FN_walk_to_anim(int32 *params); // James (14nov96)
|
int32 FN_walk_to_anim(int32 *params);
|
||||||
int32 FN_stand_after_anim(int32 *params); // James (18jun97)
|
int32 FN_stand_after_anim(int32 *params);
|
||||||
int32 FN_stand(int32 *params); // James
|
int32 FN_stand(int32 *params);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue