-
Notifications
You must be signed in to change notification settings - Fork 1
/
scene_nintendo_logo_slide.z80
172 lines (160 loc) · 2.86 KB
/
scene_nintendo_logo_slide.z80
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
INCLUDE "Hardware.inc"
INCLUDE "rgbgrafx/rgbgrafx.inc"
Section "Nintendo Logo Slide",CODE
scene_nintendo_logo_slide::
; Initialize variables
xor A
ld [scene_done], A
ld [split_amount], A
ld [fade_delay], A
di
; Enable LCDC interrupt
ld A, [rIE]
or IEF_LCDC
ld [rIE], A
; Set V-blank handler
ld BC, vblank_interrupt
call set_vblank_interrupt
; Set LCDC handler
ld BC, lcdc_interrupt
call set_lcdc_interrupt
; Enable coincidence flag to cause an interrupt
; when LY equals LYC
ld A, [rSTAT]
or STATF_LYC
ld [rSTAT], A
; Set initial LYC value
ld A, 0
ld [rLYC], A
ei
.loop:
halt
ld A, [scene_done]
cp 1
jr nz, .loop
; Technically scene is not done yet, screen needs to be faded to black
; fade_delay and scene_done are reused
di
RGBG_WaitForVRAM
xor A
ld [rBGP], A
ld [fade_delay], A
ld [scene_done], A
call initialize_interrupts
ld BC, final_fade_out_interrupt
call set_vblank_interrupt
ei
.final_fade_out_loop:
halt
ld A, [scene_done]
cp 1
jr nz, .final_fade_out_loop
ret
; This interrupt fades the whole screen to black at the end of this scene
final_fade_out_interrupt:
ld A, [fade_delay]
cp $5
jr z, .delay_done
inc A
ld [fade_delay], A
jr .interrupt_done
.delay_done
ld A, [rBGP]
cp $FF
jr nz, .fade_palette
ld A, 1
ld [scene_done], A
jr .interrupt_done
.fade_palette:
ld A, [rBGP]
add %01010101
ld [rBGP], A
xor A
ld [fade_delay], A
.interrupt_done:
ret
final_fade_out:
xor A
ld [rBGP], A
.final_fade_outer_loop:
ld A, [rBGP]
cp $FF
jr z, .all_done
add %01010101
ld [rBGP], A
ld A, $FF
.final_fade_inner_loop:
cp $00
jr z, .final_fade_outer_loop
dec A
jr .final_fade_inner_loop
.all_done:
ret
vblank_interrupt:
RGBG_WaitForVRAM
xor A
ld [rLYC], A
ld A, [split_amount]
inc A
ld [split_amount], A
; Start fade after 20 V-blanks
ld B, $20
cp B
jr c, .skip_fade
; Wait 10 V-blanks before each palette change to slow things down.
ld A, [fade_delay]
cp $10
jr z, .delay_over
inc A
ld [fade_delay], A
jr .skip_fade
.delay_over:
; Execute actual palette change
xor A
ld [fade_delay], A
ld A, [rBGP]
ld B, A
and %00001111
cp $00
jr z, .skip_fade
ld A, B
sub %0100
ld [rBGP], A
.skip_fade:
; Set scene_done after $7A V-blanks
ld A, [split_amount]
ld B, $7A
cp B
jr nz, .return
ld A, 1
ld [scene_done], A
.return:
ret
lcdc_interrupt:
RGBG_WaitForVRAM
; Check if scanline is odd or even to determine direction
ld A, [rLY]
and 1
jr nz, .odd
.even:
; On even lines SCX increases
ld A, [split_amount]
ld [rSCX], A
jr .rest
.odd:
; On odd lines SCX decreases
ld A, [split_amount]
ld B, A
ld A, $FF
sub B
ld [rSCX], A
.rest
; Increment LYC on every line
ld A, [rLYC]
inc A
ld [rLYC], A
ret
Section "Variables",BSS
split_amount: DS 1
scene_done: DS 1
fade_delay: DS 1