@@ -110,42 +110,62 @@ async fn render_background(ppu: &mut Ppu<PpuMemory>) {
110110
111111async fn render_sprites ( ppu : & Ppu < PpuMemory > ) {
112112 for oam_idx in ( 0 ..OAM_SIZE ) . step_by ( 4 ) . rev ( ) {
113- let sprite = Sprite :: from_data ( & ppu. oam [ oam_idx..oam_idx + 4 ] ) ;
113+ let sprite = Sprite :: from_data ( & ppu. oam [ oam_idx..oam_idx + 4 ] , ppu . tall_sprites ( ) ) ;
114114 if !sprite. visible {
115115 continue ;
116116 }
117- let bank = ppu. sprite_pattern_addr ( ) ;
118- let tile = sprite. tile_index as u16 ;
119- let chr_data = ppu. memory . chr_rom
120- [ ( bank + tile * 16 ) as usize ..( bank + tile * 16 + 16 ) as usize ]
121- . to_vec ( ) ;
122- let pixels = chr_data_to_pixels ( chr_data) ;
123117
124- let colors = get_sprite_palette ( ppu, sprite. palette as u16 ) ;
125-
126- for x in 0 ..8 {
127- for y in 0 ..8 {
128- let pixel_idx = ( y * 8 + x) as usize ;
129- if pixels[ pixel_idx] == 0 {
130- continue ;
131- }
132-
133- let x = if sprite. flip_horizontally { 7 - x } else { x } ;
134- let y = if sprite. flip_vertically { 7 - y } else { y } ;
135-
136- if sprite. x as u16 + x > SCREEN_WIDTH || sprite. y as u16 + y > SCREEN_HEIGHT {
137- continue ;
138- }
139- let ( screen_x, screen_y) = ( sprite. x as u16 + x, sprite. y as u16 + y) ;
140-
141- draw_rectangle (
142- screen_x as f32 * RENDER_SCALE ,
143- screen_y as f32 * RENDER_SCALE ,
144- RENDER_SCALE ,
145- RENDER_SCALE ,
146- colors[ pixels[ pixel_idx] as usize ] ,
147- )
118+ if ppu. tall_sprites ( ) {
119+ let bank = sprite. bank ;
120+ let ( mut top_tile, mut bottom_tile) = ( sprite. tile_index , sprite. tile_index + 1 ) ;
121+ if sprite. flip_vertically {
122+ ( top_tile, bottom_tile) = ( bottom_tile, top_tile) ;
123+ }
124+ render_sprite_tile ( & sprite, ppu, bank, top_tile, 0 ) . await ;
125+ render_sprite_tile ( & sprite, ppu, bank, bottom_tile, 8 ) . await ;
126+ } else {
127+ let bank = ppu. sprite_pattern_addr ( ) ;
128+ let tile = sprite. tile_index ;
129+ render_sprite_tile ( & sprite, ppu, bank, tile, 0 ) . await ;
130+ }
131+ }
132+ }
133+
134+ async fn render_sprite_tile (
135+ sprite : & Sprite ,
136+ ppu : & Ppu < PpuMemory > ,
137+ bank : u16 ,
138+ tile : u16 ,
139+ y_offset : u16 ,
140+ ) {
141+ let chr_data =
142+ ppu. memory . chr_rom [ ( bank + tile * 16 ) as usize ..( bank + tile * 16 + 16 ) as usize ] . to_vec ( ) ;
143+ let pixels = chr_data_to_pixels ( chr_data) ;
144+
145+ let colors = get_sprite_palette ( ppu, sprite. palette as u16 ) ;
146+
147+ for x in 0 ..8 {
148+ for y in 0 ..8 {
149+ let pixel_idx = ( y * 8 + x) as usize ;
150+ if pixels[ pixel_idx] == 0 {
151+ continue ;
148152 }
153+
154+ let x = if sprite. flip_horizontally { 7 - x } else { x } ;
155+ let y = if sprite. flip_vertically { 7 - y } else { y } ;
156+ if sprite. x + x > SCREEN_WIDTH || sprite. y + y_offset + y > SCREEN_HEIGHT {
157+ continue ;
158+ }
159+
160+ let ( screen_x, screen_y) = ( sprite. x + x, sprite. y + y_offset + y) ;
161+
162+ draw_rectangle (
163+ screen_x as f32 * RENDER_SCALE ,
164+ screen_y as f32 * RENDER_SCALE ,
165+ RENDER_SCALE ,
166+ RENDER_SCALE ,
167+ colors[ pixels[ pixel_idx] as usize ] ,
168+ )
149169 }
150170 }
151171}
0 commit comments