Start adding GUI

This commit is contained in:
Joshua Goins 2025-03-02 18:16:43 -05:00
parent 47830cb926
commit 95e002ad9a
8 changed files with 3859 additions and 38 deletions

3743
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -7,3 +7,4 @@ edition = "2024"
flate2 = { version = "1.0", features = ["zlib-ng"], default-features = false }
binrw = { version = "0.14", features = ["std"], default-features = false }
paramacro = { path = "paramacro" }
eframe = { version= "0.31" }

77
src/bin/gui.rs Normal file
View file

@ -0,0 +1,77 @@
use std::{env, io::Cursor};
use binrw::BinRead;
use eframe::egui;
use ireko::{
CompressedSaveFile,
property::map_property::{MabSubProperty, MapKeyProperty},
save_object::{LocalProfileObject, PersistentObject},
};
fn main() -> eframe::Result {
let args: Vec<String> = env::args().collect();
let save_dir = args[1].clone();
let local_profile_path = format!("{save_dir}/LocalProfile.sav");
let mut local_profile_data = Cursor::new(std::fs::read(&local_profile_path).unwrap());
let compressed =
CompressedSaveFile::<LocalProfileObject>::read_le(&mut local_profile_data).unwrap();
println!("{:#?}", compressed);
let local_profile = compressed.value.objs;
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
enum AppState {
SelectSlot,
EditSlot {
name: String,
persistent: PersistentObject,
},
};
let mut state = AppState::SelectSlot;
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| match &mut state {
AppState::SelectSlot => {
ui.heading("Slots");
for slot in &local_profile.name_list.entries {
let MabSubProperty::String(name) = &slot.value else {
panic!("Expected a stirng!");
};
let MapKeyProperty::String(id) = &slot.key else {
panic!("Expected a stirng!");
};
if ui.button(&name.value).clicked() {
let persistent_path = format!("{save_dir}/{}/Persistent.sav", id.value);
let mut persistent_data =
Cursor::new(std::fs::read(&persistent_path).unwrap());
let compressed =
CompressedSaveFile::<PersistentObject>::read_le(&mut persistent_data)
.unwrap();
state = AppState::EditSlot {
name: name.value.clone(),
persistent: compressed.value.objs,
};
}
}
}
AppState::EditSlot { name, persistent } => {
ui.heading(format!("Editing {name}"));
ui.checkbox(&mut persistent.demo_version.value, "Demo Version");
ui.add(egui::DragValue::new(&mut persistent.money.value).suffix(" cell"));
}
});
})
}

View file

@ -24,6 +24,7 @@ where
for<'a> T: BinWrite<Args<'a> = ()> + 'a,
{
pub size_in_bytes: u32,
pub obj_size_in_bytes: u32,
pub objs: T,
}

View file

