mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
thing worky now :), no more thinky for me
This commit is contained in:
parent
2fed3cc807
commit
8917668475
5 changed files with 166 additions and 160 deletions
|
@ -27,21 +27,22 @@ impl State {
|
|||
y: y as f32,
|
||||
}
|
||||
.to_chunk();
|
||||
unsafe { self.particle_world_state.assume_init_mut() }.set_chunk(pos.x, pos.y)?;
|
||||
if let Some(cell) = unsafe { self.particle_world_state.assume_init_mut() }.get_cell_raw(
|
||||
(x.floor() as isize).rem_euclid(CHUNK_SIZE as isize),
|
||||
(y.floor() as isize).rem_euclid(CHUNK_SIZE as isize),
|
||||
) {
|
||||
noita_api::print(format!("{cell:?}"));
|
||||
noita_api::print(format!("{:?}", unsafe { cell.material_ptr.0.as_ref() }));
|
||||
} else {
|
||||
noita_api::print("mat nil");
|
||||
if self.particle_world_state.set_chunk(pos.x, pos.y).is_ok() {
|
||||
if let Some(cell) = self.particle_world_state.get_cell_raw(
|
||||
(x.floor() as isize).rem_euclid(CHUNK_SIZE as isize),
|
||||
(y.floor() as isize).rem_euclid(CHUNK_SIZE as isize),
|
||||
) {
|
||||
noita_api::print(format!("{cell:?}"));
|
||||
noita_api::print(format!("{:?}", unsafe { cell.material_ptr.as_ref() }));
|
||||
} else {
|
||||
noita_api::print("mat nil");
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.blobs.is_empty() {
|
||||
self.blobs.push(Blob::new(256.0, -64.0 - 32.0));
|
||||
}
|
||||
for blob in self.blobs.iter_mut() {
|
||||
'upper: for blob in self.blobs.iter_mut() {
|
||||
blob.update_pos()?;
|
||||
let c = blob.pos.to_chunk();
|
||||
for ((x, y), chunk) in (c.x - OFFSET..=c.x + OFFSET)
|
||||
|
@ -49,9 +50,9 @@ impl State {
|
|||
.zip(self.world.iter_mut())
|
||||
{
|
||||
unsafe {
|
||||
self.particle_world_state
|
||||
.assume_init_mut()
|
||||
.encode_area(x, y, chunk)?
|
||||
if self.particle_world_state.encode_area(x, y, chunk).is_err() {
|
||||
continue 'upper;
|
||||
}
|
||||
}
|
||||
}
|
||||
blob.update(&mut self.world)?;
|
||||
|
@ -61,9 +62,9 @@ impl State {
|
|||
{
|
||||
if chunk.modified {
|
||||
unsafe {
|
||||
self.particle_world_state
|
||||
.assume_init_mut()
|
||||
.decode_area(x, y, chunk)?
|
||||
if self.particle_world_state.decode_area(x, y, chunk).is_err() {
|
||||
continue 'upper;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ pub mod chunk;
|
|||
pub mod noita;
|
||||
use crate::blob_guy::Blob;
|
||||
use crate::chunk::Chunk;
|
||||
use crate::noita::{ParticleWorldState, ntypes};
|
||||
use crate::noita::ParticleWorldState;
|
||||
use noita_api::add_lua_fn;
|
||||
use noita_api::lua::LUA;
|
||||
use noita_api::lua::LuaState;
|
||||
|
@ -12,21 +12,20 @@ use smallvec::SmallVec;
|
|||
use std::cell::{LazyCell, RefCell};
|
||||
use std::ffi::{c_int, c_void};
|
||||
use std::hint::black_box;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::sync::LazyLock;
|
||||
pub const CHUNK_SIZE: usize = 128;
|
||||
pub const CHUNK_AMOUNT: usize = 3;
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
particle_world_state: MaybeUninit<ParticleWorldState>,
|
||||
particle_world_state: ParticleWorldState,
|
||||
blobs: SmallVec<[Blob; 8]>,
|
||||
world: [Chunk; CHUNK_AMOUNT * CHUNK_AMOUNT],
|
||||
blob_guy: u16,
|
||||
}
|
||||
thread_local! {
|
||||
static STATE: LazyCell<RefCell<State>> = LazyCell::new(|| {
|
||||
State {
|
||||
particle_world_state: MaybeUninit::uninit(),blobs: Default::default(),world: Default::default(),blob_guy: 0,}
|
||||
}.into());
|
||||
Default::default()
|
||||
});
|
||||
}
|
||||
static KEEP_SELF_LOADED: LazyLock<Result<libloading::Library, libloading::Error>> =
|
||||
LazyLock::new(|| unsafe { libloading::Library::new("blob_guy.dll") });
|
||||
|
@ -52,26 +51,35 @@ pub unsafe extern "C" fn luaopen_blob_guy(lua: *mut lua_State) -> c_int {
|
|||
fn init_particle_world_state(lua: LuaState) -> eyre::Result<()> {
|
||||
STATE.with(|state| {
|
||||
let mut state = state.borrow_mut();
|
||||
let world_ptr = lua.to_integer(1) as *const ntypes::GridWorld;
|
||||
let chunk_map_ptr = unsafe { (lua.to_integer(2) as *mut c_void).offset(8) };
|
||||
let material_list_ptr = lua.to_integer(3) as *const ntypes::CellData;
|
||||
let construct_ptr = lua.to_integer(5) as *mut c_void;
|
||||
let remove_ptr = lua.to_integer(6) as *mut c_void;
|
||||
#[cfg(target_arch = "x86")]
|
||||
let world_ptr = lua.to_integer(1) as *const c_void;
|
||||
let chunk_map_ptr = unsafe { (lua.to_integer(2) as *const c_void).offset(8) };
|
||||
let material_list_ptr = lua.to_integer(3) as *const c_void;
|
||||
#[cfg(target_arch = "x86")]
|
||||
let construct_ptr = lua.to_integer(4) as *const c_void;
|
||||
#[cfg(target_arch = "x86")]
|
||||
let remove_ptr = lua.to_integer(5) as *const c_void;
|
||||
let blob_guy = noita_api::raw::cell_factory_get_type("blob_guy".into())? as u16;
|
||||
state.blob_guy = blob_guy;
|
||||
let pws = ParticleWorldState {
|
||||
#[cfg(target_arch = "x86")]
|
||||
world_ptr,
|
||||
chunk_map_ptr,
|
||||
material_list_ptr,
|
||||
blob_guy,
|
||||
blob_ptr: unsafe { material_list_ptr.offset(blob_guy as isize) },
|
||||
blob_ptr: unsafe {
|
||||
material_list_ptr
|
||||
.offset(size_of::<noita::ntypes::CellData>() as isize * blob_guy as isize)
|
||||
},
|
||||
pixel_array: Default::default(),
|
||||
#[cfg(target_arch = "x86")]
|
||||
construct_ptr,
|
||||
#[cfg(target_arch = "x86")]
|
||||
remove_ptr,
|
||||
shift_x: 0,
|
||||
shift_y: 0,
|
||||
};
|
||||
state.particle_world_state = MaybeUninit::new(pws);
|
||||
state.particle_world_state = pws;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,42 +1,95 @@
|
|||
use crate::CHUNK_SIZE;
|
||||
use crate::chunk::{CellType, Chunk};
|
||||
use eyre::eyre;
|
||||
#[cfg(target_arch = "x86")]
|
||||
use std::arch::asm;
|
||||
use std::ffi::c_void;
|
||||
use std::{mem, ptr};
|
||||
use std::{ffi::c_void, mem, ptr};
|
||||
pub(crate) mod ntypes;
|
||||
//pub(crate) mod pixel;
|
||||
#[derive(Debug)]
|
||||
#[derive(Default)]
|
||||
pub(crate) struct ParticleWorldState {
|
||||
pub(crate) world_ptr: *const ntypes::GridWorld,
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub(crate) world_ptr: *const c_void,
|
||||
pub(crate) chunk_map_ptr: *const c_void,
|
||||
pub(crate) material_list_ptr: *const ntypes::CellData,
|
||||
pub(crate) material_list_ptr: *const c_void,
|
||||
pub(crate) blob_guy: u16,
|
||||
pub(crate) blob_ptr: *const ntypes::CellData,
|
||||
pub(crate) blob_ptr: *const c_void,
|
||||
pub(crate) pixel_array: *const c_void,
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub(crate) construct_ptr: *const c_void,
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub(crate) remove_ptr: *const c_void,
|
||||
pub(crate) shift_x: isize,
|
||||
pub(crate) shift_y: isize,
|
||||
}
|
||||
impl ParticleWorldState {
|
||||
pub fn set_chunk(&mut self, x: isize, y: isize) -> eyre::Result<()> {
|
||||
fn create_cell(
|
||||
&mut self,
|
||||
x: isize,
|
||||
y: isize,
|
||||
material: *const c_void,
|
||||
//_memory: *const c_void,
|
||||
) -> *mut ntypes::Cell {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let cell_ptr: *mut ntypes::Cell;
|
||||
asm!(
|
||||
"mov ecx, {world}",
|
||||
"push 0",
|
||||
"push {material}",
|
||||
"push {y:e}",
|
||||
"push {x:e}",
|
||||
"call {construct}",
|
||||
world = in(reg) self.world_ptr,
|
||||
x = in(reg) x,
|
||||
y = in(reg) y,
|
||||
material = in(reg) material,
|
||||
construct = in(reg) self.construct_ptr,
|
||||
clobber_abi("C"),
|
||||
out("eax") cell_ptr,
|
||||
);
|
||||
cell_ptr
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
std::hint::black_box((x, y, material));
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
fn remove_cell(&mut self, cell: *mut ntypes::Cell, x: isize, y: isize) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ecx, {world}",
|
||||
"push 0",
|
||||
"push {y:e}",
|
||||
"push {x:e}",
|
||||
"push {cell}",
|
||||
"call {remove}",
|
||||
world = in(reg) self.world_ptr,
|
||||
cell = in(reg) cell,
|
||||
x = in(reg) x,
|
||||
y = in(reg) y,
|
||||
remove = in(reg) self.remove_ptr,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
std::hint::black_box((x, y, cell));
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn set_chunk(&mut self, x: isize, y: isize) -> Result<(), ()> {
|
||||
const SCALE: isize = (512 / CHUNK_SIZE as isize).ilog2() as isize;
|
||||
self.shift_x = (x * CHUNK_SIZE as isize).rem_euclid(512);
|
||||
self.shift_y = (y * CHUNK_SIZE as isize).rem_euclid(512);
|
||||
let chunk_index = ((((y >> SCALE) - 256) & 511) << 9) | (((x >> SCALE) - 256) & 511);
|
||||
let chunk_index = (((((y >> SCALE) - 256) & 511) << 9) | (((x >> SCALE) - 256) & 511)) * 4;
|
||||
// Deref 1/3
|
||||
let chunk_arr = unsafe { self.chunk_map_ptr.cast::<*const c_void>().read() };
|
||||
// Deref 2/3
|
||||
let chunk = unsafe {
|
||||
chunk_arr
|
||||
.offset(chunk_index * 4)
|
||||
.cast::<*const c_void>()
|
||||
.read()
|
||||
};
|
||||
let chunk = unsafe { chunk_arr.offset(chunk_index).cast::<*const c_void>().read() };
|
||||
if chunk.is_null() {
|
||||
return Err(eyre!("could not find chunk {}", chunk_index));
|
||||
return Err(());
|
||||
}
|
||||
// Deref 3/3
|
||||
let pixel_array = unsafe { chunk.cast::<*const c_void>().read() };
|
||||
|
@ -46,21 +99,27 @@ impl ParticleWorldState {
|
|||
pub fn get_cell_raw(&self, x: isize, y: isize) -> Option<&ntypes::Cell> {
|
||||
let x = x + self.shift_x;
|
||||
let y = y + self.shift_y;
|
||||
let index = ((y & 511) << 9) | (x & 511);
|
||||
let pixel = unsafe { self.pixel_array.offset(index * 4) };
|
||||
let pixel = unsafe { self.pixel_array.offset((((y & 511) << 9) | (x & 511)) * 4) };
|
||||
if pixel.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe { pixel.cast::<*const ntypes::Cell>().read().as_ref() }
|
||||
}
|
||||
fn get_cell_raw_mut(&mut self, x: isize, y: isize) -> *mut *mut ntypes::Cell {
|
||||
let x = x + self.shift_x;
|
||||
let y = y + self.shift_y;
|
||||
let pixel = unsafe { self.pixel_array.offset((((y & 511) << 9) | (x & 511)) * 4) };
|
||||
pixel as *mut *mut ntypes::Cell
|
||||
}
|
||||
fn get_cell_material_id(&self, cell: &ntypes::Cell) -> u16 {
|
||||
let mat_ptr = cell.material_ptr();
|
||||
let offset = unsafe { mat_ptr.0.offset_from(self.material_list_ptr) };
|
||||
offset as u16
|
||||
let offset = unsafe { mat_ptr.cast::<c_void>().offset_from(self.material_list_ptr) };
|
||||
(offset / size_of::<ntypes::CellData>() as isize) as u16
|
||||
}
|
||||
|
||||
fn get_cell_type(&self, cell: &ntypes::Cell) -> Option<ntypes::CellType> {
|
||||
Some(unsafe { cell.material_ptr().0.as_ref()? }.cell_type)
|
||||
unsafe { Some(cell.material_ptr().as_ref()?.cell_type) }
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn encode_area(
|
||||
|
@ -68,7 +127,7 @@ impl ParticleWorldState {
|
|||
x: isize,
|
||||
y: isize,
|
||||
chunk: &mut Chunk,
|
||||
) -> eyre::Result<()> {
|
||||
) -> Result<(), ()> {
|
||||
self.set_chunk(x, y)?;
|
||||
let mut modified = false;
|
||||
for ((i, j), pixel) in (0..CHUNK_SIZE as isize)
|
||||
|
@ -108,7 +167,7 @@ impl ParticleWorldState {
|
|||
x: isize,
|
||||
y: isize,
|
||||
chunk: &Chunk,
|
||||
) -> eyre::Result<()> {
|
||||
) -> Result<(), ()> {
|
||||
self.set_chunk(x, y)?;
|
||||
let x = x * CHUNK_SIZE as isize;
|
||||
let y = y * CHUNK_SIZE as isize;
|
||||
|
@ -116,44 +175,32 @@ impl ParticleWorldState {
|
|||
.flat_map(|i| (0..CHUNK_SIZE as isize).map(move |j| (i, j)))
|
||||
.zip(chunk.iter())
|
||||
{
|
||||
macro_rules! get_cell_raw_mut {
|
||||
($x:tt,$y:tt) => {{
|
||||
let x = x + self.shift_x;
|
||||
let y = y + self.shift_y;
|
||||
let index = ((y & 511) << 9) | (x & 511);
|
||||
let pixel = unsafe { self.pixel_array.offset(index * 4) };
|
||||
pixel as *mut *mut ntypes::Cell
|
||||
}};
|
||||
}
|
||||
match pixel {
|
||||
CellType::Blob => {
|
||||
noita_api::game_print("a");
|
||||
let x = x + i;
|
||||
let y = y + j;
|
||||
let cell = get_cell_raw_mut!(i, j);
|
||||
unsafe {
|
||||
let cell = self.get_cell_raw_mut(i, j);
|
||||
if !(*cell).is_null() {
|
||||
remove_cell(self.world_ptr, self.remove_ptr, *cell, x, y);
|
||||
self.remove_cell(*cell, x, y);
|
||||
*cell = ptr::null_mut();
|
||||
}
|
||||
let src =
|
||||
create_cell(self.world_ptr, self.construct_ptr, x, y, self.blob_ptr);
|
||||
let src = self.create_cell(x, y, self.blob_ptr);
|
||||
if !src.is_null() {
|
||||
let liquid: &mut ntypes::LiquidCell =
|
||||
&mut *src.cast::<ntypes::LiquidCell>();
|
||||
&mut *(src as *mut ntypes::LiquidCell);
|
||||
liquid.is_static = true;
|
||||
*cell = src;
|
||||
}
|
||||
}
|
||||
}
|
||||
CellType::Remove => {
|
||||
noita_api::game_print("b");
|
||||
let x = x + i;
|
||||
let y = y + j;
|
||||
let cell = get_cell_raw_mut!(i, j);
|
||||
unsafe {
|
||||
let cell = self.get_cell_raw_mut(i, j);
|
||||
if !(*cell).is_null() {
|
||||
remove_cell(self.world_ptr, self.remove_ptr, *cell, x, y);
|
||||
self.remove_cell(*cell, x, y);
|
||||
*cell = ptr::null_mut();
|
||||
}
|
||||
}
|
||||
|
@ -164,67 +211,3 @@ impl ParticleWorldState {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
fn create_cell(
|
||||
world_ptr: *const ntypes::GridWorld,
|
||||
construct_ptr: *const c_void,
|
||||
x: isize,
|
||||
y: isize,
|
||||
material: *const ntypes::CellData,
|
||||
//_memory: *const c_void,
|
||||
) -> *mut ntypes::Cell {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let cell_ptr: *mut ntypes::Cell;
|
||||
asm!(
|
||||
"mov ecx, {world}",
|
||||
"push 0",
|
||||
"push {material}",
|
||||
"push {y:e}",
|
||||
"push {x:e}",
|
||||
"call {construct}",
|
||||
world = in(reg) world_ptr,
|
||||
x = in(reg) x,
|
||||
y = in(reg) y,
|
||||
material = in(reg) material,
|
||||
construct = in(reg) construct_ptr,
|
||||
clobber_abi("C"),
|
||||
out("eax") cell_ptr,
|
||||
);
|
||||
cell_ptr
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
std::hint::black_box((x, y, material, world_ptr, construct_ptr));
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
fn remove_cell(
|
||||
world_ptr: *const ntypes::GridWorld,
|
||||
remove_ptr: *const c_void,
|
||||
cell: *const ntypes::Cell,
|
||||
x: isize,
|
||||
y: isize,
|
||||
) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ecx, {world}",
|
||||
"push 0",
|
||||
"push {y:e}",
|
||||
"push {x:e}",
|
||||
"push {cell}",
|
||||
"call {remove}",
|
||||
world = in(reg) world_ptr,
|
||||
cell = in(reg) cell,
|
||||
x = in(reg) x,
|
||||
y = in(reg) y,
|
||||
remove = in(reg) remove_ptr,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
std::hint::black_box((x, y, cell, world_ptr, remove_ptr));
|
||||
unreachable!()
|
||||
}
|
||||
}
|
|
@ -3,7 +3,8 @@
|
|||
use std::ffi::{c_char, c_void};
|
||||
|
||||
//pub(crate) const CELLDATA_SIZE: isize = 0x290;
|
||||
//const _: () = assert!(CELLDATA_SIZE == size_of::<CellData>() as isize);
|
||||
#[cfg(target_arch = "x86")]
|
||||
const _: () = assert!(0x290 == size_of::<CellData>());
|
||||
#[cfg(target_arch = "x86")]
|
||||
use std::arch::asm;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
|
@ -16,7 +17,7 @@ pub struct Colour {
|
|||
a: u8,
|
||||
}
|
||||
|
||||
impl Debug for CellArrayPtr {
|
||||
/*impl Debug for CellArrayPtr {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", unsafe { self.0.as_ref() })
|
||||
}
|
||||
|
@ -40,7 +41,6 @@ pub(crate) struct CellDataPtr(pub *const CellData);
|
|||
|
||||
#[repr(C)]
|
||||
pub(crate) struct CellArrayPtr(pub *mut CellPtr);
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub(crate) struct ChunkArray(pub *mut CellArrayPtr);
|
||||
|
@ -87,7 +87,7 @@ pub struct GridWorld {
|
|||
pub chunk_map: ChunkMap,
|
||||
unknown2: [isize; 41],
|
||||
m_thread_impl: *const c_void,
|
||||
}
|
||||
}*/
|
||||
|
||||
#[repr(C)]
|
||||
union Buffer {
|
||||
|
@ -303,13 +303,13 @@ pub struct Position {
|
|||
}
|
||||
#[allow(dead_code)]
|
||||
impl CellVTable {
|
||||
pub fn destroy(&self, cell: CellPtr) {
|
||||
pub fn destroy(&self, cell: *const Cell) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.destroy,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
|
@ -320,14 +320,14 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn get_cell_type(&self, cell: CellPtr) -> CellType {
|
||||
pub fn get_cell_type(&self, cell: *const Cell) -> CellType {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let ret: u32;
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.get_cell_type,
|
||||
out("eax") ret,
|
||||
clobber_abi("C"),
|
||||
|
@ -340,14 +340,14 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn get_color(&self, cell: CellPtr) -> Colour {
|
||||
pub fn get_color(&self, cell: *const Cell) -> Colour {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let ret: u32;
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.get_color,
|
||||
out("eax") ret,
|
||||
clobber_abi("C"),
|
||||
|
@ -360,7 +360,7 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn set_color(&self, cell: CellPtr, color: Colour) {
|
||||
pub fn set_color(&self, cell: *const Cell, color: Colour) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let color: u32 = std::mem::transmute(color);
|
||||
|
@ -368,7 +368,7 @@ impl CellVTable {
|
|||
"mov ecx, {cell}",
|
||||
"push {color}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.set_color,
|
||||
color = in(reg) color,
|
||||
clobber_abi("C"),
|
||||
|
@ -380,19 +380,19 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn get_material(&self, cell: CellPtr) -> CellDataPtr {
|
||||
pub fn get_material(&self, cell: *const Cell) -> *const CellData {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let ret: *const CellData;
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.get_material,
|
||||
out("eax") ret,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
CellDataPtr(ret)
|
||||
ret
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
|
@ -400,7 +400,7 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn get_position(&self, cell: CellPtr) -> *const Position {
|
||||
pub fn get_position(&self, cell: *const Cell) -> *const Position {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let mut ret: *const Position;
|
||||
|
@ -408,7 +408,7 @@ impl CellVTable {
|
|||
"mov ecx, {cell}",
|
||||
"push 0",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.get_position,
|
||||
out("eax") ret,
|
||||
clobber_abi("C"),
|
||||
|
@ -421,14 +421,14 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn is_burning(&self, cell: CellPtr) -> bool {
|
||||
pub fn is_burning(&self, cell: *const Cell) -> bool {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
let ret: u16;
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.is_burning,
|
||||
out("eax") ret,
|
||||
clobber_abi("C"),
|
||||
|
@ -442,13 +442,13 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn stop_burning(&self, cell: CellPtr) {
|
||||
pub fn stop_burning(&self, cell: *const Cell) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.stop_burning,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
|
@ -459,13 +459,13 @@ impl CellVTable {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
pub fn remove(&self, cell: CellPtr) {
|
||||
pub fn remove(&self, cell: *const Cell) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ecx, {cell}",
|
||||
"call {fn}",
|
||||
cell = in(reg) cell.0,
|
||||
cell = in(reg) cell,
|
||||
fn = in(reg) self.remove,
|
||||
clobber_abi("C"),
|
||||
);
|
||||
|
@ -487,7 +487,7 @@ pub(crate) struct Cell {
|
|||
unknown1: [u8; 8],
|
||||
is_burning: bool,
|
||||
unknown2: [u8; 3],
|
||||
pub material_ptr: CellDataPtr,
|
||||
pub material_ptr: *const CellData,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -506,7 +506,7 @@ pub(crate) struct LiquidCell {
|
|||
}
|
||||
|
||||
impl Cell {
|
||||
pub(crate) fn material_ptr(&self) -> &CellDataPtr {
|
||||
&self.material_ptr
|
||||
pub(crate) fn material_ptr(&self) -> *const CellData {
|
||||
self.material_ptr
|
||||
}
|
||||
}
|
||||
|
|
|
@ -743,6 +743,20 @@ pub fn print(value: impl AsRef<str>) {
|
|||
let _ = raw::print(value.as_ref());
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! game_print {
|
||||
($($arg:tt)*) => {
|
||||
$crate::game_print(format!($($arg)*))
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => {
|
||||
$crate::print(format!($($arg)*))
|
||||
};
|
||||
}
|
||||
|
||||
pub mod raw {
|
||||
use eyre::Context;
|
||||
use eyre::eyre;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue