-
Notifications
You must be signed in to change notification settings - Fork 0
/
graphics.mfk
173 lines (141 loc) · 3.47 KB
/
graphics.mfk
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
import nes_graphics
import palette
import fish/fish
enum ColorEffect {
red,
blue,
green,
grey,
red_blue,
clear
}
byte oam_index = 0
bool drawing_enabled
// enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
const byte standard_ppu_ctrl = %10010000
// Same as above, but increment address by 32
const byte vertical_ppu_ctrl = %10010100
// enable sprites, enable background, no clipping on left side
const byte default_mask = %00011110
inline void init_graphics() {
ppu_wait_vblank()
//for now, turn off the screen and nmi
read_ppu_status()
ppu_ctrl = 0
ppu_mask = 0
clear_nametables()
init_sprites()
}
inline void enable_graphics() {
// TODO: Figure out initial load flicker
// Reset vblank flag
read_ppu_status()
ppu_ctrl = standard_ppu_ctrl
read_ppu_status()
ppu_set_scroll(0, 0)
ppu_mask = default_mask
drawing_enabled = true
}
inline void wait_for_sprite0_nmi() {
if (enable_sprite0) {
wait_for_sprite0_clear()
// Wait for sprite0
while (ppu_status & %01000000 == 0) {}
}
}
inline void wait_for_sprite0_clear() {
if (enable_sprite0) {
// Wait for frame to start
while (ppu_status & %01000000 != 0) {}
}
}
inline void clear_nametables() {
byte i
byte j
read_ppu_status()
ppu_set_addr(ppu_nametable0)
for i,0,until,8 {
for j,0,until,32 {
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
ppu_write_data(0)
}
}
}
inline void init_sprites() {
oam_index = 0
clear_remaining_oam()
}
inline void sprite_tick() {
oam_index = 0
}
inline void render_sprite0() {
// Disabled, as it is not currently used
// oam_buffer[oam_index] = 8 * 5
// oam_buffer[oam_index + 1] = $1
// // Palette 2
// oam_buffer[oam_index + 2] = $2
// oam_buffer[oam_index + 3] = 8
// oam_index += 4
}
inline void clear_remaining_oam() {
byte i
for i,oam_index,until,255 {
if (i & %00000011) == 0 {
//each sprite takes up 4 bytes, and we want to edit
//the y position of each sprite (0th byte)
//so we use the %00000011 mask to write every 4th byte (every 0th sprite byte)
oam_buffer[i] = $FF // move the sprite off screen
} else {
oam_buffer[i] = 0
}
}
}
inline void sprite_render() {
//Push sprite information to the PPU through DMA transfer
ppu_oam_dma_write(oam_buffer.addr.hi)
}
inline void load_transition_palette() {
byte i
ppu_set_addr(ppu_palette_ram)
for i,0,until,transition_palette.length {
ppu_write_data(transition_palette[i])
}
}
inline void set_color_effect(ColorEffect effect) {
if (effect == red) {
ppu_mask = default_mask | %00100000
} else if (effect == green) {
ppu_mask = default_mask | %01000000
} else if (effect == blue) {
ppu_mask = default_mask | %10000000
} else if (effect == grey) {
ppu_mask = default_mask | %00000001
} else if (effect == red_blue) {
ppu_mask = default_mask | %10100000
} else {
ppu_mask = default_mask
}
}
/**
* Sets PPU_CTRL to the proper selected nametable
*/
inline void set_ppu_ctrl(bool right, bool bottom) {
byte temp_ctrl
temp_ctrl = standard_ppu_ctrl
if right {
temp_ctrl = temp_ctrl | %1
}
if bottom {
temp_ctrl = temp_ctrl | %10
}
read_ppu_status()
ppu_ctrl = temp_ctrl
}
segment(chrrom) const array bank0 @ $0000 = file("bank0.chr")
segment(chrrom) const array bank2 @ $4000 = file("bank2.chr")