-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput.s
201 lines (190 loc) · 4.09 KB
/
input.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
.include "global.inc"
.export readcontroller
.export handle_input
.segment "ZEROPAGE"
input_result: .res 1
.segment "CODE"
.proc handle_input
lda controller1release
and #%10000000 ; a
beq check_movement
jmp handle_action
check_movement:
; update player pos to memory
lda mobs + Mob::coords + Coord::xcoord
sta xpos
lda mobs + Mob::coords + Coord::ycoord
sta ypos
; handle player movement
lda controller1release
and #%00000010 ; left
bne attempt_left
lda controller1release
and #%00000001 ; right
bne attempt_right
lda controller1release
and #%00000100 ; down
bne attempt_down
lda controller1release
and #%00001000 ; up
bne attempt_up
; no input
lda #InputResult::none
rts
attempt_left:
dec xpos
; update player direction
lda #Direction::left
sta mobs + Mob::direction
jsr attempt_move
rts
attempt_right:
inc xpos
lda #Direction::right
sta mobs + Mob::direction
jsr attempt_move
rts
attempt_down:
inc ypos
lda #Direction::down
sta mobs + Mob::direction
jsr attempt_move
rts
attempt_up:
dec ypos
lda #Direction::up
sta mobs + Mob::direction
jsr attempt_move
rts
.endproc
; handle a button
; returns InputResult for handling of input
.proc handle_action
check_dstair:
ldx mobs + Mob::coords + Coord::xcoord
ldy mobs + Mob::coords + Coord::ycoord
cpx down_x
bne check_upstair
cpy down_y
bne check_upstair
; on downstair, generate new level
inc dlevel
lda dlevel
cmp #10 ; todo custom win condition
beq win
lda #InputResult::new_dlevel
rts
check_upstair:
ldx mobs + Mob::coords + Coord::xcoord
lda mobs + Mob::coords + Coord::ycoord
cpx up_x
bne input_done
cpy up_y
bne input_done
; on upstair, generate new level
dec dlevel
lda dlevel
cmp #0
beq escape
lda #InputResult::new_dlevel
rts
escape:
; escape dungeon
lda #InputResult::escape
rts
win:
; win dungeon
lda #InputResult::win
rts
input_done:
lda #InputResult::none
rts
.endproc
; attempt move at xpos, ypos
; returns InputResult for handling of input
.proc attempt_move
jsr within_bounds
beq do_move
lda #InputResult::none
rts
do_move:
jsr mob_at
beq attack_mob
jsr is_passable
bne input_done
; move successful
lda xpos
sta mobs+Mob::coords+Coord::xcoord
lda ypos
sta mobs+Mob::coords+Coord::ycoord
lda #InputResult::move
rts
attack_mob:
; use damage calc for player
jsr player_dmg
tax ; preserve for messaging
jsr damage_mob
; if dead, push kill message
jsr is_alive
bne mob_killed
; push damage message, uses x register above
lda #Messages::hit
jsr push_msg
; done
lda #InputResult::attack
rts
mob_killed:
tya
pha
; push damage message, uses x register above
lda #Messages::hit
jsr push_msg
; push kill message
lda #Messages::kill
jsr push_msg
; award exp
pla
tay
jsr award_exp
; done
lda #InputResult::attack
rts
input_done:
lda #InputResult::none
rts
.endproc
.proc readcontroller
; previous controller1 state
ldx controller1
; tell CPU we're reading controller
lda #$01
sta $4016
; store a single bit in controller 1
sta controller1
; reset latching so we can read all buttons
lsr a
sta $4016
controllerloop:
lda $4016
lsr a
; carry will be 1 when bit from above is rotated off
rol controller1
bcc controllerloop
readreleased:
; figure out released buttons between x and controller1
; see: released.txt for example states
;
; first, we EOR previous controller state with new state
txa
eor controller1
; now, store the EOR'ed state to var
sta controller1release
; now, we have to AND the stored var with previous state
; this will *only* set the bit if the button was in previous
; state, and not in new state due to EOR
txa
and controller1release
sta controller1release
; done!
rts
.endproc