diff --git a/src/scene/title_scene.rs b/src/scene/title_scene.rs index a27b6c6..f1ee750 100644 --- a/src/scene/title_scene.rs +++ b/src/scene/title_scene.rs @@ -1,12 +1,9 @@ -use crate::common::{FadeState, Rect}; -use crate::ggez::{Context, filesystem, GameResult, graphics}; +use crate::common::Rect; +use crate::ggez::{Context, GameResult, graphics}; use crate::ggez::graphics::Color; use crate::menu::{Menu, MenuEntry, MenuSelectionResult}; -use crate::profile::GameProfile; -use crate::scene::game_scene::GameScene; use crate::scene::Scene; use crate::shared_game_state::SharedGameState; -use crate::text_script::TextScriptExecutionState; #[derive(PartialEq, Eq, Copy, Clone)] #[repr(u8)] @@ -34,18 +31,6 @@ impl TitleScene { } } - fn start_game(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { - let mut next_scene = GameScene::new(state, ctx, 13)?; - next_scene.player.x = 10 * 16 * 0x200; - next_scene.player.y = 8 * 16 * 0x200; - state.fade_state = FadeState::Hidden; - state.textscript_vm.state = TextScriptExecutionState::Running(200, 0); - - state.next_scene = Some(Box::new(next_scene)); - - Ok(()) - } - fn draw_background(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "bkMoon")?; let offset = (self.tick % 640) as isize; @@ -158,31 +143,12 @@ impl Scene for TitleScene { } CurrentMenu::StartGame => { if self.tick == 30 { - self.start_game(state, ctx)?; + state.start_new_game(ctx)?; } } CurrentMenu::LoadGame => { if self.tick == 30 { - if let Ok(data) = filesystem::open(ctx, "/Profile.dat") { - match GameProfile::load_from_save(data) { - Ok(profile) => { - state.reset(); - let mut next_scene = GameScene::new(state, ctx, profile.current_map as usize)?; - - profile.apply(state, &mut next_scene, ctx); - - state.next_scene = Some(Box::new(next_scene)); - return Ok(()); - } - Err(e) => { - log::warn!("Failed to load save game, starting new one: {}", e); - } - } - } else { - log::warn!("No save game found, starting new one..."); - } - - self.start_game(state, ctx)?; + state.load_or_start_game(ctx)?; } } } diff --git a/src/shared_game_state.rs b/src/shared_game_state.rs index 4f68895..f1dd38d 100644 --- a/src/shared_game_state.rs +++ b/src/shared_game_state.rs @@ -14,8 +14,10 @@ use crate::scene::Scene; use crate::sound::SoundManager; use crate::stage::StageData; use crate::str; -use crate::text_script::TextScriptVM; +use crate::text_script::{TextScriptVM, TextScriptExecutionState}; use crate::texture_set::TextureSet; +use crate::profile::GameProfile; +use crate::scene::game_scene::GameScene; pub struct SharedGameState { pub control_flags: ControlFlags, @@ -103,6 +105,41 @@ impl SharedGameState { }) } + pub fn start_new_game(&mut self, ctx: &mut Context) -> GameResult { + let mut next_scene = GameScene::new(self, ctx, 13)?; + next_scene.player.x = 10 * 16 * 0x200; + next_scene.player.y = 8 * 16 * 0x200; + self.fade_state = FadeState::Hidden; + self.textscript_vm.state = TextScriptExecutionState::Running(200, 0); + + self.next_scene = Some(Box::new(next_scene)); + + Ok(()) + } + + pub fn load_or_start_game(&mut self, ctx: &mut Context) -> GameResult { + if let Ok(data) = filesystem::open(ctx, "/Profile.dat") { + match GameProfile::load_from_save(data) { + Ok(profile) => { + self.reset(); + let mut next_scene = GameScene::new(self, ctx, profile.current_map as usize)?; + + profile.apply(self, &mut next_scene, ctx); + + self.next_scene = Some(Box::new(next_scene)); + return Ok(()); + } + Err(e) => { + log::warn!("Failed to load save game, starting new one: {}", e); + } + } + } else { + log::warn!("No save game found, starting new one..."); + } + + self.start_new_game(ctx) + } + pub fn reset(&mut self) { self.control_flags.0 = 0; self.game_flags = bitvec::bitvec![0; 8000]; diff --git a/src/text_script.rs b/src/text_script.rs index c892d04..5239349 100644 --- a/src/text_script.rs +++ b/src/text_script.rs @@ -224,6 +224,7 @@ pub enum TextScriptExecutionState { WaitStanding(u16, u32), WaitConfirmation(u16, u32, u16, u8, ConfirmSelection), WaitFade(u16, u32), + LoadProfile, } pub struct TextScriptVM { @@ -466,6 +467,10 @@ impl TextScriptVM { } break; } + TextScriptExecutionState::LoadProfile => { + state.load_or_start_game(ctx)?; + break; + } } } @@ -1042,11 +1047,14 @@ impl TextScriptVM { exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32); } + OpCode::LDP => { + exec_state = TextScriptExecutionState::LoadProfile; + } // unimplemented opcodes // Zero operands OpCode::CAT | OpCode::CIL | OpCode::CPS | OpCode::CRE | OpCode::CSS | OpCode::FLA | - OpCode::INI | OpCode::LDP | OpCode::MLP | + OpCode::INI | OpCode::MLP | OpCode::SAT | OpCode::SLP | OpCode::SPS | OpCode::STC | OpCode::SVP | OpCode::TUR => { log::warn!("unimplemented opcode: {:?}", op);