Skip to content

Commit

Permalink
feat: reading and writing entity data
Browse files Browse the repository at this point in the history
  • Loading branch information
markisha64 committed Jan 16, 2024
1 parent 2fa46d2 commit ea7c540
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub const LI_INSTRUCTION: &[u8; 2] = b"\x02\x24";
pub const JR_RA_INSTRUCTION: &[u8; 4] = b"\x08\x00\xe0\x03";

pub const ENVIRONMENTAL_INSTRUCTION: &[u8; 4] = b"\x14\x00\x22\xae";
pub const ENTITIES_INSTRUCTION: &[u8; 4] = b"\x4c\x00\x22\xae";
pub const STAGE_COLOR_INSTRUCTION_HALF: &[u8; 2] = b"\x38\x00";

pub const ADDIU: u8 = 0x24;
Expand Down
71 changes: 70 additions & 1 deletion src/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod scaling;
mod shops;
pub mod structs;
use structs::{
DigivolutionConditions, DigivolutionData, EncounterData, EnemyStats, Environmental,
DigivolutionConditions, DigivolutionData, EncounterData, EnemyStats, EntityData, Environmental,
ItemShopData, MapColor, MoveData, Pointer, Shop, StageLoadData,
};

Expand Down Expand Up @@ -78,6 +78,7 @@ pub struct MapObject {
environmentals: Option<ObjectArray<Environmental>>,
map_color: Option<Object<MapColor>>,
background_file_index: Object<u16>,
entities: Option<ObjectArray<EntityData>>,
_stage_id: u16,
}

Expand Down Expand Up @@ -340,6 +341,9 @@ fn read_map_objects(
let mut environmentals: Vec<Environmental> = Vec::new();
let mut environmentals_index: Option<u32> = None;

let mut entities: Vec<EntityData> = Vec::new();
let mut entities_index: Option<u32> = None;

// we need to assemble full sw instruction
let environmental_instruction = [
consts::ENVIRONMENTAL_INSTRUCTION[0],
Expand All @@ -348,6 +352,13 @@ fn read_map_objects(
sw[1],
];

let entities_instruction = [
consts::ENTITIES_INSTRUCTION[0],
consts::ENTITIES_INSTRUCTION[1],
sw[0],
sw[1],
];

if let Some(environmental_set) = buf[initsp_index..initp_end_index]
.windows(4)
.position(|x| x == environmental_instruction)
Expand Down Expand Up @@ -380,6 +391,47 @@ fn read_map_objects(
}
}

if let Some(entities_set) = buf[initsp_index..initp_end_index]
.windows(4)
.position(|x| x == entities_instruction)
{
let entities_address = Pointer::from_instruction(&buf, initsp_index + entities_set);

if entities_address.is_valid() {
let ent_index = entities_address.to_index_overlay(stage.value as u32) as usize;

let mut i = 0;
loop {
let ptr = Pointer::from(&buf[ent_index + i * 4..ent_index + (i + 1) * 4]);

if ptr.null() {
break;
}

i += 1;
}

let real_pointer = Pointer::from(&buf[ent_index..ent_index + 4]);

let real_idx = real_pointer.to_index_overlay(stage.value as u32);
entities_index = Some(real_idx);

let mut entities_reader =
Cursor::new(&buf[(real_idx as usize)..(real_idx as usize) + 0x14 * i]);

for _ in 0..i {
let entity = EntityData::read(&mut entities_reader);

match entity {
Ok(ent) => {
entities.push(ent);
}
Err(_) => panic!("binread error"),
}
}
}
}

let environmental_object = match environmentals_index {
Some(idx) => Some(ObjectArray {
original: environmentals.clone(),
Expand All @@ -390,10 +442,23 @@ fn read_map_objects(
None => None,
};

let entities_object = match entities_index {
Some(idx) => Some(ObjectArray {
original: entities.clone(),
modified: entities.clone(),
index: idx as usize,
slen: 0x14,
}),
None => None,
};

// TODO: instead of always checking first 2 instructions before
// I need to find the first lui (which is considerably suckier)
result.push(MapObject {
file_name,
buf,
environmentals: environmental_object,
entities: entities_object,
map_color,
background_file_index: background_object,
_stage_id: stage_id,
Expand Down Expand Up @@ -827,6 +892,10 @@ fn write_map_objects(path: &PathBuf, objects: &mut Vec<MapObject>) -> Result<(),
environmentals.write_buf(buf);
}

if let Some(entities) = &mut object.entities {
entities.write_buf(buf);
}

if let Some(map_color) = &mut object.map_color {
map_color.write_buf(buf);
}
Expand Down
23 changes: 23 additions & 0 deletions src/rand/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,25 @@ pub struct Environmental {
unk1: u32,
}

#[derive(BinRead, Debug, Clone, BinWrite)]
pub struct EntityData {
conditions: Pointer,
pub logic: Pointer,
pub sprite: u16,
sprite_buffer_index: u16,
x: u16,
y: u16,
direction: u16,
padding: u16,
}

#[derive(BinRead, Debug, Clone, BinWrite)]
pub struct EntityLogic {
conditions: Pointer,
script: Pointer,
text_index: Pointer,
}

#[derive(BinRead, Debug, Clone, BinWrite)]
pub struct MapColor {
pub red: u8,
Expand Down Expand Up @@ -281,6 +300,10 @@ impl Pointer {
pub fn is_valid(&self) -> bool {
return 0x80000000 <= self.value && self.value <= 0x80100000;
}

pub fn null(&self) -> bool {
return self.value == 0;
}
}

impl From<&[u8]> for Pointer {
Expand Down

0 comments on commit ea7c540

Please sign in to comment.