mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-11-25 21:55:50 +00:00
Improve TextScript VM to make it execute ingame-conversations
This commit is contained in:
parent
677f928467
commit
8f908b306d
|
|
@ -88,12 +88,18 @@ impl Clone for WorldConsts {
|
|||
#[derive(Debug)]
|
||||
pub struct TextScriptConsts {
|
||||
pub encoding: TextScriptEncoding,
|
||||
pub textbox_rect_top: Rect<usize>,
|
||||
pub textbox_rect_middle: Rect<usize>,
|
||||
pub textbox_rect_bottom: Rect<usize>,
|
||||
}
|
||||
|
||||
impl Clone for TextScriptConsts {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
encoding: self.encoding,
|
||||
textbox_rect_top: self.textbox_rect_top,
|
||||
textbox_rect_middle: self.textbox_rect_middle,
|
||||
textbox_rect_bottom: self.textbox_rect_bottom,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -364,7 +370,10 @@ impl EngineConstants {
|
|||
},
|
||||
textscript: TextScriptConsts {
|
||||
encoding: TextScriptEncoding::UTF8,
|
||||
}
|
||||
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 },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ impl LiveDebugger {
|
|||
.size([300.0, 100.0], Condition::Appearing)
|
||||
.build(ui, || {
|
||||
ui.push_item_width(-1.0);
|
||||
ui.text(self.error.as_ref().unwrap());
|
||||
ui.text_wrapped(self.error.as_ref().unwrap());
|
||||
|
||||
if ui.button(im_str!("OK"), [0.0, 0.0]) {
|
||||
self.error = None;
|
||||
|
|
@ -135,25 +135,29 @@ impl LiveDebugger {
|
|||
Window::new(im_str!("Events"))
|
||||
.resizable(false)
|
||||
.position([80.0, 80.0], Condition::FirstUseEver)
|
||||
.size([250.0, 300.0], Condition::FirstUseEver)
|
||||
.size([280.0, 300.0], Condition::FirstUseEver)
|
||||
.build(ui, || {
|
||||
if self.events.is_empty() {
|
||||
self.event_ids.clear();
|
||||
|
||||
let vm = &state.textscript_vm;
|
||||
for event in vm.global_script.get_event_ids() {
|
||||
for event in vm.scripts.global_script.get_event_ids() {
|
||||
self.events.push(ImString::new(format!("Global: #{:04}", event)));
|
||||
self.event_ids.push(event);
|
||||
}
|
||||
|
||||
for event in vm.scene_script.get_event_ids() {
|
||||
for event in vm.scripts.scene_script.get_event_ids() {
|
||||
self.events.push(ImString::new(format!("Scene: #{:04}", event)));
|
||||
self.event_ids.push(event);
|
||||
}
|
||||
}
|
||||
let events: Vec<&ImStr> = self.events.iter().map(|e| e.as_ref()).collect();
|
||||
|
||||
ui.text(format!("Execution state: {:?}", state.textscript_vm.state));
|
||||
ui.text_wrapped(&ImString::new(format!("Execution state: {:?}", state.textscript_vm.state)));
|
||||
let line1: String = state.textscript_vm.line_1.iter().collect();
|
||||
let line2: String = state.textscript_vm.line_2.iter().collect();
|
||||
ui.text_wrapped(&ImString::new(&line1));
|
||||
ui.text_wrapped(&ImString::new(&line2));
|
||||
|
||||
ui.push_item_width(-1.0);
|
||||
ui.list_box(im_str!(""), &mut self.selected_event, &events, 10);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ bitfield! {
|
|||
}
|
||||
|
||||
bitfield! {
|
||||
pub struct ControlFlags(u32);
|
||||
pub struct ControlFlags(u16);
|
||||
impl Debug;
|
||||
pub flag_x01, set_flag_x01: 0;
|
||||
pub control_enabled, set_control_enabled: 1;
|
||||
|
|
|
|||
|
|
@ -87,12 +87,12 @@ pub struct Player {
|
|||
pub unit: u8,
|
||||
pub question: bool,
|
||||
pub booster_fuel: usize,
|
||||
pub up: bool,
|
||||
pub down: bool,
|
||||
pub shock_counter: u8,
|
||||
index_x: isize,
|
||||
index_y: isize,
|
||||
sprash: bool,
|
||||
up: bool,
|
||||
down: bool,
|
||||
shock_counter: u8,
|
||||
booster_switch: u8,
|
||||
star: u8,
|
||||
bubble: u8,
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ use crate::entity::GameEntity;
|
|||
use crate::frame::Frame;
|
||||
use crate::ggez::{Context, GameResult, timer};
|
||||
use crate::ggez::nalgebra::clamp;
|
||||
use crate::live_debugger::LiveDebugger;
|
||||
use crate::player::Player;
|
||||
use crate::scene::Scene;
|
||||
use crate::SharedGameState;
|
||||
use crate::stage::{BackgroundType, Stage};
|
||||
use crate::str;
|
||||
use crate::ui::{UI, Components};
|
||||
use crate::text_script::{TextScript, TextScriptVM};
|
||||
use crate::ui::Components;
|
||||
|
||||
pub struct GameScene {
|
||||
pub tick: usize,
|
||||
|
|
@ -22,6 +21,7 @@ pub struct GameScene {
|
|||
pub stage_id: usize,
|
||||
tex_background_name: String,
|
||||
tex_caret_name: String,
|
||||
tex_face_name: String,
|
||||
tex_hud_name: String,
|
||||
tex_npcsym_name: String,
|
||||
tex_tileset_name: String,
|
||||
|
|
@ -51,6 +51,7 @@ impl GameScene {
|
|||
|
||||
let tex_background_name = stage.data.background.filename();
|
||||
let tex_caret_name = str!("Caret");
|
||||
let tex_face_name = str!("Face");
|
||||
let tex_hud_name = str!("TextBox");
|
||||
let tex_npcsym_name = str!("Npc/NpcSym");
|
||||
let tex_tileset_name = ["Stage/", &stage.data.tileset.filename()].join("");
|
||||
|
|
@ -67,6 +68,7 @@ impl GameScene {
|
|||
stage_id: id,
|
||||
tex_background_name,
|
||||
tex_caret_name,
|
||||
tex_face_name,
|
||||
tex_hud_name,
|
||||
tex_npcsym_name,
|
||||
tex_tileset_name,
|
||||
|
|
@ -208,6 +210,37 @@ impl GameScene {
|
|||
}
|
||||
|
||||
fn draw_black_bars(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_text_boxes(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||
if !state.textscript_vm.flags.render() { return Ok(()); }
|
||||
|
||||
let top_pos = if state.textscript_vm.flags.position_top() { 32.0 } else { state.canvas_size.1 as f32 - 64.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, &self.tex_hud_name)?;
|
||||
|
||||
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 + 64.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, &self.tex_face_name)?;
|
||||
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,
|
||||
48, 48,
|
||||
));
|
||||
|
||||
batch.draw(ctx)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -320,7 +353,7 @@ impl Scene for GameScene {
|
|||
}
|
||||
}
|
||||
|
||||
TextScriptVM::run(state, self);
|
||||
TextScriptVM::run(state, self)?;
|
||||
self.tick = self.tick.wrapping_add(1);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -337,6 +370,8 @@ impl Scene for GameScene {
|
|||
self.draw_hud(state, ctx)?;
|
||||
self.draw_number(state.canvas_size.0 - 8.0, 8.0, timer::fps(ctx) as usize, Alignment::Right, state, ctx)?;
|
||||
|
||||
self.draw_text_boxes(state, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use num_derive::FromPrimitive;
|
|||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::{SharedGameState, str};
|
||||
use crate::common::CursorIterator;
|
||||
use crate::bitfield;
|
||||
use crate::ggez::GameError::ParseError;
|
||||
use crate::ggez::GameResult;
|
||||
use crate::scene::game_scene::GameScene;
|
||||
|
|
@ -161,29 +161,47 @@ pub enum OpCode {
|
|||
// ---- Custom opcodes, for use by modders ----
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumIter, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
bitfield! {
|
||||
pub struct TextScriptFlags(u16);
|
||||
impl Debug;
|
||||
pub render, set_render: 0;
|
||||
pub background_visible, set_background_visible: 1;
|
||||
pub flag_x10, set_flag_x10: 4;
|
||||
pub position_top, set_position_top: 5;
|
||||
pub flag_x40, set_flag_x40: 6;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[repr(u8)]
|
||||
pub enum TextScriptEncoding {
|
||||
UTF8,
|
||||
UTF8 = 0,
|
||||
ShiftJIS,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[repr(u8)]
|
||||
pub enum TextScriptLine {
|
||||
Line1 = 0,
|
||||
Line2,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum TextScriptExecutionState {
|
||||
Ended,
|
||||
Running(u16, u32),
|
||||
Msg(u16, u32, u32),
|
||||
Msg(u16, u32, u32, u8),
|
||||
WaitTicks(u16, u32, u32),
|
||||
WaitInput(u16, u32),
|
||||
}
|
||||
|
||||
pub struct TextScriptVM {
|
||||
pub global_script: TextScript,
|
||||
pub scene_script: TextScript,
|
||||
pub scripts: TextScriptVMScripts,
|
||||
pub state: TextScriptExecutionState,
|
||||
msg_timer: u8,
|
||||
face: u16,
|
||||
line_1: Vec<char>,
|
||||
line_2: Vec<char>,
|
||||
pub flags: TextScriptFlags,
|
||||
pub face: u16,
|
||||
pub current_line: TextScriptLine,
|
||||
pub line_1: Vec<char>,
|
||||
pub line_2: Vec<char>,
|
||||
}
|
||||
|
||||
impl Default for TextScriptVM {
|
||||
|
|
@ -192,6 +210,23 @@ impl Default for TextScriptVM {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct TextScriptVMScripts {
|
||||
pub global_script: TextScript,
|
||||
pub scene_script: TextScript,
|
||||
}
|
||||
|
||||
impl TextScriptVMScripts {
|
||||
pub fn find_script(&self, event_num: u16) -> Option<&Vec<u8>> {
|
||||
if let Some(tsc) = self.scene_script.event_map.get(&event_num) {
|
||||
return Some(tsc);
|
||||
} else if let Some(tsc) = self.global_script.event_map.get(&event_num) {
|
||||
return Some(tsc);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn read_cur_varint(cursor: &mut Cursor<&Vec<u8>>) -> GameResult<i32> {
|
||||
let mut result = 0u32;
|
||||
|
||||
|
|
@ -209,9 +244,9 @@ fn read_cur_varint(cursor: &mut Cursor<&Vec<u8>>) -> GameResult<i32> {
|
|||
|
||||
/// Decodes UTF-8 character in a less strict way.
|
||||
/// http://simonsapin.github.io/wtf-8/#decoding-wtf-8
|
||||
fn read_cur_wtf8(cursor: &mut Cursor<&Vec<u8>>, max_bytes: usize) -> (u8, char) {
|
||||
fn read_cur_wtf8(cursor: &mut Cursor<&Vec<u8>>, max_bytes: u32) -> (u32, char) {
|
||||
let mut result = 0u32;
|
||||
let mut consumed = 0u8;
|
||||
let mut consumed = 0u32;
|
||||
|
||||
if max_bytes == 0 {
|
||||
return (0, '\u{fffd}');
|
||||
|
|
@ -256,39 +291,38 @@ fn read_cur_wtf8(cursor: &mut Cursor<&Vec<u8>>, max_bytes: usize) -> (u8, char)
|
|||
impl TextScriptVM {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
global_script: TextScript::new(),
|
||||
scene_script: TextScript::new(),
|
||||
scripts: TextScriptVMScripts {
|
||||
global_script: TextScript::new(),
|
||||
scene_script: TextScript::new(),
|
||||
},
|
||||
state: TextScriptExecutionState::Ended,
|
||||
msg_timer: 0,
|
||||
flags: TextScriptFlags(0),
|
||||
face: 0,
|
||||
current_line: TextScriptLine::Line1,
|
||||
line_1: Vec::with_capacity(24),
|
||||
line_2: Vec::with_capacity(24),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_global_script(&mut self, script: TextScript) {
|
||||
self.global_script = script;
|
||||
self.scripts.global_script = script;
|
||||
self.reset();
|
||||
}
|
||||
|
||||
pub fn set_scene_script(&mut self, script: TextScript) {
|
||||
self.scene_script = script;
|
||||
self.scripts.scene_script = script;
|
||||
self.reset();
|
||||
}
|
||||
|
||||
pub fn find_script(&self, event_num: u16) -> Option<&Vec<u8>> {
|
||||
if let Some(tsc) = self.scene_script.event_map.get(&event_num) {
|
||||
return Some(tsc);
|
||||
} else if let Some(tsc) = self.global_script.event_map.get(&event_num) {
|
||||
return Some(tsc);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.state = TextScriptExecutionState::Ended;
|
||||
self.clear_text_box();
|
||||
}
|
||||
|
||||
pub fn clear_text_box(&mut self) {
|
||||
self.flags.0 = 0;
|
||||
self.face = 0;
|
||||
self.current_line = TextScriptLine::Line1;
|
||||
self.line_1.clear();
|
||||
self.line_2.clear();
|
||||
}
|
||||
|
|
@ -303,14 +337,52 @@ impl TextScriptVM {
|
|||
loop {
|
||||
match state.textscript_vm.state {
|
||||
TextScriptExecutionState::Ended => {
|
||||
state.control_flags.set_flag_x04(false);
|
||||
break;
|
||||
}
|
||||
TextScriptExecutionState::Running(event, ip) => {
|
||||
state.control_flags.set_flag_x04(true);
|
||||
state.textscript_vm.state = TextScriptVM::execute(event, ip, state, game_scene)?;
|
||||
println!("new vm state: {:?}", state.textscript_vm.state);
|
||||
|
||||
if state.textscript_vm.state == TextScriptExecutionState::Ended {
|
||||
state.textscript_vm.reset();
|
||||
}
|
||||
}
|
||||
TextScriptExecutionState::Msg(event, ip, remaining) => {
|
||||
if let Some(bytecode) = state.textscript_vm.find_script(event) {} else {
|
||||
TextScriptExecutionState::Msg(event, ip, remaining, timer) => {
|
||||
if timer > 0 {
|
||||
state.textscript_vm.state = TextScriptExecutionState::Msg(event, ip, remaining, timer - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if let Some(bytecode) = state.textscript_vm.scripts.find_script(event) {
|
||||
let mut cursor = Cursor::new(bytecode);
|
||||
cursor.seek(SeekFrom::Start(ip as u64))?;
|
||||
|
||||
let (consumed, chr) = read_cur_wtf8(&mut cursor, remaining);
|
||||
println!("char: {} {} {}", chr, remaining, consumed);
|
||||
|
||||
match chr {
|
||||
'\n' => {
|
||||
state.textscript_vm.line_1.clear();
|
||||
state.textscript_vm.line_2.append(&mut state.textscript_vm.line_1);
|
||||
}
|
||||
'\r' => {}
|
||||
_ if state.textscript_vm.current_line == TextScriptLine::Line1 => {
|
||||
state.textscript_vm.line_1.push(chr);
|
||||
}
|
||||
_ if state.textscript_vm.current_line == TextScriptLine::Line2 => {
|
||||
state.textscript_vm.line_2.push(chr);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if (remaining - consumed) > 0 {
|
||||
let ticks = if state.key_state.jump() || state.key_state.fire() { 1 } else { 4 };
|
||||
state.textscript_vm.state = TextScriptExecutionState::Msg(event, ip + consumed, remaining - consumed, ticks);
|
||||
} else {
|
||||
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip + consumed);
|
||||
}
|
||||
} else {
|
||||
state.textscript_vm.reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -337,28 +409,61 @@ impl TextScriptVM {
|
|||
pub fn execute(event: u16, ip: u32, state: &mut SharedGameState, game_scene: &mut GameScene) -> GameResult<TextScriptExecutionState> {
|
||||
let mut exec_state = state.textscript_vm.state;
|
||||
|
||||
if let Some(bytecode) = state.textscript_vm.find_script(event) {
|
||||
if let Some(bytecode) = state.textscript_vm.scripts.find_script(event) {
|
||||
let mut cursor = Cursor::new(bytecode);
|
||||
cursor.seek(SeekFrom::Start(ip as u64))?;
|
||||
|
||||
let op_maybe: Option<OpCode> = FromPrimitive::from_i32(read_cur_varint(&mut cursor)?);
|
||||
|
||||
if let Some(op) = op_maybe {
|
||||
println!("opcode: {:?}", op);
|
||||
match op {
|
||||
OpCode::_NOP => {
|
||||
println!("opcode: {:?}", op);
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::_UNI => {}
|
||||
OpCode::_STR => {
|
||||
// simply skip the text if we aren't in message mode.
|
||||
let len = read_cur_varint(&mut cursor)? as u32;
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32 + len);
|
||||
if state.textscript_vm.flags.render() {
|
||||
exec_state = TextScriptExecutionState::Msg(event, cursor.position() as u32, len, 4);
|
||||
} else {
|
||||
// simply skip the text if we aren't in message mode.
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32 + len);
|
||||
}
|
||||
}
|
||||
OpCode::_END | OpCode::END => {
|
||||
state.control_flags.set_flag_x01(true);
|
||||
state.control_flags.set_control_enabled(true);
|
||||
|
||||
exec_state = TextScriptExecutionState::Ended;
|
||||
}
|
||||
OpCode::PRI => {
|
||||
state.control_flags.set_flag_x01(false);
|
||||
state.control_flags.set_control_enabled(false);
|
||||
|
||||
game_scene.player.shock_counter = 0;
|
||||
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::KEY => {
|
||||
state.control_flags.set_flag_x01(true);
|
||||
state.control_flags.set_control_enabled(false);
|
||||
|
||||
game_scene.player.up = false;
|
||||
game_scene.player.down = false;
|
||||
game_scene.player.shock_counter = 0;
|
||||
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::FRE => {
|
||||
state.control_flags.set_flag_x01(true);
|
||||
state.control_flags.set_control_enabled(true);
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::WAI => {
|
||||
let ticks = read_cur_varint(&mut cursor)? as u32;
|
||||
exec_state = TextScriptExecutionState::WaitTicks(event, cursor.position() as u32, ticks);
|
||||
}
|
||||
OpCode::NOD => {
|
||||
exec_state = TextScriptExecutionState::WaitInput(event, cursor.position() as u32);
|
||||
}
|
||||
|
|
@ -372,6 +477,8 @@ impl TextScriptVM {
|
|||
let event_num = read_cur_varint(&mut cursor)? as u16;
|
||||
if let Some(true) = state.game_flags.get(flag_num) {
|
||||
exec_state = TextScriptExecutionState::Running(event_num, 0);
|
||||
} else {
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
}
|
||||
OpCode::EVE => {
|
||||
|
|
@ -380,6 +487,7 @@ impl TextScriptVM {
|
|||
}
|
||||
OpCode::MM0 => {
|
||||
game_scene.player.vel_x = 0;
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::CMP => {
|
||||
let pos_x = read_cur_varint(&mut cursor)? as usize;
|
||||
|
|
@ -397,23 +505,41 @@ impl TextScriptVM {
|
|||
game_scene.player.max_life += life;
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::FAC => {
|
||||
let face = read_cur_varint(&mut cursor)? as u16;
|
||||
state.textscript_vm.face = face;
|
||||
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
OpCode::MSG => {
|
||||
state.textscript_vm.face = 0;
|
||||
state.textscript_vm.current_line = TextScriptLine::Line1;
|
||||
state.textscript_vm.line_1.clear();
|
||||
state.textscript_vm.line_2.clear();
|
||||
state.textscript_vm.flags.set_render(true);
|
||||
state.textscript_vm.flags.set_background_visible(true);
|
||||
state.textscript_vm.flags.set_flag_x10(state.textscript_vm.flags.flag_x40());
|
||||
state.textscript_vm.flags.set_position_top(false);
|
||||
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
|
||||
// unimplemented opcodes
|
||||
// Zero operands
|
||||
OpCode::AEp | OpCode::CAT | OpCode::CIL | OpCode::CLO | OpCode::CLR | OpCode::CPS |
|
||||
OpCode::CRE | OpCode::CSS | OpCode::ESC | OpCode::FLA | OpCode::FMU |
|
||||
OpCode::FRE | OpCode::HMC | OpCode::INI | OpCode::KEY | OpCode::LDP | OpCode::MLP |
|
||||
OpCode::MNA | OpCode::MS2 | OpCode::MS3 | OpCode::MSG |
|
||||
OpCode::PRI | OpCode::RMU | OpCode::SAT | OpCode::SLP | OpCode::SMC | OpCode::SPS |
|
||||
OpCode::HMC | OpCode::INI | OpCode::LDP | OpCode::MLP |
|
||||
OpCode::MNA | OpCode::MS2 | OpCode::MS3 |
|
||||
OpCode::RMU | OpCode::SAT | OpCode::SLP | OpCode::SMC | OpCode::SPS |
|
||||
OpCode::STC | OpCode::SVP | OpCode::TUR | OpCode::WAS | OpCode::ZAM => {
|
||||
println!("unimplemented opcode: {:?}", op);
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
// One operand codes
|
||||
OpCode::BOA | OpCode::BSL | OpCode::FOB | OpCode::FOM | OpCode::QUA | OpCode::UNI |
|
||||
OpCode::MYB | OpCode::MYD | OpCode::FAI | OpCode::FAO | OpCode::WAI | OpCode::FAC |
|
||||
OpCode::MYB | OpCode::MYD | OpCode::FAI | OpCode::FAO | OpCode::FAC |
|
||||
OpCode::GIT | OpCode::NUM | OpCode::DNA | OpCode::DNP |
|
||||
OpCode::MPp | OpCode::SKm | OpCode::SKp | OpCode::EQp | OpCode::EQm | OpCode::MLp |
|
||||
OpCode::MPp | OpCode::SKm | OpCode::SKp | OpCode::EQp | OpCode::EQm |
|
||||
OpCode::ITp | OpCode::ITm | OpCode::AMm | OpCode::UNJ | OpCode::MPJ | OpCode::YNJ |
|
||||
OpCode::XX1 | OpCode::SIL | OpCode::LIp | OpCode::SOU | OpCode::CMU |
|
||||
OpCode::SSS | OpCode::ACH => {
|
||||
|
|
@ -447,6 +573,8 @@ impl TextScriptVM {
|
|||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exec_state = TextScriptExecutionState::Ended;
|
||||
}
|
||||
} else {
|
||||
return Ok(TextScriptExecutionState::Ended);
|
||||
|
|
@ -531,7 +659,7 @@ impl TextScript {
|
|||
println!("{:x?}", &bytecode);
|
||||
event_map.insert(event_num, bytecode);
|
||||
}
|
||||
b'\r' | b'\n' => {
|
||||
b'\r' | b'\n' | b' ' => {
|
||||
iter.next();
|
||||
}
|
||||
n => {
|
||||
|
|
|
|||
|
|
@ -159,4 +159,9 @@ impl TextureSet {
|
|||
|
||||
Ok(self.tex_map.get_mut(name).unwrap())
|
||||
}
|
||||
|
||||
pub fn draw_text(&mut self, ctx: &mut Context, text: &str) -> GameResult {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue