Prev: A479 Up: Map Next: A591
A4B0: Handler: User Input
Used by the routine at GameStart.
Handles keyboard input, tokenises commands and validates the vocabulary.
Reset the screen position to defaults.
Handler_UserInput A4B0 CALL PrintPrompt Call PrintPrompt.
A4B3 LD HL,$A109 HL=CommandBuffer.
Initialise the command buffer.
A4B6 LD B,$00 Initialise a letter counter in B.
A4B8 JR UserInput_Next Jump to UserInput_Next.
Main input loop - process each keypress.
UserInput_Loop A4BA INC HL Move to the next byte of the command buffer.
A4BB INC B Increment the letter counter by one.
UserInput_Next A4BC CALL Print_Cursor Call Print_Cursor.
A4BF CALL GetUserInput Call GetUserInput.
A4C2 CP $0C Jump to ValidateUserInput if "DELETE" was not pressed.
A4C4 JR NZ,ValidateUserInput
The user pressed "DELETE".
A4C6 XOR A Jump back to UserInput_Next if there hasn't been any input yet (nothing to delete).
A4C7 OR B
A4C8 JR Z,UserInput_Next
There is input which can be deleted, so action a delete!
A4CA 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.
A4CB LD HL,$A447 HL=Messaging_SpaceBackspaceBackspaceSpaceBackspace.
A4CE CALL PrintString Call PrintString.
Adjust the command buffer position and letter counter.
A4D1 EX DE,HL Restore the command buffer pointer from DE.
A4D2 DEC HL Decrease the command buffer pointer by one.
A4D3 DEC B Decrease the letter counter by one.
A4D4 JR UserInput_Next Jump to UserInput_Next.
Check which key the user pressed:
ValidateUserInput A4D6 LD C,A Jump to UserInput_WriteKeypress if "ENTER" was pressed.
A4D7 CP $0D
A4D9 JR Z,UserInput_WriteKeypress
A4DB 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.
A4DD JR C,UserInput_Next
A4DF CP $80 If the keypress was higher than 80 it's also not valid input so jump back to UserInput_Next.
A4E1 JR NC,UserInput_Next
Is the command buffer full?
A4E3 LD A,B Jump to UserInput_Next if the letter counter is 31 (so the buffer is full).
A4E4 CP $31
A4E6 JR Z,UserInput_Next
Writes the keypress into the command buffer and print it to the screen.
UserInput_WriteKeypress A4E8 LD A,C Write the user input key to *HL.
A4E9 LD (HL),A
A4EA CALL Print_UserInputToScreen Call Print_UserInputToScreen.
Did the user press "ENTER"?
A4ED LD A,C Jump to UserInput_Loop if "ENTER" was not pressed.
A4EE CP $0D
A4F0 JR NZ,UserInput_Loop
The player pressed "ENTER" so begin to process the user input.
Clear down the user input tokens.
A4F2 LD HL,$A13B HL=UserInput_FirstToken.
A4F5 LD B,$0A Set a counter in B for all 0A user input tokens.
EmptyUserInputTokens_Loop A4F7 LD (HL),$FF Write a termination byte (FF) to *HL.
A4F9 INC HL Move HL on to the next user input token.
A4FA 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.
A4FC LD HL,$A109 HL=CommandBuffer.
A4FF LD IX,$A13B IX=UserInput_FirstToken.
A503 LD C,$0A Set a counter in C for the 0A user input tokens.
A505 JR EmptyFourLetterBuffer Jump to EmptyFourLetterBuffer.
Print "Give me a command!".
Response_NotUnderstood A507 LD HL,$0001 HL=Messaging_GiveMeACommand.
A50A CALL PrintCompressedStringAndNewline Call PrintCompressedStringAndNewline.
A50D JP Handler_UserInput Jump to Handler_UserInput.
Copy up to four letters of the current word into FourLetterBuffer.
TokeniseWord A510 PUSH HL Stash HL, DE and BC on the stack.
A511 PUSH DE
A512 PUSH BC
A513 LD HL,($A443) HL=*Pointer_CommandWord.
A516 LD DE,$A145 DE=FourLetterBuffer.
A519 LD BC,$0004 Set BC to 0004 letters at most.
A51C LD A,($A445) Jump to CopyWordToBuffer if *CommandWordLength is at least 04.
A51F CP C
A520 JR NC,CopyWordToBuffer
A522 LD C,A Copy the actual length into C.
CopyWordToBuffer A523 LDIR Copy those letters into FourLetterBuffer.
Restore the registers saved at the start of TokeniseWord.
A525 POP BC Restore BC, DE and HL from the stack.
A526 POP DE
A527 POP HL
Ignore a leading "THE" from Table_Vocabulary_The, then search the main vocabulary at Table_Vocabulary.
A528 PUSH HL Stash the command-buffer pointer on the stack.
A529 LD HL,$9DD2 Point the search at "THE" in Table_Vocabulary_The.
A52C LD ($A47F),HL
A52F CALL Handler_MatchItem Call Handler_MatchItem.
A532 LD HL,$B0ED The next search uses the main vocabulary at Table_Vocabulary.
A535 LD ($A47F),HL
A538 POP HL Restore the command-buffer pointer from the stack.
A539 JR C,EmptyFourLetterBuffer Jump to EmptyFourLetterBuffer if "THE" was matched.
Search the main vocabulary for this word.
A53B CALL Handler_MatchItem Call Handler_MatchItem.
A53E JR C,StoreTokenAndContinue Jump to StoreTokenAndContinue if the word matched.
The word is not in the vocabulary.
Print "Try another command.".
A540 LD HL,$0002 HL=Messaging_TryAnotherCommand.
A543 CALL PrintCompressedStringAndNewline Call PrintCompressedStringAndNewline.
A546 JP Handler_UserInput Jump to Handler_UserInput.
Store the token and stop after 0A tokens.
StoreTokenAndContinue A549 LD (IX+$00),A Write the token to the current token slot at UserInput_FirstToken.
A54C INC IX Move to the next token slot.
A54E DEC C Decrease the token counter by one.
A54F JR Z,CheckVerbToken Jump to CheckVerbToken if all token slots are filled.
Clear the four-letter buffer to spaces so a short word cannot match the previous one's tail.
EmptyFourLetterBuffer A551 PUSH HL Stash HL and BC on the stack.
A552 PUSH BC
A553 LD HL,$A145 HL=FourLetterBuffer.
A556 LD B,$04 Set a counter in B for the 04 letters.
EmptyFourLetterBuffer_Loop A558 LD (HL),$20 Write a space character (20) to the buffer.
A55A INC HL Move to the next letter.
A55B DJNZ EmptyFourLetterBuffer_Loop Decrease the counter by one and loop back to EmptyFourLetterBuffer_Loop until the counter is zero.
A55D POP BC Restore BC and HL from the stack.
A55E POP HL
Find the next word. ENTER finishes the command, and IsDelimiter marks a gap between words.
A55F PUSH DE Stash DE on the stack.
A560 JR FindWordStart Jump to FindWordStart.
SkipDelimiter A562 INC HL Move to the next character.
FindWordStart A563 LD A,(HL) Fetch the character at *HL into A.
A564 CP $0D Jump to EndWordParsing if the character is ENTER (0D).
A566 JR Z,EndWordParsing
A568 CALL IsDelimiter Call IsDelimiter.
A56B JR Z,SkipDelimiter Jump to SkipDelimiter if the character is a delimiter.
Remember where this word starts and how long it is, then tokenise it.
A56D LD ($A443),HL Store the starting address of this word in *Pointer_CommandWord.
A570 LD DE,$0000 Initialise DE to 0000 to count the letters.
MeasureWord A573 INC HL Move to the next character.
A574 INC DE Increment the letter counter by one.
A575 LD A,(HL) Fetch the character at *HL into A.
A576 CP $0D Jump to MeasureWord_Store if the character is ENTER (0D).
A578 JR Z,MeasureWord_Store
A57A CALL IsDelimiter Call IsDelimiter.
A57D JR NZ,MeasureWord Jump to MeasureWord if the character was not a delimiter.
MeasureWord_Store A57F LD ($A445),DE Store the length at CommandWordLength.
A583 SCF Set the carry flag to show a word was found.
Tokenise the word that was just measured.
EndWordParsing A584 POP DE Restore DE from the stack.
A585 JP C,TokeniseWord Jump to TokeniseWord if another word was found.
Check whether any token was stored; if not, the command was not understood.
CheckVerbToken A588 LD A,($A13B) Jump to Response_NotUnderstood if *UserInput_FirstToken holds the terminator byte (FF).
A58B CP $FF
A58D JP Z,Response_NotUnderstood
A590 RET Return.
Prev: A479 Up: Map Next: A591