Prev: F335 Up: Map Next: F408
F350: Choose keys
This wipes the game window, sets its attributes, draws prompts, then sits in a loop waiting for the player to make their key choices. The chosen keys (defined by port and mask) are stored in the table at keydefs. Finally the user is asked to confirm their key choices.
Used by the routine at check_menu_keys.
Start loop (infinite) - loops until the user confirms the key selection.
Clear the game window.
choose_keys F350 CALL wipe_game_window Wipe the game screen
F353 LD A,$07 Set game window attributes to attribute_WHITE_OVER_BLACK
F355 CALL set_game_window_attributes
Draw key choice prompts.
F358 LD B,$06 Set B for six iterations
F35A LD HL,$F2AD Point HL at define_key_prompts
Start loop (once per prompt)
ck_prompts_loop F35D PUSH BC Preserve the loop counter
F35E LD E,(HL) Read screen address
F35F INC HL
F360 LD D,(HL)
F361 INC HL
F362 LD B,(HL) Read string length
F363 INC HL
Draw the prompt's glyphs.
Start loop (once per character)
ck_draw_prompt F364 PUSH BC Preserve string length
Bug: The next load is needless (plot_glyph does it already).
F365 LD A,(HL) Read a glyph
F366 CALL plot_glyph Plot a single glyph (indirectly)
F369 INC HL Advance the string pointer
F36A POP BC Restore string length
F36B DJNZ ck_draw_prompt ...loop (once per character)
F36D POP BC Restore the loop counter
F36E DJNZ ck_prompts_loop ...loop (once per prompt)
Wipe key definitions.
F370 LD HL,$F06B Point HL at keydefs
F373 LD B,$0A Set B for 10 iterations
F375 XOR A Zero A in preparation
Start loop
ck_clear_keydef F376 LD (HL),A Zero a byte of keydef
F377 INC HL Advance HL
F378 DJNZ ck_clear_keydef ...loop
Now scan for keys.
F37A LD B,$05 Set B for five iterations: left/right/up/down/fire
F37C LD HL,$F32B Point HL at key_name_screen_addrs
Start loop (once per direction+fire)
ck_keyscan_loop F37F PUSH BC Preserve the loop counter
F380 LD E,(HL) Read screen address
F381 INC HL
F382 LD D,(HL)
F383 INC HL
F384 PUSH HL Preserve screen address
F385 LD ($F3E9),DE Self modify the "LD DE,$xxxx" at ck_plot_glyph to load the screen address
F389 LD A,$FF Set the debounce flag. This is only set to zero once we've checked the whole keyboard and no keys are pressed, at which point it gets set to zero
Start loop (infinite)
ck_keyscan_inner F38B EX AF,AF' Bank the debounce flag
F38C LD HL,$F2E1 Point HL at keyboard_port_hi_bytes[-1]
F38F LD D,$FF Initialise the port index
Start loop
ck_try_next_port F391 INC HL Advance HL to the next port high byte
F392 INC D Increment the port index
F393 LD A,(HL) Read the port high byte
F394 OR A Have we reached the end of keyboard_port_hi_bytes? ($00)
F395 JR Z,ck_keyscan_inner ...loop if so (zero in A becomes new debounce flag)
F397 LD B,A Read port high byte
F398 LD C,$FE Read port $FE
F39A IN A,(C) Read the keyboard port
F39C CPL Invert the bits to turn active low into active high
F39D LD E,A Copy the result into E so we can restore it each time
F39E LD C,$20 Create a mask with bit 5 set
Test bits 4,3,2,1,0
ck_keyscan_detect F3A0 SRL C Shift the mask right
F3A2 JR C,ck_try_next_port Jump (to try next port) if the mask bit got shifted out
F3A4 LD A,C Mask the result
F3A5 AND E
F3A6 JR Z,ck_keyscan_detect ...loop while no keys are pressed
We arrive here if a key was pressed.
F3A8 EX AF,AF' Unbank the debounce flag
F3A9 OR A Is it set?
F3AA JR NZ,ck_keyscan_inner Restart the loop if so (A is debounce flag)
F3AC LD A,D Bank the port index
F3AD EX AF,AF'
F3AE LD HL,$F06A Point HL at the byte before keydefs
Start loop
ck_next_keydef F3B1 INC HL Advance to the next keydef
F3B2 LD A,(HL) Read the keydef.port
F3B3 OR A Is it an empty slot?
F3B4 JR Z,ck_assign_keydef Jump if so (assign keydef)
F3B6 CP B Does the port high byte match?
F3B7 INC HL Advance HL (interleaved)
F3B8 JR NZ,ck_next_keydef ...loop if different
F3BA LD A,(HL) Read keydef.mask
F3BB CP C Does the mask match?
F3BC JR NZ,ck_next_keydef ...loop if different
F3BE JP ck_keyscan_inner ...loop (infinite) (mask in A becomes new debounce flag)
Assign key definition.
ck_assign_keydef F3C1 LD (HL),B Store port
F3C2 INC L
F3C3 LD (HL),C Store mask
F3C4 EX AF,AF' Unbank the port index
F3C5 LD B,A Multiply it by 5
F3C6 ADD A,A
F3C7 ADD A,A
F3C8 ADD A,B
F3C9 LD HL,$F302 Point HL one byte prior to keycode_to_glyph. This is off-by-one to compensate for the upcoming preincrement
F3CC ADD A,L Combine
F3CD LD L,A
F3CE JR NC,ck_find_key_glyph
F3D0 INC H
Skip entries until the mask carries out.
ck_find_key_glyph F3D1 INC HL Advance the glyph pointer
F3D2 RR C Shift mask
F3D4 JR NC,ck_find_key_glyph ...loop until the mask carries out
F3D6 LD B,$01 Set length to 1
F3D8 LD A,(HL) Load the glyph
F3D9 OR A Test the top bit
F3DA JP P,ck_plot_glyph Jump if clear (JP P => positive)
If the top bit was set then it's a special key, like SPACE or ENTER.
F3DD AND $7F Extract the byte offset into special_key_names
F3DF LD DE,$F2EB Point DE at special_key_names
F3E2 LD L,A Widen byte offset into HL
F3E3 LD H,$00
F3E5 ADD HL,DE Combine
F3E6 LD B,(HL) First byte is length of special key name
F3E7 INC HL Advance HL to point at glyphs
Plot.
ck_plot_glyph F3E8 LD DE,$40D5 Point DE at (a self modified screen address)
Start loop (draw key)
ck_plot_glyph_loop F3EB PUSH BC Preserve the loop counter
Bug: The next load is needless (plot_glyph does it already).
F3EC LD A,(HL) Read a glyph
F3ED CALL plot_glyph Plot a single glyph (indirectly)
F3F0 INC HL Advance to next glyph index
F3F1 POP BC Restore the loop counter
F3F2 DJNZ ck_plot_glyph_loop ...loop (draw key)
F3F4 POP HL Restore screen address
F3F5 POP BC Restore the loop counter
F3F6 DEC B ...loop (once per direction+fire)
F3F7 JR NZ,ck_keyscan_loop
Delay loop.
This delays execution by approximately a third of a second (~1.25M T-states).
F3F9 LD BC,$FFFF Set BC to $FFFF
ck_delay F3FC DEC BC Count down until it's zero
F3FD LD A,B
F3FE OR C
F3FF JR NZ,ck_delay
Wait for the user's confirmation.
F401 CALL user_confirm Wait for the user to confirm by pressing 'Y' or 'N'
F404 RET Z If Z set 'Y' was pressed so return
F405 JP NZ,choose_keys ...loop (infinite)
Prev: F335 Up: Map Next: F408