View difference between Paste ID: LTmnYhTx and DSucjLTg
SHOW: | | - or go back to the newest paste.
1
2
TILE_BLACK EQU $10
3
4
DIR_UP    EQU 0
5
DIR_DOWN  EQU 1
6
DIR_LEFT  EQU 2
7
DIR_RIGHT EQU 3
8
9
UP_KEY   EQU 6
10
DOWN_KEY EQU 7
11-
Pong:
11+
12
; Since this code will run in the enemy party data, 0x739 must be added to each absolute address
13-
; uncomment if not in bank f (i.e. used buffer overflow RCE exploit in trade center)
13+
14-
;	ld a, $0f
14+
; D17C
15-
;	ld ($2000), a	
15+
16
; draw bg, horizontal walls, and vertical voids
17
	call DrawBackground
18
	call DrawVoids
19
; refresh player pad	
20
	ld hl, wTileMap
21
	ld a, [wPad1Offset]	
22
	call DrawPadFromOffset
23
; refresh enemy pad	
24
	ld hl, wTileMap + 19
25
	ld a, [wPad2Offset]
26
	call DrawPadFromOffset
27
; refresh ball	
28
	ld hl, wTileMap
29
	ld a, [wBallCoordX]
30
	ld e, a
31
	ld d, 0
32
	add hl, de
33
	ld a, [wBallCoordY]
34
	ld bc, 20
35
	call AddNTimes
36
;	xor a
37
	ld [hl], a
38
	ret
39
	
40
DrawBackground:
41
	ld hl, wTileMap	
42
	call .drawWall
43
	ld a, TILE_BLACK	
44
	ld bc, 20 * (18 - 2)
45
	call FillMemory
46
;	jr .drawWall
47
.drawWall
48
	ld bc, 20
49
	xor a
50
	jp FillMemory
51
	
52
DrawVoids:
53
	ld hl, wTileMap + 20 * 1
54
	call DrawFullVerticalBlackLine
55
	ld hl, wTileMap + 20 * 1 + 19
56
;	jr DrawFullVerticalBlackLine
57
58
DrawFullVerticalBlackLine:
59
	ld a, TILE_BLACK
60
	ld e, 16
61
DrawVerticalLine:
62
; hl = start address
63
; e = how many tiles
64
; a = tile
65
	ld bc, 20
66
.loop
67
	ld [hl], a
68
	add hl, bc
69
	dec e
70
	ret z
71
	jr .loop
72
	
73
DrawPadFromOffset:
74
	ld bc, 20
75
	call AddNTimes
76
	xor a
77
	ld e, 4
78
	jr DrawVerticalLine
79
	
80
_ldahl_cp16:	
81
	ld a, [hl]
82
	cp 16
83
	ret
84
	
85
_ldahl_cp18:	
86
	ld a, [hl]
87
	cp 18
88
	ret
89
	
90
_cp13_retz_inca:	
91
	cp 17 - 4
92
	ret z
93
	inc a
94
	ret ; this always returns nz
95
	
96
	ds 3
97
98
; Entry Point: D1EF
99
; I derped and saved three bytes for a bootstrap jump, but this is the entry point!
100
	db 0, 0, 0
101
Pong: ; D1F2
102
	call ClearScreen
103
.waitingLoop
104
	ld a, $ff
105
	ld [wSerialExchangeNybbleReceiveData], a
106
	call PlaySound ; mute music
107
	ld a, 12
108
	call LinkBattleExchangeData_PrintWaiting_ExchangeNybbles
109
	ld a, [wSerialExchangeNybbleReceiveData]
110
	cp 12
111
	jr nz, .waitingLoop
112
113
; load the black tiles to VRAM
114
	di
115
.waitVblank
116
	ldh a, [rSTAT]	
117
	cp $81
118
	jr nz, .waitVblank
119
	ld hl, $9100
120
	ld bc, $16 * 3
121
	ld a, $ff
122
	call FillMemory
123
	ei
124
	
125
.newGame
126
; init game params
127
	ld hl, wPad1Offset
128
	ld a, 7
129
	ld [hli], a ; wPad1Offset
130
	ld [hli], a ; wPad2Offset
131
	inc a
132
	ld [hli], a ; wBallCoordY
133
	ldh a, [hSerialConnectionStatus]
134
	cp USING_INTERNAL_CLOCK
135
	ld a, 1
136
	ld c, 1 << DIR_UP + 1 << DIR_RIGHT
137
	jr z, .notOppositeSide
138
	ld a, 18
