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_Token_1.
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_Token_1.
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!".
Handler_UserInput_0 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 The command scan waits.
A511 PUSH DE
A512 PUSH BC
A513 LD HL,($A443) The word starts at the address in Pointer_CommandWord, and lands in FourLetterBuffer.
A516 LD DE,$A145
A519 LD BC,$0004 Four letters is the most a word contributes.
A51C LD A,($A445) A shorter word copies only as many letters as CommandWordLength holds.
A51F CP C
A520 JR NC,Handler_UserInput_1
A522 LD C,A
Handler_UserInput_1 A523 LDIR Copy those letters into FourLetterBuffer.
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 Point the search at "THE" in Table_Vocabulary_The.
A529 LD HL,$9DD2
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.
The word is in the vocabulary.
A53B CALL Handler_MatchItem Jump to StoreTokenAndContinue if the word matched.
A53E JR C,StoreTokenAndContinue
The word is not in the vocabulary.
A540 LD HL,$0002 Print "Try another command." and read the command again.
A543 CALL PrintCompressedStringAndNewline
A546 JP Handler_UserInput
Store the token and stop after 0A tokens.
StoreTokenAndContinue A549 LD (IX+$00),A The token buffer at UserInput_Token_1 holds the words understood so far.
A54C INC IX
A54E DEC C
A54F JR Z,Handler_UserInput_5
Clear the four-letter buffer to spaces before the next word.
EmptyFourLetterBuffer A551 PUSH HL Clear the four-letter buffer to spaces so a short word cannot match the previous one's tail.
A552 PUSH BC
A553 LD HL,$A145
A556 LD B,$04
Handler_UserInput_2 A558 LD (HL),$20
A55A INC HL
A55B DJNZ Handler_UserInput_2
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 Start at this character.
A560 JR Handler_UserInput_3
SkipDelimiter A562 INC HL The next character.
Handler_UserInput_3 A563 LD A,(HL) ENTER finishes the command.
A564 CP $0D
A566 JR Z,Handler_UserInput_4
A568 CALL IsDelimiter Call IsDelimiter.
A56B JR Z,SkipDelimiter Skip the gap and keep looking.
Remember where this word starts and how long it is, then tokenise it.
A56D LD ($A443),HL Remember where this word starts.
A570 LD DE,$0000
MeasureWord A573 INC HL Count this letter.
A574 INC DE
A575 LD A,(HL) ENTER ends the word.
A576 CP $0D
A578 JR Z,MeasureWord_Store
A57A CALL IsDelimiter Call IsDelimiter.
A57D JR NZ,MeasureWord A gap has not been reached yet.
MeasureWord_Store A57F LD ($A445),DE Store the length at CommandWordLength.
A583 SCF The word is ready to tokenise.
Tokenise the word that was just measured.
Handler_UserInput_4 A584 POP DE Restore the command-scan pointer from the stack.
A585 JP C,TokeniseWord Jump to TokeniseWord if another word was found.
Nothing was understood.
Handler_UserInput_5 A588 LD A,($A13B) Jump to Handler_UserInput_0 if no token was stored.
A58B CP $FF
A58D JP Z,Handler_UserInput_0
A590 RET Return.
View the equivalent code in;
Prev: A479 Up: Map Next: A591