add text box scrolling and fix opengl cliprects

This commit is contained in:
Alula 2022-01-16 02:35:36 +01:00
parent e57bf29703
commit 87bab5fca9
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
3 changed files with 62 additions and 14 deletions

View File

@ -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 {

View File

@ -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);
}

View File

@ -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