139
	ld c, 1 << DIR_UP + 1 << DIR_LEFT
140
.notOppositeSide
141
	ld [hli], a ; wBallCoordX
142
	ld a, [wRandomStartYFlag]
143
	xor 1
144
	ld [wRandomStartYFlag], a
145
	and a
146
	jr nz, .ok
147
	inc c ; replace DIR_UP with DIR_DOWN
148
.ok	
149
	ld [hl], c ; wBallDirection
150
	call RefreshPadsAndBall
151
	ld c, 12
152
	call DelayFrames	
153
154
.mainLoop
155
	call RefreshPadsAndBall
156
	ld a, [wGameOver]
157
	and a
158
	jr z, .notGameOver
159
	dec a
160
	ld [wGameOver], a
161
	jr z, .newGame
162
.notGameOver	
163
	call HandleJoypadInput
164
.skipJoypad	
165
	call SendPadOffset
166
	call MoveBall
167
	jr .mainLoop
168
169
HandleJoypadInput:
170
	ld bc, wPad1Offset
171
	ld a, [bc]
172
	ld hl, hJoyInput
173
	bit UP_KEY, [hl]
174
	jr z, .checkDown
175
	dec a ; cp 1
176
	ret z ; can't move up
177
	ld [bc], a
178
;	ret
179
.checkDown
180
	bit DOWN_KEY, [hl]
181
	ret z
182
	call _cp13_retz_inca
183
	ret z
184
	ld [bc], a
185
	ret
186
	
187
SendPadOffset:
188
	ld a, [bc] ; wPad1Offset
189
SendByte:	
190
	ld [wSerialExchangeNybbleSendData], a
191
.syncLoop1	
192
	call Serial_ExchangeNybble
193
	call DelayFrame
194
	ld a, [wSerialExchangeNybbleReceiveData]
195
	inc a
196
	jr z, .syncLoop1	
197
	ld b, 5
198
.syncLoop2
199
	call DelayFrame
200
	call Serial_ExchangeNybble
201
	dec b
202
	jr nz, .syncLoop2
203
	ld a, [wSerialExchangeNybbleReceiveData]
204
	ld [wPad2Offset], a
205
	ret
206-
	ld a, [hl] ; wBallCoordY
206+
207
MoveBall:
208
	ld hl, wBallCoordY ; handle vertical movement first
209
	ld e, 2
210
	ld a, [wBallDirection]	
211
.loop
212
	rrca
213-
	ld a, [hl] ; wBallCoordX
213+
214
	dec [hl]
215
.notUpOrLeft
216
	rrca
217
	jr nc, .notDownOrRight
218
	inc [hl]
219
.notDownOrRight
220
	dec e
221
	inc hl ; wBallCoordX
222
	jr nz, .loop ; go back to handle horizontal movement
223
; handle collisions
224
	dec hl
225
	dec hl ; wBallCoordY
226
	call _ldahl_cp16 ; avoid 0xfe here
227
	ld d, b ; 0x50 at D2B5 to terminate Pokemon #1's nickname
228
	jr z, .wall	
229
	dec a ; cp 1
230
	jr z, .wall
231
.handleCorners	
232
	inc hl
233
	call _ldahl_cp18 ; avoid 0xfe here
234
	jr z, .voidOrPad2
235
	dec a ; cp 1
236
	jr z, .voidOrPad1	
237
	ret
238
.wall
239
; change Y movement
240
	ld c, 1 << DIR_UP + 1 << DIR_DOWN
241
	call .updateBallDirectionAndPlayClickSound
242
; properly handle the corners
243
	jr .handleCorners
244
.voidOrPad2
245
	ld a, [wPad2Offset]
246
	jr .voidOrPad
247
.voidOrPad1
248
	ld a, [wPad1Offset]
249
.voidOrPad
250
	dec hl ; wBallCoordY
251
	ld e, 4
252
.padBounceCheckLoop	
253
	cp [hl]
254
	jr z, .pad
255
	inc a ; next pad tile
256
	dec e
257
	jr nz, .padBounceCheckLoop
258
; game over
259
	ld a, 3
260
	ld [wGameOver], a
261
	ret
262
.pad
263
; change X movement
264
	ld c, 1 << DIR_LEFT + 1 << DIR_RIGHT
265
;	jr .updateBallDirectionAndPlayClickSound
266
.updateBallDirectionAndPlayClickSound
267
	ld a, [wBallDirection]
268
	xor c
269
	ld [wBallDirection], a
270
	ld a, SFX_POUND
271
	jp PlaySound