Here is the reading version of the "Visual C + + adventure game Programming" book and supporting the source code, their own understanding of the book and the source and some of the experience, most of the experience is written in the form of comments in the supporting source codes;
//------------------------------------------------------------------------------------------------------------- -----------------------------
@brief The following code describes how the script compiler collects and processes tag symbols within a single Pass (1 passes)
//------------------------------------------------------------------------------------------------------------- -----------------------------
Login Label//void makescript::addlabel (const char *label) {//The function is called only when the label definition statement is found//This parameter label indicates the label name that is being defined// Iterate through all the tags that appear in the script so far, some of which already know where to define, some that are referenced by multiple instructions, but don't know where to define for (vector<label>::iterator LP = Labels.begin (); Lp<labels.end (); ++LP) {if (Lp->label = = label) {//already logged in//if the label's reference chain is empty, then the label has been defined if (Lp->ref = = NULL) {//label already defined error ("label '%s ' Rede Finition line%d and%d ", label, Lp->line, Reader->getlineno ());} else {//tags are already referenced//if the label's reference chain is not empty, the label is referenced by a number of multiple instructions//here, we traverse all the instructions referencing the tag and reset the label reference of those instructions to//the label's defined position (number of current instructions)// Here, in addition to emptying the label's reference chain, reset the label from referenced to defined labelref *chain = Lp->ref;lp->line = Reader->getlineno (); Set the number of rows for the label lp->ref = NULL; Empty reference chain lp->jmp_addr = Ncommand; Set jump Target (number of current instructions) while (Chain! = NULL) {//clear reference labelref *next = chain->next;//The value of the jump Target data member for all instructions referencing the label is set to the tag's jump target//usually only There are if and goto two instructions that will reference the tag * (chain->label_ref) = Ncommand;delete Chain;chain = Next;}} return;}} Sign in new tab///Login here label, all defined tags//and tags not defined, will be added to the Findlabel function Labels.push_bacK (label, Reader->getlineno (), Ncommand, 0));} Reference label//void Makescript::findlabel (const char *label, long *reference) {//The function is called only when a label label is found to be referenced//parameter reference all saved Pointer to jump target data member of the instruction that references the label label *reference = 0;for (vector<label>::iterator LP = Labels.begin (); Lp<labels.end (); + + LP) {//If a label label is found//Then there are two cases, either the label label has been defined, or the label tag's jump target//is filled into the parameter reference//or the label label is not defined, just forward reference, at this time in The label tag adds a reference itemif (Lp->label = = label) {//is already logged in//in the reference chain for each Item, and a pointer to the jump target data member that holds all the instructions that reference the label label if (lp->ref! = NU LL) {//tags have been referenced//added in the reference string column Lp->ref = new Labelref (lp->ref, reference);} else {//already logged in//if lable has already been defined, the label's jump target is filled directly into the parameter reference//Findlabel function will only be called by the IF Directive and goto instruction//i.e., the parameter reference is The pointer to the data member of the if directive and the jump target of the goto instruction//Backfill jump target *reference = lp->jmp_addr;} return;}} If the label is not found, the label has not been defined, but is referenced only forward//here is no defined label//login new Tag reference labelref *chain = labelref (0, reference); label S.push_back (Label, Reader->getlineno (), 0, chain));}
//------------------------------------------------------------------------------------------------------------- -----------------------------
@brief The following code describes how the script player can coordinate the execution logic of the script instruction with the Windows message loop in a very subtle way
//------------------------------------------------------------------------------------------------------------- -----------------------------
Idle processing//bool cscriptaction::idleaction () {if (status = = Continue) {//"continue" execution//blocking handles all script commands that do not require interaction with the Windows interface///such as CA LC, set, if, goto, etc.//until any one of the graphical commands is processed, the while loop exits//Because the graphics command needs to send graphics-related messages to Windows//and then needs to return from idleaction to the message loop, Windows Have the opportunity to accept the message feedback do {status = Step ();//execute 1 Step} while (status = = Continue);//Continue? When status is Waitnextidle, it is necessary to send a message to Windows//So you must first exit the current Idleaction function and return the execution opportunity to windows//if Idleaction has been running without exiting, then Wi Ndows will not have any chance to accept any message//Therefore, set the status to Continue and then return TRUE to tell the message loop if you have finished processing the message//will continue to make OnIdle call if (status = = Breakgame) {//knot Bundle abort ();} else if (status = = Waitnextidle) {//wait for the next idle again to enter status = continue;//to continue return TRUE;}} If you return FALSE, it means that idleaction does not need to handle more things.//The next time the Windows message is executed, until there is no message processing, then continue to call idleaction//here, if the Step function returns waitkeypress Ed or waitmenudone//Because the next operation needs to interact with the interface, for example, when moving the mouse to determine whether the mouse falls into the menu item//or display text, you need to wait for the player to click the mouse to jump to the scare message, so return to false//let the message loop has the opportunity to be executed/ If FALSE is returned here, then, if there is no message processing, the message loop will be blocked because of the waitmessage//block until any message is generated, the message will be processed if all messages have been processed//the OnIdle function will be called again.Enter here//return TRUE, after the function returns, if there is a message to process, after processing the message, will enter the function//if there is no message processing, do not execute the WaitMessage function in the message loop, the message loop will not be blocked//OnIdle Function will soon get execution opportunity return FALSE;} Event loop (Message loop)//int CWinApp::Run () {bool Idle = True;long count = 0;if (Mainwnd) Mainwnd->showwindow (cmdshow); for (;;) {if (::P eekmessage (&msgcur, NULL, 0, 0, pm_noremove)) {if (!::getmessage (&msgcur, NULL, 0, 0)) return Msgcur.wpara M;if (! PreTranslateMessage (&msgcur)) {:: TranslateMessage (&msgcur);::D ispatchmessage (&msgcur);} Idle = True;count = 0;} else if (idle) {if (! OnIdle (count++)) idle = false;} else {:: WaitMessage ();}}}
--2016-10-17 by Nekodev Cnblogs
--Original technical articles, reproduced please specify the source, and ensure the integrity of the content
Game Development Book "Visual C + + adventure Game Programming (version Chihiro)" Source Code and book notes