@@ -3,7 +3,7 @@ use core::alloc::Allocator;
33use thiserror:: Error ;
44use p8rs_piccolo:: ExternError ;
55use p8rs_types:: p8scii;
6-
6+ use crate :: vm :: memory :: sprites :: Sprites ;
77use crate :: vm:: P8rs ;
88
99pub struct CartLoadContext < ' vm , ' c , A : Allocator + ' static > {
@@ -47,29 +47,27 @@ impl<'vm, 'c, A: Allocator + 'static> CartLoadContext<'vm, 'c, A> {
4747
4848 fn load_gfx_section ( & mut self , data : & [ u8 ] ) -> Result < ( ) , CartLoadError > {
4949 let memory = self . vm . memory ( ) ;
50- let sprites = memory. sprites ( ) . as_slice_mut ( memory) ;
51- let mut max_offset = -1 ;
50+ let sprites = memory. sprites ( ) ;
5251
5352 if self . gfx_loaded {
5453 debug ! ( "load_gfx_section: GFX section was already loaded, overwriting data." ) ;
5554 }
5655
57- for ( offset, byte) in split_nonempty_lines ( data, 128 ) // todo: figure out pico8 behaviour, if load_ctx.long_map_loaded { 64 } else { 128 }
58- . flat_map ( |( line_idx, line) |
59- nibble_chunks ( line) . take ( 64 ) . map ( |( h, l) | ( hex_char_to_nibble ( l) . unwrap_or ( 0 ) << 4 ) | hex_char_to_nibble ( h) . unwrap_or ( 0 ) )
60- . enumerate ( ) . map ( move |( col_idx, byte) | ( ( line_idx * 64 + col_idx) as i16 , byte) )
61- )
62- {
63- sprites[ offset as usize ] = byte;
64- if offset > max_offset { max_offset = offset; }
56+ // todo: figure out pico8 behaviour, if load_ctx.long_map_loaded { 64 } else { 128 }
57+ let mut written = 0 ;
58+ for res in hex_iter :: < 1 > ( data) {
59+ if res. col > Sprites :: WIDTH as usize || res. row > Sprites :: HEIGHT as usize { continue }
60+
61+ sprites. set_pixel ( memory, res. col as u8 , res. row as u8 , res. value ) ;
62+ written += 1 ;
6563 }
6664
6765 self . gfx_loaded = true ;
6866
69- if max_offset == - 1 {
67+ if written <= 0 {
7068 debug ! ( "load_gfx_section: GFX section loaded: empty section!" ) ;
7169 } else {
72- debug ! ( "load_gfx_section: GFX section loaded: 0x{:X} bytes written to memory" , max_offset + 1 ) ;
70+ debug ! ( "load_gfx_section: GFX section loaded: 0x{:X} bytes written to memory" , written ) ;
7371 }
7472
7573 Ok ( ( ) )
@@ -78,73 +76,61 @@ impl<'vm, 'c, A: Allocator + 'static> CartLoadContext<'vm, 'c, A> {
7876 fn load_map_section ( & mut self , data : & [ u8 ] ) -> Result < ( ) , CartLoadError > {
7977 let memory = self . vm . memory ( ) ;
8078 let map = memory. map ( ) ;
81- let mut max_offset = -1 ;
8279
8380 if self . map_loaded {
8481 debug ! ( "load_map_section: MAP section was already loaded, overwriting data." )
8582 }
8683
87- for ( offset, byte) in split_nonempty_lines ( data, 33 )
88- . flat_map ( |( line_idx, line) |
89- nibble_chunks ( line) . take ( 128 ) . map ( |( h, l) | {
90- if let ( Some ( h) , Some ( l) ) = ( hex_char_to_nibble ( h) , hex_char_to_nibble ( l) ) {
91- ( h << 4 ) | l
92- } else {
93- 0
94- }
95- } ) . enumerate ( ) . map ( move |( col_idx, byte) | ( ( line_idx * 128 + col_idx) as i16 , byte) )
96- )
97- {
98- // TODO: FIX
99- // if offset >= 0x1000 { max_offset = 0x1000; break; }
100- // let addr = offset as usize;
101- // memory[addr] = byte;
102- // if offset > max_offset { max_offset = offset; }
84+ // todo: figure out pico8 behaviour, if load_ctx.long_map_loaded { 64 } else { 128 }
85+ let mut written = 0 ;
86+ for res in hex_iter :: < 2 > ( data) {
87+ if res. col > map. width ( ) as usize || res. row > map. height ( ) as usize { continue }
88+
89+ map. set_sprite ( memory, res. col as u16 , res. row as u16 , res. value ) ;
90+ written += 1 ;
10391 }
10492
105- // if gfx is loaded and the map section is longer than 0x1000, zero out the remaining shared memory area written by gfx (0x1000..0x2000, shared between MAP and GFX)
106- // (Pico8 behavior)
107-
108- // todo: figure out the behaviour
109- // load_ctx.map_loaded = true;
110- // if max_offset >= 0x1000 {
111- // load_ctx.long_map_loaded = true;
112- //
113- // if load_ctx.gfx_loaded {
114- // debug!("Clearing extended GFX from 0x{:X}", max_offset);
115- // for offset in 0x1000..0x2000 {
116- // let addr = gfx_base_addr + offset;
117- // vm.runtime.memory[addr] = 0;
118- // }
119- // }
120- // }
121-
122- if max_offset == -1 {
93+ if written == -1 {
12394 debug ! ( "load_map_section: MAP section loaded: empty section!" ) ;
12495 } else {
125- debug ! ( "load_map_section: MAP section loaded: 0x{:X} bytes written" , max_offset ) ;
96+ debug ! ( "load_map_section: MAP section loaded: 0x{:X} bytes written to memory " , written ) ;
12697 }
12798
12899 Ok ( ( ) )
129100 }
130101}
131102
132- fn hex_char_to_nibble ( hex_char : u8 ) -> Option < u8 > {
133- match hex_char {
134- b'0' ..=b'9' => Some ( hex_char - b'0' ) ,
135- b'a' ..=b'f' => Some ( hex_char - b'a' + 10 ) ,
136- b'A' ..=b'F' => Some ( hex_char - b'A' + 10 ) ,
137- _ => None ,
138- }
103+ struct HexIterValue {
104+ value : u8 ,
105+ row : usize ,
106+ col : usize ,
139107}
140108
141- fn split_nonempty_lines ( data : & [ u8 ] , max_lines : usize ) -> impl Iterator < Item =( usize , & [ u8 ] ) > {
142- data. split ( |& b| b == b'\n' || b == b'\r' )
143- . filter ( |line| !line. is_empty ( ) ) . take ( max_lines) . enumerate ( )
109+ fn hex_iter < const Word : usize > ( lines : & [ u8 ] ) -> impl Iterator < Item =HexIterValue > {
110+ lines. split ( |& b| b == b'\n' || b == b'\r' )
111+ . filter ( |line| !line. is_empty ( ) )
112+ . enumerate ( )
113+ . flat_map ( |( row, line) |
114+ line. as_chunks :: < Word > ( ) . 0
115+ . iter ( )
116+ . enumerate ( )
117+ . map ( move |( col, chunk) | HexIterValue {
118+ row,
119+ col,
120+ value : chunk. iter ( )
121+ . copied ( )
122+ . map ( hex_value)
123+ . fold ( 0 , |acc, val| ( acc << 4 ) + val. unwrap_or ( 0 ) ) ,
124+ } ) )
144125}
145126
146- fn nibble_chunks ( text : & [ u8 ] ) -> impl Iterator < Item =( u8 , u8 ) > + ' _ {
147- text. chunks ( 2 ) . map ( |chunk| ( chunk[ 0 ] , chunk. get ( 1 ) . copied ( ) . unwrap_or ( b'0' ) ) )
127+ fn hex_value ( char : u8 ) -> Option < u8 > {
128+ match char {
129+ b'0' ..=b'9' => Some ( char - b'0' ) ,
130+ b'a' ..=b'f' => Some ( char - b'a' + 10 ) ,
131+ b'A' ..=b'F' => Some ( char - b'A' + 10 ) ,
132+ _ => None ,
133+ }
148134}
149135
150136#[ derive( Error , Debug ) ]
0 commit comments