tsc: yes/no confirmation box

This commit is contained in:
Alula 2020-09-05 04:56:29 +02:00
parent 4e57455a96
commit 3f7174df66
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
3 changed files with 86 additions and 9 deletions

View File

@ -100,6 +100,8 @@ pub struct TextScriptConsts {
pub textbox_rect_top: Rect<usize>,
pub textbox_rect_middle: Rect<usize>,
pub textbox_rect_bottom: Rect<usize>,
pub textbox_rect_yes_no: Rect<usize>,
pub textbox_rect_cursor: Rect<usize>,
}
#[derive(Debug)]
@ -337,7 +339,7 @@ impl EngineConstants {
n039_save_sign: [
Rect { left: 224, top: 64, right: 240, bottom: 80 },
Rect { left: 240, top: 64, right: 256, bottom: 80 },
]
],
},
tex_sizes: hashmap! {
str!("ArmsImage") => (256, 16),
@ -460,6 +462,8 @@ impl EngineConstants {
textbox_rect_top: Rect { left: 0, top: 0, right: 244, bottom: 8 },
textbox_rect_middle: Rect { left: 0, top: 8, right: 244, bottom: 16 },
textbox_rect_bottom: Rect { left: 0, top: 16, right: 244, bottom: 24 },
textbox_rect_yes_no: Rect { left: 152, top: 48, right: 244, bottom: 80 },
textbox_rect_cursor: Rect { left: 112, top: 88, right: 128, bottom: 104 },
},
font_path: str!("builtin/builtin_font.fnt"),
font_scale: 1.0,

View File

@ -12,7 +12,7 @@ use crate::scene::Scene;
use crate::SharedGameState;
use crate::stage::{BackgroundType, Stage};
use crate::str;
use crate::text_script::TextScriptVM;
use crate::text_script::{ConfirmSelection, TextScriptExecutionState, TextScriptVM};
use crate::ui::Components;
pub struct GameScene {
@ -302,20 +302,41 @@ impl GameScene {
let top_pos = if state.textscript_vm.flags.position_top() { 32.0 } else { state.canvas_size.1 as f32 - 66.0 };
let left_pos = (state.canvas_size.0 / 2.0 - 122.0).floor();
if state.textscript_vm.flags.background_visible() {
{
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "TextBox")?;
batch.add_rect(left_pos, top_pos, &state.constants.textscript.textbox_rect_top);
for i in 1..7 {
batch.add_rect(left_pos, top_pos + i as f32 * 8.0, &state.constants.textscript.textbox_rect_middle);
if state.textscript_vm.flags.background_visible() {
batch.add_rect(left_pos, top_pos, &state.constants.textscript.textbox_rect_top);
for i in 1..7 {
batch.add_rect(left_pos, top_pos + i as f32 * 8.0, &state.constants.textscript.textbox_rect_middle);
}
batch.add_rect(left_pos, top_pos + 56.0, &state.constants.textscript.textbox_rect_bottom);
}
if let TextScriptExecutionState::WaitConfirmation(_, _, _, wait, selection) = state.textscript_vm.state {
let pos_y = if wait > 14 {
state.canvas_size.1 - 96.0 - (wait as f32 - 2.0) * 4.0
} else {
state.canvas_size.1 - 96.0
};
batch.add_rect((state.canvas_size.0 / 2.0 + 56.0).floor(), pos_y,
&state.constants.textscript.textbox_rect_yes_no);
if wait == 0 {
let pos_x = if selection == ConfirmSelection::No { 41.0 } else { 0.0 };
batch.add_rect((state.canvas_size.0 / 2.0 + 51.0).floor() + pos_x,
state.canvas_size.1 - 86.0,
&state.constants.textscript.textbox_rect_cursor);
}
}
batch.add_rect(left_pos, top_pos + 56.0, &state.constants.textscript.textbox_rect_bottom);
batch.draw(ctx)?;
}
if state.textscript_vm.face != 0 {
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "Face")?;
batch.add_rect(left_pos + 14.0, top_pos + 8.0, &Rect::<usize>::new_size(
(state.textscript_vm.face as usize % 6) * 48,
(state.textscript_vm.face as usize / 6) * 48,

View File

@ -4,6 +4,7 @@ use std::io::Cursor;
use std::io::Seek;
use std::io::SeekFrom;
use std::iter::Peekable;
use std::ops::Not;
use std::str::FromStr;
use byteorder::ReadBytesExt;
@ -187,6 +188,25 @@ pub enum TextScriptLine {
Line3,
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[repr(u8)]
pub enum ConfirmSelection {
Yes,
No,
}
impl Not for ConfirmSelection {
type Output = ConfirmSelection;
fn not(self) -> ConfirmSelection {
if self == ConfirmSelection::Yes {
ConfirmSelection::No
} else {
ConfirmSelection::Yes
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(u8)]
pub enum TextScriptExecutionState {
@ -195,6 +215,7 @@ pub enum TextScriptExecutionState {
Msg(u16, u32, u32, u8),
WaitTicks(u16, u32, u32),
WaitInput(u16, u32),
WaitConfirmation(u16, u32, u16, u8, ConfirmSelection),
WaitFade(u16, u32),
}
@ -208,6 +229,7 @@ pub struct TextScriptVM {
pub strict_mode: bool,
pub suspend: bool,
pub face: u16,
pub item: u16,
pub current_line: TextScriptLine,
pub line_1: Vec<char>,
pub line_2: Vec<char>,
@ -305,6 +327,7 @@ impl TextScriptVM {
strict_mode: false,
suspend: true,
flags: TextScriptFlags(0),
item: 0,
face: 0,
current_line: TextScriptLine::Line1,
line_1: Vec::with_capacity(24),
@ -415,6 +438,30 @@ impl TextScriptVM {
break;
}
}
TextScriptExecutionState::WaitConfirmation(event, ip, no_event, wait, selection) => {
if wait > 0 {
state.textscript_vm.state = TextScriptExecutionState::WaitConfirmation(event, ip, no_event, wait - 1, selection);
break;
}
if state.key_trigger.left() || state.key_trigger.right() {
state.textscript_vm.state = TextScriptExecutionState::WaitConfirmation(event, ip, no_event, 0, !selection);
break;
}
if state.key_trigger.jump() {
match selection {
ConfirmSelection::Yes => {
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
},
ConfirmSelection::No => {
state.textscript_vm.state = TextScriptExecutionState::Running(no_event, 0);
},
}
}
break;
}
TextScriptExecutionState::WaitInput(event, ip) => {
if state.key_trigger.jump() || state.key_trigger.fire() {
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
@ -592,6 +639,11 @@ impl TextScriptVM {
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
}
OpCode::YNJ => {
let event_no = read_cur_varint(&mut cursor)? as u16;
exec_state = TextScriptExecutionState::WaitConfirmation(event, cursor.position() as u32, event_no, 16, ConfirmSelection::No);
}
OpCode::TRA => {
let map_id = read_cur_varint(&mut cursor)? as usize;
let event_num = read_cur_varint(&mut cursor)? as u16;
@ -687,7 +739,7 @@ impl TextScriptVM {
OpCode::BOA | OpCode::BSL | OpCode::FOB | OpCode::FOM | OpCode::UNI |
OpCode::MYB | OpCode::GIT | OpCode::NUM | OpCode::DNA |
OpCode::MPp | OpCode::SKm | OpCode::SKp | OpCode::EQp | OpCode::EQm |
OpCode::ITp | OpCode::ITm | OpCode::AMm | OpCode::UNJ | OpCode::MPJ | OpCode::YNJ |
OpCode::ITp | OpCode::ITm | OpCode::AMm | OpCode::UNJ | OpCode::MPJ |
OpCode::XX1 | OpCode::SIL | OpCode::LIp | OpCode::SOU |
OpCode::SSS | OpCode::ACH => {
let par_a = read_cur_varint(&mut cursor)?;