mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-09-28 21:19:24 +00:00
add text box scrolling and fix opengl cliprects
This commit is contained in:
parent
e57bf29703
commit
87bab5fca9
|
@ -3,6 +3,7 @@ use crate::entity::GameEntity;
|
|||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::graphics;
|
||||
use crate::graphics::draw_rect;
|
||||
use crate::scripting::tsc::text_script::{ConfirmSelection, TextScriptExecutionState, TextScriptLine};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
|
@ -156,15 +157,29 @@ impl GameEntity<()> for TextBoxes {
|
|||
|
||||
let text_offset = if state.textscript_vm.face == 0 { 0.0 } else { 56.0 };
|
||||
|
||||
let y_offset = if let TextScriptExecutionState::MsgNewLine(_, _, _, _, counter) = state.textscript_vm.state {
|
||||
16.0 - counter as f32 * 4.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
let lines = [&state.textscript_vm.line_1, &state.textscript_vm.line_2, &state.textscript_vm.line_3];
|
||||
|
||||
let clip_rect = Rect::new_size(
|
||||
0,
|
||||
((top_pos + 6.0) * state.scale) as isize,
|
||||
state.screen_size.0 as isize,
|
||||
(48.0 * state.scale) as isize,
|
||||
);
|
||||
|
||||
graphics::set_clip_rect(ctx, Some(clip_rect))?;
|
||||
for (idx, line) in lines.iter().enumerate() {
|
||||
if !line.is_empty() {
|
||||
if state.constants.textscript.text_shadow {
|
||||
state.font.draw_text_with_shadow(
|
||||
line.iter().copied(),
|
||||
left_pos + text_offset + 14.0,
|
||||
top_pos + 10.0 + idx as f32 * 16.0,
|
||||
top_pos + 10.0 + idx as f32 * 16.0 - y_offset,
|
||||
&state.constants,
|
||||
&mut state.texture_set,
|
||||
ctx,
|
||||
|
@ -173,7 +188,7 @@ impl GameEntity<()> for TextBoxes {
|
|||
state.font.draw_text(
|
||||
line.iter().copied(),
|
||||
left_pos + text_offset + 14.0,
|
||||
top_pos + 10.0 + idx as f32 * 16.0,
|
||||
top_pos + 10.0 + idx as f32 * 16.0 - y_offset,
|
||||
&state.constants,
|
||||
&mut state.texture_set,
|
||||
ctx,
|
||||
|
@ -181,6 +196,7 @@ impl GameEntity<()> for TextBoxes {
|
|||
}
|
||||
}
|
||||
}
|
||||
graphics::set_clip_rect(ctx, None)?;
|
||||
|
||||
if let TextScriptExecutionState::WaitInput(_, _, tick) = state.textscript_vm.state {
|
||||
if tick > 10 {
|
||||
|
|
|
@ -714,6 +714,7 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
unsafe {
|
||||
let (width_u, height_u) = (width as u32, height as u32);
|
||||
if self.imgui_data.last_size != (width_u, height_u) {
|
||||
self.imgui_data.last_size = (width_u, height_u);
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, self.imgui_data.surf_texture);
|
||||
|
||||
|
@ -1028,7 +1029,12 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
unsafe {
|
||||
if let Some(rect) = &rect {
|
||||
gl.gl.Enable(gl::SCISSOR_TEST);
|
||||
gl.gl.Scissor(rect.left as GLint, rect.top as GLint, rect.width() as GLint, rect.height() as GLint);
|
||||
gl.gl.Scissor(
|
||||
rect.left as GLint,
|
||||
self.imgui_data.last_size.1 as GLint - rect.bottom as GLint,
|
||||
rect.width() as GLint,
|
||||
rect.height() as GLint,
|
||||
);
|
||||
} else {
|
||||
gl.gl.Disable(gl::SCISSOR_TEST);
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ use std::rc::Rc;
|
|||
use num_traits::{clamp, FromPrimitive};
|
||||
|
||||
use crate::bitfield;
|
||||
use crate::common::Direction::{Left, Right};
|
||||
use crate::common::{Direction, FadeDirection, FadeState, Rect};
|
||||
use crate::common::Direction::{Left, Right};
|
||||
use crate::engine_constants::EngineConstants;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::UpdateTarget;
|
||||
|
@ -87,6 +87,7 @@ pub enum TextScriptExecutionState {
|
|||
Ended,
|
||||
Running(u16, u32),
|
||||
Msg(u16, u32, u32, u8),
|
||||
MsgNewLine(u16, u32, u32, u8, u8),
|
||||
WaitTicks(u16, u32, u16),
|
||||
WaitInput(u16, u32, u16),
|
||||
WaitStanding(u16, u32),
|
||||
|
@ -324,6 +325,7 @@ impl TextScriptVM {
|
|||
|
||||
if let Some((_, bytecode)) = cached_event {
|
||||
let mut cursor = Cursor::new(bytecode);
|
||||
let mut new_line = false;
|
||||
cursor.seek(SeekFrom::Start(ip as u64))?;
|
||||
|
||||
let chr = std::char::from_u32(read_cur_varint(&mut cursor)? as u32).unwrap_or('\u{fffd}');
|
||||
|
@ -336,9 +338,7 @@ impl TextScriptVM {
|
|||
state.textscript_vm.current_line = TextScriptLine::Line3;
|
||||
}
|
||||
'\n' => {
|
||||
state.textscript_vm.line_1.clear();
|
||||
state.textscript_vm.line_1.append(&mut state.textscript_vm.line_2);
|
||||
state.textscript_vm.line_2.append(&mut state.textscript_vm.line_3);
|
||||
new_line = true;
|
||||
}
|
||||
'\r' => {}
|
||||
_ if state.textscript_vm.current_line == TextScriptLine::Line1 => {
|
||||
|
@ -368,9 +368,7 @@ impl TextScriptVM {
|
|||
let text_len =
|
||||
state.font.text_width(state.textscript_vm.line_3.iter().copied(), &state.constants);
|
||||
if text_len >= 284.0 {
|
||||
state.textscript_vm.line_1.clear();
|
||||
state.textscript_vm.line_1.append(&mut state.textscript_vm.line_2);
|
||||
state.textscript_vm.line_2.append(&mut state.textscript_vm.line_3);
|
||||
new_line = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -395,8 +393,11 @@ impl TextScriptVM {
|
|||
state.sound_manager.play_sfx(2);
|
||||
}
|
||||
|
||||
state.textscript_vm.state =
|
||||
TextScriptExecutionState::Msg(event, cursor.position() as u32, remaining - 1, ticks);
|
||||
state.textscript_vm.state = if !new_line {
|
||||
TextScriptExecutionState::Msg(event, cursor.position() as u32, remaining - 1, ticks)
|
||||
} else {
|
||||
TextScriptExecutionState::MsgNewLine(event, cursor.position() as u32, remaining - 1, ticks, 4)
|
||||
};
|
||||
} else {
|
||||
state.textscript_vm.state =
|
||||
TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
|
@ -405,6 +406,23 @@ impl TextScriptVM {
|
|||
state.textscript_vm.reset();
|
||||
}
|
||||
}
|
||||
TextScriptExecutionState::MsgNewLine(event, ip, remaining, ticks, mut counter) => {
|
||||
counter = if state.textscript_vm.flags.fast() || state.textscript_vm.flags.cutscene_skip() {
|
||||
0
|
||||
} else {
|
||||
counter.saturating_sub(1)
|
||||
};
|
||||
|
||||
if counter == 0 {
|
||||
state.textscript_vm.line_1.clear();
|
||||
state.textscript_vm.line_1.append(&mut state.textscript_vm.line_2);
|
||||
state.textscript_vm.line_2.append(&mut state.textscript_vm.line_3);
|
||||
state.textscript_vm.state = TextScriptExecutionState::Msg(event, ip, remaining, ticks);
|
||||
} else {
|
||||
state.textscript_vm.state = TextScriptExecutionState::MsgNewLine(event, ip, remaining, ticks, counter);
|
||||
}
|
||||
break;
|
||||
}
|
||||
TextScriptExecutionState::WaitTicks(event, ip, ticks) => {
|
||||
if ticks == 0 {
|
||||
state.textscript_vm.state = TextScriptExecutionState::Running(event, ip);
|
||||
|
@ -543,7 +561,8 @@ impl TextScriptVM {
|
|||
pos_y += 0x33;
|
||||
}
|
||||
|
||||
state.textscript_vm.state = TextScriptExecutionState::FallingIsland(event, ip, pos_x, pos_y, tick, mode);
|
||||
state.textscript_vm.state =
|
||||
TextScriptExecutionState::FallingIsland(event, ip, pos_x, pos_y, tick, mode);
|
||||
break;
|
||||
}
|
||||
TextScriptExecutionState::SaveProfile(event, ip) => {
|
||||
|
@ -1622,7 +1641,14 @@ impl TextScriptVM {
|
|||
TSCOpCode::XX1 => {
|
||||
let mode = read_cur_varint(&mut cursor)?;
|
||||
|
||||
exec_state = TextScriptExecutionState::FallingIsland(event, cursor.position() as u32, 0x15000, 0x8000, 0, mode != 0);
|
||||
exec_state = TextScriptExecutionState::FallingIsland(
|
||||
event,
|
||||
cursor.position() as u32,
|
||||
0x15000,
|
||||
0x8000,
|
||||
0,
|
||||
mode != 0,
|
||||
);
|
||||
}
|
||||
// unimplemented opcodes
|
||||
// Zero operands
|
||||
|
|
Loading…
Reference in a new issue