![]() |
Routines |
Prev: ACFB | Up: Map | Next: AE36 |
Used by the routine at GameLoop.
Handles keyboard input, tokenises commands and validates the vocabulary.
|
||||
Reset the screen position to defaults.
|
||||
Handler_UserInput | AD32 | CALL SetDefaultScreenPosition | Call SetDefaultScreenPosition. | |
AD35 | CALL PrintInputPrompt | Call PrintInputPrompt. | ||
Initialise the command buffer.
|
||||
AD38 | LD HL,$A7F2 | HL=CommandBuffer. | ||
AD3B | LD B,$00 | Initialise a letter counter in B. | ||
AD3D | JR UserInput_Next | Jump to UserInput_Next. | ||
Main input loop - process each keypress.
|
||||
UserInput_Loop | AD3F | INC HL | Move to the next byte of the command buffer. | |
AD40 | INC B | Increment the letter counter by one. | ||
UserInput_Next | AD41 | CALL Print_Cursor | Call Print_Cursor. | |
AD44 | CALL GetUserInput | Call GetUserInput. | ||
AD47 | CP $0C | Jump to ValidateUserInput if "DELETE" was not pressed. | ||
AD49 | JR NZ,ValidateUserInput | |||
The user pressed "DELETE".
|
||||
AD4B | XOR A | Jump back to UserInput_Next if there hasn't been any input yet (nothing to delete). | ||
AD4C | OR B | |||
AD4D | JR Z,UserInput_Next | |||
There is input which can be deleted, so action a delete!
|
||||
AD4F | EX DE,HL | Temporarily stash the command buffer pointer in DE. | ||
Print "SPACE BACKSPACE BACKSPACE SPACE BACKSPACE" to move the current print position on the screen to the previous character, and to delete the character present using a space.
|
||||
AD50 | LD HL,$ACC6 | HL=Messaging_SpaceBackspaceBackspaceSpaceBackspace. | ||
AD53 | CALL PrintString | Call PrintString. | ||
Adjust the command buffer position and letter counter.
|
||||
AD56 | EX DE,HL | Restore the command buffer pointer from DE. | ||
AD57 | DEC HL | Decrease the command buffer pointer by one. | ||
AD58 | DEC B | Decrease the letter counter by one. | ||
AD59 | JR UserInput_Next | Jump to UserInput_Next. | ||
Check which key the user pressed:
|
||||
ValidateUserInput | AD5B | LD C,A | Jump to UserInput_WriteKeypress if "ENTER" was pressed. | |
AD5C | CP $0D | |||
AD5E | JR Z,UserInput_WriteKeypress | |||
AD60 | CP $20 | If the keypress was any other control key (the value being under 20 ASCII "SPACE"), it's not valid input so jump back to UserInput_Next. | ||
AD62 | JR C,UserInput_Next | |||
AD64 | CP $80 | If the keypress was higher than 80 it's also not valid input so jump back to UserInput_Next. | ||
AD66 | JR NC,UserInput_Next | |||
Is the command buffer full?
|
||||
AD68 | LD A,B | Jump to UserInput_Next if the letter counter is 31 (so the buffer is full). | ||
AD69 | CP $31 | |||
AD6B | JR Z,UserInput_Next | |||
Writes the keypress into the command buffer and print it to the screen.
|
||||
UserInput_WriteKeypress | AD6D | LD A,C | Write the user input key to *HL. | |
AD6E | LD (HL),A | |||
AD6F | CALL Print_UserInputToScreen | Call Print_UserInputToScreen. | ||
Did the user press "ENTER"?
|
||||
AD72 | LD A,C | Jump to UserInput_Loop if "ENTER" was not pressed. | ||
AD73 | CP $0D | |||
AD75 | JR NZ,UserInput_Loop | |||
The player pressed "ENTER" so begin to process the user input.
Clear down the user input tokens.
|
||||
AD77 | LD HL,$A824 | HL=UserInput_Token_1. | ||
AD7A | LD B,$0A | Set a counter in B for all 0A user input tokens. | ||
EmptyUserInputTokens_Loop | AD7C | LD (HL),$FF | Write a termination byte (FF) to *HL. | |
AD7E | INC HL | Increment HL by one. | ||
AD7F | DJNZ EmptyUserInputTokens_Loop | Decrease the user input tokens counter by one and loop back to EmptyUserInputTokens_Loop until all the tokens have been set to termination bytes (FF). | ||
Set up pointers for the command buffer, the user input tokens and the count of the number of user input tokens.
|
||||
AD81 | LD HL,$A7F2 | HL=CommandBuffer. | ||
AD84 | LD IX,$A824 | IX=UserInput_Token_1. | ||
AD88 | LD C,$0A | Set a counter in C for the 0A user input tokens. | ||
AD8A | JR EmptyFourLetterBuffer | Jump to EmptyFourLetterBuffer. | ||
What's been entered isn't parsable.
Print "I don't understand.".
|
||||
Response_NotUnderstood | AD8C | LD HL,$A84F | HL=Messaging_IDontUnderstand. | |
AD8F | CALL PrintStringAndNewline | Call PrintStringAndNewline. | ||
AD92 | JP Handler_UserInput | Jump to Handler_UserInput. | ||
Process found word into user input token.
|
||||
ProcessFoundWord | AD95 | PUSH HL | Stash the command buffer pointer, DE and user input tokens counter on the stack. | |
AD96 | PUSH DE | |||
AD97 | PUSH BC | |||
AD98 | LD HL,($ACC2) | HL=*TempStore_CommandBufferPointer. | ||
AD9B | LD DE,$A82F | DE=FourLetterBuffer. | ||
Ensure that the length is not more than 04.
|
||||
AD9E | LD BC,$0004 | BC=0004. | ||
ADA1 | LD A,($ACC4) | Jump to CopyWordToBuffer if *TempStore_CommandBufferCount is greater than or equal to 04. | ||
ADA4 | CP C | |||
ADA5 | JR NC,CopyWordToBuffer | |||
The length is less than 04 so no need to copy 04 bytes.
|
||||
ADA7 | LD C,A | Copy the actual length of the word into C. | ||
Copy the word (up to 04 characters in length) into the four letter buffer.
|
||||
CopyWordToBuffer | ADA8 | LDIR | Copy the "up-to-04" letters from the command buffer into the four-letter buffer. | |
ADAA | POP BC | Restore the user input token counter, DE and command buffer pointer from the stack. | ||
ADAB | POP DE | |||
ADAC | POP HL | |||
ADAD | PUSH HL | Stash the command buffer pointer back on the stack. | ||
Stash the vocabulary pointer for a separate check...
|
||||
ADAE | LD HL,($A7C6) | Stash *Pointer_Vocabulary on the stack. | ||
ADB1 | PUSH HL | |||
Ignore any usage of "THE" - this is a very good idea! If the player enters: "EXAMINE THE SKULL", this ensures it's evaluated in the exact same way as "EXAMINE SKULL" (or really, "EXAM SKUL").
|
||||
ADB2 | LD HL,$A667 | Write Table_Vocabulary_The to *Pointer_Vocabulary. | ||
ADB5 | LD ($A7C6),HL | |||
ADB8 | CALL Handler_MatchItem | Call Handler_MatchItem. | ||
Do nothing with with this match - just restore the vocabulary pointer from the stack.
|
||||
ADBB | POP HL | Restore *Pointer_Vocabulary from the stack and write it back to *Pointer_Vocabulary. | ||
ADBC | LD ($A7C6),HL | |||
ADBF | POP HL | Restore HL from the stack. | ||
ADC0 | JR C,EmptyFourLetterBuffer | Jump to EmptyFourLetterBuffer if "THE" was successfully found. | ||
ADC2 | CALL Handler_MatchItem | Call Handler_MatchItem. | ||
ADC5 | JR C,StoreTokenAndContinue | Jump to StoreTokenAndContinue if an item was successfully found. | ||
Nothing matched ... Inform the player.
Print "I don't know the word:-".
|
||||
ADC7 | LD HL,$A863 | HL=Messaging_IDontKnowTheWord. | ||
ADCA | CALL PrintStringAndNewline | Call PrintStringAndNewline. | ||
Print a double quote character: "
" ".
|
||||
ADCD | LD A,$22 | Call PrintCharacter to print a double quote character (ASCII 22). | ||
ADCF | CALL PrintCharacter | |||
ADD2 | LD HL,($ACC4) | HL=*TempStore_CommandBufferCount. | ||
ADD5 | LD DE,($ACC2) | HL+=*TempStore_CommandBufferPointer. | ||
ADD9 | ADD HL,DE | |||
ADDA | LD (HL),$FF | Write FF to *HL. | ||
ADDC | EX DE,HL | Exchange the DE and HL registers. | ||
ADDD | CALL PrintString | Call PrintString. | ||
Print a double quote character: "
" ".
|
||||
ADE0 | LD A,$22 | Call PrintCharacter to print another double quote character (ASCII 22). | ||
ADE2 | CALL PrintCharacter | |||
Print ".".
|
||||
ADE5 | LD HL,$AA15 | HL=Messaging_FullStop. | ||
ADE8 | CALL PrintStringAndNewline | Call PrintStringAndNewline. | ||
ADEB | JP Handler_UserInput | Jump to Handler_UserInput. | ||
The word in the four-letter buffer was matched!
Store the found token and check if we can continue parsing.
|
||||
StoreTokenAndContinue | ADEE | LD (IX+$00),A | Write the token to the current token slot. | |
ADF1 | INC IX | Move to the next token slot. | ||
ADF3 | DEC C | Decrease the token counter by one. | ||
ADF4 | JR Z,CheckVerbToken | Jump to CheckVerbToken if all token slots are filled. | ||
Token matching only uses four letters of every word so a buffer is used for processing.
Start by clearing the buffer.
|
||||
EmptyFourLetterBuffer | ADF6 | PUSH HL | Stash the command buffer pointer and user input tokens counter on the stack. | |
ADF7 | PUSH BC | |||
ADF8 | LD HL,$A82F | Load FourLetterBuffer into HL. | ||
ADFB | LD B,$04 | Set a counter in B for the 04 letters in the buffer. | ||
EmptyFourLetterBuffer_Loop | ADFD | LD (HL),$20 | Write ASCII "SPACE" (20) to *HL. | |
ADFF | INC HL | Increment HL by one. | ||
AE00 | DJNZ EmptyFourLetterBuffer_Loop | Decrease the letter buffer counter by one and loop back to EmptyFourLetterBuffer_Loop until all four letters have been cleared. | ||
AE02 | POP BC | Restore the user input tokens counter and command buffer pointer from the stack. | ||
AE03 | POP HL | |||
AE04 | PUSH DE | Stash DE on the stack. | ||
AE05 | JR FindWordStart | Jump to FindWordStart. | ||
Skip delimiter characters to find the next word.
|
||||
SkipDelimiters | AE07 | INC HL | Move to the next byte of the command buffer. | |
FindWordStart | AE08 | LD A,(HL) | Fetch a character from the command buffer. | |
AE09 | CP $0D | Jump to EndWordParsing if the character is "ENTER" (ASCII 0D). | ||
AE0B | JR Z,EndWordParsing | |||
AE0D | CALL IsDelimiter | Call IsDelimiter. | ||
AE10 | JR Z,SkipDelimiters | Jump to SkipDelimiters if the character is a delimiter. | ||
The character is not a delimiter.
|
||||
AE12 | LD ($ACC2),HL | Store the starting address of this new word in *TempStore_CommandBufferPointer. | ||
AE15 | LD DE,$0000 | Initialise DE to 0000 to count the number of letters in the word. | ||
Just keep looping and moving across the command buffer until we hit a delimiter or an "ENTER" character.
|
||||
CountWordLength | AE18 | INC HL | Move to the next byte of the command buffer. | |
AE19 | INC DE | Increment the letter counter by one. | ||
AE1A | LD A,(HL) | Fetch a character from the command buffer. | ||
AE1B | CP $0D | Jump to StoreWordLength if the character is "ENTER" (ASCII 0D). | ||
AE1D | JR Z,StoreWordLength | |||
AE1F | CALL IsDelimiter | Call IsDelimiter. | ||
AE22 | JR NZ,CountWordLength | Jump to CountWordLength if the character was not a delimiter. | ||
This is the end of the word, so store the word length.
|
||||
StoreWordLength | AE24 | LD ($ACC4),DE | Write the letter counter to *TempStore_CommandBufferCount. | |
AE28 | SCF | Set the carry flag to indicate that a word was successfully found. | ||
EndWordParsing | AE29 | POP DE | Restore DE from the stack. | |
AE2A | JP C,ProcessFoundWord | Jump to ProcessFoundWord if a word was found. | ||
Check to see if any of the user input tokens have been populated, and if not, print "I don't understand.".
|
||||
CheckVerbToken | AE2D | LD A,($A824) | Jump to Response_NotUnderstood if *UserInput_Token_1 hold the terminator byte (FF). | |
AE30 | CP $FF | |||
AE32 | JP Z,Response_NotUnderstood | |||
AE35 | RET | Return. | ||
View the equivalent code in The Jewels Of Babylon.
|
Prev: ACFB | Up: Map | Next: AE36 |