diff options
author | Torbjörn Andersson | 2003-09-20 12:43:52 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2003-09-20 12:43:52 +0000 |
commit | 6539b8a0e64ffceb90c2bc8eaeae87b9b3dae7a0 (patch) | |
tree | 77450539ca0e86012772fe3a46d2d755ca217621 /sword2 | |
parent | f4861af4d22e42d6ca4c6eafaa9bce72e0533d5d (diff) | |
download | scummvm-rg350-6539b8a0e64ffceb90c2bc8eaeae87b9b3dae7a0.tar.gz scummvm-rg350-6539b8a0e64ffceb90c2bc8eaeae87b9b3dae7a0.tar.bz2 scummvm-rg350-6539b8a0e64ffceb90c2bc8eaeae87b9b3dae7a0.zip |
cleanup
svn-id: r10333
Diffstat (limited to 'sword2')
-rw-r--r-- | sword2/interpreter.cpp | 689 | ||||
-rw-r--r-- | sword2/interpreter.h | 206 | ||||
-rw-r--r-- | sword2/object.h | 153 | ||||
-rw-r--r-- | sword2/scroll.cpp | 192 | ||||
-rw-r--r-- | sword2/scroll.h | 6 | ||||
-rw-r--r-- | sword2/sound.cpp | 538 | ||||
-rw-r--r-- | sword2/sound.h | 21 | ||||
-rw-r--r-- | sword2/speech.cpp | 2672 | ||||
-rw-r--r-- | sword2/speech.h | 25 | ||||
-rw-r--r-- | sword2/walker.cpp | 1070 | ||||
-rw-r--r-- | sword2/walker.h | 12 |
11 files changed, 2516 insertions, 3068 deletions
diff --git a/sword2/interpreter.cpp b/sword2/interpreter.cpp index dfaaeb58e6..daeb6453d8 100644 --- a/sword2/interpreter.cpp +++ b/sword2/interpreter.cpp @@ -19,20 +19,18 @@ #include "stdafx.h" -#ifndef INSIDE_LINC // Are we running in linc? #include "console.h" -#endif - #include "driver/driver96.h" #include "interpreter.h" +// This file serves two purposes. It is compiled as part of the test functions +// 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. -// This file serves two purposes. It is compiled as part of the test functions -// of Linc, and also as part of the game - - -// The machine code table +// The machine code table int32 FN_test_function(int32 *params); int32 FN_test_flags(int32 *params); @@ -50,11 +48,11 @@ int32 FN_add_subject(int32 *); int32 FN_interact(int32 *); int32 FN_choose(int32 *); int32 FN_walk(int32 *); -int32 FN_walk_to_anim(int32 *); // walk to start position of anim -int32 FN_turn(int32 *); // turn to (dir) -int32 FN_stand_at(int32 *); // stand at (x,y,dir) -int32 FN_stand(int32 *); // stand facing (dir) -int32 FN_stand_after_anim(int32 *); // stand at end position of anim +int32 FN_walk_to_anim(int32 *); // walk to start position of anim +int32 FN_turn(int32 *); // turn to (dir) +int32 FN_stand_at(int32 *); // stand at (x,y,dir) +int32 FN_stand(int32 *); // stand facing (dir) +int32 FN_stand_after_anim(int32 *); // stand at end position of anim int32 FN_pause(int32 *); int32 FN_mega_table_anim(int32 *); int32 FN_add_menu_object(int32 *); @@ -154,16 +152,15 @@ int32 FN_change_shadows(int32 *params); #define MAX_FN_NUMBER 117 -extern int32 (*McodeTable[])(int32 *); +extern int32 (*McodeTable[]) (int32 *); -#ifndef INSIDE_LINC -int32 * globalInterpreterVariables2 = NULL; // Point to the global varibale data -int g_debugFlag = 0; // Set this to turn debugging on -#endif +// Point to the global variable data +int32 *globalInterpreterVariables2 = NULL; +int g_debugFlag = 0; // Set this to turn debugging on -int32 (*McodeTable[MAX_FN_NUMBER+1])(int32 *) = -{ FN_test_function, +int32 (*McodeTable[MAX_FN_NUMBER + 1]) (int32 *) = { + FN_test_function, FN_test_flags, FN_register_start_point, FN_init_background, @@ -283,320 +280,276 @@ int32 (*McodeTable[MAX_FN_NUMBER+1])(int32 *) = FN_change_shadows, }; -#define CHECKSTACKPOINTER2 ASSERT((stackPointer2>=0)&&(stackPointer2<STACK_SIZE)); -#define PUSHONSTACK(x) {stack2[stackPointer2] = (x);stackPointer2++;CHECKSTACKPOINTER2;} -#define POPOFFSTACK(x) {x=stack2[stackPointer2-1];stackPointer2--;CHECKSTACKPOINTER2;} -#define DOOPERATION(x) {stack2[stackPointer2-2] = (x);stackPointer2--;CHECKSTACKPOINTER2;} +#define CHECKSTACKPOINTER2 ASSERT(stackPointer2 >= 0 && stackPointer2 < STACK_SIZE); +#define PUSHONSTACK(x) { stack2[stackPointer2] = (x); stackPointer2++; CHECKSTACKPOINTER2 } +#define POPOFFSTACK(x) { x = stack2[stackPointer2 - 1]; stackPointer2--; CHECKSTACKPOINTER2 } +#define DOOPERATION(x) { stack2[stackPointer2 - 2] = (x); stackPointer2--; CHECKSTACKPOINTER2 } -#ifndef INSIDE_LINC -void SetGlobalInterpreterVariables(int32 *vars) -{ +void SetGlobalInterpreterVariables(int32 *vars) { globalInterpreterVariables2 = vars; } -#endif -#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 -{ +int RunScript(char *scriptData, char *objectData, uint32 *offset) { #define STACK_SIZE 10 - _standardHeader *header = (_standardHeader *)scriptData; + _standardHeader *header = (_standardHeader *) scriptData; scriptData += sizeof(_standardHeader) + sizeof(_object_hub); // The script data format: - - - // int32_TYPE 1 Size of variable space in bytes - // ... The variable space - // int32_TYPE 1 numberOfScripts - // int32_TYPE numberOfScripts The offsets for each script - + // int32_TYPE 1 Size of variable space in bytes + // ... The variable space + // int32_TYPE 1 numberOfScripts + // int32_TYPE numberOfScripts The offsets for each script // Initialise some stuff - int ip = 0; // Code pointer - int curCommand,parameter,value; // Command and parameter variables - int32 stack2[STACK_SIZE]; // The current stack - int32 stackPointer2 = 0; // Position within stack - int parameterReturnedFromMcodeFunction=0; // Allow scripts to return things - int savedStartOfMcode=0; // For saving start of mcode commands + int ip = 0; // Code pointer + int curCommand,parameter, value; // Command and parameter variables + int32 stack2[STACK_SIZE]; // The current stack + int32 stackPointer2 = 0; // Position within stack + int parameterReturnedFromMcodeFunction = 0; // Allow scripts to return things + 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 - 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, // this code writes into 'variables' so it can not be const. + char *variables = scriptData + sizeof(int); - const char *code = scriptData + (int32)READ_LE_UINT32(scriptData) + sizeof(int); - uint32 noScripts = (int32)READ_LE_UINT32(code); - if ( (*offset) < noScripts) - { ip = (int32)READ_LE_UINT32((const int *)code + (*offset) + 1); - DEBUG2("Start script %d with offset %d",*offset,ip); - } - else - { ip = (*offset); - DEBUG1("Start script with offset %d",ip); + const char *code = scriptData + (int32) READ_LE_UINT32(scriptData) + sizeof(int); + uint32 noScripts = (int32) READ_LE_UINT32(code); + + if (*offset < noScripts) { + ip = READ_LE_UINT32((const int *) code + *offset + 1); + DEBUG("Start script %d with offset %d",*offset,ip); + } else { + ip = *offset; + DEBUG("Start script with offset %d",ip); } code += noScripts * sizeof(int) + sizeof(int); -/************************************************************************************************/ #ifdef DONTPROCESSSCRIPTCHECKSUM - code += sizeof(int) * 3; - #else - - // Code should nopw be pointing at an identifier and a checksum - const int *checksumBlock = (const int *)code; + // Code should nop be pointing at an identifier and a checksum + const int *checksumBlock = (const int *) code; code += sizeof(int) * 3; - if ((int32)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); -#endif - return(0); + if (READ_LE_UINT32(checksumBlock) != 12345678) { + Con_fatal_error("Invalid script in object %s", header->name); + return 0; } - int codeLen = (int32)READ_LE_UINT32(checksumBlock + 1); + + int codeLen = READ_LE_UINT32(checksumBlock + 1); int checksum = 0; - for (int count = 0 ; count < codeLen ; count++) - checksum += (unsigned char)code[count]; - 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); -#endif - return(0); - } -#endif //DONTPROCESSSCRIPTCHECKSUM + for (count = 0; count < codeLen; count++) + checksum += (unsigned char) code[count]; -/************************************************************************************************/ + if (checksum != (int32) READ_LE_UINT32(checksumBlock + 2)) { + Con_fatal_error("Checksum error in object %s", header->name); + return 0; + } +#endif int runningScript = 1; - while ( runningScript ) - { curCommand = code[ip++]; - switch(curCommand) - { case CP_END_SCRIPT: // 0 End the script - DEBUG1("End script",0); + + while (runningScript) { + curCommand = code[ip++]; + + switch(curCommand) { + case CP_END_SCRIPT: + // End the script + DEBUG("End script",0); runningScript = 0; -#ifdef INSIDE_LINC - engine.AddTextLine( "End script" , VS_COL_GREY ); - engine.AddTextLine( "" , VS_COL_GREY ); -#endif break; - case CP_PUSH_LOCAL_VAR32: // 1 Push the contents of a local variable - Read16ip(parameter) - DEBUG2("Push local var %d (%d)",parameter,*(int32 *)(variables+parameter)); - PUSHONSTACK ( *(int32 *)(variables+parameter) ); + case CP_PUSH_LOCAL_VAR32: + // Push the contents of a local variable + Read16ip(parameter); + DEBUG("Push local var %d (%d)", parameter, *(int32 *) (variables + parameter)); + PUSHONSTACK(*(int32 *) (variables + parameter)); break; - - case CP_PUSH_GLOBAL_VAR32: // 2 Push a global variable - Read16ip(parameter) -#ifdef INSIDE_LINC - 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]); + case CP_PUSH_GLOBAL_VAR32: + // Push a global variable + Read16ip(parameter); + DEBUG("Push global var %d (%d)", parameter, globalInterpreterVariables2[parameter]); ASSERT(globalInterpreterVariables2); - PUSHONSTACK ( globalInterpreterVariables2[parameter] ); -#endif + PUSHONSTACK(globalInterpreterVariables2[parameter]); break; - case CP_POP_LOCAL_VAR32: // 3 Pop a value into a local word variable - Read16ip(parameter) - POPOFFSTACK ( value ); - DEBUG2("Pop %d into var %d",value,parameter); - *((int32 *)(variables+parameter)) = value; + case CP_POP_LOCAL_VAR32: + // Pop a value into a local word variable + Read16ip(parameter); + POPOFFSTACK(value); + DEBUG("Pop %d into var %d", value, parameter); + *((int32 *) (variables + parameter)) = value; break; - case CP_CALL_MCODE: // 4 Call an mcode routine - { - Read16ip(parameter) + case CP_CALL_MCODE: + // Call an mcode routine + Read16ip(parameter); ASSERT(parameter <= MAX_FN_NUMBER); - value = *((const int8 *)(code+ip)); // amount to adjust stack by (no of parameters) - ip ++; - DEBUG2("Call mcode %d with stack = %x",parameter,stack2+(stackPointer2-value)); -#ifdef INSIDE_LINC - int retVal = engine.McodeTable(parameter , stack2+(stackPointer2-value)); -#else - int retVal = McodeTable[parameter](stack2+(stackPointer2-value)); -#endif + // amount to adjust stack by (no of parameters) + Read8ip(value); + DEBUG("Call mcode %d with stack = %x", parameter, stack2 + stackPointer2 - value); + retVal = McodeTable[parameter](stack2 + stackPointer2 - value); stackPointer2 -= value; CHECKSTACKPOINTER2 - switch ( retVal & 7 ) - { case IR_STOP: // 0: Quit out for a cycle + + switch (retVal & 7) { + case IR_STOP: + // Quit out for a cycle *offset = ip; - return(0); + return 0; - case IR_CONT: // 1: // Continue as normal + case IR_CONT: + // Continue as normal break; - case IR_TERMINATE: // 2: - // Return without updating the offset - return(2); + case IR_TERMINATE: + // Return without updating the + // offset + return 2; - case IR_REPEAT: // 3: - // Return setting offset to start of this function call + case IR_REPEAT: + // Return setting offset to + // start of this function call *offset = savedStartOfMcode; - return(0); + return 0; - case IR_GOSUB: // 4: //that's really neat + case IR_GOSUB: + // that's really neat *offset = ip; - return(2); + return 2; default: ASSERT(FALSE); } parameterReturnedFromMcodeFunction = retVal >> 3; - } break; - case CP_PUSH_LOCAL_ADDR: // 5 push the address of a local variable - Read16ip(parameter) - DEBUG2("Push address of local variable %d (%x)",parameter,(int32)(variables + parameter)); - PUSHONSTACK ( (int32)(variables + parameter) ); + case CP_PUSH_LOCAL_ADDR: + // push the address of a local variable + Read16ip(parameter); + DEBUG("Push address of local variable %d (%x)", parameter, (int32) (variables + parameter)); + PUSHONSTACK((int32) (variables + parameter)); break; - case CP_PUSH_INT32: // 6 Push a long word value on to the stack - Read32ip(parameter) - DEBUG2("Push int32 %d (%x)",parameter,parameter); - PUSHONSTACK ( parameter ); + case CP_PUSH_INT32: + // Push a long word value on to the stack + Read32ip(parameter); + DEBUG("Push int32 %d (%x)", parameter, parameter); + PUSHONSTACK(parameter); break; - - case CP_SKIPONFALSE: // 7 Skip if the value on the stack is false - Read32ipLeaveip(parameter) - POPOFFSTACK ( value ); - DEBUG2("Skip %d if %d is false",parameter,value); + case CP_SKIPONFALSE: + // Skip if the value on the stack is false + Read32ipLeaveip(parameter); + POPOFFSTACK(value); + DEBUG("Skip %d if %d is false", parameter, value); if (value) ip += sizeof(int32); else ip += parameter; break; - case CP_SKIPALLWAYS: // 8 skip a block - Read32ipLeaveip(parameter) - DEBUG1("Skip %d",parameter); + case CP_SKIPALWAYS: + // skip a block + Read32ipLeaveip(parameter); + DEBUG("Skip %d", parameter); ip += parameter; break; - case CP_SWITCH: // 9 switch - { POPOFFSTACK ( value ); - int caseCount; - Read32ip(caseCount) + case CP_SWITCH: + // 9 switch + POPOFFSTACK(value); + Read32ip(caseCount); + // Search the cases - int foundCase = 0; - for (int count = 0 ; (count < caseCount) && (!foundCase) ; count++) - { - if (value == (int32)READ_LE_UINT32(code+ip)) - { // We have found the case, so lets jump to it + foundCase = 0; + for (count = 0; count < caseCount && !foundCase; count++) { + if (value == (int32) READ_LE_UINT32(code + ip)) { + // We have found the case, so + // lets jump to it foundCase = 1; - ip += (int32)READ_LE_UINT32(code+ip+sizeof(int32)); - } - else + ip += READ_LE_UINT32(code + ip + sizeof(int32)); + } else 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) - { - ip += (int32)READ_LE_UINT32(code+ip); - } - } + ip += READ_LE_UINT32(code + ip); + break; - case CP_ADDNPOP_LOCAL_VAR32: // 10 - Read16ip(parameter) - POPOFFSTACK ( value ); - *((int32 *)(variables+parameter)) += value; - DEBUG3("+= %d into var %d->%d",value,parameter,*(int32 *)(variables+parameter)); + case CP_ADDNPOP_LOCAL_VAR32: + Read16ip(parameter); + POPOFFSTACK(value); + *((int32 *) (variables + parameter)) += value; + DEBUG("+= %d into var %d->%d", value, parameter, *(int32 *) (variables + parameter)); break; - case CP_SUBNPOP_LOCAL_VAR32: // 11 - Read16ip(parameter) - POPOFFSTACK ( value ); - *((int32 *)(variables+parameter)) -= value; - DEBUG3("-= %d into var %d->%d",value,parameter,*(int32 *)(variables+parameter)); + case CP_SUBNPOP_LOCAL_VAR32: + Read16ip(parameter); + POPOFFSTACK(value); + *((int32 *) (variables + parameter)) -= value; + DEBUG("-= %d into var %d->%d", value, parameter, *(int32 *) (variables + parameter)); break; - case CP_SKIPONTRUE: // 12 Skip if the value on the stack is TRUE - Read32ipLeaveip(parameter) - POPOFFSTACK ( value ); - DEBUG2("Skip %d if %d is false",parameter,value); + case CP_SKIPONTRUE: + // Skip if the value on the stack is TRUE + Read32ipLeaveip(parameter); + POPOFFSTACK(value); + DEBUG("Skip %d if %d is false", parameter, value); if (!value) ip += sizeof(int32); else ip += parameter; break; - case CP_POP_GLOBAL_VAR32: // 13 // Pop a global variable - Read16ip(parameter) - POPOFFSTACK ( value ); - DEBUG2("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 + case CP_POP_GLOBAL_VAR32: + // Pop a global variable + Read16ip(parameter); + POPOFFSTACK(value); + DEBUG("Pop %d into global var %d", value, parameter); #ifdef TRACEGLOBALVARIABLESET - TRACEGLOBALVARIABLESET(parameter,value); + TRACEGLOBALVARIABLESET(parameter, value); #endif globalInterpreterVariables2[parameter] = value; - -#endif break; - case CP_ADDNPOP_GLOBAL_VAR32: // 14 Add and pop a global variable - { Read16ip(parameter) -// parameter = *((int16_TYPE *)(code+ip)); -// ip += 2; - 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 + case CP_ADDNPOP_GLOBAL_VAR32: + // Add and pop a global variable + Read16ip(parameter); + // parameter = *((int16_TYPE *) (code + ip)); + // ip += 2; + POPOFFSTACK(value); globalInterpreterVariables2[parameter] += value; - DEBUG3("+= %d into global var %d->%d",value,parameter,*(int32 *)(variables+parameter)); -#endif + DEBUG("+= %d into global var %d->%d", value, parameter, *(int32 *) (variables + parameter)); break; - } - - case CP_SUBNPOP_GLOBAL_VAR32: // 15 Sub and pop a global variable - { Read16ip(parameter) -// parameter = *((int16_TYPE *)(code+ip)); -// ip += 2; - 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 + + case CP_SUBNPOP_GLOBAL_VAR32: + // Sub and pop a global variable + Read16ip(parameter); + POPOFFSTACK(value); globalInterpreterVariables2[parameter] -= value; - DEBUG3("-= %d into global var %d->%d",value,parameter,*(int32 *)(variables+parameter)); -#endif + DEBUG("-= %d into global var %d->%d", value, parameter, *(int32 *) (variables + parameter)); break; - } case CP_DEBUGON: // Turn debugging on @@ -609,187 +562,195 @@ int RunScript ( char * scriptData , char * objectData , uint32 *offset ) break; case CP_QUIT: -#ifdef INSIDE_LINC - break; -#else // Quit out for a cycle *offset = ip; - return(0); -#endif + return 0; case CP_TERMINATE: - // Quit out immediately without affecting the offset pointer - return(3); - -/****************************************************************************************************************** -******************************************************************************************************************/ + // Quit out immediately without affecting the + // offset pointer + return 3; // Operators - case OP_ISEQUAL: // 20 // '==' - DEBUG3("%d == %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] == stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] == stack2[stackPointer2-1]) ); + case OP_ISEQUAL: + // '==' + DEBUG("%d == %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] == stack2[stackPointer2 - 1]); + DOOPERATION (stack2[stackPointer2 - 2] == stack2[stackPointer2 - 1]); break; - case OP_PLUS: // 21 // '+' - DEBUG3("%d + %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] + stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] + stack2[stackPointer2-1]) ); + case OP_PLUS: + // '+' + DEBUG("%d + %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] + stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] + stack2[stackPointer2 - 1]); break; - case OP_MINUS: // 22 // '+' - DEBUG3("%d - %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] - stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] - stack2[stackPointer2-1]) ); + case OP_MINUS: + // '-' + DEBUG("%d - %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] - stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] - stack2[stackPointer2 - 1]); break; - case OP_TIMES: // 23 // '+' - DEBUG3("%d * %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] * stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] * stack2[stackPointer2-1]) ); + case OP_TIMES: + // '*' + DEBUG("%d * %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] * stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] * stack2[stackPointer2 - 1]); break; - case OP_DEVIDE: // 24 // '+' - DEBUG3("%d / %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] / stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] / stack2[stackPointer2-1]) ); + case OP_DIVIDE: + // '/' + DEBUG("%d / %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] / stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] / stack2[stackPointer2 - 1]); break; - case OP_NOTEQUAL: // 25 // '!=' - DEBUG3("%d != %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] != stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] != stack2[stackPointer2-1]) ); + case OP_NOTEQUAL: + // '!=' + DEBUG("%d != %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] != stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] != stack2[stackPointer2 - 1]); break; - case OP_ANDAND: // 26 - DEBUG3("%d != %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] && stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] && stack2[stackPointer2-1]) ); + case OP_ANDAND: + // '&&' + DEBUG("%d != %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] && stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] && stack2[stackPointer2 - 1]); break; - case OP_GTTHAN: // 27 > - DEBUG3("%d > %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] > stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] > stack2[stackPointer2-1]) ); + case OP_GTTHAN: + // '>' + DEBUG("%d > %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] > stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] > stack2[stackPointer2 - 1]); break; - case OP_LSTHAN: // 28 < - DEBUG3("%d < %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] < stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] < stack2[stackPointer2-1]) ); + case OP_LSTHAN: + // '<' + DEBUG("%d < %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] < stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] < stack2[stackPointer2 - 1]); break; - case CP_JUMP_ON_RETURNED: // 29 - { // Jump to a part of the script depending on the return value from an mcode routine - parameter = *((const int8 *)(code+ip)); // Get the maximum value - ip++; -#ifdef INSIDE_LINC - TRACE("ip %d: Parameter %d skip %d\r\n", ip, - parameterReturnedFromMcodeFunction, - (int32)READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4) ); -#endif + case CP_JUMP_ON_RETURNED: + // Jump to a part of the script depending on + // the return value from an mcode routine - ip += (int32)READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4); - } + // Get the maximum value + Read8ip(parameter); + + ip += READ_LE_UINT32(code + ip + parameterReturnedFromMcodeFunction * 4); break; - case CP_TEMP_TEXT_PROCESS: // 30 + case CP_TEMP_TEXT_PROCESS: // Process a text line - Read32ip(parameter) -// parameter = *((int32_TYPE *)(code+ip)); -// ip += sizeof(int32_TYPE);; - DEBUG1("Process text id %d",parameter); -#ifdef INSIDE_LINC - // Linc only for the moment - engine.ProcessTextLine(parameter); -#endif //INSIDE_LINC - break; - - case CP_SAVE_MCODE_START: // 31 - // Save the start position on an mcode instruction in case we need to restart it again - savedStartOfMcode = ip-1; - break; - - case CP_RESTART_SCRIPT: // 32 - { // Start the script again - // Do a ip search to find the script we are running - const char *tempScrPtr = scriptData + (int32)READ_LE_UINT32(scriptData) + sizeof(int); - int scriptNumber = 0; - int foundScript = 0; - uint32 count = 0; - for (count = 1 ; (count < noScripts) && (!foundScript) ; count++) - { if (ip < ((const int *)tempScrPtr)[count+1]) - { scriptNumber = count - 1 ; + // This was apparently used in Linc + Read32ip(parameter); + DEBUG("Process text id %d", parameter); + break; + + case CP_SAVE_MCODE_START: + // Save the start position on an mcode + // instruction in case we need to restart it + // again + savedStartOfMcode = ip - 1; + break; + + case CP_RESTART_SCRIPT: + // Start the script again + // Do a ip search to find the script we are + // running + + tempScrPtr = scriptData + READ_LE_UINT32(scriptData) + sizeof(int); + scriptNumber = 0; + foundScript = 0; + + for (count = 1; count < (int) noScripts && !foundScript; count++) { + if (ip < ((const int *) tempScrPtr)[count + 1]) { + scriptNumber = count - 1; foundScript = 1; } } + if (!foundScript) - scriptNumber = count - 1 ; - // So we know what script we are running, lets restart it - ip = ((const int *)tempScrPtr)[scriptNumber+1]; + scriptNumber = count - 1; + + // So we know what script we are running, + // lets restart it + + ip = ((const int *) tempScrPtr)[scriptNumber + 1]; break; - } - case CP_PUSH_STRING: // 33 - { // Push the address of a string on to the stack - parameter = *((const int8 *)(code+ip)); // Get the string size - ip += 1; + case CP_PUSH_STRING: + // Push the address of a string on to the stack + // Get the string size + Read8ip(parameter); // ip points to the string - PUSHONSTACK( (int)(code+ip) ); - ip += (parameter+1); + PUSHONSTACK((int) (code + ip)); + ip += (parameter + 1); break; - } - case CP_PUSH_DEREFERENCED_STRUCTURE: // 34 - { // Push the address of a dereferenced structure - Read32ip(parameter) - DEBUG1("Push address of far variable (%x)",(int32)(variables + parameter)); - PUSHONSTACK( (int)(objectData + sizeof(int) + sizeof(_standardHeader) + sizeof(_object_hub) + parameter)); + case CP_PUSH_DEREFERENCED_STRUCTURE: + // Push the address of a dereferenced structure + Read32ip(parameter); + DEBUG("Push address of far variable (%x)", (int32) (variables + parameter)); + PUSHONSTACK((int) (objectData + sizeof(int) + sizeof(_standardHeader) + sizeof(_object_hub) + parameter)); break; - } - case OP_GTTHANE: // 35 >= - DEBUG3("%d > %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] >= stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] >= stack2[stackPointer2-1]) ); + case OP_GTTHANE: + // '>=' + DEBUG("%d > %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] >= stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] >= stack2[stackPointer2 - 1]); break; - case OP_LSTHANE: // 36 <= - DEBUG3("%d < %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] <= stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] <= stack2[stackPointer2-1]) ); + case OP_LSTHANE: + // '<=' + DEBUG("%d < %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] <= stack2[stackPointer2 - 1]); + DOOPERATION(stack2[stackPointer2 - 2] <= stack2[stackPointer2 - 1]); break; - case OP_OROR: // 37 - DEBUG3("%d || %d -> %d", stack2[stackPointer2-2], - stack2[stackPointer2-1], - stack2[stackPointer2-2] || stack2[stackPointer2-1]); - DOOPERATION ( (stack2[stackPointer2-2] || stack2[stackPointer2-1]) ); + case OP_OROR: + // '||' + DEBUG("%d || %d -> %d", + stack2[stackPointer2 - 2], + stack2[stackPointer2 - 1], + stack2[stackPointer2 - 2] || stack2[stackPointer2 - 1]); + DOOPERATION (stack2[stackPointer2 - 2] || stack2[stackPointer2 - 1]); break; - default: -#ifdef INSIDE_LINC - AfxMessageBox(CVString("Invalid interpreter token %d",curCommand)); -#else Con_fatal_error("Interpreter error: Invalid token %d", curCommand); -#endif - return(3); + return 3; } - } - return(1); + return 1; } diff --git a/sword2/interpreter.h b/sword2/interpreter.h index 13493c06aa..769267278b 100644 --- a/sword2/interpreter.h +++ b/sword2/interpreter.h @@ -17,157 +17,81 @@ * $Header$ */ -// Interpreter return codes - -#define IR_STOP 0 -#define IR_CONT 1 -#define IR_TERMINATE 2 -#define IR_REPEAT 3 -#define IR_GOSUB 4 - - -#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 +#ifndef _INTERPRETER +#define _INTERPRETER -#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 +// Interpreter return codes -#define ASSERT(x) {if(!(x)){Zdebug("Interpreter ASSERT %s,%d",__FILE__,__LINE__);Con_fatal_error("Assert error in interpreter");}} +#define IR_STOP 0 +#define IR_CONT 1 +#define IR_TERMINATE 2 +#define IR_REPEAT 3 +#define IR_GOSUB 4 +#define DEBUG if (g_debugFlag) Zdebug -#endif +#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 - // 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 Read32ip(var) {var = (int32)READ_LE_UINT32(code+ip);ip+=sizeof(int32);} -#define Read32ipLeaveip(var) {var = (int32)READ_LE_UINT32(code+ip);} +#define Read8ip(var) { var = *((const int8 *) (code + ip)); ip++; } +#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 Read32ipLeaveip(var) { var = (int32) READ_LE_UINT32(code + ip); } void SetGlobalInterpreterVariables(int32 *vars); +int RunScript (char *scriptData, char *objectData, uint32 *offset); + +// Compiled tokens + +#define CP_END_SCRIPT 0 +#define CP_PUSH_LOCAL_VAR32 1 // Push a local variable on to the stack +#define CP_PUSH_GLOBAL_VAR32 2 // Push a global variable +#define CP_POP_LOCAL_VAR32 3 // Pop a local variable from the stack +#define CP_CALL_MCODE 4 // Call a machine code function +#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_SKIPONFALSE 7 // Skip if the bottom value on the stack is false +#define CP_SKIPALWAYS 8 // Skip a block of code +#define CP_SWITCH 9 // Switch on last stack value +#define CP_ADDNPOP_LOCAL_VAR32 10 // Add to a local varible +#define CP_SUBNPOP_LOCAL_VAR32 11 // Subtract to a local variable +#define CP_SKIPONTRUE 12 // Skip if the bottom value on the stack is true +#define CP_POP_GLOBAL_VAR32 13 // Pop a global variable +#define CP_ADDNPOP_GLOBAL_VAR32 14 +#define CP_SUBNPOP_GLOBAL_VAR32 15 +#define CP_DEBUGON 16 // Turn debugging on +#define CP_DEBUGOFF 17 // Turn debugging off +#define CP_QUIT 18 // Quit for a cycle +#define CP_TERMINATE 19 // Quit script completely + +// Operators + +#define OP_ISEQUAL 20 // '==' +#define OP_PLUS 21 // '+' +#define OP_MINUS 22 // '-' +#define OP_TIMES 23 // '*' +#define OP_DIVIDE 24 // '/' +#define OP_NOTEQUAL 25 // '==' +#define OP_ANDAND 26 // '&&' +#define OP_GTTHAN 27 // '>' +#define OP_LSTHAN 28 // '<' + +// More tokens, mixed types + +#define CP_JUMP_ON_RETURNED 29 // Use table of jumps with value returned from fn_mcode +#define CP_TEMP_TEXT_PROCESS 30 // A dummy text process command for me +#define CP_SAVE_MCODE_START 31 // Save the mcode code start for restarting when necessary +#define CP_RESTART_SCRIPT 32 // Start the script from the beginning +#define CP_PUSH_STRING 33 // Push a pointer to a string on the stack +#define CP_PUSH_DEREFERENCED_STRUCTURE 34 // Push the address of a structure thing + +#define OP_GTTHANE 35 // >= +#define OP_LSTHANE 36 // <= +#define OP_OROR 37 // || or OR -#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 - -#define CP_END_SCRIPT 0 -#define CP_PUSH_LOCAL_VAR32 1 // Push a local variable on to the stack -#define CP_PUSH_GLOBAL_VAR32 2 // Push a global variable -#define CP_POP_LOCAL_VAR32 3 // Pop a local variable from the stack -#define CP_CALL_MCODE 4 // Call a machine code function -#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_SKIPONFALSE 7 // Skip if the bottom value on the stack is false -#define CP_SKIPALLWAYS 8 // Skip a block of code -#define CP_SWITCH 9 // Switch on last stack value -#define CP_ADDNPOP_LOCAL_VAR32 10 // Add to a local varible -#define CP_SUBNPOP_LOCAL_VAR32 11 // Subtract to a local variable -#define CP_SKIPONTRUE 12 // Skip if the bottom value on the stack is true -#define CP_POP_GLOBAL_VAR32 13 // Pop a global variable -#define CP_ADDNPOP_GLOBAL_VAR32 14 -#define CP_SUBNPOP_GLOBAL_VAR32 15 -#define CP_DEBUGON 16 // Turn debugging on -#define CP_DEBUGOFF 17 // Turn debugging off -#define CP_QUIT 18 // Quit for a cycle -#define CP_TERMINATE 19 // Quit script completely - -// Operators - -#define OP_ISEQUAL 20 // '==' -#define OP_PLUS 21 // '+' -#define OP_MINUS 22 // '-' -#define OP_TIMES 23 // '*' -#define OP_DEVIDE 24 // '/' -#define OP_NOTEQUAL 25 // '==' -#define OP_ANDAND 26 // && -#define OP_GTTHAN 27 // > -#define OP_LSTHAN 28 // < - -// More tokens, mixed types - -#define CP_JUMP_ON_RETURNED 29 // Use table of jumps with value returned from fn_mcode -#define CP_TEMP_TEXT_PROCESS 30 // A dummy text process command for me -#define CP_SAVE_MCODE_START 31 // Save the mcode code start for restarting when necessary -#define CP_RESTART_SCRIPT 32 // Start the script from the beginning -#define CP_PUSH_STRING 33 // Push a pointer to a string on the stack -#define CP_PUSH_DEREFERENCED_STRUCTURE 34 // Push the address of a structure thing - -#define OP_GTTHANE 35 // >= -#define OP_LSTHANE 36 // <= -#define OP_OROR 37 // || or OR diff --git a/sword2/object.h b/sword2/object.h index b5e5763c77..c158a22075 100644 --- a/sword2/object.h +++ b/sword2/object.h @@ -23,102 +23,103 @@ #include "driver/driver96.h" // 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) - - -// mouse structure - defines mouse detection area, detection priority & 'type' flag -typedef struct -{ - int32 x1; // top-left of mouse area is (x1,y1) - int32 y1; - int32 x2; // bottom-right of area is (x2,y2) (these coords are inclusive) - int32 y2; - int32 priority; - int32 pointer; // type (or resource id?) of pointer used over this area -} Object_mouse; +// 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 +typedef struct { + int32 x1; // Top-left and bottom-right of mouse + int32 y1; // area. (These coords are inclusive.) + int32 x2; + int32 y2; + int32 priority; + int32 pointer; // type (or resource id?) of pointer used over this area + +} Object_mouse; // logic structure - contains fields used in logic script processing -typedef struct -{ - int32 looping; // 0 when first calling FN_<function>; 1 when calling subsequent times in same loop - int32 pause; // pause count, used by FN_pause() + +typedef struct { + int32 looping; // 0 when first calling FN_<function>; + // 1 when calling subsequent times in same loop + int32 pause; // pause count, used by FN_pause() } Object_logic; -//------------------------------------------------ // status bits for 'type' field of Object_graphic) + // in low word: -#define NO_SPRITE 0x00000000 // don't print -#define BGP0_SPRITE 0x00000001 // fixed to background parallax[0] -#define BGP1_SPRITE 0x00000002 // fixed to background parallax[1] -#define BACK_SPRITE 0x00000004 // 'background' sprite, fixed to main background -#define SORT_SPRITE 0x00000008 // 'sorted' sprite, fixed to main background -#define FORE_SPRITE 0x00000010 // 'foreground' sprite, fixed to main background -#define FGP0_SPRITE 0x00000020 // fixed to foreground parallax[0] -#define FGP1_SPRITE 0x00000040 // fixed to foreground parallax[0] + +#define NO_SPRITE 0x00000000 // don't print +#define BGP0_SPRITE 0x00000001 // fixed to background parallax[0] +#define BGP1_SPRITE 0x00000002 // fixed to background parallax[1] +#define BACK_SPRITE 0x00000004 // 'background' sprite, fixed to main background +#define SORT_SPRITE 0x00000008 // 'sorted' sprite, fixed to main background +#define FORE_SPRITE 0x00000010 // 'foreground' sprite, fixed to main background +#define FGP0_SPRITE 0x00000020 // fixed to foreground parallax[0] +#define FGP1_SPRITE 0x00000040 // fixed to foreground parallax[0] // in high word: + #define UNSHADED_SPRITE 0x00000000 // not to be shaded #define SHADED_SPRITE 0x00010000 // to be shaded, based on shading mask -//------------------------------------------------ // graphic structure - contains fields appropriate to sprite output -typedef struct -{ - int32 type; // see above - int32 anim_resource; // resource id of animation file - int32 anim_pc; // current frame number of animation -} Object_graphic; +typedef struct { + int32 type; // see above + int32 anim_resource; // resource id of animation file + int32 anim_pc; // current frame number of animation +} Object_graphic; // speech structure - contains fields used by speech scripts & text output -typedef struct -{ - int32 pen; // colour to use for body of characters - int32 width; // max width of text sprite - int32 command; // speech script command id - int32 ins1; // speech script instruction parameters (may need more now?) - int32 ins2; - int32 ins3; - int32 ins4; - int32 ins5; - int32 wait_state; //0 not waiting 1 waiting for next speech command -} Object_speech; +typedef struct { + int32 pen; // colour to use for body of characters + int32 width; // max width of text sprite + int32 command; // speech script command id + int32 ins1; // speech script instruction parameters (may need more now?) + int32 ins2; + int32 ins3; + int32 ins4; + int32 ins5; + int32 wait_state; // 0 not waiting, 1 waiting for next speech command +} Object_speech; -// mega structure - contains fields used for mega-character & mega-set processing -typedef struct -{ - 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_3; // id of object which we are getting to - int32 NOT_USED_4; // pixel distance to stand from player character when in conversation - int32 currently_walking; // number given us by the auto router - int32 walk_pc; // current frame number of walk-anim - int32 scale_a; // current scale factors, taken from floor data - int32 scale_b; - int32 feet_x; // mega feet coords - frame-offsets are added to these position mega frames - int32 feet_y; - 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 megaset_res; // resource id of mega-set file - int32 NOT_USED_5; // NOT USED +// mega structure - contains fields used for mega-character & mega-set +// processing + +typedef struct { + 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_3; // id of object which we are getting to + int32 NOT_USED_4; // pixel distance to stand from player character when in conversation + int32 currently_walking; // number given us by the auto router + int32 walk_pc; // current frame number of walk-anim + int32 scale_a; // current scale factors, taken from floor data + int32 scale_b; + int32 feet_x; // mega feet coords - frame-offsets are added to these position mega frames + int32 feet_y; + int32 current_dir; // current dirction faced by mega; used by autorouter to determine turns required + int32 NOT_USED_5; // means were currently avoiding a collision (see FN_walk) + int32 megaset_res; // resource id of mega-set file + int32 NOT_USED_6; // NOT USED } Object_mega; - -// walk-data structure - contains details of layout of frames in the mega-set, and how they are to be used -typedef struct -{ - int32 nWalkFrames; // no. of frames per walk-cycle - int32 usingStandingTurnFrames; // 0=no 1=yes - int32 usingWalkingTurnFrames; // 0=no 1=yes - int32 usingSlowInFrames; // 0=no 1=yes - int32 usingSlowOutFrames; // 0=no !0=number of slow-out frames in each direction - int32 nSlowInFrames[8]; // no. of slow-in frames in each direction - int32 leadingLeg[8]; // leading leg for walk in each direction (0=left 1=right) - int32 dx[8*(12+1)]; // walk step distances in x direction - int32 dy[8*(12+1)]; // walk step distances in y direction +// walk-data structure - contains details of layout of frames in the +// mega-set, and how they are to be used + +typedef struct { + int32 nWalkFrames; // no. of frames per walk-cycle + int32 usingStandingTurnFrames; // 0 = no 1 = yes + int32 usingWalkingTurnFrames; // 0 = no 1 = yes + int32 usingSlowInFrames; // 0 = no 1 = yes + int32 usingSlowOutFrames; // 0 = no !0 = number of slow-out frames in each direction + int32 nSlowInFrames[8]; // no. of slow-in frames in each direction + int32 leadingLeg[8]; // leading leg for walk in each direction (0 = left 1 = right) + int32 dx[8 * (12 + 1)]; // walk step distances in x direction + int32 dy[8 * (12 + 1)]; // walk step distances in y direction } Object_walkdata; - #endif diff --git a/sword2/scroll.cpp b/sword2/scroll.cpp index 5f07e332e4..1768339f18 100644 --- a/sword2/scroll.cpp +++ b/sword2/scroll.cpp @@ -17,139 +17,159 @@ * $Header$ */ -//------------------------------------------------------------------------------------ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - #include "stdafx.h" -//#include "src\driver96.h" -#include "build_display.h" #include "debug.h" #include "defs.h" #include "header.h" #include "interpreter.h" #include "layers.h" -#include "memory.h" -#include "object.h" -#include "protocol.h" -#include "resman.h" #include "scroll.h" -//------------------------------------------------------------------------------------ -#define MAX_SCROLL_DISTANCE 8 // max no of pixel allowed to scroll per cycle +// max no of pixel allowed to scroll per cycle +#define MAX_SCROLL_DISTANCE 8 -//------------------------------------------------------------------------------------ -uint8 scroll_fraction=16; // used to be a define, but now it's flexible (see new functions below) -//------------------------------------------------------------------------------------ -void Set_scrolling(void) //S2.1(2Mar94jel) refurnished Tony25Sept96 :-) -{ - // feet_x = 128+320 // normally we aim to get George's feet at (320,250) from top left of screen window - // feet_y = 128+250 +// used to be a define, but now it's flexible (see new functions below) +uint8 scroll_fraction = 16; - // set scroll offsets according to the player's coords +void Set_scrolling(void) { // S2.1(2Mar94jel) refurnished Tony25Sept96 :-) + // normally we aim to get George's feet at (320,250) from top left + // of screen window + // feet_x = 128 + 320 + // feet_y = 128 + 250 - int16 offset_x; - int16 offset_y; - int16 dx, dy; - uint16 scroll_distance_x; // how much we want to scroll - uint16 scroll_distance_y; + // set scroll offsets according to the player's coords + int16 offset_x; + int16 offset_y; + int16 dx, dy; + uint16 scroll_distance_x; // how much we want to scroll + uint16 scroll_distance_y; - if (SCROLL_X || SCROLL_Y) // if the scroll offsets are being forced in script (05feb97 JAMES) - { + // if the scroll offsets are being forced in script (05feb97 JAMES) + if (SCROLL_X || SCROLL_Y) { // 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; else this_screen.scroll_offset_x = this_screen.max_scroll_offset_x; // 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; else this_screen.scroll_offset_y = this_screen.max_scroll_offset_y; - } - else - { - offset_x = this_screen.player_feet_x-this_screen.feet_x; // George's offset from the centre - the desired position for him - offset_y = this_screen.player_feet_y-this_screen.feet_y; + } else { + // 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; // 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! - { - //Zdebug(42,"init scroll"); + 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"); this_screen.scroll_offset_x = offset_x; this_screen.scroll_offset_y = offset_y; - this_screen.scroll_flag=1; - } - else // catch up with required scroll offsets - speed depending on distance to catch up (dx and dy) & 'SCROLL_FRACTION' used - { // but limit to certain number of pixels per cycle (MAX_SCROLL_DISTANCE) + this_screen.scroll_flag = 1; + } else { + // catch up with required scroll offsets - speed + // 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; dy = this_screen.scroll_offset_y - offset_y; - if (dx < 0) // 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; - } - 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 - if (dy < 0) - { - scroll_distance_y = (1+(-dy)/scroll_fraction); - this_screen.scroll_offset_y += scroll_distance_y < MAX_SCROLL_DISTANCE ? scroll_distance_y : MAX_SCROLL_DISTANCE; + // current scroll_offset_x is less than the required + // value + + // NB. I'm adding 1 to the result of + // dx / SCROLL_FRACTION, because it would otherwise + // not scroll at all when dx < SCROLL_FRACTION + + if (dx < 0) { + // => inc by (fraction of the differnce) + // 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) - { - 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 (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; + } 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 + // call when starting screens and to change the camera within screens + // 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 - // param 1 feet_y value + // 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 + // params: 0 feet_x value + // 1 feet_y value this_screen.feet_x = params[0]; this_screen.feet_y = params[1]; - - - return(IR_CONT); + return IR_CONT; } -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -int32 FN_set_scroll_speed_normal(int32 *params) // James08aug97 -{ - scroll_fraction=16; - return(IR_CONT); +int32 FN_set_scroll_speed_normal(int32 *params) { // James08aug97 + scroll_fraction = 16; + return IR_CONT; } -//------------------------------------------------------------------------------------ -int32 FN_set_scroll_speed_slow(int32 *params) // James08aug97 -{ - scroll_fraction=32; - return(IR_CONT); +int32 FN_set_scroll_speed_slow(int32 *params) { // James08aug97 + scroll_fraction = 32; + return IR_CONT; } -//------------------------------------------------------------------------------------ - diff --git a/sword2/scroll.h b/sword2/scroll.h index 649ffb71f1..6dce692850 100644 --- a/sword2/scroll.h +++ b/sword2/scroll.h @@ -17,13 +17,11 @@ * $Header$ */ -//the usual suspects +// the usual suspects #ifndef _SCROLL #define _SCROLL -//#include "src\driver96.h" - -void Set_scrolling(void); +void Set_scrolling(void); #endif diff --git a/sword2/sound.cpp b/sword2/sound.cpp index d8fb5ad89f..7928ffc9b3 100644 --- a/sword2/sound.cpp +++ b/sword2/sound.cpp @@ -17,346 +17,330 @@ * $Header$ */ -//-------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------- // BROKEN SWORD 2 // -// SOUND.CPP Contains the sound engine, fx & music functions -// Some very 'sound' code in here ;) +// SOUND.CPP Contains the sound engine, fx & music functions +// Some very 'sound' code in here ;) // // (16Dec96 JEL) // -//-------------------------------------------------------------------------------------- +// --------------------------------------------------------------------------- #include <stdio.h> #include "stdafx.h" -//#include "src\driver96.h" #include "console.h" -#include "defs.h" // for RESULT +#include "defs.h" // for RESULT #include "interpreter.h" -#include "protocol.h" // for FetchObjectName() for debugging FN_play_fx +#include "protocol.h" // for FetchObjectName() for debugging FN_play_fx #include "resman.h" #include "sound.h" #include "sword2.h" -//-------------------------------------------------------------------------------------- -typedef struct -{ - uint32 resource; // resource id of sample - uint32 fetchId; // Id of resource in PSX CD queue. :) - uint16 delay; // cycles to wait before playing (or 'random chance' if FX_RANDOM) - uint8 volume; // 0..16 - int8 pan; // -16..16 - uint8 type; // FX_SPOT, FX_RANDOM or FX_LOOP +typedef struct { + uint32 resource; // resource id of sample + uint32 fetchId; // Id of resource in PSX CD queue. :) + uint16 delay; // cycles to wait before playing (or 'random chance' if FX_RANDOM) + uint8 volume; // 0..16 + int8 pan; // -16..16 + uint8 type; // FX_SPOT, FX_RANDOM or FX_LOOP } _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]; -//-------------------------------------------------------------------------------------- +// 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]; -//-------------------------------------------------------------------------------------- -// local function prototypes +void Trigger_fx(uint8 j); -void Trigger_fx (uint8 j); - -//-------------------------------------------------------------------------------------- // initialise the fxq by clearing all the entries -void Init_fx_queue(void) -{ - uint8 j; - - - for (j=0; j < FXQ_LENGTH; j++) // scan the queue - { - fxq[j].resource = 0; // 0 resource means 'empty' slot - fxq[j].fetchId = 0; // Not being fetched. +void Init_fx_queue(void) { + for (int j = 0; j < FXQ_LENGTH; j++) { + fxq[j].resource = 0; // 0 resource means 'empty' slot + fxq[j].fetchId = 0; // Not being fetched. } } -//-------------------------------------------------------------------------------------- // process the fxq once every game cycle -void Process_fx_queue(void) -{ - uint8 j; // assuming FXQ_LENGTH is 255 or less +void Process_fx_queue(void) { + for (int j = 0; j < FXQ_LENGTH; j++) { + 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 - { - if (fxq[j].resource) // if this entry isn't empty - { - if (fxq[j].type == FX_RANDOM) // if it's type FX_RANDOM - { - 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 + case FX_SPOT: + if (fxq[j].delay) + fxq[j].delay--; + else { + Trigger_fx(j); fxq[j].type = FX_SPOT2; } - } - else if (fxq[j].type == FX_SPOT2) - { - if (g_sound->IsFxOpen(j+1)) - fxq[j].resource = 0; // Once the Fx has finished remove it from the queue. - } + break; + + case FX_SPOT2: + // Once the Fx has finished remove it from + // the queue. + + if (g_sound->IsFxOpen(j + 1)) + 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; int32 id; 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) - { - data = res_man.Res_open(fxq[j].resource); // load in the sample + if (fxq[j].type == FX_SPOT) { + // load in the sample + data = res_man.Res_open(fxq[j].resource); data += sizeof(_standardHeader); - rv = g_sound->PlayFx( id, data, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT ); // wav data gets copied to sound memory - res_man.Res_close(fxq[j].resource); // release the sample -// fxq[j].resource = 0; // clear spot fx from queue - } - else // 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) - rv = g_sound->PlayFx( id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT ); // not looped - else // FX_LOOP - rv = g_sound->PlayFx( id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXLOOP ); // looped + // wav data gets copied to sound memory + rv = g_sound->PlayFx(id, data, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT); + // release the sample + res_man.Res_close(fxq[j].resource); + } else { + // 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) { + // Not looped + rv = g_sound->PlayFx(id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXSPOT); + } else { + // Looped + rv = g_sound->PlayFx(id, NULL, fxq[j].volume, fxq[j].pan, RDSE_FXLOOP); + } } - #ifdef _SWORD2_DEBUG +#ifdef _SWORD2_DEBUG if (rv) Zdebug("SFX ERROR: PlayFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__); - #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 - // 1 type (FX_SPOT, FX_RANDOM, FX_LOOP) - // 2 delay (0..65535) - // 3 volume (0..16) - // 4 pan (-16..16) - - // example script: FN_play_fx (FXWATER, FX_LOOP, 0, 10, 15); - // fx_water = result; // fx_water is just a local script flag - // . - // . - // . - // FN_stop_fx (fx_water); - - uint8 j=0; - uint8 *data; - uint32 id; + // 1 type (FX_SPOT, FX_RANDOM, FX_LOOP) + // 2 delay (0..65535) + // 3 volume (0..16) + // 4 pan (-16..16) + + // example script: + // FN_play_fx (FXWATER, FX_LOOP, 0, 10, 15); + // // fx_water is just a local script flag + // fx_water = result; + // . + // . + // . + // FN_stop_fx (fx_water); + + uint8 j = 0; + uint8 *data; + uint32 id; uint32 rv; - //---------------------------------- - #ifdef _SWORD2_DEBUG - +#ifdef _SWORD2_DEBUG _standardHeader *header; char type[10]; - - if (wantSfxDebug) - { + if (wantSfxDebug) { switch (params[1]) // 'type' { case FX_SPOT: - strcpy(type,"SPOT"); + strcpy(type, "SPOT"); break; case FX_LOOP: - strcpy(type,"LOOPED"); + strcpy(type, "LOOPED"); break; case FX_RANDOM: - strcpy(type,"RANDOM"); + strcpy(type, "RANDOM"); break; default: - strcpy(type,"INVALID"); + strcpy(type, "INVALID"); } 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++; - if (j==FXQ_LENGTH) - { - return (IR_CONT); -// Con_fatal_error("ERROR: Sound queue overflow in FN_play_fx() (%s line %u)",__FILE__,__LINE__); + if (j == FXQ_LENGTH) + return IR_CONT; + + fxq[j].resource = params[0]; // wav resource id + fxq[j].type = params[1]; // FX_SPOT, FX_LOOP or FX_RANDOM + + if (fxq[j].type == FX_RANDOM) { + // 'delay' param is the intended average no. seconds between + // playing this effect (+1 to avoid divide-by-zero in + // 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]; } - else - { - fxq[j].resource = params[0]; // wav resource id - fxq[j].type = params[1]; // FX_SPOT, FX_LOOP or FX_RANDOM - if (fxq[j].type == FX_RANDOM) // 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) - else // FX_SPOT or FX_LOOP: - fxq[j].delay = params[2]; // 'delay' is no. frames to wait before playing + fxq[j].volume = params[3]; // 0..16 + fxq[j].pan = params[4]; // -16..16 - fxq[j].volume = params[3]; // 0..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); +#ifdef _SWORD2_DEBUG + header = (_standardHeader*) data; + if (header->fileType != WAV_FILE) + Con_fatal_error("FN_play_fx given invalid resource (%s line %u)", __FILE__, __LINE__); +#endif - if (fxq[j].type == FX_SPOT) // spot fx - { - #ifdef _SWORD2_DEBUG - data = res_man.Res_open(fxq[j].resource); // "pre-load" the sample; this gets it into memory - header = (_standardHeader*)data; - if (header->fileType != WAV_FILE) - 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 - res_man.Res_close(fxq[j].resource); // but then releases it to "age" out if the space is needed - } - else // random & looped fx - { - id = (uint32)j+1; // because 0 is not a valid id + // but then releases it to "age" out if the space is needed + res_man.Res_close(fxq[j].resource); + } else { + // random & looped fx - data = res_man.Res_open(fxq[j].resource); // load in the sample + id = (uint32) j + 1; // because 0 is not a valid id - #ifdef _SWORD2_DEBUG - header = (_standardHeader*)data; - if (header->fileType != WAV_FILE) - Con_fatal_error("FN_play_fx given invalid resource (%s line %u)",__FILE__,__LINE__); - #endif + // load in the sample + data = res_man.Res_open(fxq[j].resource); - data += sizeof(_standardHeader); - rv = g_sound->OpenFx(id,data); // copy it to sound memory, using position in queue as 'id' +#ifdef _SWORD2_DEBUG + header = (_standardHeader*)data; + if (header->fileType != WAV_FILE) + Con_fatal_error("FN_play_fx given invalid resource (%s line %u)", __FILE__, __LINE__); +#endif - #ifdef _SWORD2_DEBUG - if (rv) - Zdebug("SFX ERROR: OpenFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__); - #endif + data += sizeof(_standardHeader); - res_man.Res_close(fxq[j].resource); // release the sample - } - } + // copy it to sound memory, using position in queue as 'id' + rv = g_sound->OpenFx(id,data); + +#ifdef _SWORD2_DEBUG + if (rv) + Zdebug("SFX ERROR: OpenFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__); +#endif + // release the sample + res_man.Res_close(fxq[j].resource); + } - //--------------------------------------------- // (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) { + // play now, rather than in Process_fx_queue where it was + // getting played again & again! + Trigger_fx(j); + } - RESULT = j; // in case we want to call FN_stop_fx() later, to kill this fx (mainly for FX_LOOP & FX_RANDOM) + // in case we want to call FN_stop_fx() later, to kill this fx + // (mainly for FX_LOOP & FX_RANDOM) - return(IR_CONT); // continue script + RESULT = j; + return IR_CONT; } -//-------------------------------------------------------------------------------------- -int32 FN_sound_fetch(int32 *params) -{ +int32 FN_sound_fetch(int32 *params) { return (IR_CONT); } -//-------------------------------------------------------------------------------------- -// to alter the volume and pan of a currently playing fx -int32 FN_set_fx_vol_and_pan(int32 *params) -{ -// params 0 id of fx (ie. the id returned in 'result' from FN_play_fx -// 1 new volume (0..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]); - - return (IR_CONT); +// to alter the volume and pan of a currently playing fx +int32 FN_set_fx_vol_and_pan(int32 *params) { + // params: 0 id of fx (ie. the id returned in 'result' from + // FN_play_fx + // 1 new volume (0..16) + // 2 new pan (-16..16) + + // Zdebug("%d", params[2]); + + // 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 -int32 FN_set_fx_vol(int32 *params) -{ -// params 0 id of fx (ie. the id returned in 'result' from FN_play_fx -// 1 new volume (0..16) - -// SetFxIdVolume(int32 id, uint8 vol); - g_sound->SetFxIdVolume(1+params[0], params[1]); - return (IR_CONT); +// to alter the volume of a currently playing fx +int32 FN_set_fx_vol(int32 *params) { + // params: 0 id of fx (ie. the id returned in 'result' from + // FN_play_fx + // 1 new volume (0..16) + + // SetFxIdVolume(int32 id, uint8 vol); + g_sound->SetFxIdVolume(1 + params[0], params[1]); + 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 - // This will stop looped & random fx instantly, and remove the fx from the queue. - // So although it doesn't stop spot fx, it will remove them from the queue if they haven't yet played + // This will stop looped & random fx instantly, and remove the fx + // 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]; - uint32 id; - uint32 rv; + uint8 j = (uint8) params[0]; + uint32 id; + uint32 rv; + + if (fxq[j].type == FX_RANDOM || fxq[j].type == FX_LOOP) { + id = (uint32) j + 1; // because 0 is not a valid id - if ((fxq[j].type == FX_RANDOM) || (fxq[j].type == FX_LOOP)) - { - 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) Zdebug("SFX ERROR: CloseFx() returned %.8x (%s line %u)", rv, __FILE__, __LINE__); - #endif +#endif } - fxq[j].resource = 0; // remove from queue + // remove from queue + fxq[j].resource = 0; - - return(IR_CONT); // continue script + return IR_CONT; } -//-------------------------------------------------------------------------------------- -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 - // NO PARAMS + // params: none Clear_fx_queue(); - - return(IR_CONT); // continue script + return IR_CONT; } -//-------------------------------------------------------------------------------------- + // Stops all looped & random fx and clears the entire queue -void Clear_fx_queue(void) -{ - g_sound->ClearAllFx(); // stop all fx & remove the samples from sound memory - Init_fx_queue(); // clean out the queue -} +void Clear_fx_queue(void) { + // stop all fx & remove the samples from sound memory + g_sound->ClearAllFx(); -//-------------------------------------------------------------------------------------- + // clean out the queue + Init_fx_queue(); +} -//============================================================================= +// =========================================================================== // int32 StreamMusic(uint8 *filename, int32 loopFlag) // // 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. // The return value must be checked for any problems. // -// -------------------------------------------------------------------------- +// --------------------------------------------------------------------------- // // int32 PauseMusic(void) // // Stops the music dead in it's tracks. // -// -------------------------------------------------------------------------- +// --------------------------------------------------------------------------- // // int32 UnpauseMusic(void) // // Re-starts the music from where it was stopped. // -//============================================================================= -int32 FN_prepare_music(int32 *params) -{ - return (IR_CONT); +// =========================================================================== + +int32 FN_prepare_music(int32 *params) { + return IR_CONT; } -//-------------------------------------------------------------------------------------- -// Start a tune playing, to play once or to loop until stopped or next one played -int32 FN_play_music(int32 *params) // updated by James on 10apr97 -{ - // params 0 tune id - // 1 loop flag (0 or 1) +// Start a tune playing, to play once or to loop until stopped or next one +// played - char filename[128]; - uint32 loopFlag; - uint32 rv; // drivers return value +int32 FN_play_music(int32 *params) { // updated by James on 10apr97 + // params: 0 tune id + // 1 loop flag (0 or 1) + char filename[128]; + uint32 loopFlag; + 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; - looping_music_id = params[0]; // keep a note of the id, for restarting after an interruption to gameplay - } - else // just play once - { + + // keep a note of the id, for restarting after an + // interruption to gameplay + looping_music_id = params[0]; + } else { loopFlag = RDSE_FXSPOT; - looping_music_id = 0; // don't need to restart this tune after control panel or restore - } + // don't need to restart this tune after control panel or + // restore + looping_music_id = 0; + } // 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 // could use the music from the first CD of the complete game, // I suppose... strcpy(filename, "music.clu"); - else { + } else { File f; sprintf(filename, "music%d.clu", res_man.WhichCd()); @@ -427,59 +412,49 @@ int32 FN_play_music(int32 *params) // updated by James on 10apr97 rv = g_sound->StreamCompMusic(filename, params[0], loopFlag); - #ifdef _SWORD2_DEBUG +#ifdef _SWORD2_DEBUG if (rv) Zdebug("ERROR: StreamCompMusic(%s, %d, %d) returned error 0x%.8x", filename, params[0], loopFlag, rv); - #endif +#endif -// 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 - - looping_music_id=0; // clear the 'looping' flag - + looping_music_id = 0; // clear the 'looping' flag g_sound->StopMusic(); - - if (params); - - return(IR_CONT); // continue script + return IR_CONT; } -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- -void Kill_music(void) // James22aug97 -{ - uint8 count; - looping_music_id=0; // clear the 'looping' flag +void Kill_music(void) { // James22aug97 + looping_music_id = 0; // clear the 'looping' flag g_sound->StopMusic(); +/* I don't think this is needed with our music code // THIS BIT CAUSES THE MUSIC TO STOP INSTANTLY! - for(count=0; count<16; count++) + for(int count=0; count<16; count++) g_sound->UpdateCompSampleStreaming(); +*/ } -//-------------------------------------------------------------------------------------- -int32 FN_check_music_playing(int32 *params) // James (30july97) -{ - // params: none +int32 FN_check_music_playing(int32 *params) { // James (30july97) + // params: none + // sets result to no. of seconds of current tune remaining // 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 -{ - uint32 rv; // for drivers return value + +void PauseAllSound(void) { // James25july97 + uint32 rv; rv = g_sound->PauseMusic(); if (rv != RD_OK) @@ -493,10 +468,9 @@ void PauseAllSound(void) // James25july97 if (rv != RD_OK) Zdebug("ERROR: PauseFx() returned %.8x in PauseAllSound()", rv); } -//-------------------------------------------------------------------------------------- -void UnpauseAllSound(void) // James25july97 -{ - uint32 rv; // for drivers return value + +void UnpauseAllSound(void) { // James25july97 + uint32 rv; rv = g_sound->UnpauseMusic(); if (rv != RD_OK) @@ -510,5 +484,3 @@ void UnpauseAllSound(void) // James25july97 if (rv != RD_OK) Zdebug("ERROR: UnpauseFx() returned %.8x in UnpauseAllSound()", rv); } -//-------------------------------------------------------------------------------------- - diff --git a/sword2/sound.h b/sword2/sound.h index 5a504a88a4..4ba808b966 100644 --- a/sword2/sound.h +++ b/sword2/sound.h @@ -33,23 +33,30 @@ #include "common/scummsys.h" // fx types + #define FX_SPOT 0 #define FX_LOOP 1 #define FX_RANDOM 2 #define FX_SPOT2 3 -void Init_fx_queue(void); // to be called during system initialisation -void Process_fx_queue(void); // to be called from the main loop, once per cycle -void Clear_fx_queue(void); // stops all fx & clears the queue - eg. when leaving a location -void PauseAllSound(void); // James25july97 -void UnpauseAllSound(void); // James25july97 +// to be called during system initialisation +void Init_fx_queue(void); + +// 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 Kill_music(void); // James22aug97 +void PauseAllSound(void); +void UnpauseAllSound(void); +void Kill_music(void); int32 FN_play_music(int32 *params); // for save_Rest.cpp 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 diff --git a/sword2/speech.cpp b/sword2/speech.cpp index afd082c755..bdf30604c6 100644 --- a/sword2/speech.cpp +++ b/sword2/speech.cpp @@ -17,11 +17,9 @@ * $Header$ */ -//------------------------------------------------------------------------------------ #include "stdafx.h" #include "stdafx.h" -//#include "src\driver96.h" #include "anims.h" #include "console.h" #include "controls.h" // for 'subtitles' & 'speechSelected' @@ -42,1869 +40,1574 @@ #include "speech.h" #include "sword2.h" #include "walker.h" -//------------------------------------------------------------------------------------ - -#define INS_talk 1 -#define INS_anim 2 -#define INS_reverse_anim 3 -#define INS_walk 4 -#define INS_turn 5 -#define INS_face 6 -#define INS_trace 7 -#define INS_no_sprite 8 -#define INS_sort 9 -#define INS_foreground 10 -#define INS_background 11 -#define INS_table_anim 12 + +#define INS_talk 1 +#define INS_anim 2 +#define INS_reverse_anim 3 +#define INS_walk 4 +#define INS_turn 5 +#define INS_face 6 +#define INS_trace 7 +#define INS_no_sprite 8 +#define INS_sort 9 +#define INS_foreground 10 +#define INS_background 11 +#define INS_table_anim 12 #define INS_reverse_table_anim 13 -#define INS_walk_to_anim 14 -#define INS_set_frame 15 +#define INS_walk_to_anim 14 +#define INS_set_frame 15 #define INS_stand_after_anim 16 -#define INS_quit 42 +#define INS_quit 42 + +// when not playing a wav we calculate the speech time based upon length of +// ascii -//------------------------------------------------------------------------------------ +uint32 speech_time = 0; -uint32 speech_time=0; //when not playing a wav we calculate the speech time based upon length of ascii +uint32 speech_text_bloc_no = 0; +uint32 anim_id = 0; -uint32 speech_text_bloc_no=0; -uint32 anim_id=0; -uint32 speech_anim_type; //0 lip synced and repeating - 1 normal once through -uint32 left_click_delay=0; // click-delay for LEFT mouse button -uint32 right_click_delay=0; // click-delay for RIGHT mouse button +// 0 lip synced and repeating - 1 normal once through +uint32 speech_anim_type; -uint32 default_response_id=0; // ref number for default response when luggage icon is used on a person - // & it doesn't match any of the icons which would have been in the chooser -int16 officialTextNumber=0; // "TEXT" - current official text line number - will match the wav filenames +uint32 left_click_delay = 0; // click-delay for LEFT mouse button +uint32 right_click_delay = 0; // click-delay for RIGHT mouse button -int32 speechScriptWaiting = 0; // usually 0; if non-zero then it's the id of whoever we're waiting for in a speech script - // see FN_they_do, FN_they_do_we_wait & FN_we_wait +// ref number for default response when luggage icon is used on a person +// & it doesn't match any of the icons which would have been in the chooser +uint32 default_response_id = 0; -int16 text_x, text_y; // calculated by LocateTalker() for use in speech-panning & text-sprite positioning +// "TEXT" - current official text line number - will match the wav filenames +int16 officialTextNumber = 0; -_subject_unit subject_list[MAX_SUBJECT_LIST]; +// usually 0; if non-zero then it's the id of whoever we're waiting for in a +// speech script see FN_they_do, FN_they_do_we_wait & FN_we_wait +int32 speechScriptWaiting = 0; +// calculated by LocateTalker() for use in speech-panning & text-sprite +// positioning +int16 text_x, text_y; -//------------------------------------------------------------------------------------ -// local function prototypes +_subject_unit subject_list[MAX_SUBJECT_LIST]; -int32 FN_i_speak(int32 *params); -void LocateTalker(int32 *params); // (James 01july97) -void Form_text(int32 *params); //Tony18Oct96 -BOOL Is_anim_boxed(uint32 res); //Tony20Oct96 -uint8 WantSpeechForLine(uint32 wavId); // James (29july97) +int32 FN_i_speak(int32 *params); +void LocateTalker(int32 *params); +void Form_text(int32 *params); +BOOL Is_anim_boxed(uint32 res); +uint8 WantSpeechForLine(uint32 wavId); #ifdef _SWORD2_DEBUG void GetCorrectCdForSpeech(int32 wavId); // for testing speech & text #endif -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -int32 FN_add_subject(int32 *params) // James12nov96 / Tony18Nov96 -{ -// param[0] id -// param[1] daves reference number - - if (IN_SUBJECT==0) // if this is the start of the new subject list (James 07may97) - default_response_id=0; // set the default repsonse id to zero in case we're never passed one - // - this just means we'd get the response for the 1st icon in the chooser - // which is better than crashing - - if (params[0] == -1) // this isn't an icon at all, it's telling us the id of the default response - { - default_response_id = params[1]; // and here it is - this is the ref number we will return if - // a luggage icon is clicked on someone when it wouldn't have - // been in the chooser list (see FN_choose below) +int32 FN_add_subject(int32 *params) { // James12nov96 / Tony18Nov96 + // params: 0 id + // 1 daves reference number + + if (IN_SUBJECT==0) { + // This is the start of the new subject list (James 07may97) + // Set the default repsonse id to zero in case we're never + // passed one + default_response_id = 0; } - else + + // - this just means we'd get the response for the 1st icon in the + // chooser which is better than crashing + + if (params[0] == -1) { - subject_list[IN_SUBJECT].res=params[0]; - subject_list[IN_SUBJECT].ref=params[1]; + // this isn't an icon at all, it's telling us the id of the + // default response -// Zdebug("FN_add_subject res %d, uid %d", params[0], params[1]); + // and here it is - this is the ref number we will return if + default_response_id = params[1]; - IN_SUBJECT+=1; - } + // a luggage icon is clicked on someone when it wouldn't have + // been in the chooser list (see FN_choose below) + } else { + subject_list[IN_SUBJECT].res = params[0]; + subject_list[IN_SUBJECT].ref = params[1]; + // Zdebug("FN_add_subject res %d, uid %d", params[0], params[1]); - return(IR_CONT); // continue script -} -//------------------------------------------------------------------------------------ -int choosing=0; //could alternately use logic->looping of course + IN_SUBJECT++; + } -int32 FN_choose(int32 *params) //Tony19Nov96 -{ -//no params + return IR_CONT; +} -//the human is switched off so there will be no normal mouse engine +// could alternately use logic->looping of course +int choosing = 0; +int32 FN_choose(int32 *params) { //Tony19Nov96 + // params: none - _mouseEvent *me; - uint32 j,hit; - uint8 *icon; - uint32 pos=0; + // the human is switched off so there will be no normal mouse engine -// Zdebug("into choose"); + _mouseEvent *me; + uint32 j, hit; + uint8 *icon; + uint32 pos = 0; - - AUTO_SELECTED=0; // see below (James23may97) + // Zdebug("into choose"); + AUTO_SELECTED = 0; // see below (James23may97) - //------------------------------------------- // new thing to intercept objects held at time of clicking on a person // (James 06may97) - if (OBJECT_HELD) // if we are using a luggage icon on the person - { - // scan the subject list to see if this icon would have been available at this time - // if it is there, return the relevant 'ref' number (as if it had been selected from within the conversation) - // if not, just return a special code to get the default text line(s) for unsupported objects + if (OBJECT_HELD) { + // If we are using a luggage icon on the person, scan the + // subject list to see if this icon would have been available + // at this time. + // + // If it is there, return the relevant 'ref' number (as if it + // had been selected from within the conversation). If not, + // just return a special code to get the default text line(s) + // for unsupported objects. + // // Note that we won't display the subject icons in this case! - while (pos < IN_SUBJECT) // scan the subject list for a match with our 'object_held' - { - if (subject_list[pos].res == OBJECT_HELD) // if we've found a match - { - OBJECT_HELD=0; // clear it so it doesn't keep happening! - IN_SUBJECT=0; // clear the subject list - return(IR_CONT+(subject_list[pos].ref<<3)); // return special subject chosen code (same as in normal chooser routine below) + // scan the subject list for a match with our 'object_held' + while (pos < IN_SUBJECT) { + if (subject_list[pos].res == OBJECT_HELD) { + // if we've found a match, clear it so it + // doesn't keep happening! + OBJECT_HELD = 0; + + // clear the subject list + IN_SUBJECT = 0; + + // return special subject chosen code (same + // as in normal chooser routine below) + return IR_CONT + (subject_list[pos].ref << 3); } - pos++; // next position + pos++; } - OBJECT_HELD=0; // clear it so it doesn't keep happening! - IN_SUBJECT=0; // clear the subject list - return(IR_CONT+(default_response_id<<3)); // so that the speech script uses the default text for objects that are not accounted for + OBJECT_HELD = 0; // clear it so it doesn't keep happening! + IN_SUBJECT = 0; // clear the subject list + + // so that the speech script uses the default text for + // objects that are not accounted for + return IR_CONT + (default_response_id << 3); } - //------------------------------------------- + // new thing for skipping chooser with "nothing else to say" text // (James 23may97) - // If this is the 1st time the chooser is coming up in this conversation - // AND there's only 1 subject - // AND it's the EXIT icon - if ((CHOOSER_COUNT_FLAG==0) && (IN_SUBJECT==1) && (subject_list[0].res == EXIT_ICON)) - { - AUTO_SELECTED=1; // for speech script - - IN_SUBJECT=0; // clear the subject list - return(IR_CONT+(subject_list[0].ref<<3)); // return special subject chosen code (same as in normal chooser routine below) - } - //------------------------------------------- - + // If this is the 1st time the chooser is coming up in this + // conversation, AND there's only 1 subject, AND it's the EXIT icon - if (!choosing) //new choose session - { + if (CHOOSER_COUNT_FLAG == 0 && IN_SUBJECT == 1 && subject_list[0].res == EXIT_ICON) { + AUTO_SELECTED = 1; // for speech script + IN_SUBJECT = 0; // clear the subject list + // return special subject chosen code (same as in normal + // chooser routine below) + return IR_CONT + (subject_list[0].ref << 3); + } -// build menus from subject_list + if (!choosing) { + // new choose session + // build menus from subject_list - if (!IN_SUBJECT) + if (!IN_SUBJECT) Con_fatal_error("FN_choose with no subjects :-O"); -//init top menu from master list - for (j=0;j<15;j++) //all icons are highlighted / full colour - { - if (j<IN_SUBJECT) - { -// Zdebug(" ICON res %d for %d", subject_list[j].res, j); - icon = res_man.Res_open( subject_list[j].res ) + sizeof(_standardHeader) + RDMENU_ICONWIDE*RDMENU_ICONDEEP; + // init top menu from master list + // all icons are highlighted / full colour + + for (j = 0; j < 15; j++) { + if (j < IN_SUBJECT) { + // Zdebug(" ICON res %d for %d", subject_list[j].res, j); + icon = res_man.Res_open(subject_list[j].res) + sizeof(_standardHeader) + RDMENU_ICONWIDE * RDMENU_ICONDEEP; SetMenuIcon(RDMENU_BOTTOM, (uint8) j, icon); - res_man.Res_close( subject_list[j].res ); - } - else - { SetMenuIcon(RDMENU_BOTTOM, (uint8) j, NULL); //no icon here + res_man.Res_close(subject_list[j].res); + } else { + //no icon here //Zdebug(" NULL for %d", j); + SetMenuIcon(RDMENU_BOTTOM, (uint8) j, NULL); } } -// start menus appearing + // start menus appearing ShowMenu(RDMENU_BOTTOM); - -// lets have the mouse pointer back + // lets have the mouse pointer back Set_mouse(NORMAL_MOUSE_ID); - choosing=1; + choosing = 1; - return(IR_REPEAT); //again next cycle - } + // again next cycle + return IR_REPEAT; + } else { + // menu is there - we're just waiting for a click + // Zdebug("choosing"); - else //menu is there - we're just waiting for a click - { -// Zdebug("choosing"); - me = MouseEvent(); //get mouse event - -// we only care about left clicks -// we ignore mouse releases - - if ((me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) - { -// check for click on a menu -// if so then end the choose, highlight only the chosen, blank the mouse and return the ref code *8 - - if ((mousey>399)&&(mousex>=24)&&(mousex<640-24)) - { - hit=(mousex-24)/40; //which are we over? - - if (hit<IN_SUBJECT) //clicked on something - what button? - { - //-------------------------------------- - // Write to walkthrough file (zebug0.txt) - #ifdef _SWORD2_DEBUG - Zdebug(0,"----------------------"); - Zdebug(0,"Icons available:"); - #endif - //-------------------------------------- - - for (j=0;j<IN_SUBJECT;j++) //change icons - { - //-------------------------------------- - // Write to walkthrough file (zebug0.txt) - #ifdef _SWORD2_DEBUG - Zdebug(0,"%s", FetchObjectName(subject_list[j].res)); - #endif - //-------------------------------------- - - if (j!=hit) //change all others to grey - { - icon = res_man.Res_open( subject_list[j].res ) + sizeof(_standardHeader); //now grey + me = MouseEvent(); + + // we only care about left clicks + // we ignore mouse releases + + if (me && (me->buttons & RD_LEFTBUTTONDOWN)) { + // check for click on a menu + // if so then end the choose, highlight only the + // chosen, blank the mouse and return the ref code * 8 + + if (mousey > 399 && mousex >= 24 && mousex < 640 - 24) { + //which are we over? + hit = (mousex - 24) / 40; + + //clicked on something - what button? + if (hit < IN_SUBJECT) { +#ifdef _SWORD2_DEBUG + // Write to walkthrough file + // (zebug0.txt) + Zdebug(0, "----------------------"); + Zdebug(0, "Icons available:"); +#endif + + // change icons + for (j = 0; j < IN_SUBJECT; j++) { +#ifdef _SWORD2_DEBUG + // Write to walkthrough file + // (zebug0.txt) + Zdebug(0, "%s", FetchObjectName(subject_list[j].res)); +#endif + + // change all others to grey + if (j != hit) { + icon = res_man.Res_open( subject_list[j].res ) + sizeof(_standardHeader); SetMenuIcon(RDMENU_BOTTOM, (uint8) j, icon); - res_man.Res_close( subject_list[j].res ); + res_man.Res_close(subject_list[j].res); } } - //-------------------------------------- - // Write to walkthrough file (zebug0.txt) - #ifdef _SWORD2_DEBUG - Zdebug(0,"Selected: %s", FetchObjectName(subject_list[hit].res)); - Zdebug(0,"----------------------"); - #endif - //-------------------------------------- - choosing=0; //this is our looping flag +#ifdef _SWORD2_DEBUG + // Write to walkthrough file + // (zebug0.txt) + Zdebug(0, "Selected: %s", FetchObjectName(subject_list[hit].res)); + Zdebug(0, "----------------------"); +#endif + + // this is our looping flag + choosing = 0; - IN_SUBJECT=0; + IN_SUBJECT = 0; - Set_mouse(0); //blank mouse again + // blank mouse again + Set_mouse(0); -// Zdebug("hit %d - ref %d ref*8 %d", hit, subject_list[hit].ref, subject_list[hit].ref*8); + // Zdebug("hit %d - ref %d ref*8 %d", hit, subject_list[hit].ref, subject_list[hit].ref * 8); - RESULT=subject_list[hit].res; //for non-speech scripts that manually call the chooser + // for non-speech scripts that manually + // call the chooser + RESULT = subject_list[hit].res; - return(IR_CONT+(subject_list[hit].ref<<3)); //return special subject chosen code + // return special subject chosen code + return IR_CONT + (subject_list[hit].ref << 3); } } } -// Zdebug("end choose"); - return(IR_REPEAT); //again next cycle + // Zdebug("end choose"); + // again next cycle + return IR_REPEAT; } } -//------------------------------------------------------------------------------------ -int32 FN_start_conversation(int32 *params) //Tony27Nov96 -{ -//Start conversation -//FN_no_human(); // an FN_no_human -//FN_change_speech_text (PLAYER, GEORGE_WIDTH, GEORGE_PEN ); +int32 FN_start_conversation(int32 *params) { // Tony27Nov96 + // Start conversation -//params: 0 <empty> + // FN_no_human(); // an FN_no_human + // FN_change_speech_text(PLAYER, GEORGE_WIDTH, GEORGE_PEN); -// Zdebug("FN_start_conversation %d", ID); + // params: none + + // Zdebug("FN_start_conversation %d", ID); - //-------------------------------------------------------------- // reset 'chooser_count_flag' at the start of each conversation: // Note that FN_start_conversation might accidently be called // every time the script loops back for another chooser - // but we only want to reset the chooser count flag the first time this function is called - // ie. when talk flag is zero - if (TALK_FLAG==0) - CHOOSER_COUNT_FLAG=0; // see FN_chooser & speech scripts - //-------------------------------------------------------------- + // but we only want to reset the chooser count flag the first time + // this function is called ie. when talk flag is zero - FN_no_human(params); + if (TALK_FLAG == 0) + CHOOSER_COUNT_FLAG = 0; // see FN_chooser & speech scripts - return(IR_CONT); + FN_no_human(params); + return IR_CONT; } -//------------------------------------------------------------------------------------ -int32 FN_end_conversation(int32 *params) //Tony27Nov96 -{ -//end conversation -//talk_flag=0; -//FN_end_chooser(); -//FN_add_human(); -//FN_change_speech_text (PLAYER, VOICE_OVER_WIDTH, VOICE_OVER_PEN ); -//FN_idle(); -//params: 0 <empty> +int32 FN_end_conversation(int32 *params) { // Tony27Nov96 + // end conversation + // talk_flag=0; + // FN_end_chooser(); + // FN_add_human(); + // FN_change_speech_text(PLAYER, VOICE_OVER_WIDTH, VOICE_OVER_PEN); + // FN_idle(); + // params: none -// Zdebug("FN_end_conversation"); + // Zdebug("FN_end_conversation"); HideMenu(RDMENU_BOTTOM); - if (mousey>399) - { mouse_mode=MOUSE_holding; //will wait for cursor to move off the bottom menu + if (mousey > 399) { + // will wait for cursor to move off the bottom menu + mouse_mode = MOUSE_holding; Zdebug(" holding"); } - TALK_FLAG=0; //in-case DC forgets + TALK_FLAG = 0; //in-case DC forgets + // restart george's base script + // LLogic.Total_restart(); -// restart george's base script -// LLogic.Total_restart(); + //drop out without saving pc and go around again + return IR_CONT; +} - // if (params); what is this supposed to do? - khalek +int32 FN_they_do(int32 *params) { // S2.1(18Jan95tw) Tony3Dec96 + // doesn't send the command until target is waiting - once sent we + // carry on - return(IR_CONT); //drop out without saving pc and go around again -} -//------------------------------------------------------------------------------------ -int32 FN_they_do(int32 *params) //S2.1(18Jan95tw) Tony3Dec96 -{ -//doesn't send the command until target is waiting - once sent we carry on - -//params 0 target -// 1 command -// 2 ins1 -// 3 ins2 -// 4 ins3 -// 5 ins4 -// 6 ins5 - - uint32 null_pc=5; //4th script - get-speech-state - char *raw_script_ad; - _standardHeader *head; - int32 target=params[0]; + // params: 0 target + // 1 command + // 2 ins1 + // 3 ins2 + // 4 ins3 + // 5 ins4 + // 6 ins5 + uint32 null_pc = 5; // 4th script - get-speech-state + char *raw_script_ad; + _standardHeader *head; + int32 target = params[0]; -//request status of target + // request status of target head = (_standardHeader*) res_man.Res_open(target); - if (head->fileType!=GAME_OBJECT) + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_they_do %d not an object", target); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data + raw_script_ad = (char *) head; + + //call the base script - this is the graphic/mouse service call + RunScript(raw_script_ad, raw_script_ad, &null_pc); - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call res_man.Res_close(target); -//result is 1 for waiting, 0 for busy + // result is 1 for waiting, 0 for busy - if ((RESULT==1)&&(!INS_COMMAND)) //its waiting and no other command is queueing - { - speechScriptWaiting = 0; // reset debug flag now that we're no longer waiting - see debug.cpp + if (RESULT == 1 && !INS_COMMAND) { + // its waiting and no other command is queueing + // reset debug flag now that we're no longer waiting - see + // debug.cpp - SPEECH_ID = params[0]; - INS_COMMAND = params[1]; - INS1 = params[2]; - INS2 = params[3]; - INS3 = params[4]; - INS4 = params[5]; - INS5 = params[6]; + speechScriptWaiting = 0; - return(IR_CONT); //script cont + SPEECH_ID = params[0]; + INS_COMMAND = params[1]; + INS1 = params[2]; + INS2 = params[3]; + INS3 = params[4]; + INS4 = params[5]; + INS5 = params[6]; + + return IR_CONT; } - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // target is busy so come back again next cycle + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; + + // target is busy so come back again next cycle + return IR_REPEAT; } -//------------------------------------------------------------------------------------ -int32 FN_they_do_we_wait(int32 *params) //Tony3Dec96 -{ -//give target a command and wait for it to register as finished - -//params 0 pointer to ob_logic -// 1 target -// 2 command -// 3 ins1 -// 4 ins2 -// 5 ins3 -// 6 ins4 -// 7 ins5 - -//'looping' flag is used as a sent command yes/no - - Object_logic *ob_logic; - - uint32 null_pc=5; //4th script - get-speech-state - char *raw_script_ad; - _standardHeader *head; - int32 target=params[1]; +int32 FN_they_do_we_wait(int32 *params) { //Tony3Dec96 + // give target a command and wait for it to register as finished + + // params: 0 pointer to ob_logic + // 1 target + // 2 command + // 3 ins1 + // 4 ins2 + // 5 ins3 + // 6 ins4 + // 7 ins5 -// Zdebug("FN_they_do_we_wait id %d, command %d", params[1], params[2]); + // 'looping' flag is used as a sent command yes/no + + Object_logic *ob_logic; + + uint32 null_pc = 5; // 4th script - get-speech-state + char *raw_script_ad; + _standardHeader *head; + int32 target = params[1]; + // Zdebug("FN_they_do_we_wait id %d, command %d", params[1], params[2]); + + // ok, see if the target is busy - we must request this info from the + // target object -// ok, see if the target is busy - we must request this info from the target object head = (_standardHeader*) res_man.Res_open(target); - if (head->fileType!=GAME_OBJECT) + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_they_do_we_wait %d not an object", target); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data - - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call - res_man.Res_close(target); + raw_script_ad = (char *) head; + // call the base script - this is the graphic/mouse service call + RunScript(raw_script_ad, raw_script_ad, &null_pc); + res_man.Res_close(target); + ob_logic = (Object_logic *) params[0]; + if (!INS_COMMAND && RESULT == 1 && ob_logic->looping == 0) { + // first time so set up targets command if target is waiting - ob_logic = (Object_logic *)params[0]; + // Zdebug("FNtdww sending command to %d", target); - if ((!INS_COMMAND)&&(RESULT==1)&&(ob_logic->looping==0)) //first time so set up targets command if target is waiting - { + SPEECH_ID = params[1]; + INS_COMMAND = params[2]; + INS1 = params[3]; + INS2 = params[4]; + INS3 = params[5]; + INS4 = params[6]; + INS5 = params[7]; -// Zdebug("FNtdww sending command to %d", target); + ob_logic->looping = 1; - SPEECH_ID = params[1]; - INS_COMMAND = params[2]; - INS1 = params[3]; - INS2 = params[4]; - INS3 = params[5]; - INS4 = params[6]; - INS5 = params[7]; + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; - ob_logic->looping=1; + // finish this cycle - but come back again to check for it + // being finished + return IR_REPEAT; + } else if (ob_logic->looping == 0) { + // did not send the command + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // finish this cycle - but come back again to check for it being finished + // come back next go and try again to send the instruction + return IR_REPEAT; } - else if (ob_logic->looping==0) //did not send the command - { - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // come back next go and try again to send the instruction - } - -//ok, the command has been sent - has the target actually done it yet? + // ok, the command has been sent - has the target actually done it yet? -//result is 1 for waiting, 0 for busy + // result is 1 for waiting, 0 for busy - if (RESULT==1) // its waiting now so we can be finished with all this - { -// Zdebug("FNtdww finished"); - ob_logic->looping=0; // not looping anymore + if (RESULT == 1) { + // its waiting now so we can be finished with all this + // Zdebug("FNtdww finished"); + // not looping anymore + ob_logic->looping = 0; - speechScriptWaiting = 0; // reset debug flag now that we're no longer waiting - see debug.cpp - return(IR_CONT); // script cont + // reset debug flag now that we're no longer waiting - see + // debug.cpp + speechScriptWaiting = 0; + return IR_CONT; } -// Zdebug("FNtdww just waiting"); + // Zdebug("FNtdww just waiting"); - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // see ya next cycle + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; + + // see ya next cycle + return IR_REPEAT; } -//------------------------------------------------------------------------------------ -int32 FN_we_wait(int32 *params) //Tony3Dec96 -{ -//loop until the target is free -//params 0 target +int32 FN_we_wait(int32 *params) { // Tony3Dec96 + // loop until the target is free + // params: 0 target - uint32 null_pc=5; //4th script - get-speech-state - char *raw_script_ad; + uint32 null_pc = 5; // 4th script - get-speech-state + char *raw_script_ad; _standardHeader *head; - int32 target=params[0]; + int32 target = params[0]; -//request status of target + // request status of target head = (_standardHeader*) res_man.Res_open(target); - if (head->fileType!=GAME_OBJECT) + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_we_wait %d not an object", target); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data + raw_script_ad = (char *) head; + + // call the base script - this is the graphic/mouse service call + RunScript(raw_script_ad, raw_script_ad, &null_pc); - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call res_man.Res_close(target); -//result is 1 for waiting, 0 for busy + // result is 1 for waiting, 0 for busy - if (RESULT==1) - { - speechScriptWaiting = 0; // reset debug flag now that we're no longer waiting - see debug.cpp - return(IR_CONT); // script cont + if (RESULT == 1) { + // reset debug flag now that we're no longer waiting - see + // debug.cpp + speechScriptWaiting = 0; + return IR_CONT; } - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // target is busy so come back again next cycle + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; + + // target is busy so come back again next cycle + return IR_REPEAT; } -//------------------------------------------------------------------------------------ -int32 FN_timed_wait(int32 *params) //Tony12Dec96 -{ -//loop until the target is free but only while the timer is high -//useful when clicking on a target to talk to them - if they never reply then this'll fall out avoiding a lock up - -//params 0 ob_logic -// 1 target -// 2 number of cycles before give up - - uint32 null_pc=5; //4th script - get-speech-state - char *raw_script_ad; - Object_logic *ob_logic; - _standardHeader *head; - int32 target=params[1]; +int32 FN_timed_wait(int32 *params) { // Tony12Dec96 + // loop until the target is free but only while the timer is high + // useful when clicking on a target to talk to them - if they never + // reply then this'll fall out avoiding a lock up - ob_logic = (Object_logic *)params[0]; + // params: 0 ob_logic + // 1 target + // 2 number of cycles before give up + uint32 null_pc = 5; // 4th script - get-speech-state + char *raw_script_ad; + Object_logic *ob_logic; + _standardHeader *head; + int32 target = params[1]; - if (!ob_logic->looping) - ob_logic->looping=params[2]; //first time in + ob_logic = (Object_logic *) params[0]; + if (!ob_logic->looping) + ob_logic->looping = params[2]; //first time in -//request status of target + // request status of target head = (_standardHeader*) res_man.Res_open(target); - if (head->fileType!=GAME_OBJECT) + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_timed_wait %d not an object", target); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data + raw_script_ad = (char *) head; - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call - res_man.Res_close(target); - -//result is 1 for waiting, 0 for busy + // call the base script - this is the graphic/mouse service call + RunScript(raw_script_ad, raw_script_ad, &null_pc); - ob_logic->looping--; - - if (RESULT==1) //its waiting - { - ob_logic->looping=0; //reset because counter is likely to be still high - RESULT=0; //means ok - - speechScriptWaiting = 0; // reset debug flag now that we're no longer waiting - see debug.cpp - return(IR_CONT); // script cont - } - - - if (!ob_logic->looping) //time up - caller must check RESULT - { + res_man.Res_close(target); - RESULT=1; //not ok + // result is 1 for waiting, 0 for busy -// kill the event + if (RESULT == 1) { + // reset because counter is likely to be still high + ob_logic->looping = 0; - Kill_all_ids_events(target); //clear the event that hasn't been picked up - in theory, none of this should ever happen + //means ok + RESULT = 0; - Zdebug("EVENT timed out"); + // reset debug flag now that we're no longer waiting - see + // debug.cpp + speechScriptWaiting = 0; - speechScriptWaiting = 0; // reset debug flag now that we're no longer waiting - see debug.cpp - return(IR_CONT); //script cont + return IR_CONT; } - speechScriptWaiting = target; // debug flag to indicate who we're waiting for - see debug.cpp - return(IR_REPEAT); // target is busy so come back again next cycle -} -//------------------------------------------------------------------------------------ -int32 FN_speech_process(int32 *params) //Tony5Dec96 -{ -//recieve and sequence the commands sent from the conversation script -//we have to do this in a slightly tweeky manner as we can no longer have generic scripts -//this function comes in with all the structures that will be required - -//param 0 pointer to ob_graphic -//param 1 pointer to ob_speech -//param 2 pointer to ob_logic -//param 3 pointer to ob_mega -//param 4 pointer to ob_walkdata - -//note - we could save a var and ditch wait_state and check 'command' for non zero means busy - - Object_speech *ob_speech; - - int32 pars[9]; - int32 ret; - - - ob_speech = (Object_speech*) params[1]; - - -// Zdebug(" SP"); - - while(1) - { - if (ob_speech->command) //we are currently running a command - { - switch(ob_speech->command) - { - //---------------------------------------------- - case INS_talk: - - pars[0]=params[0]; //ob_graphic - pars[1]=params[1]; //ob_speech - pars[2]=params[2]; //ob_logic - pars[3]=params[3]; //ob_mega - - pars[4]=ob_speech->ins1; //param 4 encoded text number - pars[5]=ob_speech->ins2; //param 5 wav res id - pars[6]=ob_speech->ins3; //param 6 anim res id - pars[7]=ob_speech->ins4; //param 7 anim table res id - pars[8]=ob_speech->ins5; //param 8 animation mode 0 lip synced, 1 just straight animation - - // Zdebug("speech-process talk"); - - ret = FN_i_speak(pars); //run the function - (it thinks its been called from script - bloody fool) - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command -// Zdebug("speech-process talk finished"); - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_turn: - - pars[0]=params[2]; // ob_logic - pars[1]=params[0]; // ob_graphic - pars[2]=params[3]; // ob_mega - pars[3]=params[4]; // ob_walkdata - pars[4]=ob_speech->ins1; // direction to turn to - - ret = FN_turn(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_face: - - pars[0]=params[2]; // ob_logic - pars[1]=params[0]; // ob_graphic - pars[2]=params[3]; // ob_mega - pars[3]=params[4]; // ob_walkdata - pars[4]=ob_speech->ins1; // target - - ret = FN_face_mega(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_anim: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=ob_speech->ins1; //anim res - - ret= FN_anim(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_reverse_anim: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=ob_speech->ins1; //anim res - - ret= FN_reverse_anim(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_table_anim: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=params[3]; //ob_mega - pars[3]=ob_speech->ins1; //pointer to anim table - - ret= FN_mega_table_anim(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_reverse_table_anim: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=params[3]; //ob_mega - pars[3]=ob_speech->ins1; //pointer to anim table - - ret= FN_reverse_mega_table_anim(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_no_sprite: - - FN_no_sprite(params); // ob_graphic; - - ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - - return(IR_REPEAT); - - //---------------------------------------------- - case INS_sort: - - FN_sort_sprite(params); // ob_graphic; - - ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - - return(IR_REPEAT); - - //---------------------------------------------- - case INS_foreground: - - FN_fore_sprite(params); // ob_graphic; - - ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - - return(IR_REPEAT); - - //---------------------------------------------- - case INS_background: - - FN_back_sprite(params); // ob_graphic; - - ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - - return(IR_REPEAT); - - //---------------------------------------------- - case INS_walk: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=params[3]; //ob_mega - pars[3]=params[4]; //ob_walkdata - - pars[4]=ob_speech->ins1; //target x - pars[5]=ob_speech->ins2; //target y - pars[6]=ob_speech->ins3; //target direction - - ret= FN_walk(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command -// Zdebug("speech-process walk finished"); - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_walk_to_anim: - - pars[0]=params[2]; //ob_logic - pars[1]=params[0]; //ob_graphic - pars[2]=params[3]; //ob_mega - pars[3]=params[4]; //ob_walkdata - - pars[4]=ob_speech->ins1; // anim resource - - ret= FN_walk_to_anim(pars); - - if (ret!=IR_REPEAT) - { ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command -// Zdebug("speech-process walk finished"); - } - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_stand_after_anim: - - pars[0]=params[0]; // ob_graphic - pars[1]=params[3]; // ob_mega - pars[2]=ob_speech->ins1; // anim resource - - ret= FN_stand_after_anim(pars); - - ob_speech->command=0; // command finished - ob_speech->wait_state=1; // waiting for command - - return(IR_REPEAT); // come back again next cycle - - //---------------------------------------------- - case INS_set_frame: - - pars[0]=params[0]; // ob_graphic - pars[1]=ob_speech->ins1; // anim_resource - pars[2]=ob_speech->ins2; // FIRST_FRAME or LAST_FRAME - - ret= FN_set_frame(pars); - - ob_speech->command=0; //command finished - ob_speech->wait_state=1; //waiting for command - - return(IR_REPEAT); //come back again next cycle - - //---------------------------------------------- - case INS_quit: - -// Zdebug("speech-process - quit"); - ob_speech->command=0; //finish with all this - // ob_speech->wait_state=0; //start with waiting for command next conversation - return(IR_CONT); //thats it, we're finished with this - - //---------------------------------------------- - default: - - ob_speech->command=0; //not yet implemented - just cancel - ob_speech->wait_state=1; //waiting for command - break; - - //---------------------------------------------- - } - } - - - - if (SPEECH_ID==ID) //new command for us! - { - - SPEECH_ID=0; //clear this or it could trigger next go - -// grab the command - potentially, we only have this cycle to do this - ob_speech->command = INS_COMMAND; - ob_speech->ins1 = INS1; - ob_speech->ins2 = INS2; - ob_speech->ins3 = INS3; - ob_speech->ins4 = INS4; - ob_speech->ins5 = INS5; - - INS_COMMAND=0; //the current send has been recieved - i.e. seperate multiple they-do's + ob_logic->looping--; - ob_speech->wait_state=0; //now busy + if (!ob_logic->looping) { // time up - caller must check RESULT + // not ok + RESULT = 1; -// Zdebug("received new command %d", INS_COMMAND); + //clear the event that hasn't been picked up - in theory, + // none of this should ever happen + Kill_all_ids_events(target); -// we'll drop off and be caught by the while(1), so kicking in the new command straight away + Zdebug("EVENT timed out"); - } - else //no new command - { -// we could run a blink anim (or something) here + // reset debug flag now that we're no longer waiting - see + // debug.cpp + speechScriptWaiting = 0; - ob_speech->wait_state=1; //now free - return(IR_REPEAT); //come back again next cycle - } + return IR_CONT; } + // debug flag to indicate who we're waiting for - see debug.cpp + speechScriptWaiting = target; + // target is busy so come back again next cycle + return IR_REPEAT; } -//------------------------------------------------------------------------------------ +int32 FN_speech_process(int32 *params) { // Tony5Dec96 + // Recieve and sequence the commands sent from the conversation + // script. + // We have to do this in a slightly tweeky manner as we can no longer + // have generic scripts. + // This function comes in with all the structures that will be + // required. + // params: 0 pointer to ob_graphic + // 1 pointer to ob_speech + // 2 pointer to ob_logic + // 3 pointer to ob_mega + // 4 pointer to ob_walkdata + // note - we could save a var and ditch wait_state and check + // 'command' for non zero means busy + Object_speech *ob_speech; + int32 pars[9]; + int32 ret; + ob_speech = (Object_speech *) params[1]; + // Zdebug(" SP"); + while(1) { + //we are currently running a command + switch (ob_speech->command) { + case 0: + // Do nothing + break; + case INS_talk: + pars[0] = params[0]; // ob_graphic + pars[1] = params[1]; // ob_speech + pars[2] = params[2]; // ob_logic + pars[3] = params[3]; // ob_mega + pars[4] = ob_speech->ins1; // encoded text number + pars[5] = ob_speech->ins2; // wav res id + pars[6] = ob_speech->ins3; // anim res id + pars[7] = ob_speech->ins4; // anim table res id + pars[8] = ob_speech->ins5; // animation mode - 0 lip synced, 1 just straight animation + // Zdebug("speech-process talk"); + // run the function - (it thinks it's been + // called from script - bloody fool) + if (FN_i_speak(pars) != IR_REPEAT) { + // Zdebug("speech-process talk finished"); + // command finished + ob_speech->command = 0; + // waiting for command + ob_speech->wait_state = 1; + } + // come back again next cycle + return IR_REPEAT; + case INS_turn: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = params[4]; // ob_walkdata + pars[4] = ob_speech->ins1; // direction to turn to + if (FN_turn(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; + // waiting for command + ob_speech->wait_state = 1; + } -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -#if 1==2 + // come back again next cycle + return IR_REPEAT; + case INS_face: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = params[4]; // ob_walkdata + pars[4] = ob_speech->ins1; // target - ooo l dddd sss ttttt u u fffff fffff -o o l d d s t u u f f -o o l d d sss t u u ffff ffff -o o l d d s t u u f f -o o l d d s s t u u f f -o o l d d s s t u u f f - ooo llll dddd sss t uuu f f + if (FN_face_mega(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; + // waiting for command + ob_speech->wait_state = 1; + } + // come back again next cycle + return IR_REPEAT; + case INS_anim: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = ob_speech->ins1; // anim res -// ScriptReference 0,19 -mega_interact //standard interact protocol for megas who have been clicked on -{ //replaces S2's mega_sss... (Jan95tw) + if (FN_anim(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; - o_down_flag=0; //reset on entry - we dont know what this flag will be - //we will not be wiping a command because the player will - //not start until we signal - at the end of this loop... - //"smart" - readers voice - do - { - if (o_down_flag!=0) //recieved any instructions? - - switch(o_down_flag) - { - //-------------------------------------------- - case INS_talk: // (o_ins3=cdt or anim table, o_ins2=text id, o_ins1=graphic or 0) - { - FN_I_speak(o_ins3, o_ins2, o_ins1); - o_down_flag=0; + // waiting for command + ob_speech->wait_state = 1; } - break; - //-------------------------------------------- - case INS_anim: //run coord-less anim (o_ins1=cdt or anim table, o_ins2=graphic or 0, o_ins3=0) - { - FN_anim( o_ins1, o_ins2 ); - o_down_flag=0; - } - break; + // come back again next cycle + return IR_REPEAT; - //-------------------------------------------- + case INS_reverse_anim: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = ob_speech->ins1; // anim res - case INS_full_anim: //run anim with coords (o_ins1=cdt o_ins2=graphic o_ins3=0) - { - FN_full_anim( o_ins1, o_ins2 ); - o_down_flag=0; - } - break; + if (FN_reverse_anim(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; - //-------------------------------------------- - case INS_walk: // walk to (o_ins1,o_ins2) & stand in direction 'o_ins3' - { - FN_walk(o_ins1,o_ins2,o_ins3,STAND); - o_down_flag=0; + // waiting for command + ob_speech->wait_state = 1; } - break; - //-------------------------------------------- - case INS_turn: //turn/stand as specified - { - FN_turn(o_ins1,STAND); // turn to direction 'o_ins1' - o_down_flag=0; - } - break; + // come back again next cycle + return IR_REPEAT; - //-------------------------------------------- - case INS_face: //turn to face specified mega character - { - FN_face(o_ins1); - o_down_flag=0; - } - break; + case INS_table_anim: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = ob_speech->ins1; // pointer to anim table - //-------------------------------------------- - case INS_trace: // face compact id 'o_ins1' - continues until next command (because 'o_down_flag' not reset to zero) - { - FN_face(o_ins1); - o_down_flag=INS_trace; // do this again & again until a new command is received - } - break; + if (FN_mega_table_anim(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; - //-------------------------------------------- - case INS_no_sprite: - { - FN_no_sprite(); - o_down_flag=0; + // waiting for command + ob_speech->wait_state = 1; } - break; - //-------------------------------------------- - case INS_sort: - { - FN_sort(); - o_down_flag=0; - } - break; + // come back again next cycle + return IR_REPEAT; - //-------------------------------------------- - case INS_foreground: - { - FN_foreground(); - o_down_flag=0; - } - break; + case INS_reverse_table_anim: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = ob_speech->ins1; // pointer to anim table - //-------------------------------------------- - case INS_background: - { - FN_background(); - o_down_flag=0; - } - break; + if (FN_reverse_mega_table_anim(pars) != IR_REPEAT) { + // command finished + ob_speech->command = 0; - //-------------------------------------------- - case INS_quit: - { + // waiting for command + ob_speech->wait_state = 1; } - break; //fall out of outer loop - //-------------------------------------------- - default: - { - FN_talk_error(); //shut the system down - I can't be bothered to recover from this + // come back again next cycle + return IR_REPEAT; + + case INS_no_sprite: + FN_no_sprite(params); // ob_graphic + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT ; + + case INS_sort: + FN_sort_sprite(params); // ob_graphic + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT; + + case INS_foreground: + FN_fore_sprite(params); // ob_graphic + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT; + + case INS_background: + FN_back_sprite(params); // ob_graphic + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT; + + case INS_walk: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = params[4]; // ob_walkdata + pars[4] = ob_speech->ins1; // target x + pars[5] = ob_speech->ins2; // target y + pars[6] = ob_speech->ins3; // target direction + + if (FN_walk(pars) != IR_REPEAT) { + // Zdebug("speech-process walk finished"); + // command finished + ob_speech->command = 0; + + //waiting for command + ob_speech->wait_state = 1; } - break; - - //-------------------------------------------- - } - - - FN_add_talk_wait_status_bit(); // add waiting bit to status for player to pickup - FN_quit(); // drop out of script until next cycle to see if new instructions have arrived - FN_remove_talk_wait_status_bit(); // off again, in case command received - - } - while(o_down_flag!=INS_quit); //until we're told to terminate - - - FN_goto_bookmark(); //get the mega going again -} -//----------------------------------------------------------------------------------------- -// ScriptReference 0,20 - -mega_approach_script // George runs this script to get over to 'target_mega', who's already running 'mega_interact' -{ - - //FN_they_do_we_wait(target_mega,INS_trace,GEORGE,0,0); // 'target_mega' repeatedly faces george while he walks over - - FN_they_do_we_wait(target_mega,INS_face,GEORGE,0,0); // Mega turns to face George - - FN_get_pos(target_mega); - target_x = return_value; - target_y = return_value_2; - distance_apart = return_value_4; - - walk_attempt = 0; // keep count of attempts - - if ((o_xcoord) < target_x) // If George is currently left of Duane - walk_flag = 0; // try LHS first - else - walk_flag = 1; // try RHS first - - //-------------------------------------------------------- - do - { - if (walk_flag==0) // (0) try LHS - & face DOWN_RIGHT - { - FN_walk(target_x-distance_apart,target_y,DOWN_RIGHT,STAND); - - if (o_down_flag) - walk_flag=2; // made it - else - walk_flag=1; // try RHS next, or fail (to anywhere) - } - - else // (1) try RHS & face DOWN_LEFT - { - FN_walk(target_x+distance_apart,target_y,DOWN_LEFT,STAND); + // come back again next cycle + return IR_REPEAT; + + case INS_walk_to_anim: + pars[0] = params[2]; // ob_logic + pars[1] = params[0]; // ob_graphic + pars[2] = params[3]; // ob_mega + pars[3] = params[4]; // ob_walkdata + pars[4] = ob_speech->ins1; // anim resource + + if (FN_walk_to_anim(pars) != IR_REPEAT) { + // Zdebug("speech-process walk finished"); + // command finished + ob_speech->command = 0; + // waiting for command + ob_speech->wait_state = 1; + } - if (o_down_flag) - walk_flag=2; // made it - else - walk_flag=0; // try LHS next, or fail (to anywhere) + // come back again next cycle + return IR_REPEAT; + + case INS_stand_after_anim: + pars[0] = params[0]; // ob_graphic + pars[1] = params[3]; // ob_mega + pars[2] = ob_speech->ins1; // anim resource + FN_stand_after_anim(pars); + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT; // come back again next cycle + + case INS_set_frame: + + pars[0] = params[0]; // ob_graphic + pars[1] = ob_speech->ins1; // anim_resource + pars[2] = ob_speech->ins2; // FIRST_FRAME or LAST_FRAME + ret= FN_set_frame(pars); + ob_speech->command = 0; // command finished + ob_speech->wait_state = 1; // waiting for command + return IR_REPEAT; // come back again next cycle + + case INS_quit: + // Zdebug("speech-process - quit"); + ob_speech->command = 0; // finish with all this + // ob_speech->wait_state = 0; // start with waiting for command next conversation + return IR_CONT; // thats it, we're finished with this + + default: + ob_speech->command = 0; // not yet implemented - just cancel + ob_speech->wait_state = 1; // waiting for command + break; } - walk_attempt+=1; - } - while ((walk_flag<2)&&(walk_attempt<2)); // try again until we get there or we've tried both sides - //-------------------------------------------------------- - - - if (walk_flag!=2) // if LHS & RHS both failed - try anywhere - { - FN_walk(target_x,target_y,ANY,STAND); // walk George to (near) Mega's coords - } - - - FN_we_wait(target_mega); // wait for Duane to be ready to receive a command - - if ((o_xcoord) < target_x) // If George is now left of Duane - { - FN_they_do_we_wait(target_mega,INS_turn,DOWN_LEFT,0,0); // Mega faces DOWN_LEFT - FN_turn(DOWN_RIGHT, STAND); // George faces DOWN_RIGHT - } - else // George is now right of Duane - { - FN_they_do_we_wait(target_mega,INS_turn,DOWN_RIGHT,0,0); // Mega faces DOWN_LEFT - FN_turn(DOWN_LEFT, STAND); // George faces DOWN_RIGHT - } - //----------------------------------------------------------------------------------- -} -//------------------------------------------------------------------------------------ -int32 FN_they_do(object *compact, int32 id, int32 tar, int32 a, int32 b, int32 c, int32 d, int32 x) //S2.1(18Jan95tw) -{ - // NB. a, b & c could be resID's!! (25jul95 JEL) - - object *target; - - compact;id;x; - - //Tdebug("FN_they_do %d %d %d %d %d", tar,a,b,c,d); + if (SPEECH_ID == ID) { + // new command for us! + // clear this or it could trigger next go + SPEECH_ID = 0; - target = (object *) Lock_object(tar); + // grab the command - potentially, we only have this + // cycle to do this - target->o_down_flag = a; // the actual instruction; INS_talk, INS_quit, etc. - target->o_ins1 = b; // and now the 3 parameters... (updated 24apr95JEL) - target->o_ins2 = c; - target->o_ins3 = d; + ob_speech->command = INS_COMMAND; + ob_speech->ins1 = INS1; + ob_speech->ins2 = INS2; + ob_speech->ins3 = INS3; + ob_speech->ins4 = INS4; + ob_speech->ins5 = INS5; - Unlock_object(tar); + // the current send has been recieved - i.e. seperate + // multiple they-do's - return(1); //script cont -} - -//-------------------------------------------------------------------------------------- - -//send an instruction to mega we're talking to and wait until it has finished before -//returning to script - -int32 FN_they_do_we_wait(object *compact, int32 id, int32 tar, int32 a, int32 b, int32 c, int32 d, int32 x) -{ //S2.1(18Jan95tw) - - // NB. a, b & c could be resID's!! (25jul95 JEL) - - object *target; - - compact;id;x; + INS_COMMAND = 0; - //Tdebug("FN_they_do_we_wait %d %d %d %d %d", tar,a,b,c,d); - - target = (object *) Lock_object(tar); - - target->o_down_flag = a; // the actual instruction; INS_talk, INS_quit, etc. - target->o_ins1 = b; // and now the 3 parameters... (updated 24apr95JEL) - target->o_ins2 = c; - target->o_ins3 = d; - - compact->o_logic = LOGIC_wait_for_talk; // we wait until they've finished - compact->o_down_flag=tar; // we wait for this person - - target->o_status &= (0xffffffff-STAT_TALK_WAIT); // remove for this cycle - remember, this damn system is totally seamless... - - Unlock_object(tar); - return(0); //script stop -} + // now busy + ob_speech->wait_state = 0; -//-------------------------------------------------------------------------------------- -// wait until last instruction it has finished before returning to script + // Zdebug("received new command %d", INS_COMMAND); -int32 FN_we_wait(object *compact, int32 id, int32 tar, int32 a, int32 b, int32 c, int32 d, int32 e) // (7JULY95 JEL) -{ - object *target; + // we'll drop off and be caught by the while(1), so + // kicking in the new command straight away + } else { + // no new command + // we could run a blink anim (or something) here - compact;id;a;b;c;d;e; + // now free + ob_speech->wait_state = 1; - target = (object *) Lock_object(tar); - - //Tdebug("FN_we_wait %d", tar); - - compact->o_logic = LOGIC_wait_for_talk; // we wait until they've finished - compact->o_down_flag=tar; // we wait for this person - - target->o_status &= (0xffffffff-STAT_TALK_WAIT); // remove for this cycle - remember, this damn system is totally seamless... - - Unlock_object(tar); - return(0); //script stop -} - -//-------------------------------------------------------------------------------------- -int32 FN_add_talk_wait_status_bit(object *compact, int32 id, int32 tar, int32 a, int32 b, int32 c, int32 d, int32 e) // (21may96 JEL) -{ - id;tar;a;b;c;d;e; - - compact->o_status |= STAT_TALK_WAIT; - - return(1); //script continue -} -//-------------------------------------------------------------------------------------- -int32 FN_remove_talk_wait_status_bit(object *compact, int32 id, int32 tar, int32 a, int32 b, int32 c, int32 d, int32 e) // (21may96 JEL) -{ - id;tar;a;b;c;d;e; - - compact->o_status &= (0xffffffff-STAT_TALK_WAIT); - - return(1); //script continue -} -//-------------------------------------------------------------------------------------- - -//mega_interact has recieved an instruction it does not understand - I have chosen to -//halt the game to ensure the error is noticed... - -int32 FN_talk_error(object *compact, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) //S2.1(18Jan95tw) -{ - compact;id;a;b;c;d;z;x; - - Tdebug("FN_talk_error for %d - instruct = %d",id, compact->o_down_flag); - Go_dos("FN_talk_error for %d - instruct = %d",id, compact->o_down_flag); - - return(0); -} - -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- - -//wait for target to switch into STAT_TALK_WAIT then go back into script mode -//used during speech they_do commands - we must look to a specific target in-case -//of multiple particpents in the conversation - a sync from the target is not enough... - -Logic_wait_talk(object *compact, int id) //S2.1(25Jan95tw) -{ - object *target; - - id; - - target = (object *) Lock_object(compact->o_down_flag); //holds id of person we're waiting for - - - if (!(target->o_status&STAT_TALK_WAIT)) - { - Unlock_object(compact->o_down_flag); //holds id of person we're waiting for - return(0); //0 which means drop out of logic - } - else - { - compact->o_logic=LOGIC_script; //back to script again next cycle - Unlock_object(compact->o_down_flag); //holds id of person we're waiting for - return(1); // go straight back into script - //return(0); // drop out for one cycle (allows speech text sprite to disappear before continuing - 13Mar95JEL) + // come back again next cycle + return IR_REPEAT; + } } } -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ +#define S_OB_GRAPHIC 0 +#define S_OB_SPEECH 1 +#define S_OB_LOGIC 2 +#define S_OB_MEGA 3 + +#define S_TEXT 4 +#define S_WAV 5 +#define S_ANIM 6 +#define S_DIR_TABLE 7 +#define S_ANIM_MODE 8 + +uint32 unpause_zone = 0; + +int32 FN_i_speak(int32 *params) { // Tony18Oct96 (revamped by James01july97) + // its the super versatile FN_speak + // text and wavs can be selected in any combination + + // we can assume no human - there should be no human at least! + + // params: 0 pointer to ob_graphic + // 1 pointer to ob_speech + // 2 pointer to ob_logic + // 3 pointer to ob_mega + // 4 encoded text number + // 5 wav res id + // 6 anim res id + // 7 anim table res id + // 8 animation mode 0 lip synced, + // 1 just straight animation + + _mouseEvent *me; + _animHeader *anim_head; + Object_logic *ob_logic; + Object_graphic *ob_graphic; + Object_mega *ob_mega; + uint8 *anim_file; + uint32 local_text; + uint32 text_res; + uint8 *text; + static uint8 textRunning, speechRunning; + int32 *anim_table; + uint8 speechFinished = 0; // James25feb97 + int8 speech_pan; + char speechFile[256]; + static uint8 cycle_skip = 0; + uint32 rv; + +#ifdef _SWORD2_DEBUG // (James26jun97) + // for text/speech testing & checking for correct file type + _standardHeader *head; + // for text/speech testing - keeping track of text resource currently being tested + static uint32 currentTextResource = 0; #endif - - -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -uint32 unpause_zone=0; -//------------------------------------------------------------------------------------ -int32 FN_i_speak(int32 *params) //Tony18Oct96 (revamped by James01july97) -{ -//its the super versatile FN_speak -//text and wavs can be selected in any combination - -//we can assume no human - there should be no human at least! - -//param 0 pointer to ob_graphic -//param 1 pointer to ob_speech -//param 2 pointer to ob_logic -//param 3 pointer to ob_mega - -//param 4 encoded text number -//param 5 wav res id -//param 6 anim res id -//param 7 anim table res id -//param 8 animation mode 0 lip synced, 1 just straight animation - -#define S_OB_GRAPHIC 0 -#define S_OB_SPEECH 1 -#define S_OB_LOGIC 2 -#define S_OB_MEGA 3 - -#define S_TEXT 4 -#define S_WAV 5 -#define S_ANIM 6 -#define S_DIR_TABLE 7 -#define S_ANIM_MODE 8 - - _mouseEvent *me; - _animHeader *anim_head; - Object_logic *ob_logic; - Object_graphic *ob_graphic; - Object_mega *ob_mega; - uint8 *anim_file; - uint32 local_text; - uint32 text_res; - uint8 *text; - static uint8 textRunning, speechRunning; - int32 *anim_table; - uint8 speechFinished=0; // James25feb97 - int8 speech_pan; - char speechFile[256]; - static uint8 cycle_skip=0; - - #ifdef _SWORD2_DEBUG // (James26jun97) - _standardHeader *head; // for text/speech testing & checking for correct file type - static uint32 currentTextResource=0; // for text/speech testing - keeping track of text resource currently being tested - #endif - - uint32 rv; // drivers return value - - - //----------------------------------------------- // set up the pointers which we know we'll always need - ob_logic = (Object_logic *) params[S_OB_LOGIC]; - ob_graphic = (Object_graphic *) params[S_OB_GRAPHIC]; + ob_logic = (Object_logic *) params[S_OB_LOGIC]; + ob_graphic = (Object_graphic *) params[S_OB_GRAPHIC]; - //----------------------------------------------- - // FIRST TIME ONLY: create the text, load the wav, set up the anim, etc. + // FIRST TIME ONLY: create the text, load the wav, set up the anim, + // etc. - if (!ob_logic->looping) - { - //------------------------- - // New fudge to wait for smacker samples to finish (James31july97) - // since they can over-run into the game + if (!ob_logic->looping) { + // New fudge to wait for smacker samples to finish + // (James31july97) since they can over-run into the game - if (g_sound->GetSpeechStatus()!=RDSE_SAMPLEFINISHED) // has it finished? - return (IR_REPEAT); + if (g_sound->GetSpeechStatus() != RDSE_SAMPLEFINISHED) + return IR_REPEAT; - //------------------------- // New fudge for 'fx' subtitles (James 29july97) - // If subtitles switched off, and we don't want to use a wav for this line either, - // then just quit back to script right now! - if ((subtitles==0) && (WantSpeechForLine(params[S_WAV])==0)) - return (IR_CONT); - - //------------------------- - if (cycle_skip==0) // (James 17july97) - { - // drop out for 1st cycle to allow walks/anims to end & display last frame - // before system locks while speech loaded - cycle_skip=1; - return (IR_REPEAT); - } - else - cycle_skip=0; - //------------------------- + // If subtitles switched off, and we don't want to use a wav + // for this line either, then just quit back to script right + // now! + + if (subtitles == 0 && WantSpeechForLine(params[S_WAV]) == 0) + return IR_CONT; - //----------------------------------------------------------- - #ifdef _SWORD2_DEBUG // (James26jun97) + if (cycle_skip == 0) { // (James 17july97) + // drop out for 1st cycle to allow walks/anims to end + // & display last frame/ before system locks while + // speech loaded - textNumber = params[S_TEXT]; // for debug info + cycle_skip = 1; + return IR_REPEAT; + } else + cycle_skip = 0; + +#ifdef _SWORD2_DEBUG // (James26jun97) + textNumber = params[S_TEXT]; // for debug info // For testing all text & speech! (James26jun97) - // A script loop can send any text number to FN_I_speak & it will only run the valid ones - // or return with 'result' equal to '1' or '2' to mean 'invalid text resource' - // and 'text number out of range' respectively - // See 'testing_routines' object in George's Player Character section of linc - - if (SYSTEM_TESTING_TEXT) - { - RESULT=0; - - text_res = params[S_TEXT]/SIZE; - local_text = params[S_TEXT]&0xffff; - - if (res_man.Res_check_valid(text_res)) // if the resource number is within range & it's not a null resource - { - head = (_standardHeader*) res_man.Res_open(text_res); // open the resource - - if (head->fileType==TEXT_FILE) // if it's not an animation file - { - if (CheckTextLine((uint8*)head,local_text)==0) // if line number is out of range - RESULT=2; // line number out of range + // A script loop can send any text number to FN_I_speak & it + // will only run the valid ones or return with 'result' equal + // to '1' or '2' to mean 'invalid text resource' and 'text + // number out of range' respectively + // + // See 'testing_routines' object in George's Player Character + // section of linc + + if (SYSTEM_TESTING_TEXT) { + RESULT = 0; + + text_res = params[S_TEXT] / SIZE; + local_text = params[S_TEXT] & 0xffff; + + // if the resource number is within range & it's not + // a null resource + + if (res_man.Res_check_valid(text_res)) { + // open the resource + head = (_standardHeader*) res_man.Res_open(text_res); + + if (head->fileType == TEXT_FILE) { + // if it's not an animation file + // if line number is out of range + if (CheckTextLine((uint8*) head, local_text) == 0) { + // line number out of range + RESULT = 2; + } + } else { + // invalid (not a text resource) + RESULT = 1; } - else - RESULT=1; // invalid (not a text resource) - res_man.Res_close(text_res); // close the resource + // close the resource + res_man.Res_close(text_res); if (RESULT) - return(IR_CONT); - } - else - { // not a valid resource number - RESULT=1; // invalid (null resource) - return(IR_CONT); + return IR_CONT; + } else { + // not a valid resource number - invalid (null + // resource) + RESULT = 1; + return IR_CONT; } } +#endif - #endif // _SWORD2_DEBUG - //----------------------------------------------------------- - // pull out the text line to get the official text number (for wav id) - // Once the wav id's go into all script text commands, we'll only need this for _SWORD2_DEBUG + // Pull out the text line to get the official text number + // (for wav id). Once the wav id's go into all script text + // commands, we'll only need this for _SWORD2_DEBUG - text_res = params[S_TEXT]/SIZE; - local_text = params[S_TEXT]&0xffff; + text_res = params[S_TEXT] / SIZE; + local_text = params[S_TEXT] & 0xffff; - text = FetchTextLine( res_man.Res_open(text_res), local_text ); // open text file & get the line + // open text file & get the line + text = FetchTextLine(res_man.Res_open(text_res), local_text); officialTextNumber = READ_LE_UINT16(text); - res_man.Res_close(text_res); // now ok to close the text file - - //-------------------------------------- - #ifdef _SWORD2_DEBUG // (James09jul97) + // now ok to close the text file + res_man.Res_close(text_res); +#ifdef _SWORD2_DEBUG // (James09jul97) // prevent dud lines from appearing while testing text & speech // since these will not occur in the game anyway - if (SYSTEM_TESTING_TEXT) // if testing text & speech - { // if actor number is 0 and text line is just a 'dash' character - if ((officialTextNumber==0) && (text[2]=='-') && (text[3]==NULL)) - { - RESULT=3; // dud line - return(IR_CONT); // return & continue script + if (SYSTEM_TESTING_TEXT) { // if testing text & speech + // if actor number is 0 and text line is just a 'dash' + // character + if (officialTextNumber == 0 && text[2] == '-' && text[3] == 0) { + // dud line - return & continue script + RESULT = 3; + return IR_CONT; } } +#endif - #endif // _SWORD2_DEBUG - //-------------------------------------- // set the 'looping_flag' & the text-click-delay - ob_logic->looping=1; - left_click_delay=6; // can't left-click past the text for the first half second - right_click_delay=3; // can't right-click past the text for the first quarter second + ob_logic->looping = 1; - //---------------------------------------------------------- + // can't left-click past the text for the first half second + left_click_delay = 6; + + // can't right-click past the text for the first quarter second + right_click_delay = 3; + +#ifdef _SWORD2_DEBUG // Write to walkthrough file (zebug0.txt) + // if (player_id != george), then player is controlling Nico - #ifdef _SWORD2_DEBUG - if (PLAYER_ID!=CUR_PLAYER_ID) // if (player_id != george), then player is controlling Nico - Zdebug(0,"(%d) Nico: %s", officialTextNumber, text+2); // so write 'Nico' instead of George - else // ok, it's George anyway - Zdebug(0,"(%d) %s: %s", officialTextNumber, FetchObjectName(ID), text+2); - #endif + // Oh, really? I thought Nico used the same object... + + if (PLAYER_ID != CUR_PLAYER_ID) + Zdebug(0, "(%d) Nico: %s", officialTextNumber, text + 2); + else + Zdebug(0, "(%d) %s: %s", officialTextNumber, FetchObjectName(ID), text + 2); +#endif - //-------------------------------------- // Set up the speech animation - if (params[S_ANIM]) //just a straight anim - { - anim_id=params[S_ANIM]; - speech_anim_type=SPEECHANIMFLAG; //params[S_ANIM_MODE]; //anim type + if (params[S_ANIM]) { + // just a straight anim + anim_id = params[S_ANIM]; + + // anim type + speech_anim_type = SPEECHANIMFLAG; + + // set the talker's graphic to this speech anim now + ob_graphic->anim_resource = anim_id; + + // set to first frame + ob_graphic->anim_pc = 0; + } else if (params[S_DIR_TABLE]) { + // use this direction table to derive the anim + // NB. ASSUMES WE HAVE A MEGA OBJECT!! - ob_graphic->anim_resource = anim_id; // set the talker's graphic to this speech anim now - ob_graphic->anim_pc = 0; // set to first frame - } - else if (params[S_DIR_TABLE]) //use this direction table to derive the anim NB. ASSUMES WE HAVE A MEGA OBJECT!! - { ob_mega = (Object_mega*) params[S_OB_MEGA]; - anim_table = (int32 *)params[S_DIR_TABLE]; // pointer to anim table - anim_id = anim_table[ob_mega->current_dir]; // appropriate anim resource is in 'table[direction]' + // pointer to anim table + anim_table = (int32 *) params[S_DIR_TABLE]; - speech_anim_type=SPEECHANIMFLAG; //params[S_ANIM_MODE]; //anim type + // appropriate anim resource is in 'table[direction]' + anim_id = anim_table[ob_mega->current_dir]; - ob_graphic->anim_resource = anim_id; // set the talker's graphic to this speech anim now - ob_graphic->anim_pc = 0; // set to first frame - } - else //no animation choosen - { - anim_id=0; //no animation + // anim type + speech_anim_type = SPEECHANIMFLAG; + + // set the talker's graphic to this speech anim now + ob_graphic->anim_resource = anim_id; + + // set to first frame + ob_graphic->anim_pc = 0; + } else { + // no animation choosen + anim_id = 0; } - SPEECHANIMFLAG = 0; // Default back to looped lip synced anims. + // Default back to looped lip synced anims. + SPEECHANIMFLAG = 0; - //-------------------------------------- - // set up 'text_x' & 'text_y' for speech-pan and/or text-sprite position + // set up 'text_x' & 'text_y' for speech-pan and/or + // text-sprite position LocateTalker(params); - //-------------------------------------- // is it to be speech or subtitles or both? - speechRunning=0; // assume not running until know otherwise + // assume not running until know otherwise + speechRunning = 0; // New fudge for 'fx' subtitles (James 29july97) - // if speech is selected, and this line is allowed speech (not if it's an fx subtitle!) - if (speechSelected && WantSpeechForLine(officialTextNumber)) - { - // if the wavId paramter is zero because not yet compiled into speech command, - // we can still get it from the 1st 2 chars of the text line + // if speech is selected, and this line is allowed speech + // (not if it's an fx subtitle!) + + if (speechSelected && WantSpeechForLine(officialTextNumber)) { + // if the wavId paramter is zero because not yet + // compiled into speech command, we can still get it + // from the 1st 2 chars of the text line + if (!params[S_WAV]) - params[S_WAV] = (int32)officialTextNumber; - - #define SPEECH_VOLUME 16 // 0..16 - #define SPEECH_PAN 0 // -16..16 - - speech_pan = ((text_x-320)*16)/320; - // 'text_x' 'speech_pan' - // 0 -16 - // 320 0 - // 640 16 - - if (speech_pan<-16) // keep within limits of -16..16, just in case - speech_pan=-16; - else if (speech_pan>16) - speech_pan=16; - - #ifdef _SWORD2_DEBUG - if (SYSTEM_TESTING_TEXT) // if we're testing text & speech - { - // if we've moved onto a new text resource, we will want to check - // if the CD needs changing again - // - can only know which CD to get if the wavID is non-zero - if ((text_res != currentTextResource) && (params[S_WAV])) - { - GetCorrectCdForSpeech(params[S_WAV]); // ensure correct CD is in for this wavId + params[S_WAV] = (int32) officialTextNumber; + +#define SPEECH_VOLUME 16 // 0..16 +#define SPEECH_PAN 0 // -16..16 + + speech_pan = ((text_x - 320) * 16) / 320; + + // 'text_x' 'speech_pan' + // 0 -16 + // 320 0 + // 640 16 + + // keep within limits of -16..16, just in case + if (speech_pan < -16) + speech_pan = -16; + else if (speech_pan > 16) + speech_pan = 16; + +#ifdef _SWORD2_DEBUG + // if we're testing text & speech + if (SYSTEM_TESTING_TEXT) { + // if we've moved onto a new text resource, + // we will want to check if the CD needs + // changing again - can only know which CD to + // get if the wavID is non-zero + + if ((text_res != currentTextResource) && params[S_WAV]) { + // ensure correct CD is in for this + // wavId + GetCorrectCdForSpeech(params[S_WAV]); currentTextResource = text_res; } } - #endif +#endif - //------------------------------ // set up path to speech cluster - // first checking if we have speech1.clu or speech2.clu in current directory (for translators to test) + // first checking if we have speech1.clu or + // speech2.clu in current directory (for translators + // to test) File fp; sprintf(speechFile, "speech%d.clu", res_man.WhichCd()); + if (fp.open(speechFile)) fp.close(); else strcpy(speechFile, "speech.clu"); - rv = g_sound->PlayCompSpeech(speechFile, params[S_WAV], SPEECH_VOLUME, speech_pan); // Load speech but don't start playing yet - if (rv == RD_OK) - { - speechRunning=1; // ok, we've got something to play (2 means not playing yet - see below) - g_sound->UnpauseSpeech(); // set it playing now (we might want to do this next cycle, don't know yet) - } - #ifdef _SWORD2_DEBUG - else - { + // Load speech but don't start playing yet + rv = g_sound->PlayCompSpeech(speechFile, params[S_WAV], SPEECH_VOLUME, speech_pan); + if (rv == RD_OK) { + // ok, we've got something to play + // (2 means not playing yet - see below) + speechRunning = 1; + + // set it playing now (we might want to do + // this next cycle, don't know yet) + g_sound->UnpauseSpeech(); + } else { +#ifdef _SWORD2_DEBUG Zdebug("ERROR: PlayCompSpeech(speechFile=\"%s\", wav=%d (res=%d pos=%d)) returned %.8x", speechFile, params[S_WAV], text_res, local_text, rv); +#endif } - #endif - - - } - - if (subtitles || (speechRunning==0)) // if we want subtitles, or speech failed to load - { - textRunning=1; // then we're going to show the text - Form_text(params); // so create the text sprite } - else - textRunning=0; // otherwise don't want text - //-------------------------------------- + // if we want subtitles, or speech failed to load + if (subtitles || speechRunning == 0) { + // then we're going to show the text + textRunning = 1; + // so create the text sprite + Form_text(params); + } else { + // otherwise don't want text + textRunning = 0; + } } - //----------------------------------------------- + // EVERY TIME: run a cycle of animation, if there is one - if (anim_id) // there is an animation - { - ob_graphic->anim_pc++; // increment the anim frame number - - anim_file = res_man.Res_open(ob_graphic->anim_resource); // open the anim file - anim_head = FetchAnimHeader( anim_file ); - - if (!speech_anim_type) // ANIM IS TO BE LIP-SYNC'ED & REPEATING - { - if (ob_graphic->anim_pc == (int32)(anim_head->noAnimFrames)) // if finished the anim - ob_graphic->anim_pc=0; // restart from frame 0 - else if (speechRunning) // if playing a sample - { - if (!unpause_zone) - { if (g_sound->AmISpeaking()==RDSE_QUIET) // if we're at a quiet bit - ob_graphic->anim_pc=0; // restart from frame 0 ('closed mouth' frame) + if (anim_id) { + // there is an animation + // increment the anim frame number + ob_graphic->anim_pc++; + + // open the anim file + anim_file = res_man.Res_open(ob_graphic->anim_resource); + anim_head = FetchAnimHeader(anim_file); + + if (!speech_anim_type) { + // ANIM IS TO BE LIP-SYNC'ED & REPEATING + // if finished the anim + if (ob_graphic->anim_pc == (int32) (anim_head->noAnimFrames)) { + // restart from frame 0 + ob_graphic->anim_pc = 0; + } else if (speechRunning) { + // if playing a sample + if (!unpause_zone) { + // if we're at a quiet bit + if (g_sound->AmISpeaking() == RDSE_QUIET) { + // restart from frame 0 + // ('closed mouth' frame) + ob_graphic->anim_pc = 0; + } } } - } - else // ANIM IS TO PLAY ONCE ONLY - { - if (ob_graphic->anim_pc == (int32)(anim_head->noAnimFrames)-1) // reached the last frame of the anim - { - anim_id=0; // hold anim on this last frame + } else { + // ANIM IS TO PLAY ONCE ONLY + if (ob_graphic->anim_pc == (int32) (anim_head->noAnimFrames) - 1) { + // reached the last frame of the anim + // hold anim on this last frame + anim_id = 0; } } - res_man.Res_close(ob_graphic->anim_resource); // close the anim file + // close the anim file + res_man.Res_close(ob_graphic->anim_resource); + } else if (speech_anim_type) { + // Placed here so we actually display the last frame of the + // anim. + speech_anim_type = 0; } - else if (speech_anim_type) - speech_anim_type = 0; // Placed here so we actually display the last frame of the anim. - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- // EVERY TIME: FIND OUT IF WE NEED TO STOP THE SPEECH NOW... - //----------------------------------------------------------------------- + // if there is a wav then we're using that to end the speech naturally - if (speechRunning==1) // if playing a sample (note that value of '2' means about to play!) - { - if (!unpause_zone) - { if (g_sound->GetSpeechStatus()==RDSE_SAMPLEFINISHED) // has it finished? - speechFinished=1; // James25feb97 - } - else unpause_zone--; - } - //----------------------------------------------------------------------- - // if no sample then we're using speech_time to end speech naturally + // if playing a sample (note that value of '2' means about to play!) + + if (speechRunning==1) { + if (!unpause_zone) { + // has it finished? James25feb97 + if (g_sound->GetSpeechStatus() == RDSE_SAMPLEFINISHED) + speechFinished=1; + } else + unpause_zone--; + } else if (speechRunning == 0 && speech_time) { + // counting down text time because there is no sample - this + // ends the speech + + // if no sample then we're using speech_time to end speech + // naturally James25feb97 - else if ((speechRunning==0)&&(speech_time)) // counting down text time because there is no sample - this ends the speech - { speech_time--; if (!speech_time) - speechFinished=1; // James25feb97 + speechFinished = 1; } - //----------------------------------------------------------------------- - // ok, all is running along smoothly - but a click means stop unnaturally - #ifdef _SWORD2_DEBUG - if ((SYSTEM_TESTING_TEXT==0)||(mousey>0)) // so that we can go to the options panel while text & speech is being tested - #endif - { - me = MouseEvent(); // get mouse event - - // Note that we now have TWO click-delays - one for LEFT button, one for RIGHT BUTTON - if ( ((!left_click_delay)&&(me!=NULL)&&(me->buttons&RD_LEFTBUTTONDOWN)) || ((!right_click_delay)&&(me!=NULL)&&(me->buttons&RD_RIGHTBUTTONDOWN)) ) - { - // mouse click, after click_delay has expired -> end the speech - // we ignore mouse releases - - //----------------------------------------------------------- - #ifdef _SWORD2_DEBUG // (James26jun97) - if (SYSTEM_TESTING_TEXT) // if testing text & speech - { - if (me->buttons&RD_RIGHTBUTTONDOWN) // and RB used to click past text - SYSTEM_WANT_PREVIOUS_LINE=1; // then we want the previous line again - else - SYSTEM_WANT_PREVIOUS_LINE=0; // LB just want next line again + // ok, all is running along smoothly - but a click means stop + // unnaturally + +#ifdef _SWORD2_DEBUG + // so that we can go to the options panel while text & speech is + // being tested + if (SYSTEM_TESTING_TEXT == 0 || mousey > 0) { +#endif + + me = MouseEvent(); + + // Note that we now have TWO click-delays - one for LEFT button, one + // for RIGHT BUTTON + + if ((!left_click_delay && me && (me->buttons & RD_LEFTBUTTONDOWN)) || + (!right_click_delay && me && (me->buttons&RD_RIGHTBUTTONDOWN))) { + // mouse click, after click_delay has expired -> end the speech + // we ignore mouse releases + +#ifdef _SWORD2_DEBUG // (James26jun97) + // if testing text & speech + if (SYSTEM_TESTING_TEXT) { + // and RB used to click past text + if (me->buttons & RD_RIGHTBUTTONDOWN) { + // then we want the previous line again + SYSTEM_WANT_PREVIOUS_LINE = 1; + } else { + // LB just want next line again + SYSTEM_WANT_PREVIOUS_LINE = 0; } - #endif - //----------------------------------------------------------- + } +#endif - do - me = MouseEvent(); //trash anything thats buffered - while(me!=NULL); + do { + // trash anything thats buffered + me = MouseEvent(); + } while (me); - speechFinished=1; // James25feb97 + speechFinished = 1; // James25feb97 - if (speechRunning) // if speech sample playing - { - g_sound->StopSpeechSword2(); // halt the sample prematurely - } + // if speech sample playing + if (speechRunning) { + // halt the sample prematurely + g_sound->StopSpeechSword2(); } } - //----------------------------------------------------------------------- + +#ifdef _SWORD2_DEBUG + } +#endif + // if we are finishing the speech this cycle, do the business - if (speechFinished && !speech_anim_type) // !speech_anim_type, as we want an anim which is playing once to have finished. - { - if (speech_text_bloc_no) // if there is text - { - Kill_text_bloc(speech_text_bloc_no); // kill the text block - speech_text_bloc_no=0; + // !speech_anim_type, as we want an anim which is playing once to + // have finished. + + if (speechFinished && !speech_anim_type) { + // if there is text + if (speech_text_bloc_no) { + // kill the text block + Kill_text_bloc(speech_text_bloc_no); + speech_text_bloc_no = 0; } - if (anim_id) // if there is a speech anim - { - anim_id=0; - ob_graphic->anim_pc=0; // end it on 1st frame (closed mouth) + // if there is a speech anim + if (anim_id) { + // end it on 1st frame (closed mouth) + anim_id = 0; + ob_graphic->anim_pc = 0; } - textRunning=0; - speechRunning=0; + textRunning = 0; + speechRunning = 0; - ob_logic->looping=0; // no longer in a script function loop + // no longer in a script function loop + ob_logic->looping = 0; #ifdef _SWORD2_DEBUG - textNumber = 0; // reset for debug info -#endif // _SWORD2_DEBUG - officialTextNumber = 0; // reset to zero, in case text line not even extracted (since this number comes from the text line) + // reset for debug info + textNumber = 0; +#endif - RESULT=0; // ok (James09july97) - return(IR_CONT); // continue with the script + // reset to zero, in case text line not even extracted (since + // this number comes from the text line) + officialTextNumber = 0; + + RESULT = 0; // ok (James09july97) + return IR_CONT; } - //----------------------------------------------------------------------- - // speech still going, so decrement the click_delay if it's still active + + // speech still going, so decrement the click_delay if it's still + // active + + // count down to clickability if (left_click_delay) - left_click_delay--; // count down to clickability + left_click_delay--; if (right_click_delay) - right_click_delay--; // count down to clickability + right_click_delay--; - //----------------------------------------------------------------------- + // back again next cycle + return IR_REPEAT; +} - return(IR_REPEAT); // back again next cycle +#define GAP_ABOVE_HEAD 20 // distance kept above talking sprite -} -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -void LocateTalker(int32 *params) // (James 01july97) -{ +void LocateTalker(int32 *params) { // (James 01july97) // sets 'text_x' & 'text_y' for position of text sprite // but 'text_x' also used to calculate speech-pan - //param 0 pointer to ob_graphic - //param 1 pointer to ob_speech - //param 2 pointer to ob_logic - //param 3 pointer to ob_mega - - //param 4 encoded text number - //param 5 wav res id - //param 6 anim res id - //param 7 pointer to anim table - //param 8 animation mode 0 lip synced, 1 just straight animation + // params: 0 pointer to ob_graphic + // 1 pointer to ob_speech + // 2 pointer to ob_logic + // 3 pointer to ob_mega + // 4 encoded text number + // 5 wav res id + // 6 anim res id + // 7 pointer to anim table + // 8 animation mode 0 lip synced, + // 1 just straight animation Object_mega *ob_mega; - uint8 *file; - _frameHeader *frame_head; - _animHeader *anim_head; - _cdtEntry *cdt_entry; - uint16 scale; + uint8 *file; + _frameHeader *frame_head; + _animHeader *anim_head; + _cdtEntry *cdt_entry; + uint16 scale; + + // if there's no anim + if (anim_id == 0) { + // assume it's Voice-Over text, so it goes at bottom of screen + text_x = 320; + text_y = 400; + } else { + // Note: this code has been adapted from Register_frame() in + // build_display.cpp + // open animation file & set up the necessary pointers + file = res_man.Res_open(anim_id); + anim_head = FetchAnimHeader(file); + // '0' means 1st frame + cdt_entry = FetchCdtEntry(file, 0); - if (anim_id==0) // if there's no anim - { // assume it's Voice-Over text - text_x = 320; // so it goes at bottom of screen - text_y = 400; - } - else - { - #define GAP_ABOVE_HEAD 20 // distance kept above talking sprite + // '0' means 1st frame + frame_head = FetchFrameHeader(file, 0); - //------------------------------------------- - // Note: this code has been adapted from Register_frame() in build_display.cpp - //------------------------------------------- - // open animation file & set up the necessary pointers + // check if this frame has offsets ie. this is a scalable + // mega frame - file = res_man.Res_open(anim_id); + if (cdt_entry->frameType & FRAME_OFFSET) { + // this may be NULL + ob_mega = (Object_mega*) params[S_OB_MEGA]; - anim_head = FetchAnimHeader( file ); - cdt_entry = FetchCdtEntry( file, 0 ); // '0' means 1st frame - frame_head = FetchFrameHeader( file, 0 ); // '0' means 1st frame + // calc scale at which to print the sprite, based on + // feet y-coord & scaling constants (NB. 'scale' is + // actually 256 * true_scale, to maintain accuracy) - //------------------------------------------- - // check if this frame has offsets ie. this is a scalable mega frame + // Ay+B gives 256 * scale ie. 256 * 256 * true_scale + // for even better accuracy, ie. scale = (Ay + B) / 256 + scale = (uint16) ((ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b) / 256); - if ((cdt_entry->frameType) & FRAME_OFFSET) - { - ob_mega = (Object_mega*) params[S_OB_MEGA]; // this may be NULL + // calc suitable centre point above the head, based on + // scaled height - // calc scale at which to print the sprite, based on feet y-coord & scaling constants (NB. 'scale' is actually 256*true_scale, to maintain accuracy) - scale = (uint16) ((ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b)/256); // Ay+B gives 256*scale ie. 256*256*true_scale for even better accuracy, ie. scale = (Ay+B)/256 + // just use 'feet_x' as centre + text_x = (int16) (ob_mega->feet_x); - // calc suitable centre point above the head, based on scaled height - text_x = (int16) (ob_mega->feet_x); // just use 'feet_x' as centre - text_y = (int16) (ob_mega->feet_y + (cdt_entry->y * scale)/256); // add scaled y-offset to feet_y coord to get top of sprite - } - else // it's a non-scaling anim - { - // calc suitable centre point above the head, based on scaled width - text_x = cdt_entry->x + (frame_head->width)/2; // x-coord + half of width - text_y = cdt_entry->y; // y-coord + // add scaled y-offset to feet_y coord to get top of + // sprite + text_y = (int16) (ob_mega->feet_y + (cdt_entry->y * scale) / 256); + } else { + // it's a non-scaling anim - calc suitable centre + // point above the head, based on scaled width + + // x-coord + half of width + text_x = cdt_entry->x + (frame_head->width) / 2; + text_y = cdt_entry->y; } - text_y -= GAP_ABOVE_HEAD; // leave space above their head + // leave space above their head + text_y -= GAP_ABOVE_HEAD; - //------------------------------------------- // adjust the text coords for RDSPR_DISPLAYALIGN text_x -= this_screen.scroll_offset_x; text_y -= this_screen.scroll_offset_y; - //------------------------------------------- // release the anim resource - res_man.Res_close(anim_id); - - //------------------------------------------- } } -//------------------------------------------------------------------------------------ -//------------------------------------------------------------------------------------ -void Form_text(int32 *params) //Tony18Oct96 -{ -//its the first time in so we build the text block if we need one -//we also bring in the wav if there is one -//also setup the animation if there is one -//anim is optional - anim can be a repeating lip-sync or a run-once anim -//if there is no wav then the text comes up instead -//there can be any combination of text/wav playing +void Form_text(int32 *params) { // Tony18Oct96 + // its the first time in so we build the text block if we need one + // we also bring in the wav if there is one + // also setup the animation if there is one -//param 0 pointer to ob_graphic -//param 1 pointer to ob_speech -//param 2 pointer to ob_logic -//param 3 pointer to ob_mega + // anim is optional - anim can be a repeating lip-sync or a run-once + // anim -//param 4 encoded text number -//param 5 wav res id -//param 6 anim res id -//param 7 pointer to anim table -//param 8 animation mode 0 lip synced, 1 just straight animation + // if there is no wav then the text comes up instead + // there can be any combination of text/wav playing + // params 0 pointer to ob_graphic + // 1 pointer to ob_speech + // 2 pointer to ob_logic + // 3 pointer to ob_mega + // 4 encoded text number + // 5 wav res id + // 6 anim res id + // 7 pointer to anim table + // 8 animation mode 0 lip synced, + // 1 just straight animation - uint32 local_text; - uint32 text_res; - uint8 *text; - uint32 textWidth; - Object_speech *ob_speech; + uint32 local_text; + uint32 text_res; + uint8 *text; + uint32 textWidth; + Object_speech *ob_speech; + // should always be a text line, as all text is derived from line of + // text + if (params[S_TEXT]) { + ob_speech = (Object_speech *) params[S_OB_SPEECH]; - if (params[S_TEXT]) //should always be a text line, as all text is derived from line of text - { - ob_speech = (Object_speech*) params[S_OB_SPEECH]; - - //---------------------------------------------------------- // establish the max width allowed for this text sprite - if (ob_speech->width) // if a specific width has been set up for this character - textWidth = ob_speech->width; // override the default + // if a specific width has been set up for this character, + // then override the default + + if (ob_speech->width) + textWidth = ob_speech->width; else - textWidth = 400; // otherwise use the default + textWidth = 400; - //---------------------------------------------------------- // pull out the text line & make the sprite & text block - text_res = params[S_TEXT]/SIZE; - local_text = params[S_TEXT]&0xffff; + text_res = params[S_TEXT] / SIZE; + local_text = params[S_TEXT] & 0xffff; - text = FetchTextLine( res_man.Res_open(text_res), local_text ); // open text file & get the line + // open text file & get the line + text = FetchTextLine(res_man.Res_open(text_res), local_text); - // 'text+2' to skip the first 2 bytes which form the line reference number - speech_text_bloc_no = Build_new_block(text+2, text_x, text_y, textWidth, ob_speech->pen, RDSPR_TRANS+RDSPR_DISPLAYALIGN, speech_font_id, POSITION_AT_CENTRE_OF_BASE); + // 'text + 2' to skip the first 2 bytes which form the line + // reference number - res_man.Res_close(text_res); // now ok to close the text file + speech_text_bloc_no = Build_new_block(text + 2, text_x, text_y, + textWidth, ob_speech->pen, + RDSPR_TRANS | RDSPR_DISPLAYALIGN, speech_font_id, + POSITION_AT_CENTRE_OF_BASE); - //---------------------------------------------------------- - // set speech duration, in case not using wav + // now ok to close the text file + res_man.Res_close(text_res); - speech_time = strlen((char *)text) + 30; // no. of cycles = (no. of chars) + 10 + // set speech duration, in case not using wav + // no. of cycles = (no. of chars) + 30 - //---------------------------------------------------------- - } - else // no text line passed? - this is bad - { - // Zdebug(9,"no text line for speech wav %d", params[S_WAV]); //stream 9 for missing text & wavs - Zdebug("no text line for speech wav %d", params[S_WAV]); //stream 9 for missing text & wavs + speech_time = strlen((char *) text) + 30; + } else { + // no text line passed? - this is bad + // Zdebug(9, "no text line for speech wav %d", params[S_WAV]); + Zdebug("no text line for speech wav %d", params[S_WAV]); } } -//------------------------------------------------------------------------------------ -#ifdef _SWORD2_DEBUG -void GetCorrectCdForSpeech(int32 wavId) -{ +#ifdef _SWORD2_DEBUG +void GetCorrectCdForSpeech(int32 wavId) { File fp; - uint8 cd; // 1, 2 or 0 (if speech on both cd's, ie. no need to change) - if (fp.open("cd.bin") == false) + // 1, 2 or 0 (if speech on both cd's, ie. no need to change) + uint8 cd; + + if (!fp.open("cd.bin")) Con_fatal_error("Need cd.bin file for testing speech!"); fp.seek(wavId, SEEK_SET); @@ -1912,65 +1615,62 @@ void GetCorrectCdForSpeech(int32 wavId) fp.close(); - if ((cd==1)||(cd==2)) // if we specifically need CD1 or CD2 (ie. it's not on both) - res_man.GetCd(cd); // then check it's there (& ask for it if it's not there) + // if we specifically need CD1 or CD2 (ie. it's not on both) + // then check it's there (& ask for it if it's not there) + if (cd == 1 || cd == 2) + res_man.GetCd(cd); } - #endif -//------------------------------------------------------------------------------------ + // For preventing sfx subtitles from trying to load speech samples -// - since the sfx are implemented as normal sfx, so we don't want them as speech samples too +// - since the sfx are implemented as normal sfx, so we don't want them as +// speech samples too // - and we only want the subtitles if selected, not if samples can't be found! -uint8 WantSpeechForLine(uint32 wavId) // James (29july97) -{ - switch (wavId) - { +uint8 WantSpeechForLine(uint32 wavId) { // James (29july97) + switch (wavId) { case 1328: // AttendantSpeech - // SFX(Phone71); - // FX <Telephone rings> + // SFX(Phone71); + // FX <Telephone rings> case 2059: // PabloSpeech - // SFX (2059); - // FX <Sound of sporadic gunfire from below> + // SFX (2059); + // FX <Sound of sporadic gunfire from below> case 4082: // DuaneSpeech - // SFX (4082); - // FX <Pffffffffffft! Frp. (Unimpressive, flatulent noise.)> + // SFX (4082); + // FX <Pffffffffffft! Frp. (Unimpressive, flatulent noise.)> case 4214: // cat_52 - // SFX (4214); - // 4214FXMeow! + // SFX (4214); + // 4214FXMeow! case 4568: // trapdoor_13 - // SFX (4568); - // 4568fx<door slamming> + // SFX (4568); + // 4568fx<door slamming> case 4913: // LobineauSpeech - // SFX (tone2); - // FX <Lobineau hangs up> + // SFX (tone2); + // FX <Lobineau hangs up> case 5120: // bush_66 - // SFX (5120); - // 5120FX<loud buzzing> + // SFX (5120); + // 5120FX<loud buzzing> case 528: // PresidentaSpeech - // SFX (528); - // FX <Nearby Crash of Collapsing Masonry> + // SFX (528); + // FX <Nearby Crash of Collapsing Masonry> case 920: // location 62 case 923: // location 62 case 926: // location 62 - - { - return 0; // don't want speech for these lines! - break; - } + // don't want speech for these lines! + return 0; default: - return 1; // ok for all other lines + // ok for all other lines + return 1; } } -//------------------------------------------------------------------------------------ diff --git a/sword2/speech.h b/sword2/speech.h index 3630f56110..f137fdb991 100644 --- a/sword2/speech.h +++ b/sword2/speech.h @@ -20,25 +20,26 @@ #ifndef _SPEECH #define _SPEECH -//#include "src\driver96.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 { + uint32 res; + uint32 ref; +} _subject_unit; +// so speech text cleared when running a new start-script +extern uint32 speech_text_bloc_no; +extern int16 officialTextNumber; -typedef struct //array of these for subject menu build up -{ - uint32 res; - uint32 ref; -} _subject_unit; +extern int32 speechScriptWaiting; -extern uint32 speech_text_bloc_no; // so speech text cleared when running a new start-script -extern int16 officialTextNumber; +//could alternately use logic->looping of course +extern int choosing; -extern int32 speechScriptWaiting; +extern uint32 unpause_zone; -extern int choosing; //could alternately use logic->looping of course -extern uint32 unpause_zone; #endif diff --git a/sword2/walker.cpp b/sword2/walker.cpp index 6430152acd..96cf0444c4 100644 --- a/sword2/walker.cpp +++ b/sword2/walker.cpp @@ -17,388 +17,331 @@ * $Header$ */ -//-------------------------------------------------------------------------------------- // WALKER.CPP by James (14nov96) -// script functions for moving megas about the place & also for keeping tabs on them +// script functions for moving megas about the place & also for keeping tabs +// on them -// FN_walk() // walk to (x,y,dir) +// FN_walk() // walk to (x,y,dir) // FN_walk_to_anim() // walk to start position of anim -// FN_turn() // turn to (dir) -// FN_stand_at() // stand at (x,y,dir) -// FN_stand() // stand facing (dir) +// FN_turn() // turn to (dir) +// FN_stand_at() // stand at (x,y,dir) +// FN_stand() // stand facing (dir) // FN_stand_after_anim() // stand at end position of anim -// FN_face_id() // turn to face object (id) -// FN_face_xy() // turn to face point (x,y) -// FN_is_facing() // is mega (id) facing us? -// FN_get_pos() // get details of another mega's position - -//-------------------------------------------------------------------------------------- +// FN_face_id() // turn to face object (id) +// FN_face_xy() // turn to face point (x,y) +// FN_is_facing() // is mega (id) facing us? +// FN_get_pos() // get details of another mega's position #include "stdafx.h" -//#include "src\driver96.h" #include "console.h" #include "defs.h" #include "events.h" #include "function.h" #include "interpreter.h" -#include "logic.h" // for FN_add_to_kill_list +#include "logic.h" // for FN_add_to_kill_list #include "object.h" #include "protocol.h" #include "router.h" #include "sync.h" -//-------------------------------------------------------------------------------------- - -int16 standby_x; // see FN_set_standby_coords -int16 standby_y; -uint8 standby_dir; - -//-------------------------------------------------------------------------------------- -/* -uint8 Check_walk_anim_ok( Object_mega *ob_mega, Object_walkdata *ob_walkdata ); -//-------------------------------------------------------------------------------------- -// NEW CODE TO VERIFY THAT THE WALK-ANIM CONTAINS NO INVALID FRAMES! -// (James 15sep97) -uint8 Check_walk_anim_ok( Object_mega *ob_mega, Object_walkdata *ob_walkdata ) -{ - int32 walk_pc=0; - _walkData *walkAnim; - uint8 *anim_file; - _animHeader *anim_head; - uint32 lastValidFrameNo; - uint8 ok=1; - - - anim_file = res_man.Res_open(ob_mega->megaset_res); // open mega-set file - anim_head = FetchAnimHeader( anim_file ); // set up pointer to the animation header - lastValidFrameNo = anim_head->noAnimFrames-1; // get last valid frame number - res_man.Res_close(ob_mega->megaset_res); // close file - - walkAnim = LockRouteMem(); // lock the _walkData array - - while (ok && (walkAnim[walk_pc].frame != 512)) // '512' id end-marker - { - if (walkAnim[walk_pc].frame > lastValidFrameNo) // if frame exceeds the allowed range - ok=0; - - walk_pc++; - } - - FloatRouteMem(); // allow _walkData array to float about memory again +int16 standby_x; // see FN_set_standby_coords +int16 standby_y; +uint8 standby_dir; - return(ok); -} -*/ -//-------------------------------------------------------------------------------------- // walk mega to (x,y,dir) -int32 FN_walk(int32 *params) // James (14nov96) -{ +int32 FN_walk(int32 *params) { // James (14nov96) // params: 0 pointer to object's logic structure - // 1 pointer to object's graphic structure - // 2 pointer to object's mega structure - // 3 pointer to object's walkdata structure - // 4 target x-coord - // 5 target y-coord - // 6 target direction - - Object_logic *ob_logic; - Object_graphic *ob_graph; - Object_mega *ob_mega; - Object_walkdata *ob_walkdata; - int16 target_x; - int16 target_y; - uint8 target_dir; - int8 route; - int32 walk_pc; - _walkData *walkAnim; - - //---------------------------------------------------------------------------------------- + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 target x-coord + // 5 target y-coord + // 6 target direction + + Object_logic *ob_logic; + Object_graphic *ob_graph; + Object_mega *ob_mega; + Object_walkdata *ob_walkdata; + int16 target_x; + int16 target_y; + uint8 target_dir; + int8 route; + int32 walk_pc; + _walkData *walkAnim; + // get the parameters - ob_logic = (Object_logic *)params[0]; - ob_graph = (Object_graphic *)params[1]; - ob_mega = (Object_mega *)params[2]; + ob_logic = (Object_logic *) params[0]; + ob_graph = (Object_graphic *) params[1]; + ob_mega = (Object_mega *) params[2]; - target_x = (int16) params[4]; - target_y = (int16) params[5]; - target_dir = (uint8) params[6]; + target_x = (int16) params[4]; + target_y = (int16) params[5]; + target_dir = (uint8) params[6]; - //---------------------------------------------------------------------------------------- // if this is the start of the walk, calculate route - if (ob_logic->looping==0) - { - //--------------------------- - // If we're already there, don't even bother allocating memory and calling the router, - // just quit back & continue the script! - // This avoids an embarassing mega stand frame appearing for one cycle when we're already - // in position for an anim eg. repeatedly clicking on same object to repeat an anim - // - no mega frame will appear in between runs of the anim. + if (ob_logic->looping == 0) { + // If we're already there, don't even bother allocating + // memory and calling the router, just quit back & continue + // the script! This avoids an embarassing mega stand frame + // appearing for one cycle when we're already in position for + // an anim eg. repeatedly clicking on same object to repeat + // an anim - no mega frame will appear in between runs of the + // anim. - if ((ob_mega->feet_x == target_x) && (ob_mega->feet_y == target_y) - && (ob_mega->current_dir == target_dir)) - { - RESULT = 0; // 0 means ok - finished walk - return(IR_CONT); // may as well continue the script + if (ob_mega->feet_x == target_x && ob_mega->feet_y == target_y && ob_mega->current_dir == target_dir) { + RESULT = 0; // 0 means ok - finished walk + return IR_CONT; // may as well continue the script } - //--------------------------- - if ((params[6] < 0) || (params[6] > 8)) // invalid direction (NB. '8' means end walk on ANY direction) - Con_fatal_error("Invalid direction (%d) in FN_walk (%s line %u)",params[6],__FILE__,__LINE__); - //--------------------------- + // invalid direction (NB. '8' means end walk on ANY direction) + if (params[6] < 0 || params[6] > 8) + Con_fatal_error("Invalid direction (%d) in FN_walk (%s line %u)", params[6], __FILE__, __LINE__); + + ob_walkdata = (Object_walkdata *) params[3]; + + ob_mega->walk_pc = 0; // always - ob_walkdata = (Object_walkdata *)params[3]; + // set up mem for _walkData in route_slots[] & set mega's + // 'route_slot_id' accordingly - ob_mega->walk_pc=0; //always + AllocateRouteMem(); - AllocateRouteMem(); // set up mem for _walkData in route_slots[] & set mega's 'route_slot_id' accordingly route = (int8) RouteFinder(ob_mega, ob_walkdata, target_x, target_y, target_dir); - /* - if (id == PLAYER) - { - nExtraBars = 0; - nExtraNodes = 0; - if ((route == 1) || (route == 2)) - { - megaOnGrid = 0; // if we have just checked a grid with the mega on the grid take the mega off - reRouteGeorge = 0; - } - } - */ + // 0 = can't make route to target + // 1 = created route + // 2 = zero route but may need to turn - if ((route == 1) || (route == 2)) // 1=created route 2=zero route but may need to turn - { - //------------------------------------------- - ob_logic->looping = 1; // so script FN_walk loop continues until end of walk-anim - // need to animate the route now, so don't set result or return yet! + if (route == 1 || route == 2) { + // so script FN_walk loop continues until end of + // walk-anim - ob_mega->currently_walking=1; // started walk(James23jun97) - // (see FN_get_player_savedata() in save_rest.cpp - //------------------------------------------- - } - else // 0=can't make route to target - { - FreeRouteMem(); // free up the walkdata mem block - RESULT = 1; // 1 means error, no walk created - return(IR_CONT); // may as well continue the script + ob_logic->looping = 1; + + // need to animate the route now, so don't set result + // or return yet! + + // started walk(James23jun97) + ob_mega->currently_walking = 1; + + // (see FN_get_player_savedata() in save_rest.cpp + } else { + // free up the walkdata mem block + FreeRouteMem(); + + // 1 means error, no walk created + RESULT = 1; + + // may as well continue the script + return IR_CONT; } - // ok, walk is about to start, so set the mega's graphic resource + // ok, walk is about to start, so set the mega's graphic + // resource + ob_graph->anim_resource = ob_mega->megaset_res; - } - //---------------------------------------------------------------------------------------- - // double clicked an exit so quit the walk when screen is black + } else if (EXIT_FADING && GetFadeStatus() == RDFADE_BLACK) { + // double clicked an exit so quit the walk when screen is black - else if ((EXIT_FADING) && (GetFadeStatus()==RDFADE_BLACK)) - { -// ok, thats it - back to script and change screen + // ok, thats it - back to script and change screen - ob_logic->looping=0; // so script loop stops - FreeRouteMem(); // free up the walkdata mem block + ob_logic->looping = 0; // so script loop stops + FreeRouteMem(); // free up the walkdata mem block - EXIT_CLICK_ID=0; // must clear in-case on the new screen there's a walk instruction (which would get cut short) -// EXIT_FADING=0; // this will be reset when we change screens, so we can use it in script to check if a 2nd-click came along + // must clear in-case on the new screen there's a walk + // instruction (which would get cut short) + EXIT_CLICK_ID = 0; + // this will be reset when we change screens, so we can use + // it in script to check if a 2nd-click came along + // EXIT_FADING = 0; - ob_mega->currently_walking=0; // finished walk (James23jun97) - // (see FN_get_player_savedata() in save_rest.cpp + // finished walk (James23jun97) + ob_mega->currently_walking = 0; - ob_mega->colliding=0; + // (see FN_get_player_savedata() in save_rest.cpp - RESULT = 0; // 0 means ok - return(IR_CONT); // continue the script so that RESULT can be checked! + RESULT = 0; // 0 means ok + + // continue the script so that RESULT can be checked! + return(IR_CONT); } - //---------------------------------------------------------------------------------------- + // get pointer to walkanim & current frame position - walkAnim = LockRouteMem(); // lock the _walkData array - walk_pc = ob_mega->walk_pc; + // lock the _walkData array + walkAnim = LockRouteMem(); + walk_pc = ob_mega->walk_pc; - //---------------------------------------------------------------------------------------- - // if stopping the walk early, overwrite the next step with a slow-out, then finish + // if stopping the walk early, overwrite the next step with a + // slow-out, then finish - if (Check_event_waiting()) - { - if ((walkAnim[walk_pc].step == 0) && (walkAnim[walk_pc+1].step == 1)) // at the beginning of a step - { - ob_walkdata = (Object_walkdata *)params[3]; - EarlySlowOut(ob_mega,ob_walkdata); + if (Check_event_waiting()) { + if (walkAnim[walk_pc].step == 0 && walkAnim[walk_pc + 1].step == 1) { + // at the beginning of a step + ob_walkdata = (Object_walkdata *) params[3]; + EarlySlowOut(ob_mega, ob_walkdata); } } -/* - else if (CheckForCollision()) - { - if ((walkAnim[walk_pc].step == 0) && (walkAnim[walk_pc+1].step == 1)) // at the beginning of a step - { - ob_walkdata = (Object_walkdata *)params[3]; - EarlySlowOut(ob_mega,ob_walkdata); - ob_mega->colliding=1; - } - } -*/ - //------------------------------------------------------------------ // get new frame of walk - ob_graph->anim_pc = walkAnim[walk_pc].frame; - ob_mega->current_dir = walkAnim[walk_pc].dir; - ob_mega->feet_x = walkAnim[walk_pc].x; - ob_mega->feet_y = walkAnim[walk_pc].y; + ob_graph->anim_pc = walkAnim[walk_pc].frame; + ob_mega->current_dir = walkAnim[walk_pc].dir; + ob_mega->feet_x = walkAnim[walk_pc].x; + ob_mega->feet_y = walkAnim[walk_pc].y; - //------------------------------------------------------------------ // check if NEXT frame is in fact the end-marker of the walk sequence - // so we can return to script just as the final (stand) frame of the walk is set - // - so that if followed by an anim, the anim's first frame replaces the final stand-frame - // of the walk (see below) - - if (walkAnim[walk_pc+1].frame==512) // '512' is end-marker - { - ob_logic->looping=0; // so script loop stops - FreeRouteMem(); // free up the walkdata mem block - - ob_mega->currently_walking=0; // finished walk(James23jun97) - // (see FN_get_player_savedata() in save_rest.cpp -/* - if (ID==CUR_PLAYER_ID) - { - george_walking = 0; + // so we can return to script just as the final (stand) frame of the + // walk is set - so that if followed by an anim, the anim's first + // frame replaces the final stand-frame of the walk (see below) - if (megaOnGrid == 2) - megaOnGrid = 0; - } -*/ + // '512' is end-marker + if (walkAnim[walk_pc + 1].frame == 512) { + ob_logic->looping = 0; // so script loop stops + FreeRouteMem(); // free up the walkdata mem block + + // finished walk(James23jun97) + ob_mega->currently_walking = 0; + + // (see FN_get_player_savedata() in save_rest.cpp + + // if George's walk has been interrupted to run a new action + // script for instance or Nico's walk has been interrupted by + // player clicking on her to talk - if (Check_event_waiting()) // if George's walk has been interrupted to run a new action script for instance - { // or Nico's walk has been interrupted by player clicking on her to talk - ob_mega->colliding=0; // Don't care about collision now we've got an event + // There used to be code here for checking if two megas were + // colliding, but that code had been commented out, and it + // was only run if a function that always returned zero + // returned non-zero. + + if (Check_event_waiting()) { Start_event(); - RESULT = 1; // 1 means didn't finish walk - return(IR_TERMINATE); - } - else if (ob_mega->colliding) // If we almost collided with another mega, - { // then we want to re-route from scratch. - ob_mega->colliding=0; // reset the flag now we've acknowledged the collision - return(IR_REPEAT); // Stop the script, but repeat this call next cycle - } - else - { - RESULT = 0; // 0 means ok - finished walk - return(IR_CONT); // CONTINUE the script so that RESULT can be checked! - // Also, if an anim command follows the FN_walk command, - // the 1st frame of the anim (which is always a stand frame itself) - // can replace the final stand frame of the walk, to hide the - // slight difference between the shrinking on the mega frames - // and the pre-shrunk anim start-frame. + RESULT = 1; // 1 means didn't finish walk + return IR_TERMINATE; + } else { + RESULT = 0; // 0 means ok - finished walk + + // CONTINUE the script so that RESULT can be checked! + // Also, if an anim command follows the FN_walk + // command, the 1st frame of the anim (which is always + // a stand frame itself) can replace the final stand + // frame of the walk, to hide the slight difference + // between the shrinking on the mega frames and the + // pre-shrunk anim start-frame. + + return IR_CONT; } } - //---------------------------------------------------------------------------------------- - // increment the walkanim frame number, float the walkanim & come back next cycle + + // increment the walkanim frame number, float the walkanim & come + // back next cycle ob_mega->walk_pc++; - FloatRouteMem(); // allow _walkData array to float about memory again - return(IR_REPEAT); // stop the script, but repeat this call next cycle + // allow _walkData array to float about memory again + FloatRouteMem(); - //------------------------------------------------------------------ + // stop the script, but repeat this call next cycle + return IR_REPEAT; } -//-------------------------------------------------------------------------------------- + // walk mega to start position of anim -int32 FN_walk_to_anim(int32 *params) // James (14nov96) -{ +int32 FN_walk_to_anim(int32 *params) { // James (14nov96) // params: 0 pointer to object's logic structure - // 1 pointer to object's graphic structure - // 2 pointer to object's mega structure - // 3 pointer to object's walkdata structure - // 4 anim resource id + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 anim resource id - Object_logic *ob_logic; - uint8 *anim_file; - _animHeader *anim_head; - int32 pars[7]; + Object_logic *ob_logic; + uint8 *anim_file; + _animHeader *anim_head; + int32 pars[7]; - //---------------------------------------------------------------------------------------- // if this is the start of the walk, read anim file to get start coords - ob_logic = (Object_logic *)params[0]; + ob_logic = (Object_logic *) params[0]; - if (ob_logic->looping==0) - { - anim_file = res_man.Res_open(params[4]); // open anim file - anim_head = FetchAnimHeader( anim_file ); // point to animation header + if (ob_logic->looping == 0) { + // open anim file + anim_file = res_man.Res_open(params[4]); - pars[4] = anim_head->feetStartX; // target_x - pars[5] = anim_head->feetStartY; // target_y - pars[6] = anim_head->feetStartDir; // target_dir + // point to animation header + anim_head = FetchAnimHeader( anim_file ); - res_man.Res_close(params[4]); // close anim file + pars[4] = anim_head->feetStartX; // target_x + pars[5] = anim_head->feetStartY; // target_y + pars[6] = anim_head->feetStartDir; // target_dir - //------------------------------------------ - if ((pars[4]==0)&&(pars[5]==0)) // if start coords not yet set in anim header - { - pars[4] = standby_x; // use the standby coords - pars[5] = standby_y; // (which should be set beforehand in the script) + // close anim file + res_man.Res_close(params[4]); + + // if start coords not yet set in anim header, use the standby + // coords (which should be set beforehand in the script) + + if (pars[4] == 0 && pars[5] == 0) { + pars[4] = standby_x; + pars[5] = standby_y; pars[6] = standby_dir; Zdebug("WARNING: FN_walk_to_anim(%s) used standby coords", FetchObjectName(params[4])); } - if ((pars[6] < 0) || (pars[6] > 7)) // check for invalid direction - Con_fatal_error("Invalid direction (%d) in FN_walk_to_anim (%s line %u)", pars[6],__FILE__,__LINE__); - - //------------------------------------------ + if (pars[6] < 0 || pars[6] > 7) + Con_fatal_error("Invalid direction (%d) in FN_walk_to_anim (%s line %u)", pars[6], __FILE__, __LINE__); } - //---------------------------------------------------------------------------------------- + // set up the rest of the parameters for FN_walk() pars[0] = params[0]; pars[1] = params[1]; pars[2] = params[2]; - pars[3] = params[3]; // walkdata - needed for EarlySlowOut if player clicks elsewhere during the walk + pars[3] = params[3]; - //------------------------------------------------------------------------------------------------------- + // walkdata (param 3) is needed for EarlySlowOut if player clicks + // elsewhere during the walk - return FN_walk(pars); // call FN_walk() with target coords set to anim start position + // call FN_walk() with target coords set to anim start position + return FN_walk(pars); } -//-------------------------------------------------------------------------------------- // turn mega to <direction> -// just needs to call FN_walk() with current feet coords, so router can produce anim of turn frames +// just needs to call FN_walk() with current feet coords, so router can +// produce anim of turn frames -int32 FN_turn(int32 *params) // James (15nov96) -{ +int32 FN_turn(int32 *params) { // James (15nov96) // params: 0 pointer to object's logic structure - // 1 pointer to object's graphic structure - // 2 pointer to object's mega structure - // 3 pointer to object's walkdata structure - // 4 target direction + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 target direction - Object_logic *ob_logic; - Object_mega *ob_mega; - int32 pars[7]; + Object_logic *ob_logic; + Object_mega *ob_mega; + int32 pars[7]; - // if this is the start of the turn, get the mega's current feet coords + the required direction + // if this is the start of the turn, get the mega's current feet + // coords + the required direction - ob_logic = (Object_logic *)params[0]; + ob_logic = (Object_logic *) params[0]; - if (ob_logic->looping==0) - { - //-------------------------------------------- - if ((params[4] < 0) || (params[4] > 7)) // invalid direction - Con_fatal_error("Invalid direction (%d) in FN_turn (%s line %u)",params[4],__FILE__,__LINE__); - //-------------------------------------------- + if (ob_logic->looping == 0) { + if (params[4] < 0 || params[4] > 7) + Con_fatal_error("Invalid direction (%d) in FN_turn (%s line %u)", params[4], __FILE__, __LINE__); - ob_mega = (Object_mega *)params[2]; + ob_mega = (Object_mega *) params[2]; pars[4] = ob_mega->feet_x; pars[5] = ob_mega->feet_y; - pars[6] = params[4]; // DIRECTION to turn to + pars[6] = params[4]; // DIRECTION to turn to } - //---------------------------------------------------------------------------------------- // set up the rest of the parameters for FN_walk() pars[0] = params[0]; @@ -406,285 +349,226 @@ int32 FN_turn(int32 *params) // James (15nov96) pars[2] = params[2]; pars[3] = params[3]; - //---------------------------------------------------------------------------------------- - - return FN_walk(pars); // call FN_walk() with target coords set to feet coords + // call FN_walk() with target coords set to feet coords + return FN_walk(pars); } -//-------------------------------------------------------------------------------------- + // stand mega at (x,y,dir) -// sets up the graphic object, but also needs to set the new 'current_dir' in the mega object, so the router knows in future +// sets up the graphic object, but also needs to set the new 'current_dir' in +// the mega object, so the router knows in future -int32 FN_stand_at(int32 *params) // James -{ +int32 FN_stand_at(int32 *params) { // James // params: 0 pointer to object's graphic structure - // 1 pointer to object's mega structure - // 2 target x-coord - // 3 target y-coord - // 4 target direction + // 1 pointer to object's mega structure + // 2 target x-coord + // 3 target y-coord + // 4 target direction - Object_mega *ob_mega; - Object_graphic *ob_graph; + Object_mega *ob_mega; + Object_graphic *ob_graph; - //---------------------------------------------------------------------------------------- // check for invalid direction - if ((params[4] < 0) || (params[4] > 7)) // invalid direction - Con_fatal_error("Invalid direction (%d) in FN_stand_at (%s line %u)",params[4],__FILE__,__LINE__); + if (params[4] < 0 || params[4] > 7) + Con_fatal_error("Invalid direction (%d) in FN_stand_at (%s line %u)", params[4], __FILE__, __LINE__); - //---------------------------------------------------------------------------------------- // set up pointers to the graphic & mega structure - ob_graph = (Object_graphic *)params[0]; - ob_mega = (Object_mega *)params[1]; + ob_graph = (Object_graphic *) params[0]; + ob_mega = (Object_mega *) params[1]; - //---------------------------------------------------------------------------------------- // set up the stand frame & set the mega's new direction - ob_graph->anim_resource = ob_mega->megaset_res; // mega-set animation file - ob_mega->feet_x = params[2]; // x - ob_mega->feet_y = params[3]; // y - ob_graph->anim_pc = params[4]+96; // dir + first stand frame (always frame 96) - ob_mega->current_dir = params[4]; // dir + // mega-set animation file + ob_graph->anim_resource = ob_mega->megaset_res; + + ob_mega->feet_x = params[2]; + ob_mega->feet_y = params[3]; + + // dir + first stand frame (always frame 96) + ob_graph->anim_pc = params[4] + 96; - //---------------------------------------------------------------------------------------- + ob_mega->current_dir = params[4]; - return(IR_CONT); // continue the script + return IR_CONT; } -//-------------------------------------------------------------------------------------- // stand mega in <direction> at current feet coords // just needs to call FN_stand_at() with current feet coords -int32 FN_stand(int32 *params) // James (15nov96) -{ +int32 FN_stand(int32 *params) { // James (15nov96) // params: 0 pointer to object's graphic structure - // 1 pointer to object's mega structure - // 2 target direction + // 1 pointer to object's mega structure + // 2 target direction - Object_mega *ob_mega = (Object_mega *)params[1]; + Object_mega *ob_mega = (Object_mega *) params[1]; int32 pars[5]; pars[0] = params[0]; pars[1] = params[1]; pars[2] = ob_mega->feet_x; pars[3] = ob_mega->feet_y; - pars[4] = params[2]; // DIRECTION to stand in + pars[4] = params[2]; // DIRECTION to stand in - return FN_stand_at(pars); // call FN_stand_at() with target coords set to feet coords + // call FN_stand_at() with target coords set to feet coords + return FN_stand_at(pars); } -//-------------------------------------------------------------------------------------- + // stand mega at end position of anim -int32 FN_stand_after_anim(int32 *params) // James (14nov96) -{ +int32 FN_stand_after_anim(int32 *params) { // James (14nov96) // params: 0 pointer to object's graphic structure - // 1 pointer to object's mega structure - // 2 anim resource id + // 1 pointer to object's mega structure + // 2 anim resource id uint8 *anim_file; _animHeader *anim_head; int32 pars[5]; - //---------------------------------------------------------------------------------------- // open the anim file & set up a pointer to the animation header - anim_file = res_man.Res_open(params[2]); // open anim file - anim_head = FetchAnimHeader( anim_file ); + // open anim file + anim_file = res_man.Res_open(params[2]); + anim_head = FetchAnimHeader(anim_file); - //---------------------------------------------------------------------------------------- // set up the parameter list for FN_walk_to() pars[0] = params[0]; pars[1] = params[1]; - pars[2] = anim_head->feetEndX; // x - pars[3] = anim_head->feetEndY; // y - pars[4] = anim_head->feetEndDir; // dir + pars[2] = anim_head->feetEndX; + pars[3] = anim_head->feetEndY; + pars[4] = anim_head->feetEndDir; - //---------------------------------------------------------------------------------------- + // if start coords not available either use the standby coords (which + // should be set beforehand in the script) - if ((pars[2]==0)&&(pars[3]==0)) // if start coords not available either - { - pars[2] = standby_x; // use the standby coords - pars[3] = standby_y; // (which should be set beforehand in the script) + if (pars[2] == 0 && pars[3] == 0) { + pars[2] = standby_x; + pars[3] = standby_y; pars[4] = standby_dir; Zdebug("WARNING: FN_stand_after_anim(%s) used standby coords", FetchObjectName(params[2])); } - if ((pars[4] < 0) || (pars[4] > 7)) // check for invalid direction - Con_fatal_error("Invalid direction (%d) in FN_stand_after_anim (%s line %u)", pars[4],__FILE__,__LINE__); + if (pars[4] < 0 || pars[4] > 7) + Con_fatal_error("Invalid direction (%d) in FN_stand_after_anim (%s line %u)", pars[4], __FILE__, __LINE__); - //---------------------------------------------------------------------------------------- // close the anim file + res_man.Res_close(params[2]); - res_man.Res_close(params[2]); // close anim file - - //---------------------------------------------------------------------------------------- - - return FN_stand_at(pars); // call FN_stand_at() with target coords set to anim end position + // call FN_stand_at() with target coords set to anim end position + return FN_stand_at(pars); } -//-------------------------------------------------------------------------------------- // stand mega at start position of anim -int32 FN_stand_at_anim(int32 *params) // James (07feb97) -{ +int32 FN_stand_at_anim(int32 *params) { // James (07feb97) // params: 0 pointer to object's graphic structure - // 1 pointer to object's mega structure - // 2 anim resource id + // 1 pointer to object's mega structure + // 2 anim resource id uint8 *anim_file; _animHeader *anim_head; int32 pars[5]; - //---------------------------------------------------------------------------------------- // open the anim file & set up a pointer to the animation header - anim_file = res_man.Res_open(params[2]); // open anim file - anim_head = FetchAnimHeader( anim_file ); + // open anim file + anim_file = res_man.Res_open(params[2]); + anim_head = FetchAnimHeader(anim_file); - //---------------------------------------------------------------------------------------- // set up the parameter list for FN_walk_to() pars[0] = params[0]; pars[1] = params[1]; - pars[2] = anim_head->feetStartX; // x - pars[3] = anim_head->feetStartY; // y - pars[4] = anim_head->feetStartDir; // dir + pars[2] = anim_head->feetStartX; + pars[3] = anim_head->feetStartY; + pars[4] = anim_head->feetStartDir; + + // if start coords not available use the standby coords (which should + // be set beforehand in the script) - if ((pars[2]==0)&&(pars[3]==0)) // if start coords not available - { - pars[2] = standby_x; // use the standby coords - pars[3] = standby_y; // (which should be set beforehand in the script) + if (pars[2] == 0 && pars[3]==0) { + pars[2] = standby_x; + pars[3] = standby_y; pars[4] = standby_dir; Zdebug("WARNING: FN_stand_at_anim(%s) used standby coords", FetchObjectName(params[2])); } - if ((pars[4] < 0) || (pars[4] > 7)) // check for invalid direction - Con_fatal_error("Invalid direction (%d) in FN_stand_after_anim (%s line %u)", pars[4],__FILE__,__LINE__); + if (pars[4] < 0 || pars[4] > 7) + Con_fatal_error("Invalid direction (%d) in FN_stand_after_anim (%s line %u)", pars[4], __FILE__, __LINE__); - //------------------------------------------------------------------------------------------------------- // close the anim file + res_man.Res_close(params[2]); - res_man.Res_close(params[2]); // close anim file - - //------------------------------------------------------------------------------------------------------- - - return FN_stand_at(pars); // call FN_stand_at() with target coords set to anim end position + // call FN_stand_at() with target coords set to anim end position + return FN_stand_at(pars); } -//-------------------------------------------------------------------------------------- // Code to workout direction from start to dest -#define diagonalx 36 // used in what_target not valid for all megas jps 17mar95 +// used in what_target not valid for all megas jps 17mar95 +#define diagonalx 36 #define diagonaly 8 +int What_target(int startX, int startY, int destX, int destY) { // S2.1(20Jul95JPS) + int deltaX = destX - startX; + int deltaY = destY - startY; -int What_target(int startX, int startY, int destX, int destY) //S2.1(20Jul95JPS) -{ - int tar_dir; -//setting up - int deltaX = destX-startX; - int deltaY = destY-startY; - int signX = (deltaX > 0); - int signY = (deltaY > 0); - int slope; + // 7 0 1 + // 6 2 + // 5 4 3 - if ( (abs(deltaY) * diagonalx ) < (abs(deltaX) * diagonaly / 2)) - { - slope = 0;// its flat - } - else if ( (abs(deltaY) * diagonalx / 2) > (abs(deltaX) * diagonaly ) ) - { - slope = 2;// its vertical - } - else - { - slope = 1;// its diagonal - } + // Flat route - if (slope == 0) //flat - { - if (signX == 1) // going right - { - tar_dir = 2; - } - else - { - tar_dir = 6; - } - } - else if (slope == 2) //vertical - { - if (signY == 1) // going down - { - tar_dir = 4; - } - else - { - tar_dir = 0; - } - } - else if (signX == 1) //right diagonal - { - if (signY == 1) // going down - { - tar_dir = 3; - } - else - { - tar_dir = 1; - } - } - else //left diagonal - { - if (signY == 1) // going down - { - tar_dir = 5; - } - else - { - tar_dir = 7; - } - } - return tar_dir; + if (abs(deltaY) * diagonalx < abs(deltaX) * diagonaly / 2) + return (deltaX > 0) ? 2 : 6; + + // Vertical route + + if (abs(deltaY) * diagonalx / 2 > abs(deltaX) * diagonaly) + return (deltaY > 0) ? 4 : 0; + + // Diagonal route + + if (deltaX > 0) + return (deltaY > 0) ? 3 : 1; + + return (deltaY > 0) ? 5 : 7; } -//-------------------------------------------------------------------------------------- // turn mega to face point (x,y) on the floor -// just needs to call FN_walk() with current feet coords & direction computed by What_target() +// just needs to call FN_walk() with current feet coords & direction computed +// by What_target() -int32 FN_face_xy(int32 *params) // James (29nov96) -{ +int32 FN_face_xy(int32 *params) { // James (29nov96) // params: 0 pointer to object's logic structure - // 1 pointer to object's graphic structure - // 2 pointer to object's mega structure - // 3 pointer to object's walkdata structure - // 4 target x-coord - // 5 target y-coord + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 target x-coord + // 5 target y-coord - Object_logic *ob_logic; - Object_mega *ob_mega; - int32 pars[7]; + Object_logic *ob_logic; + Object_mega *ob_mega; + int32 pars[7]; - //---------------------------------------------------------------------------------------- - // if this is the start of the turn, get the mega's current feet coords + the required direction + // if this is the start of the turn, get the mega's current feet + // coords + the required direction - ob_logic = (Object_logic *)params[0]; + ob_logic = (Object_logic *) params[0]; - if (ob_logic->looping==0) - { - ob_mega = (Object_mega *)params[2]; + if (ob_logic->looping == 0) { + ob_mega = (Object_mega *) params[2]; pars[4] = ob_mega->feet_x; pars[5] = ob_mega->feet_y; - pars[6] = What_target( ob_mega->feet_x, ob_mega->feet_y, params[4], params[5] ); // set target direction + pars[6] = What_target(ob_mega->feet_x, ob_mega->feet_y, params[4], params[5]); } - //---------------------------------------------------------------------------------------- // set up the rest of the parameters for FN_walk() pars[0] = params[0]; @@ -692,102 +576,80 @@ int32 FN_face_xy(int32 *params) // James (29nov96) pars[2] = params[2]; pars[3] = params[3]; - //---------------------------------------------------------------------------------------- - - return FN_walk(pars); // call FN_walk() with target coords set to feet coords + // call FN_walk() with target coords set to feet coords + return FN_walk(pars); } -//-------------------------------------------------------------------------------------- -int32 FN_face_mega(int32 *params) //S2.1(3mar95jps) Tony29Nov96 -{ -//params 0 pointer to object's logic structure -// 1 pointer to object's graphic structure -// 2 pointer to object's mega structure -// 3 pointer to object's walkdata structure - -// 4 id of target mega to face - - uint32 null_pc=3; //get ob_mega - char *raw_script_ad; - int32 pars[7]; - Object_logic *ob_logic; - Object_mega *ob_mega; - _standardHeader *head; - - - ob_mega = (Object_mega *)params[2]; - ob_logic = (Object_logic *)params[0]; +int32 FN_face_mega(int32 *params) { // S2.1(3mar95jps) Tony29Nov96 + // params: 0 pointer to object's logic structure + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 id of target mega to face + + uint32 null_pc = 3; // get ob_mega + char *raw_script_ad; + int32 pars[7]; + Object_logic *ob_logic; + Object_mega *ob_mega; + _standardHeader *head; - if (ob_logic->looping==0) - { + ob_mega = (Object_mega *) params[2]; + ob_logic = (Object_logic *) params[0]; -// get targets info + if (ob_logic->looping == 0) { + // get targets info head = (_standardHeader*) res_man.Res_open(params[4]); - if (head->fileType!=GAME_OBJECT) + + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_face_mega %d not an object", params[4]); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data + raw_script_ad = (char *) head; + + //call the base script - this is the graphic/mouse service call + RunScript(raw_script_ad, raw_script_ad, &null_pc); - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call res_man.Res_close(params[4]); -// engine_mega is now the Object_mega of mega we want to turn to face + // engine_mega is now the Object_mega of mega we want to turn + // to face pars[3] = params[3]; pars[4] = ob_mega->feet_x; pars[5] = ob_mega->feet_y; - pars[6] = What_target( ob_mega->feet_x, ob_mega->feet_y, engine_mega.feet_x, engine_mega.feet_y ); + pars[6] = What_target(ob_mega->feet_x, ob_mega->feet_y, engine_mega.feet_x, engine_mega.feet_y); } - - pars[0] = params[0]; pars[1] = params[1]; pars[2] = params[2]; pars[3] = params[3]; - return FN_walk(pars); // call FN_walk() with target coords set to feet coords - + // call FN_walk() with target coords set to feet coords + return FN_walk(pars); } -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- -//-------------------------------------------------------------------------------------- -// FN_walk (here for reference instead of splitting a window) - - // params: 0 pointer to object's logic structure - // 1 pointer to object's graphic structure - // 2 pointer to object's mega structure - // 3 pointer to object's walkdata structure - // 4 target x-coord - // 5 target y-coord - // 6 target direction -//------------------------------------------------------------------------------------ -int32 FN_walk_to_talk_to_mega(int32 *params) //Tony2Dec96 -{ -//we route to left or right hand side of target id if possible -//target is a shrinking mega - - Object_mega *ob_mega; - Object_logic *ob_logic; - - uint32 null_pc=3; //4th script - get mega - char *raw_script_ad; - int32 pars[7]; - int scale; - int mega_seperation=params[5]; - _standardHeader *head; +int32 FN_walk_to_talk_to_mega(int32 *params) { // Tony2Dec96 + // we route to left or right hand side of target id if possible + // target is a shrinking mega -//params 0 pointer to object's logic structure -// 1 pointer to object's graphic structure -// 2 pointer to object's mega structure -// 3 pointer to object's walkdata structure - -// 4 id of target mega to face -// 5 distance + // params: 0 pointer to object's logic structure + // 1 pointer to object's graphic structure + // 2 pointer to object's mega structure + // 3 pointer to object's walkdata structure + // 4 id of target mega to face + // 5 distance + + Object_mega *ob_mega; + Object_logic *ob_logic; + + uint32 null_pc = 3; // 4th script - get mega + char *raw_script_ad; + int32 pars[7]; + int scale; + int mega_seperation = params[5]; + _standardHeader *head; ob_logic = (Object_logic*) params[0]; ob_mega = (Object_mega*) params[2]; @@ -795,138 +657,144 @@ int32 FN_walk_to_talk_to_mega(int32 *params) //Tony2Dec96 pars[0] = params[0]; // standard stuff pars[1] = params[1]; pars[2] = params[2]; - pars[3] = params[3]; // walkdata - + pars[3] = params[3]; // walkdata - - if (!ob_logic->looping) //not been here before so decide where to walk-to - { -// first request the targets info + // not been here before so decide where to walk-to + if (!ob_logic->looping) { + // first request the targets info head = (_standardHeader*) res_man.Res_open(params[4]); - if (head->fileType!=GAME_OBJECT) + + if (head->fileType != GAME_OBJECT) Con_fatal_error("FN_walk_to_talk_to_mega %d not an object", params[4]); - raw_script_ad = (char *)head; // (head+1) + sizeof(_object_hub); //get to raw script data - RunScript( raw_script_ad, raw_script_ad, &null_pc ); //call the base script - this is the graphic/mouse service call - res_man.Res_close(params[4]); + raw_script_ad = (char *) head; -// engine_mega is now the Object_mega of mega we want to route to + // call the base script - this is the graphic/mouse service + // call + RunScript(raw_script_ad, raw_script_ad, &null_pc); + res_man.Res_close(params[4]); - pars[5] = engine_mega.feet_y; // stand exactly beside the mega, ie. at same y-coord + // engine_mega is now the Object_mega of mega we want to + // route to + // stand exactly beside the mega, ie. at same y-coord + pars[5] = engine_mega.feet_y; -// apply scale factor to walk distance - scale = (ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b)/256; // Ay+B gives 256*scale ie. 256*256*true_scale for even better accuracy, ie. scale = (Ay+B)/256 + // apply scale factor to walk distance + // Ay+B gives 256 * scale ie. 256 * 256 * true_scale for even + // better accuracy, ie. scale = (Ay + B) / 256 - mega_seperation= (mega_seperation*scale)/256; + scale = (ob_mega->scale_a * ob_mega->feet_y + ob_mega->scale_b) / 256; -// Zdebug("seperation %d", mega_seperation); -// Zdebug(" target x %d, y %d", engine_mega.feet_x, engine_mega.feet_y); + mega_seperation= (mega_seperation * scale) / 256; - if (engine_mega.feet_x < ob_mega->feet_x) // target is left of us - { - pars[4] = engine_mega.feet_x+mega_seperation; // so aim to stand to their right - pars[6] = 5; // face down_left - } - else // ok, must be right of us + // Zdebug("seperation %d", mega_seperation); + // Zdebug(" target x %d, y %d", engine_mega.feet_x, engine_mega.feet_y); + + if (engine_mega.feet_x < ob_mega->feet_x) { - pars[4] = engine_mega.feet_x-mega_seperation; // so aim to stand to their left - pars[6] = 3; // face down_right + // Target is left of us, so aim to stand to their + // right. Face down_left + + pars[4] = engine_mega.feet_x + mega_seperation; + pars[6] = 5; + } else { + // Ok, must be right of us so aim to stand to their + // left. Face down_right. + + pars[4] = engine_mega.feet_x - mega_seperation; + pars[6] = 3; } } - //first cycle builds the route - thereafter merely follows it + // first cycle builds the route - thereafter merely follows it - return FN_walk(pars); //call FN_walk() with target coords set to feet coords - //RESULT will be 1 when it finishes or 0 if it failed to build route + // Call FN_walk() with target coords set to feet coords. RESULT will + // be 1 when it finishes, or 0 if it failed to build route. + return FN_walk(pars); } -//------------------------------------------------------------------------------------ -int32 FN_set_walkgrid(int32 *params) // (6dec96 JEL) -{ + +int32 FN_set_walkgrid(int32 *params) { // (6dec96 JEL) Con_fatal_error("FN_set_walkgrid no longer valid"); - return(IR_CONT); // continue script + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- -// add this walkgrid resource to the list of those used for routing in this location -// - note this is ignored in the resource is already in the list -int32 FN_add_walkgrid(int32 *params) // (03mar97 JEL) -{ - // params 0 id of walkgrid resource +// add this walkgrid resource to the list of those used for routing in this +// location - note this is ignored in the resource is already in the list + +int32 FN_add_walkgrid(int32 *params) { // (03mar97 JEL) + // params: 0 id of walkgrid resource - // all objects that add walkgrids must be restarted whenever we reneter a location + // all objects that add walkgrids must be restarted whenever we + // re-enter a location - if (ID != 8) // DON'T EVER KILL GEORGE! - FN_add_to_kill_list(params);// need to call this in case it wasn't called in script! ('params' just used as dummy param) + // DON'T EVER KILL GEORGE! + if (ID != 8) { + // need to call this in case it wasn't called in script! + // ('params' just used as dummy param) + FN_add_to_kill_list(params); + } AddWalkGrid(params[0]); - res_man.Res_open(params[0]); // Touch the grid, getting it into memory. + // Touch the grid, getting it into memory. + res_man.Res_open(params[0]); res_man.Res_close(params[0]); - return(IR_CONT); // continue script + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- -// remove this walkgrid resource from the list of those used for routing in this location -// - note that this is ignored if the resource isn't actually in the list -int32 FN_remove_walkgrid(int32 *params) // (03mar97 JEL) -{ - // params 0 id of walkgrid resource +// remove this walkgrid resource from the list of those used for routing in +// this location - note that this is ignored if the resource isn't actually +// in the list - RemoveWalkGrid(params[0]); +int32 FN_remove_walkgrid(int32 *params) { // (03mar97 JEL) + // params: 0 id of walkgrid resource - return(IR_CONT); // continue script + RemoveWalkGrid(params[0]); + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- -int32 FN_register_walkgrid(int32 *params) -{ + +int32 FN_register_walkgrid(int32 *params) { Con_fatal_error("FN_register_walkgrid no longer valid"); - return(IR_CONT); // continue script + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- -int32 FN_set_scaling(int32 *params) // (6dec96 JEL) -{ - // params 0 pointer to object's mega structure - // 1 scale constant A - // 2 scale constant B - // 256*s = A*y + B +int32 FN_set_scaling(int32 *params) { // (6dec96 JEL) + // params: 0 pointer to object's mega structure + // 1 scale constant A + // 2 scale constant B - // where s is system scale, which itself is (256 * actual_scale) ie. s==128 is half size + // 256 * s = A * y + B + + // where s is system scale, which itself is (256 * actual_scale) ie. + // s == 128 is half size Object_mega *ob_mega = (Object_mega *) params[0]; ob_mega->scale_a = params[1]; ob_mega->scale_b = params[2]; - return(IR_CONT); // continue script + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- -int32 FN_set_standby_coords(int32 *params) // (10dec97 JEL) -{ - // set the standby walk coords to be used by FN_walk_to_anim & FN_stand_after_anim - // when the anim header's start/end coords are zero - // useful during development; can stay in final game anyway +int32 FN_set_standby_coords(int32 *params) { // (10dec97 JEL) + // set the standby walk coords to be used by FN_walk_to_anim & + // FN_stand_after_anim when the anim header's start/end coords are zero - // params 0 x-coord - // 1 y-coord - // 2 direction (0..7) - - //---------------------------------------------------------------------------------------- - // check for invalid direction + // useful during development; can stay in final game anyway - if ((params[2] < 0) || (params[2] > 7)) // invalid direction - Con_fatal_error("Invalid direction (%d) in FN_set_standby_coords (%s line %u)",params[2],__FILE__,__LINE__); + // params: 0 x-coord + // 1 y-coord + // 2 direction (0..7) - //---------------------------------------------------------------------------------------- + if (params[2] < 0 || params[2] > 7) + Con_fatal_error("Invalid direction (%d) in FN_set_standby_coords (%s line %u)", params[2], __FILE__, __LINE__); - standby_x = (int16) params[0]; - standby_y = (int16) params[1]; - standby_dir = (uint8) params[2]; + standby_x = (int16) params[0]; + standby_y = (int16) params[1]; + standby_dir = (uint8) params[2]; - return(IR_CONT); // continue script + return IR_CONT; } -//--------------------------------------------------------------------------------------------------------------------- diff --git a/sword2/walker.h b/sword2/walker.h index 864c239c60..ab7bec0b2f 100644 --- a/sword2/walker.h +++ b/sword2/walker.h @@ -20,15 +20,11 @@ #ifndef _WALKER #define _WALKER -//#include "src\driver96.h" - - - int32 FN_face_mega(int32 *params); int32 FN_turn(int32 *params); -int32 FN_walk(int32 *params); // James (14nov96) -int32 FN_walk_to_anim(int32 *params); // James (14nov96) -int32 FN_stand_after_anim(int32 *params); // James (18jun97) -int32 FN_stand(int32 *params); // James +int32 FN_walk(int32 *params); +int32 FN_walk_to_anim(int32 *params); +int32 FN_stand_after_anim(int32 *params); +int32 FN_stand(int32 *params); #endif |