diff options
Diffstat (limited to 'sword2/speech.cpp')
-rw-r--r-- | sword2/speech.cpp | 2672 |
1 files changed, 1186 insertions, 1486 deletions
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; } } -//------------------------------------------------------------------------------------ |