@ -1,4 +1,4 @@
use binrw::{BinRead, BinResult, BinWrite, binrw};
use binrw::{BinRead, BinResult, BinWrite, binrw, helpers::until_eof};
use crate::{
common::{read_string_with_length, write_string_with_length},
@ -85,8 +85,7 @@ fn custom_tagged_object_writer(entries: &Vec<Entry>) -> BinResult<()> {
#[binrw]
#[derive(Debug)]
pub struct GenericTaggedObject {
pub size_in_bytes: u32,
#[br(parse_with = custom_tagged_object_parser, args(size_in_bytes))]
#[br(parse_with = until_eof)]
#[bw(write_with = custom_tagged_object_writer)]
pub entries: Vec<Entry>,
}

View file

@ -5,17 +5,17 @@ use crate::property::{BoolProperty, IntProperty, StrProperty, map_property::MapP
#[derive(Debug)]
pub struct LocalProfileObject {
#[paramacro::serialized_field = "SavedDataVersion"]
version: IntProperty,
pub version: IntProperty,
#[paramacro::serialized_field = "bDemoVersion"]
demo: BoolProperty,
pub demo: BoolProperty,
#[paramacro::serialized_field = "RegisteredNameList"]
name_list: MapProperty,
pub name_list: MapProperty,
#[paramacro::serialized_field = "SaveGameName"]
name: StrProperty,
pub name: StrProperty,
#[paramacro::serialized_field = "bUseSaveSlot"]
use_save_slot: BoolProperty,
pub use_save_slot: BoolProperty,
}

View file

@ -11,92 +11,92 @@ use crate::{
#[derive(Debug)]
pub struct PersistentObject {
#[paramacro::serialized_field = "SavedDataVersion"]
version: IntProperty,
pub version: IntProperty,
#[paramacro::serialized_field = "bDemoVersion"]
demo_version: BoolProperty,
pub demo_version: BoolProperty,
#[paramacro::serialized_field = "Money"]
money: IntProperty,
pub money: IntProperty,
#[paramacro::serialized_field = "ObtainedItems"]
obtained_items: SetProperty,
pub obtained_items: SetProperty,
#[paramacro::serialized_field = "ItemSlots"]
item_slots: ArrayProperty,
pub item_slots: ArrayProperty,
#[paramacro::serialized_field = "CurrentItemSlotNum"]
current_item_slot: IntProperty,
pub current_item_slot: IntProperty,
#[paramacro::serialized_field = "NormalItemInventory"]
normal_item_inventory: MapProperty,
pub normal_item_inventory: MapProperty,
#[paramacro::serialized_field = "ModuleInventory"]
module_inventory: MapProperty,
pub module_inventory: MapProperty,
#[paramacro::serialized_field = "PartsInventory"]
parts_inventory: MapProperty,
pub parts_inventory: MapProperty,
#[paramacro::serialized_field = "CurrentBuildData"]
current_build_data: DABuildDataStruct,
pub current_build_data: DABuildDataStruct,
#[paramacro::serialized_field = "SavedBuildData"]
saved_build_data: ArrayProperty,
pub saved_build_data: ArrayProperty,
#[paramacro::serialized_field = "Palettes"]
palettes: MapProperty,
pub palettes: MapProperty,
#[paramacro::serialized_field = "TuningPointData"]
tuning_point_data: DATuningPointData,
pub tuning_point_data: DATuningPointData,
#[paramacro::serialized_field = "EventParams"]
event_params: MapProperty,
pub event_params: MapProperty,
#[paramacro::serialized_field = "ReachedDistricts"]
reached_districts: SetProperty,
pub reached_districts: SetProperty,
#[paramacro::serialized_field = "ShopBoughtCount"]
shop_bought_count: MapProperty,
pub shop_bought_count: MapProperty,
#[paramacro::serialized_field = "AcquiredItemBoxIds"]
acquired_item_box_ids: SetProperty,
pub acquired_item_box_ids: SetProperty,
#[paramacro::serialized_field = "OpenedStrongBoxIds"]
opened_strong_box_ids: SetProperty,
pub opened_strong_box_ids: SetProperty,
#[paramacro::serialized_field = "RegressionPlayerStartTag"]
regression_player_start_tag: NameProperty,
pub regression_player_start_tag: NameProperty,
#[paramacro::serialized_field = "RegressionLevelName"]
regression_level_name: NameProperty,
pub regression_level_name: NameProperty,
#[paramacro::serialized_field = "bStartFromRegressionPoint"]
start_from_regression_point: BoolProperty,
pub start_from_regression_point: BoolProperty,
#[paramacro::serialized_field = "ReleasedCheckpoints"]
released_checkpoints: SetProperty,
pub released_checkpoints: SetProperty,
#[paramacro::serialized_field = "SuspendTransform"]
suspend_transform: TransformStruct,
pub suspend_transform: TransformStruct,
#[paramacro::serialized_field = "CharacterPersistentDataList"]
character_persistent_data_list: MapProperty,
pub character_persistent_data_list: MapProperty,
#[paramacro::serialized_field = "BossStates"]
boss_states: MapProperty,
pub boss_states: MapProperty,
#[paramacro::serialized_field = "NPCStates"]
npc_states: MapProperty,
pub npc_states: MapProperty,
#[paramacro::serialized_field = "ReadDialogues"]
read_dialogues: MapProperty,
pub read_dialogues: MapProperty,
#[paramacro::serialized_field = "ReadDialogueChains"]
read_dialogue_chains: MapProperty,
pub read_dialogue_chains: MapProperty,
#[paramacro::serialized_field = "SaveGameName"]
save_game_name: StrProperty,
pub save_game_name: StrProperty,
#[paramacro::serialized_field = "bUseSaveSlot"]
use_save_slot: BoolProperty,
pub use_save_slot: BoolProperty,
}