summaryrefslogtreecommitdiff
path: root/src/home/scroll.asm
blob: 94896cff935c49636db1e3e6b22cfb47852dcce6 (plain)
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
; something window scroll
Func_3e44:
	push af
	push hl
	push bc
	push de
	ld hl, wd657
	bit 0, [hl]
	jr nz, .done
	set 0, [hl]
	ld b, $00
	ld hl, wd658
	ld c, [hl]
	inc [hl]
	ld hl, wd64b
	add hl, bc
	ld a, [hl]
	ldh [rWX], a
	ld hl, rLCDC
	cp $a7
	jr c, .disable_sprites
	set 1, [hl] ; enable sprites
	jr .asm_3e6c
.disable_sprites
	res 1, [hl] ; disable sprites
.asm_3e6c
	ld hl, wd651
	add hl, bc
	ld a, [hl]
	cp $8f
	jr c, .asm_3e9a
	ld a, [wd665]
	or a
	jr z, .asm_3e93
	ld hl, wd659
	ld de, wd64b
	ld bc, $6
	call CopyDataHLtoDE
	ld hl, wd65f
	ld de, wd651
	ld bc, $6
	call CopyDataHLtoDE
.asm_3e93
	xor a
	ld [wd665], a
	ld [wd658], a
.asm_3e9a
	ldh [rLYC], a
	ld hl, wd657
	res 0, [hl]
.done
	pop de
	pop bc
	pop hl
	pop af
	ret

; apply background scroll for lines 0 to 96 using the values at BGScrollData
; skip if wApplyBGScroll is non-0
ApplyBackgroundScroll:
	push af
	push hl
	call DisableInt_LYCoincidence
	ld hl, rSTAT
	res STAT_LYCFLAG, [hl] ; reset coincidence flag
	ei
	ld hl, wApplyBGScroll
	ld a, [hl]
	or a
	jr nz, .done
	inc [hl]
	push bc
	push de
	xor a
	ld [wNextScrollLY], a
.ly_loop
	ld a, [wNextScrollLY]
	ld b, a
.wait_ly
	ldh a, [rLY]
	cp $60
	jr nc, .ly_over_0x60
	cp b ; already hit LY=b?
	jr c, .wait_ly
	call GetNextBackgroundScroll
	ld hl, rSTAT
.wait_hblank_or_vblank
	bit STAT_BUSY, [hl]
	jr nz, .wait_hblank_or_vblank
	ldh [rSCX], a
	ldh a, [rLY]
	inc a
	ld [wNextScrollLY], a
	jr .ly_loop
.ly_over_0x60
	xor a
	ldh [rSCX], a
	ld a, $00
	ldh [rLYC], a
	call GetNextBackgroundScroll
	ldh [hSCX], a
	pop de
	pop bc
	xor a
	ld [wApplyBGScroll], a
	call EnableInt_LYCoincidence
.done
	pop hl
	pop af
	ret

BGScrollData:
	db  0,  0,  0,  1,  1,  1,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3
	db  4,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  1,  1,  1,  0,  0
	db  0, -1, -1, -1, -2, -2, -2, -3, -3, -3, -4, -4, -4, -4, -4, -4
	db -5, -4, -4, -4, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, -1
; 3f38

; x = BGScrollData[(wVBlankCounter + a) & $3f]
; return, in register a, x rotated right [wBGScrollMod]-1 times (max 3 times)
GetNextBackgroundScroll:
	ld hl, wVBlankCounter
	add [hl]
	and $3f
	ld c, a
	ld b, $00
	ld hl, BGScrollData
	add hl, bc
	ld a, [wBGScrollMod]
	ld c, a
	ld a, [hl]
	dec c
	jr z, .done
	dec c
	jr z, .halve
	dec c
	jr z, .quarter
; effectively zero
	sra a
.quarter
	sra a
.halve
	sra a
.done
	ret

; enable lcdc interrupt on LYC=LC coincidence
EnableInt_LYCoincidence:
	push hl
	ld hl, rSTAT
	set STAT_LYC, [hl]
	xor a
	ld hl, rIE
	set INT_LCD_STAT, [hl]
	pop hl
	ret

; disable lcdc interrupt and the LYC=LC coincidence trigger
DisableInt_LYCoincidence:
	push hl
	ld hl, rSTAT
	res STAT_LYC, [hl]
	xor a
	ld hl, rIE
	res INT_LCD_STAT, [hl]
	pop hl
	ret