scaling / ui tweaks, persistent timing
This commit is contained in:
parent
4854d9e758
commit
d147242199
|
@ -1,5 +1,5 @@
|
|||
use crate::common::Rect;
|
||||
use crate::components::draw_common::{Alignment, draw_number};
|
||||
use crate::components::draw_common::{draw_number, Alignment};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
|
@ -61,6 +61,15 @@ impl InventoryUI {
|
|||
fn get_item_event_number_action(&self, inventory: &Inventory) -> u16 {
|
||||
inventory.get_item_idx(self.selected_item as usize).map(|i| i.0 + 6000).unwrap_or(6000)
|
||||
}
|
||||
|
||||
fn exit(&mut self, state: &mut SharedGameState, player: &mut Player, inventory: &mut Inventory) {
|
||||
self.focus = InventoryFocus::None;
|
||||
inventory.current_item = 0;
|
||||
self.text_y_pos = 16;
|
||||
state.textscript_vm.reset();
|
||||
state.textscript_vm.set_mode(ScriptMode::Map);
|
||||
player.controller.update_trigger();
|
||||
}
|
||||
}
|
||||
|
||||
impl GameEntity<(&mut Context, &mut Player, &mut Inventory)> for InventoryUI {
|
||||
|
@ -80,12 +89,7 @@ impl GameEntity<(&mut Context, &mut Player, &mut Inventory)> for InventoryUI {
|
|||
|| player.controller.trigger_menu_back()
|
||||
|| (state.settings.touch_controls && state.touch_controls.consume_click_in(slot_rect)))
|
||||
{
|
||||
self.focus = InventoryFocus::None;
|
||||
inventory.current_item = 0;
|
||||
self.text_y_pos = 16;
|
||||
state.textscript_vm.reset();
|
||||
state.textscript_vm.set_mode(ScriptMode::Map);
|
||||
player.controller.update_trigger();
|
||||
self.exit(state, player, inventory);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -231,6 +235,7 @@ impl GameEntity<(&mut Context, &mut Player, &mut Inventory)> for InventoryUI {
|
|||
self.selected_weapon = i;
|
||||
inventory.current_weapon = i;
|
||||
state.textscript_vm.start_script(get_weapon_event_number(inventory));
|
||||
self.exit(state, player, inventory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,13 @@ fn get_insets() -> GameResult<(f32, f32, f32, f32)> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_scaled_size(width: u32, height: u32) -> (f32, f32) {
|
||||
let scaled_height = ((height / 480).max(1) * 480) as f32;
|
||||
let scaled_width = width as f32 * (scaled_height as f32 / height as f32);
|
||||
|
||||
(scaled_width, scaled_height)
|
||||
}
|
||||
|
||||
impl BackendEventLoop for GlutinEventLoop {
|
||||
fn run(&mut self, game: &mut Game, ctx: &mut Context) {
|
||||
let event_loop = EventLoop::new();
|
||||
|
@ -137,7 +144,8 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
|
||||
{
|
||||
let size = window.window().inner_size();
|
||||
ctx.screen_size = (size.width.max(1) as f32, size.height.max(1) as f32);
|
||||
ctx.real_screen_size = (size.width, size.height);
|
||||
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
|
||||
state_ref.handle_resize(ctx).unwrap();
|
||||
}
|
||||
|
||||
|
@ -188,7 +196,8 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
imgui.io_mut().display_size = [size.width as f32, size.height as f32];
|
||||
}
|
||||
|
||||
ctx.screen_size = (size.width as f32, size.height as f32);
|
||||
ctx.real_screen_size = (size.width, size.height);
|
||||
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
|
||||
state_ref.handle_resize(ctx).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -197,19 +206,21 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
{
|
||||
let mut controls = &mut state_ref.touch_controls;
|
||||
let scale = state_ref.scale as f64;
|
||||
let loc_x = (touch.location.x * ctx.screen_size.0 as f64 / ctx.real_screen_size.0 as f64) / scale;
|
||||
let loc_y = (touch.location.y * ctx.screen_size.1 as f64 / ctx.real_screen_size.1 as f64) / scale;
|
||||
|
||||
match touch.phase {
|
||||
TouchPhase::Started | TouchPhase::Moved => {
|
||||
if let Some(point) = controls.points.iter_mut().find(|p| p.id == touch.id) {
|
||||
point.last_position = point.position;
|
||||
point.position = (touch.location.x / scale, touch.location.y / scale);
|
||||
point.position = (loc_x, loc_y);
|
||||
} else {
|
||||
controls.touch_id_counter = controls.touch_id_counter.wrapping_add(1);
|
||||
|
||||
let point = TouchPoint {
|
||||
id: touch.id,
|
||||
touch_id: controls.touch_id_counter,
|
||||
position: (touch.location.x / scale, touch.location.y / scale),
|
||||
position: (loc_x, loc_y),
|
||||
last_position: (0.0, 0.0),
|
||||
};
|
||||
controls.points.push(point);
|
||||
|
|
|
@ -9,6 +9,7 @@ pub struct Context {
|
|||
pub(crate) filesystem: Filesystem,
|
||||
pub(crate) renderer: Option<Box<dyn BackendRenderer>>,
|
||||
pub(crate) keyboard_context: KeyboardContext,
|
||||
pub(crate) real_screen_size: (u32, u32),
|
||||
pub(crate) screen_size: (f32, f32),
|
||||
pub(crate) screen_insets: (f32, f32, f32, f32),
|
||||
}
|
||||
|
@ -20,6 +21,7 @@ impl Context {
|
|||
filesystem: Filesystem::new(),
|
||||
renderer: None,
|
||||
keyboard_context: KeyboardContext::new(),
|
||||
real_screen_size: (320, 240),
|
||||
screen_size: (320.0, 240.0),
|
||||
screen_insets: (0.0, 0.0, 0.0, 0.0),
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::cell::{RefCell, UnsafeCell};
|
|||
use std::ffi::{c_void, CStr};
|
||||
use std::mem;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::null;
|
||||
use std::sync::Arc;
|
||||
|
||||
use imgui::{DrawCmd, DrawCmdParams, DrawData, DrawIdx, DrawVert};
|
||||
|
@ -395,6 +396,9 @@ struct ImguiData {
|
|||
ebo: GLuint,
|
||||
font_texture: GLuint,
|
||||
font_tex_size: (f32, f32),
|
||||
surf_framebuffer: GLuint,
|
||||
surf_texture: GLuint,
|
||||
last_size: (u32, u32),
|
||||
}
|
||||
|
||||
impl ImguiData {
|
||||
|
@ -409,6 +413,9 @@ impl ImguiData {
|
|||
ebo: 0,
|
||||
font_texture: 0,
|
||||
font_tex_size: (1.0, 1.0),
|
||||
surf_framebuffer: 0,
|
||||
surf_texture: 0,
|
||||
last_size: (320, 240),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +517,36 @@ impl ImguiData {
|
|||
atlas.tex_id = (self.font_texture as usize).into();
|
||||
}
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, current_texture as _);
|
||||
let texture_id = return_param(|x| gl.gl.GenTextures(1, x));
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, texture_id);
|
||||
gl.gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as _);
|
||||
gl.gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as _);
|
||||
|
||||
gl.gl.TexImage2D(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as _,
|
||||
320 as _,
|
||||
240 as _,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
null() as _,
|
||||
);
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, 0 as _);
|
||||
|
||||
self.surf_texture = texture_id;
|
||||
|
||||
let framebuffer_id = return_param(|x| gl.gl.GenFramebuffers(1, x));
|
||||
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, framebuffer_id);
|
||||
gl.gl.FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, texture_id, 0);
|
||||
let draw_buffers = [gl::COLOR_ATTACHMENT0];
|
||||
gl.gl.DrawBuffers(1, draw_buffers.as_ptr() as _);
|
||||
|
||||
self.surf_framebuffer = framebuffer_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -631,10 +667,36 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some((context, gl)) = self.get_context() {
|
||||
unsafe {
|
||||
gl.gl.Finish();
|
||||
let ImguiData { program_tex, surf_texture, tex_locs: Locs { proj_mtx, .. }, .. } = self.imgui_data;
|
||||
|
||||
unsafe {
|
||||
if let Some((_, gl)) = self.get_context() {
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl.gl.ClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.gl.Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
|
||||
|
||||
let matrix =
|
||||
[[2.0f32, 0.0, 0.0, 0.0], [0.0, -2.0, 0.0, 0.0], [0.0, 0.0, -1.0, 0.0], [-1.0, 1.0, 0.0, 1.0]];
|
||||
|
||||
gl.gl.UseProgram(program_tex);
|
||||
gl.gl.UniformMatrix4fv(proj_mtx, 1, gl::FALSE, matrix.as_ptr() as _);
|
||||
|
||||
let color = (255, 255, 255, 255);
|
||||
let vertices = vec![
|
||||
VertexData { position: (0.0, 1.0), uv: (0.0, 0.0), color },
|
||||
VertexData { position: (0.0, 0.0), uv: (0.0, 1.0), color },
|
||||
VertexData { position: (1.0, 0.0), uv: (1.0, 1.0), color },
|
||||
VertexData { position: (0.0, 1.0), uv: (0.0, 0.0), color },
|
||||
VertexData { position: (1.0, 0.0), uv: (1.0, 1.0), color },
|
||||
VertexData { position: (1.0, 1.0), uv: (1.0, 0.0), color },
|
||||
];
|
||||
|
||||
self.draw_arrays_tex_id(gl::TRIANGLES, vertices, surf_texture, BackendShader::Texture)?;
|
||||
|
||||
gl.gl.Finish();
|
||||
}
|
||||
|
||||
if let Some((context, _)) = self.get_context() {
|
||||
(context.swap_buffers)(&mut context.user_data);
|
||||
}
|
||||
}
|
||||
|
@ -645,11 +707,35 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
fn prepare_draw(&mut self, width: f32, height: f32) -> GameResult {
|
||||
if let Some((_, gl)) = self.get_context() {
|
||||
unsafe {
|
||||
let (width_u, height_u) = (width as u32, height as u32);
|
||||
if 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);
|
||||
|
||||
gl.gl.TexImage2D(
|
||||
gl::TEXTURE_2D,
|
||||
0,
|
||||
gl::RGBA as _,
|
||||
width_u as _,
|
||||
height_u as _,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
null() as _,
|
||||
);
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, 0 as _);
|
||||
}
|
||||
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, self.imgui_data.surf_framebuffer);
|
||||
gl.gl.ClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl.gl.Clear(gl::COLOR_BUFFER_BIT);
|
||||
|
||||
gl.gl.ActiveTexture(gl::TEXTURE0);
|
||||
gl.gl.BlendEquation(gl::FUNC_ADD);
|
||||
gl.gl.BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.gl.Viewport(0, 0, width as _, height as _);
|
||||
gl.gl.Viewport(0, 0, width_u as _, height_u as _);
|
||||
|
||||
self.def_matrix = [
|
||||
[2.0 / width, 0.0, 0.0, 0.0],
|
||||
|
@ -677,7 +763,6 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
fn create_texture_mutable(&mut self, width: u16, height: u16) -> GameResult<Box<dyn BackendTexture>> {
|
||||
if let Some((_, gl)) = self.get_context() {
|
||||
unsafe {
|
||||
let data = vec![0u8; width as usize * height as usize * 4];
|
||||
let current_texture_id = return_param(|x| gl.gl.GetIntegerv(gl::TEXTURE_BINDING_2D, x)) as u32;
|
||||
let texture_id = return_param(|x| gl.gl.GenTextures(1, x));
|
||||
|
||||
|
@ -694,7 +779,7 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
data.as_ptr() as _,
|
||||
null() as _,
|
||||
);
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, current_texture_id);
|
||||
|
@ -707,6 +792,8 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
gl.gl.DrawBuffers(1, draw_buffers.as_ptr() as _);
|
||||
|
||||
gl.gl.Viewport(0, 0, width as _, height as _);
|
||||
gl.gl.ClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl.gl.Clear(gl::COLOR_BUFFER_BIT);
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
|
||||
// todo error checking: glCheckFramebufferStatus()
|
||||
|
@ -805,10 +892,20 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
];
|
||||
|
||||
gl.gl.UseProgram(self.imgui_data.program_fill);
|
||||
gl.gl.UniformMatrix4fv(self.imgui_data.fill_locs.proj_mtx, 1, gl::FALSE, self.curr_matrix.as_ptr() as _);
|
||||
gl.gl.UniformMatrix4fv(
|
||||
self.imgui_data.fill_locs.proj_mtx,
|
||||
1,
|
||||
gl::FALSE,
|
||||
self.curr_matrix.as_ptr() as _,
|
||||
);
|
||||
gl.gl.UseProgram(self.imgui_data.program_tex);
|
||||
gl.gl.Uniform1i(self.imgui_data.tex_locs.texture, 0);
|
||||
gl.gl.UniformMatrix4fv(self.imgui_data.tex_locs.proj_mtx, 1, gl::FALSE, self.curr_matrix.as_ptr() as _);
|
||||
gl.gl.UniformMatrix4fv(
|
||||
self.imgui_data.tex_locs.proj_mtx,
|
||||
1,
|
||||
gl::FALSE,
|
||||
self.curr_matrix.as_ptr() as _,
|
||||
);
|
||||
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, gl_texture.framebuffer_id);
|
||||
} else {
|
||||
|
@ -829,7 +926,7 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
gl::FALSE,
|
||||
self.def_matrix.as_ptr() as _,
|
||||
);
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl.gl.BindFramebuffer(gl::FRAMEBUFFER, self.imgui_data.surf_framebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,6 +1173,23 @@ impl OpenGLRenderer {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let texture_id = if let Some(texture) = texture {
|
||||
let gl_texture: &Box<OpenGLTexture> = std::mem::transmute(texture);
|
||||
gl_texture.texture_id
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
self.draw_arrays_tex_id(vert_type, vertices, texture_id, shader)
|
||||
}
|
||||
|
||||
unsafe fn draw_arrays_tex_id(
|
||||
&mut self,
|
||||
vert_type: GLenum,
|
||||
vertices: Vec<VertexData>,
|
||||
texture: u32,
|
||||
shader: BackendShader,
|
||||
) -> GameResult<()> {
|
||||
if let Some(gl) = GL_PROC.as_ref() {
|
||||
match shader {
|
||||
BackendShader::Fill => {
|
||||
|
@ -1148,14 +1262,7 @@ impl OpenGLRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
let texture_id = if let Some(texture) = texture {
|
||||
let gl_texture: &Box<OpenGLTexture> = std::mem::transmute(texture);
|
||||
gl_texture.texture_id
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, texture_id);
|
||||
gl.gl.BindTexture(gl::TEXTURE_2D, texture);
|
||||
gl.gl.BufferData(
|
||||
gl::ARRAY_BUFFER,
|
||||
(vertices.len() * mem::size_of::<VertexData>()) as _,
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -104,16 +104,16 @@ impl Game {
|
|||
if let Some(scene) = self.scene.as_mut() {
|
||||
let state_ref = unsafe { &mut *self.state.get() };
|
||||
|
||||
match state_ref.timing_mode {
|
||||
match state_ref.settings.timing_mode {
|
||||
TimingMode::_50Hz | TimingMode::_60Hz => {
|
||||
let last_tick = self.next_tick;
|
||||
|
||||
while self.start_time.elapsed().as_nanos() >= self.next_tick && self.loops < 10 {
|
||||
if (state_ref.settings.speed - 1.0).abs() < 0.01 {
|
||||
self.next_tick += state_ref.timing_mode.get_delta() as u128;
|
||||
self.next_tick += state_ref.settings.timing_mode.get_delta() as u128;
|
||||
} else {
|
||||
self.next_tick +=
|
||||
(state_ref.timing_mode.get_delta() as f64 / state_ref.settings.speed) as u128;
|
||||
(state_ref.settings.timing_mode.get_delta() as f64 / state_ref.settings.speed) as u128;
|
||||
}
|
||||
self.loops += 1;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ impl Game {
|
|||
log::warn!("Frame skip is way too high, a long system lag occurred?");
|
||||
self.last_tick = self.start_time.elapsed().as_nanos();
|
||||
self.next_tick = self.last_tick
|
||||
+ (state_ref.timing_mode.get_delta() as f64 / state_ref.settings.speed) as u128;
|
||||
+ (state_ref.settings.timing_mode.get_delta() as f64 / state_ref.settings.speed) as u128;
|
||||
self.loops = 0;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ impl Game {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if state_ref.timing_mode != TimingMode::FrameSynchronized {
|
||||
if state_ref.settings.timing_mode != TimingMode::FrameSynchronized {
|
||||
let mut elapsed = self.start_time.elapsed().as_nanos();
|
||||
|
||||
// Even with the non-monotonic Instant mitigation at the start of the event loop, there's still a chance of it not working.
|
||||
|
|
|
@ -64,7 +64,7 @@ impl SettingsMenu {
|
|||
|
||||
self.main.push_entry(MenuEntry::Options(
|
||||
"Game timing:".to_owned(),
|
||||
if state.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
|
||||
if state.settings.timing_mode == TimingMode::_50Hz { 0 } else { 1 },
|
||||
vec!["50tps (freeware)".to_owned(), "60tps (CS+)".to_owned()],
|
||||
));
|
||||
|
||||
|
@ -125,13 +125,13 @@ impl SettingsMenu {
|
|||
}
|
||||
MenuSelectionResult::Selected(2, toggle) => {
|
||||
if let MenuEntry::Options(_, value, _) = toggle {
|
||||
match state.timing_mode {
|
||||
match state.settings.timing_mode {
|
||||
TimingMode::_50Hz => {
|
||||
state.timing_mode = TimingMode::_60Hz;
|
||||
state.settings.timing_mode = TimingMode::_60Hz;
|
||||
*value = 1;
|
||||
}
|
||||
TimingMode::_60Hz => {
|
||||
state.timing_mode = TimingMode::_50Hz;
|
||||
state.settings.timing_mode = TimingMode::_50Hz;
|
||||
*value = 0;
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::input::keyboard_player_controller::KeyboardController;
|
|||
use crate::input::player_controller::PlayerController;
|
||||
use crate::input::touch_player_controller::TouchPlayerController;
|
||||
use crate::player::TargetPlayer;
|
||||
use crate::shared_game_state::TimingMode;
|
||||
use crate::sound::InterpolationMode;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
|
@ -24,6 +25,8 @@ pub struct Settings {
|
|||
pub motion_interpolation: bool,
|
||||
pub touch_controls: bool,
|
||||
pub soundtrack: String,
|
||||
#[serde(default = "default_timing")]
|
||||
pub timing_mode: TimingMode,
|
||||
#[serde(default = "default_interpolation")]
|
||||
pub organya_interpolation: InterpolationMode,
|
||||
#[serde(default = "p1_default_keymap")]
|
||||
|
@ -43,7 +46,10 @@ pub struct Settings {
|
|||
fn default_true() -> bool { true }
|
||||
|
||||
#[inline(always)]
|
||||
fn current_version() -> u32 { 3 }
|
||||
fn current_version() -> u32 { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
fn default_timing() -> TimingMode { TimingMode::_50Hz }
|
||||
|
||||
#[inline(always)]
|
||||
fn default_interpolation() -> InterpolationMode { InterpolationMode::Linear }
|
||||
|
@ -73,6 +79,11 @@ impl Settings {
|
|||
self.light_cone = true;
|
||||
}
|
||||
|
||||
if self.version == 3 {
|
||||
self.version = 4;
|
||||
self.timing_mode = default_timing();
|
||||
}
|
||||
|
||||
if self.version != initial_version {
|
||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||
}
|
||||
|
@ -112,6 +123,7 @@ impl Default for Settings {
|
|||
motion_interpolation: true,
|
||||
touch_controls: cfg!(target_os = "android"),
|
||||
soundtrack: "".to_string(),
|
||||
timing_mode: default_timing(),
|
||||
organya_interpolation: InterpolationMode::Linear,
|
||||
player1_key_map: p1_default_keymap(),
|
||||
player2_key_map: p2_default_keymap(),
|
||||
|
|
|
@ -32,7 +32,7 @@ use crate::str;
|
|||
use crate::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM};
|
||||
use crate::texture_set::TextureSet;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(PartialEq, Eq, Copy, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub enum TimingMode {
|
||||
_50Hz,
|
||||
_60Hz,
|
||||
|
@ -109,7 +109,6 @@ impl TileSize {
|
|||
}
|
||||
|
||||
pub struct SharedGameState {
|
||||
pub timing_mode: TimingMode,
|
||||
pub control_flags: ControlFlags,
|
||||
pub game_flags: BitVec,
|
||||
pub skip_flags: BitVec,
|
||||
|
@ -212,7 +211,6 @@ impl SharedGameState {
|
|||
init_hooks();
|
||||
|
||||
Ok(SharedGameState {
|
||||
timing_mode: TimingMode::_50Hz,
|
||||
control_flags: ControlFlags(0),
|
||||
game_flags: bitvec::bitvec![0; 8000],
|
||||
skip_flags: bitvec::bitvec![0; 64],
|
||||
|
@ -422,7 +420,7 @@ impl SharedGameState {
|
|||
}
|
||||
|
||||
pub fn current_tps(&self) -> f64 {
|
||||
self.timing_mode.get_tps() as f64 * self.settings.speed
|
||||
self.settings.timing_mode.get_tps() as f64 * self.settings.speed
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self) {
|
||||
|
|
Loading…
Reference in New Issue