diff --git a/ewext/src/lib.rs b/ewext/src/lib.rs index e86f7073..fe3cd9c1 100644 --- a/ewext/src/lib.rs +++ b/ewext/src/lib.rs @@ -39,6 +39,7 @@ extern "C" fn init_particle_world_state(lua: *mut lua_State) -> c_int { _world_ptr: world_pointer as *mut c_void, chunk_map_ptr: chunk_map_pointer as *mut c_void, material_list_ptr: material_list_pointer as _, + runner: Default::default(), }); }); 0 @@ -52,8 +53,8 @@ extern "C" fn encode_area(lua: *mut lua_State) -> c_int { let encoded_buffer = unsafe { LUA.lua_tointeger(lua, 5) } as *mut NoitaPixelRun; STATE.with(|state| { - let state = state.borrow_mut(); - let pws = state.particle_world_state.as_ref().unwrap(); + let mut state = state.borrow_mut(); + let pws = state.particle_world_state.as_mut().unwrap(); let runs = unsafe { pws.encode_area(start_x, start_y, end_x, end_y, encoded_buffer) }; unsafe { LUA.lua_pushinteger(lua, runs as isize) }; }); diff --git a/ewext/src/noita.rs b/ewext/src/noita.rs index 1342b2e1..e746d92a 100644 --- a/ewext/src/noita.rs +++ b/ewext/src/noita.rs @@ -27,7 +27,7 @@ struct PixelRun { /// Copied from proxy. /// Converts a normal sequence of pixels to a run-length-encoded one. -struct PixelRunner { +pub(crate) struct PixelRunner { current_pixel: Option, current_run_len: u32, runs: Vec>, @@ -64,14 +64,20 @@ impl PixelRunner { self.current_run_len = 1; } } - fn build(mut self) -> Vec> { + fn build(&mut self) -> &[PixelRun] { if self.current_run_len > 0 { self.runs.push(PixelRun { length: self.current_run_len, data: self.current_pixel.expect("has current pixel"), }); } - self.runs + &mut self.runs + } + + fn clear(&mut self) { + self.current_pixel = None; + self.current_run_len = 0; + self.runs.clear(); } } @@ -79,6 +85,8 @@ pub(crate) struct ParticleWorldState { pub(crate) _world_ptr: *mut c_void, pub(crate) chunk_map_ptr: *mut c_void, pub(crate) material_list_ptr: *const c_void, + + pub(crate) runner: PixelRunner, } impl ParticleWorldState { @@ -115,14 +123,13 @@ impl ParticleWorldState { } pub(crate) unsafe fn encode_area( - &self, + &mut self, start_x: i32, start_y: i32, end_x: i32, end_y: i32, pixel_runs: *mut NoitaPixelRun, ) -> usize { - let mut runner = PixelRunner::default(); for y in start_y..end_y { for x in start_x..end_x { let mut raw_pixel = RawPixel { @@ -148,12 +155,12 @@ impl ParticleWorldState { ntypes::CellType::Invalid => {} } } - runner.put_pixel(raw_pixel); + self.runner.put_pixel(raw_pixel); } } let mut pixel_runs = pixel_runs; - let built_runner = runner.build(); + let built_runner = self.runner.build(); let runs = built_runner.len(); for run in built_runner { let noita_pixel_run = pixel_runs.as_mut().unwrap(); @@ -162,6 +169,7 @@ impl ParticleWorldState { noita_pixel_run.flags = run.data.flags; pixel_runs = pixel_runs.offset(1); } + self.runner.clear(); runs } }