mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-03-23 10:29:18 +00:00
fix a bunch of warnings, bugs and compilation
This commit is contained in:
parent
318d94d843
commit
a8a9c6316d
12
Cargo.toml
12
Cargo.toml
|
@ -41,7 +41,7 @@ opt-level = 1
|
|||
|
||||
[features]
|
||||
default = ["scripting", "backend-sdl"]
|
||||
backend-sdl = ["sdl2", "sdl2-sys", "imgui-sdl2"]
|
||||
backend-sdl = ["sdl2"]
|
||||
backend-gfx = ["winit", "imgui-gfx-renderer", "imgui-winit-support"]
|
||||
scripting = ["lua-ffi"]
|
||||
editor = []
|
||||
|
@ -53,10 +53,9 @@ case_insensitive_hashmap = "1.0.0"
|
|||
chrono = "0.4"
|
||||
cpal = { git = "https://github.com/doukutsu-rs/cpal.git", branch = "android-support" }
|
||||
directories = "3"
|
||||
imgui = "0.6.0"
|
||||
imgui-gfx-renderer = { version = "0.6.0", optional = true }
|
||||
imgui-winit-support = { version = "0.6.0", default-features = false, features = ["winit-23"], optional = true }
|
||||
imgui-sdl2 = { version = "0.13.0", optional = true }
|
||||
imgui = "0.7.0"
|
||||
imgui-gfx-renderer = { version = "0.7.0", optional = true }
|
||||
imgui-winit-support = { version = "0.7.0", default-features = false, features = ["winit-23"], optional = true }
|
||||
image = { version = "0.22", default-features = false, features = ["png_codec", "pnm", "bmp"] }
|
||||
itertools = "0.9.0"
|
||||
lazy_static = "1.4.0"
|
||||
|
@ -67,8 +66,7 @@ num-derive = "0.3.2"
|
|||
num-traits = "0.2.12"
|
||||
paste = "1.0.0"
|
||||
pretty_env_logger = "0.4.0"
|
||||
sdl2 = { version = "0.34.3", optional = true, features = ["unsafe_textures", "bundled", "gfx"] }
|
||||
sdl2-sys = { version = "0.34", optional = true, features = ["bundled", "gfx"] }
|
||||
sdl2 = { version = "0.34", optional = true, features = ["unsafe_textures", "bundled", "gfx", "static-link"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_derive = "1"
|
||||
serde_yaml = "0.8"
|
||||
|
|
|
@ -388,22 +388,6 @@ pub struct Color {
|
|||
pub a: f32,
|
||||
}
|
||||
|
||||
/// White
|
||||
pub const WHITE: Color = Color {
|
||||
r: 1.0,
|
||||
g: 1.0,
|
||||
b: 1.0,
|
||||
a: 1.0,
|
||||
};
|
||||
|
||||
/// Black
|
||||
pub const BLACK: Color = Color {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 1.0,
|
||||
};
|
||||
|
||||
impl Color {
|
||||
/// Create a new `Color` from four `f32`'s in the range `[0.0-1.0]`
|
||||
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
|
||||
|
|
|
@ -52,5 +52,6 @@ pub fn init_backend() -> GameResult<Box<dyn Backend>> {
|
|||
|
||||
pub enum SpriteBatchCommand {
|
||||
DrawRect(Rect<f32>, Rect<f32>),
|
||||
DrawRectFlip(Rect<f32>, Rect<f32>, bool, bool),
|
||||
DrawRectTinted(Rect<f32>, Rect<f32>, Color),
|
||||
}
|
||||
|
|
|
@ -3,22 +3,23 @@ use std::cell::RefCell;
|
|||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use imgui::{DrawCmd, DrawData, ImString, TextureId, Ui};
|
||||
use imgui::internal::RawWrapper;
|
||||
use sdl2::{EventPump, keyboard, pixels, Sdl};
|
||||
use imgui::{ConfigFlags, DrawCmd, DrawData, ImString, Key, MouseCursor, TextureId, Ui};
|
||||
use sdl2::event::{Event, WindowEvent};
|
||||
use sdl2::gfx::primitives::DrawRenderer;
|
||||
use sdl2::keyboard::Scancode;
|
||||
use sdl2::mouse::{Cursor, SystemCursor};
|
||||
use sdl2::pixels::PixelFormatEnum;
|
||||
use sdl2::render::{Texture, TextureCreator, WindowCanvas};
|
||||
use sdl2::surface::Surface;
|
||||
use sdl2::video::WindowContext;
|
||||
use sdl2::{keyboard, pixels, EventPump, Sdl};
|
||||
|
||||
use crate::common::Color;
|
||||
use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand};
|
||||
use crate::framework::backend::{
|
||||
Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand,
|
||||
};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::{GameError, GameResult};
|
||||
use crate::framework::graphics::{BlendMode, imgui_context};
|
||||
use crate::framework::graphics::{imgui_context, BlendMode};
|
||||
use crate::framework::keyboard::ScanCode;
|
||||
use crate::framework::ui::init_imgui;
|
||||
use crate::Game;
|
||||
|
@ -31,9 +32,7 @@ impl SDL2Backend {
|
|||
pub fn new() -> GameResult<Box<dyn Backend>> {
|
||||
let context = sdl2::init().map_err(|e| GameError::WindowError(e))?;
|
||||
|
||||
let backend = SDL2Backend {
|
||||
context,
|
||||
};
|
||||
let backend = SDL2Backend { context };
|
||||
|
||||
Ok(Box::new(backend))
|
||||
}
|
||||
|
@ -62,13 +61,15 @@ impl SDL2EventLoop {
|
|||
|
||||
let event_pump = sdl.event_pump().map_err(|e| GameError::WindowError(e))?;
|
||||
let video = sdl.video().map_err(|e| GameError::WindowError(e))?;
|
||||
let window = video.window("Cave Story (doukutsu-rs)", 640, 480)
|
||||
let window = video
|
||||
.window("Cave Story (doukutsu-rs)", 640, 480)
|
||||
.position_centered()
|
||||
.resizable()
|
||||
.build()
|
||||
.map_err(|e| GameError::WindowError(e.to_string()))?;
|
||||
|
||||
let canvas = window.into_canvas()
|
||||
let canvas = window
|
||||
.into_canvas()
|
||||
.accelerated()
|
||||
.present_vsync()
|
||||
.build()
|
||||
|
@ -96,7 +97,10 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
let (imgui, imgui_sdl2) = unsafe {
|
||||
let renderer: &Box<SDL2Renderer> = std::mem::transmute(ctx.renderer.as_ref().unwrap());
|
||||
|
||||
(&mut *renderer.imgui.as_ptr(), &mut *renderer.imgui_event.as_ptr())
|
||||
(
|
||||
&mut *renderer.imgui.as_ptr(),
|
||||
&mut *renderer.imgui_event.as_ptr(),
|
||||
)
|
||||
};
|
||||
|
||||
{
|
||||
|
@ -115,27 +119,30 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
Event::Quit { .. } => {
|
||||
state.shutdown();
|
||||
}
|
||||
Event::Window { win_event, .. } => {
|
||||
match win_event {
|
||||
WindowEvent::Shown => {}
|
||||
WindowEvent::Hidden => {}
|
||||
WindowEvent::SizeChanged(width, height) => {
|
||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||
Event::Window { win_event, .. } => match win_event {
|
||||
WindowEvent::Shown => {}
|
||||
WindowEvent::Hidden => {}
|
||||
WindowEvent::SizeChanged(width, height) => {
|
||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||
|
||||
if let Some(renderer) = ctx.renderer.as_ref() {
|
||||
if let Ok(imgui) = renderer.imgui() {
|
||||
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||
}
|
||||
if let Some(renderer) = ctx.renderer.as_ref() {
|
||||
if let Ok(imgui) = renderer.imgui() {
|
||||
imgui.io_mut().display_size =
|
||||
[ctx.screen_size.0, ctx.screen_size.1];
|
||||
}
|
||||
state.handle_resize(ctx);
|
||||
}
|
||||
_ => {}
|
||||
state.handle_resize(ctx);
|
||||
}
|
||||
}
|
||||
Event::KeyDown { scancode, repeat, .. } => {
|
||||
_ => {}
|
||||
},
|
||||
Event::KeyDown {
|
||||
scancode, repeat, ..
|
||||
} => {
|
||||
if let Some(scancode) = scancode {
|
||||
if let Some(drs_scan) = conv_scancode(scancode) {
|
||||
game.key_down_event(drs_scan, repeat);
|
||||
if !repeat {
|
||||
state.process_debug_keys(drs_scan);
|
||||
}
|
||||
ctx.keyboard_context.set_key(drs_scan, true);
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +174,11 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
state.frame_time = 0.0;
|
||||
}
|
||||
|
||||
imgui_sdl2.prepare_frame(imgui.io_mut(), self.refs.borrow().canvas.window(), &self.event_pump.mouse_state());
|
||||
imgui_sdl2.prepare_frame(
|
||||
imgui.io_mut(),
|
||||
self.refs.borrow().canvas.window(),
|
||||
&self.event_pump.mouse_state(),
|
||||
);
|
||||
game.draw(ctx).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +191,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
struct SDL2Renderer {
|
||||
refs: Rc<RefCell<SDL2Context>>,
|
||||
imgui: Rc<RefCell<imgui::Context>>,
|
||||
imgui_event: Rc<RefCell<imgui_sdl2::ImguiSdl2>>,
|
||||
imgui_event: Rc<RefCell<ImguiSdl2>>,
|
||||
imgui_textures: HashMap<TextureId, SDL2Texture>,
|
||||
}
|
||||
|
||||
|
@ -192,42 +203,49 @@ impl SDL2Renderer {
|
|||
|
||||
imgui.set_renderer_name(ImString::new("SDL2Renderer"));
|
||||
{
|
||||
let mut refs = refs.clone();
|
||||
let refs = refs.clone();
|
||||
let mut fonts = imgui.fonts();
|
||||
let id = fonts.tex_id;
|
||||
let font_tex = fonts.build_rgba32_texture();
|
||||
|
||||
let mut texture = refs.borrow_mut().texture_creator
|
||||
let mut texture = refs
|
||||
.borrow_mut()
|
||||
.texture_creator
|
||||
.create_texture_streaming(PixelFormatEnum::RGBA32, font_tex.width, font_tex.height)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
|
||||
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
||||
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||
for y in 0..(font_tex.height as usize) {
|
||||
for x in 0..(font_tex.width as usize) {
|
||||
let offset = y * pitch + x * 4;
|
||||
let data_offset = (y * font_tex.width as usize + x) * 4;
|
||||
texture
|
||||
.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||
for y in 0..(font_tex.height as usize) {
|
||||
for x in 0..(font_tex.width as usize) {
|
||||
let offset = y * pitch + x * 4;
|
||||
let data_offset = (y * font_tex.width as usize + x) * 4;
|
||||
|
||||
buffer[offset] = font_tex.data[data_offset];
|
||||
buffer[offset + 1] = font_tex.data[data_offset + 1];
|
||||
buffer[offset + 2] = font_tex.data[data_offset + 2];
|
||||
buffer[offset + 3] = font_tex.data[data_offset + 3];
|
||||
buffer[offset] = font_tex.data[data_offset];
|
||||
buffer[offset + 1] = font_tex.data[data_offset + 1];
|
||||
buffer[offset + 2] = font_tex.data[data_offset + 2];
|
||||
buffer[offset + 3] = font_tex.data[data_offset + 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}).map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
})
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
|
||||
imgui_textures.insert(id, SDL2Texture {
|
||||
refs: refs.clone(),
|
||||
texture: Some(texture),
|
||||
width: font_tex.width as u16,
|
||||
height: font_tex.height as u16,
|
||||
commands: vec![],
|
||||
});
|
||||
imgui_textures.insert(
|
||||
id,
|
||||
SDL2Texture {
|
||||
refs: refs.clone(),
|
||||
texture: Some(texture),
|
||||
width: font_tex.width as u16,
|
||||
height: font_tex.height as u16,
|
||||
commands: vec![],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let imgui_sdl2 = unsafe {
|
||||
let refs = &mut *refs.as_ptr();
|
||||
imgui_sdl2::ImguiSdl2::new(&mut imgui, refs.canvas.window())
|
||||
ImguiSdl2::new(&mut imgui, refs.canvas.window())
|
||||
};
|
||||
|
||||
Ok(Box::new(SDL2Renderer {
|
||||
|
@ -244,7 +262,10 @@ fn to_sdl(color: Color) -> pixels::Color {
|
|||
pixels::Color::RGBA(r, g, b, a)
|
||||
}
|
||||
|
||||
unsafe fn set_raw_target(renderer: *mut sdl2::sys::SDL_Renderer, raw_texture: *mut sdl2::sys::SDL_Texture) -> GameResult {
|
||||
unsafe fn set_raw_target(
|
||||
renderer: *mut sdl2::sys::SDL_Renderer,
|
||||
raw_texture: *mut sdl2::sys::SDL_Texture,
|
||||
) -> GameResult {
|
||||
if sdl2::sys::SDL_SetRenderTarget(renderer, raw_texture) == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -253,11 +274,23 @@ unsafe fn set_raw_target(renderer: *mut sdl2::sys::SDL_Renderer, raw_texture: *m
|
|||
}
|
||||
|
||||
fn min3(x: f32, y: f32, z: f32) -> f32 {
|
||||
if x < y && x < z { x } else if y < z { y } else { z }
|
||||
if x < y && x < z {
|
||||
x
|
||||
} else if y < z {
|
||||
y
|
||||
} else {
|
||||
z
|
||||
}
|
||||
}
|
||||
|
||||
fn max3(x: f32, y: f32, z: f32) -> f32 {
|
||||
if x > y && x > z { x } else if y > z { y } else { z }
|
||||
if x > y && x > z {
|
||||
x
|
||||
} else if y > z {
|
||||
y
|
||||
} else {
|
||||
z
|
||||
}
|
||||
}
|
||||
|
||||
impl BackendRenderer for SDL2Renderer {
|
||||
|
@ -276,10 +309,15 @@ impl BackendRenderer for SDL2Renderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn create_texture_mutable(&mut self, width: u16, height: u16) -> GameResult<Box<dyn BackendTexture>> {
|
||||
let mut refs = self.refs.borrow_mut();
|
||||
fn create_texture_mutable(
|
||||
&mut self,
|
||||
width: u16,
|
||||
height: u16,
|
||||
) -> GameResult<Box<dyn BackendTexture>> {
|
||||
let refs = self.refs.borrow_mut();
|
||||
|
||||
let mut texture = refs.texture_creator
|
||||
let texture = refs
|
||||
.texture_creator
|
||||
.create_texture_target(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
|
||||
|
@ -292,27 +330,35 @@ impl BackendRenderer for SDL2Renderer {
|
|||
}))
|
||||
}
|
||||
|
||||
fn create_texture(&mut self, width: u16, height: u16, data: &[u8]) -> GameResult<Box<dyn BackendTexture>> {
|
||||
let mut refs = self.refs.borrow_mut();
|
||||
fn create_texture(
|
||||
&mut self,
|
||||
width: u16,
|
||||
height: u16,
|
||||
data: &[u8],
|
||||
) -> GameResult<Box<dyn BackendTexture>> {
|
||||
let refs = self.refs.borrow_mut();
|
||||
|
||||
let mut texture = refs.texture_creator
|
||||
let mut texture = refs
|
||||
.texture_creator
|
||||
.create_texture_streaming(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
|
||||
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
||||
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||
for y in 0..(height as usize) {
|
||||
for x in 0..(width as usize) {
|
||||
let offset = y * pitch + x * 4;
|
||||
let data_offset = (y * width as usize + x) * 4;
|
||||
texture
|
||||
.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||
for y in 0..(height as usize) {
|
||||
for x in 0..(width as usize) {
|
||||
let offset = y * pitch + x * 4;
|
||||
let data_offset = (y * width as usize + x) * 4;
|
||||
|
||||
buffer[offset] = data[data_offset];
|
||||
buffer[offset + 1] = data[data_offset + 1];
|
||||
buffer[offset + 2] = data[data_offset + 2];
|
||||
buffer[offset + 3] = data[data_offset + 3];
|
||||
buffer[offset] = data[data_offset];
|
||||
buffer[offset + 1] = data[data_offset + 1];
|
||||
buffer[offset + 2] = data[data_offset + 2];
|
||||
buffer[offset + 3] = data[data_offset + 3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}).map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
})
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
|
||||
Ok(Box::new(SDL2Texture {
|
||||
refs: self.refs.clone(),
|
||||
|
@ -344,23 +390,21 @@ impl BackendRenderer for SDL2Renderer {
|
|||
let sdl2_texture: &Box<SDL2Texture> = std::mem::transmute(texture);
|
||||
|
||||
if let Some(target) = sdl2_texture.texture.as_ref() {
|
||||
set_raw_target(renderer, target.raw());
|
||||
set_raw_target(renderer, target.raw())?;
|
||||
} else {
|
||||
set_raw_target(renderer, std::ptr::null_mut());
|
||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => unsafe {
|
||||
set_raw_target(renderer, std::ptr::null_mut());
|
||||
}
|
||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
||||
unsafe {
|
||||
Ok(&mut *self.imgui.as_ptr())
|
||||
}
|
||||
unsafe { Ok(&mut *self.imgui.as_ptr()) }
|
||||
}
|
||||
|
||||
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
||||
|
@ -391,9 +435,12 @@ impl BackendRenderer for SDL2Renderer {
|
|||
continue;
|
||||
}
|
||||
|
||||
let v1 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i] as usize];
|
||||
let v2 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 1] as usize];
|
||||
let v3 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 2] as usize];
|
||||
let v1 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i] as usize];
|
||||
let v2 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i + 1] as usize];
|
||||
let v3 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i + 2] as usize];
|
||||
|
||||
vert_x[0] = (v1.pos[0] - 0.5) as i16;
|
||||
vert_y[0] = (v1.pos[1] - 0.5) as i16;
|
||||
|
@ -404,27 +451,30 @@ impl BackendRenderer for SDL2Renderer {
|
|||
|
||||
#[allow(clippy::float_cmp)]
|
||||
if i < count - 3 {
|
||||
let v4 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 3] as usize];
|
||||
let v5 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 4] as usize];
|
||||
let v6 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 5] as usize];
|
||||
let v4 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i + 3] as usize];
|
||||
let v5 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i + 4] as usize];
|
||||
let v6 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
||||
+ idx_buffer[cmd_params.idx_offset + i + 5] as usize];
|
||||
|
||||
min[0] = min3(v1.pos[0], v2.pos[0], v3.pos[0]);
|
||||
min[1] = min3(v1.pos[1], v2.pos[1], v3.pos[1]);
|
||||
max[0] = max3(v1.pos[0], v2.pos[0], v3.pos[0]);
|
||||
max[1] = max3(v1.pos[1], v2.pos[1], v3.pos[1]);
|
||||
|
||||
is_rect = (v1.pos[0] == min[0] || v1.pos[0] == max[0]) &&
|
||||
(v1.pos[1] == min[1] || v1.pos[1] == max[1]) &&
|
||||
(v2.pos[0] == min[0] || v2.pos[0] == max[0]) &&
|
||||
(v2.pos[1] == min[1] || v2.pos[1] == max[1]) &&
|
||||
(v3.pos[0] == min[0] || v3.pos[0] == max[0]) &&
|
||||
(v3.pos[1] == min[1] || v3.pos[1] == max[1]) &&
|
||||
(v4.pos[0] == min[0] || v4.pos[0] == max[0]) &&
|
||||
(v4.pos[1] == min[1] || v4.pos[1] == max[1]) &&
|
||||
(v5.pos[0] == min[0] || v5.pos[0] == max[0]) &&
|
||||
(v5.pos[1] == min[1] || v5.pos[1] == max[1]) &&
|
||||
(v6.pos[0] == min[0] || v6.pos[0] == max[0]) &&
|
||||
(v6.pos[1] == min[1] || v6.pos[1] == max[1]);
|
||||
is_rect = (v1.pos[0] == min[0] || v1.pos[0] == max[0])
|
||||
&& (v1.pos[1] == min[1] || v1.pos[1] == max[1])
|
||||
&& (v2.pos[0] == min[0] || v2.pos[0] == max[0])
|
||||
&& (v2.pos[1] == min[1] || v2.pos[1] == max[1])
|
||||
&& (v3.pos[0] == min[0] || v3.pos[0] == max[0])
|
||||
&& (v3.pos[1] == min[1] || v3.pos[1] == max[1])
|
||||
&& (v4.pos[0] == min[0] || v4.pos[0] == max[0])
|
||||
&& (v4.pos[1] == min[1] || v4.pos[1] == max[1])
|
||||
&& (v5.pos[0] == min[0] || v5.pos[0] == max[0])
|
||||
&& (v5.pos[1] == min[1] || v5.pos[1] == max[1])
|
||||
&& (v6.pos[0] == min[0] || v6.pos[0] == max[0])
|
||||
&& (v6.pos[1] == min[1] || v6.pos[1] == max[1]);
|
||||
|
||||
if is_rect {
|
||||
tex_pos[0] = min3(v1.uv[0], v2.uv[0], v3.uv[0]);
|
||||
|
@ -434,35 +484,40 @@ impl BackendRenderer for SDL2Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(surf) = self.imgui_textures.get_mut(&cmd_params.texture_id) {
|
||||
unsafe {
|
||||
if is_rect {
|
||||
let src = sdl2::rect::Rect::new((tex_pos[0] * surf.width as f32) as i32,
|
||||
(tex_pos[1] * surf.height as f32) as i32,
|
||||
((tex_pos[2] - tex_pos[0]) * surf.width as f32) as u32,
|
||||
((tex_pos[3] - tex_pos[1]) * surf.height as f32) as u32);
|
||||
let dest = sdl2::rect::Rect::new(min[0] as i32,
|
||||
min[1] as i32,
|
||||
(max[0] - min[0]) as u32,
|
||||
(max[1] - min[1]) as u32);
|
||||
if let Some(surf) = self.imgui_textures.get_mut(&cmd_params.texture_id)
|
||||
{
|
||||
if is_rect {
|
||||
let src = sdl2::rect::Rect::new(
|
||||
(tex_pos[0] * surf.width as f32) as i32,
|
||||
(tex_pos[1] * surf.height as f32) as i32,
|
||||
((tex_pos[2] - tex_pos[0]) * surf.width as f32) as u32,
|
||||
((tex_pos[3] - tex_pos[1]) * surf.height as f32) as u32,
|
||||
);
|
||||
let dest = sdl2::rect::Rect::new(
|
||||
min[0] as i32,
|
||||
min[1] as i32,
|
||||
(max[0] - min[0]) as u32,
|
||||
(max[1] - min[1]) as u32,
|
||||
);
|
||||
|
||||
let tex = surf.texture.as_mut().unwrap();
|
||||
tex.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
||||
tex.set_alpha_mod(v1.col[3]);
|
||||
let tex = surf.texture.as_mut().unwrap();
|
||||
tex.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
||||
tex.set_alpha_mod(v1.col[3]);
|
||||
|
||||
refs.canvas.copy(tex, src, dest);
|
||||
} else {
|
||||
sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
||||
refs.canvas.raw(),
|
||||
vert_x.as_ptr(),
|
||||
vert_y.as_ptr(),
|
||||
3,
|
||||
v1.col[0],
|
||||
v1.col[1],
|
||||
v1.col[2],
|
||||
v1.col[3],
|
||||
);
|
||||
}
|
||||
refs.canvas
|
||||
.copy(tex, src, dest)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
} else {
|
||||
/*sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
||||
refs.canvas.raw(),
|
||||
vert_x.as_ptr(),
|
||||
vert_y.as_ptr(),
|
||||
3,
|
||||
v1.col[0],
|
||||
v1.col[1],
|
||||
v1.col[2],
|
||||
v1.col[3],
|
||||
);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -472,7 +527,7 @@ impl BackendRenderer for SDL2Renderer {
|
|||
DrawCmd::ResetRenderState => {}
|
||||
DrawCmd::RawCallback { callback, raw_cmd } => unsafe {
|
||||
callback(draw_list.raw(), raw_cmd)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +535,7 @@ impl BackendRenderer for SDL2Renderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn prepare_frame<'ui>(&self, ui: &Ui<'ui>) -> GameResult {
|
||||
fn prepare_frame<'ui>(&self, _ui: &Ui<'ui>) -> GameResult {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -520,9 +575,22 @@ impl BackendTexture for SDL2Texture {
|
|||
texture.set_alpha_mod(255);
|
||||
texture.set_blend_mode(refs.blend_mode);
|
||||
|
||||
refs.canvas.copy(texture,
|
||||
Some(sdl2::rect::Rect::new(src.left.round() as i32, src.top.round() as i32, src.width().round() as u32, src.height().round() as u32)),
|
||||
Some(sdl2::rect::Rect::new(dest.left.round() as i32, dest.top.round() as i32, dest.width().round() as u32, dest.height().round() as u32)))
|
||||
refs.canvas
|
||||
.copy(
|
||||
texture,
|
||||
Some(sdl2::rect::Rect::new(
|
||||
src.left.round() as i32,
|
||||
src.top.round() as i32,
|
||||
src.width().round() as u32,
|
||||
src.height().round() as u32,
|
||||
)),
|
||||
Some(sdl2::rect::Rect::new(
|
||||
dest.left.round() as i32,
|
||||
dest.top.round() as i32,
|
||||
dest.width().round() as u32,
|
||||
dest.height().round() as u32,
|
||||
)),
|
||||
)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
}
|
||||
SpriteBatchCommand::DrawRectTinted(src, dest, color) => {
|
||||
|
@ -531,9 +599,49 @@ impl BackendTexture for SDL2Texture {
|
|||
texture.set_alpha_mod(a);
|
||||
texture.set_blend_mode(refs.blend_mode);
|
||||
|
||||
refs.canvas.copy(texture,
|
||||
Some(sdl2::rect::Rect::new(src.left.round() as i32, src.top.round() as i32, src.width().round() as u32, src.height().round() as u32)),
|
||||
Some(sdl2::rect::Rect::new(dest.left.round() as i32, dest.top.round() as i32, dest.width().round() as u32, dest.height().round() as u32)))
|
||||
refs.canvas
|
||||
.copy(
|
||||
texture,
|
||||
Some(sdl2::rect::Rect::new(
|
||||
src.left.round() as i32,
|
||||
src.top.round() as i32,
|
||||
src.width().round() as u32,
|
||||
src.height().round() as u32,
|
||||
)),
|
||||
Some(sdl2::rect::Rect::new(
|
||||
dest.left.round() as i32,
|
||||
dest.top.round() as i32,
|
||||
dest.width().round() as u32,
|
||||
dest.height().round() as u32,
|
||||
)),
|
||||
)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
}
|
||||
SpriteBatchCommand::DrawRectFlip(src, dest, flip_x, flip_y) => {
|
||||
texture.set_color_mod(255, 255, 255);
|
||||
texture.set_alpha_mod(255);
|
||||
texture.set_blend_mode(refs.blend_mode);
|
||||
|
||||
refs.canvas
|
||||
.copy_ex(
|
||||
texture,
|
||||
Some(sdl2::rect::Rect::new(
|
||||
src.left.round() as i32,
|
||||
src.top.round() as i32,
|
||||
src.width().round() as u32,
|
||||
src.height().round() as u32,
|
||||
)),
|
||||
Some(sdl2::rect::Rect::new(
|
||||
dest.left.round() as i32,
|
||||
dest.top.round() as i32,
|
||||
dest.width().round() as u32,
|
||||
dest.height().round() as u32,
|
||||
)),
|
||||
0.0,
|
||||
None,
|
||||
*flip_x,
|
||||
*flip_y,
|
||||
)
|
||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
}
|
||||
}
|
||||
|
@ -551,7 +659,9 @@ impl Drop for SDL2Texture {
|
|||
mem::swap(&mut self.texture, &mut texture_opt);
|
||||
|
||||
if let Some(texture) = texture_opt {
|
||||
unsafe { texture.destroy(); }
|
||||
unsafe {
|
||||
texture.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -699,3 +809,219 @@ fn conv_scancode(code: keyboard::Scancode) -> Option<ScanCode> {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// based on imgui-sdl2 crate
|
||||
pub struct ImguiSdl2 {
|
||||
mouse_press: [bool; 5],
|
||||
ignore_mouse: bool,
|
||||
ignore_keyboard: bool,
|
||||
cursor: Option<MouseCursor>,
|
||||
sdl_cursor: Option<Cursor>,
|
||||
}
|
||||
|
||||
struct Sdl2ClipboardBackend(sdl2::clipboard::ClipboardUtil);
|
||||
|
||||
impl imgui::ClipboardBackend for Sdl2ClipboardBackend {
|
||||
fn get(&mut self) -> Option<imgui::ImString> {
|
||||
if !self.0.has_clipboard_text() {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.0.clipboard_text().ok().map(imgui::ImString::new)
|
||||
}
|
||||
|
||||
fn set(&mut self, value: &imgui::ImStr) {
|
||||
let _ = self.0.set_clipboard_text(value.to_str());
|
||||
}
|
||||
}
|
||||
|
||||
impl ImguiSdl2 {
|
||||
pub fn new(imgui: &mut imgui::Context, window: &sdl2::video::Window) -> Self {
|
||||
let clipboard_util = window.subsystem().clipboard();
|
||||
imgui.set_clipboard_backend(Box::new(Sdl2ClipboardBackend(clipboard_util)));
|
||||
|
||||
imgui.io_mut().key_map[Key::Tab as usize] = Scancode::Tab as u32;
|
||||
imgui.io_mut().key_map[Key::LeftArrow as usize] = Scancode::Left as u32;
|
||||
imgui.io_mut().key_map[Key::RightArrow as usize] = Scancode::Right as u32;
|
||||
imgui.io_mut().key_map[Key::UpArrow as usize] = Scancode::Up as u32;
|
||||
imgui.io_mut().key_map[Key::DownArrow as usize] = Scancode::Down as u32;
|
||||
imgui.io_mut().key_map[Key::PageUp as usize] = Scancode::PageUp as u32;
|
||||
imgui.io_mut().key_map[Key::PageDown as usize] = Scancode::PageDown as u32;
|
||||
imgui.io_mut().key_map[Key::Home as usize] = Scancode::Home as u32;
|
||||
imgui.io_mut().key_map[Key::End as usize] = Scancode::End as u32;
|
||||
imgui.io_mut().key_map[Key::Delete as usize] = Scancode::Delete as u32;
|
||||
imgui.io_mut().key_map[Key::Backspace as usize] = Scancode::Backspace as u32;
|
||||
imgui.io_mut().key_map[Key::Enter as usize] = Scancode::Return as u32;
|
||||
imgui.io_mut().key_map[Key::Escape as usize] = Scancode::Escape as u32;
|
||||
imgui.io_mut().key_map[Key::Space as usize] = Scancode::Space as u32;
|
||||
imgui.io_mut().key_map[Key::A as usize] = Scancode::A as u32;
|
||||
imgui.io_mut().key_map[Key::C as usize] = Scancode::C as u32;
|
||||
imgui.io_mut().key_map[Key::V as usize] = Scancode::V as u32;
|
||||
imgui.io_mut().key_map[Key::X as usize] = Scancode::X as u32;
|
||||
imgui.io_mut().key_map[Key::Y as usize] = Scancode::Y as u32;
|
||||
imgui.io_mut().key_map[Key::Z as usize] = Scancode::Z as u32;
|
||||
|
||||
Self {
|
||||
mouse_press: [false; 5],
|
||||
ignore_keyboard: false,
|
||||
ignore_mouse: false,
|
||||
cursor: None,
|
||||
sdl_cursor: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ignore_event(&self, event: &Event) -> bool {
|
||||
match *event {
|
||||
Event::KeyDown { .. }
|
||||
| Event::KeyUp { .. }
|
||||
| Event::TextEditing { .. }
|
||||
| Event::TextInput { .. } => self.ignore_keyboard,
|
||||
Event::MouseMotion { .. }
|
||||
| Event::MouseButtonDown { .. }
|
||||
| Event::MouseButtonUp { .. }
|
||||
| Event::MouseWheel { .. }
|
||||
| Event::FingerDown { .. }
|
||||
| Event::FingerUp { .. }
|
||||
| Event::FingerMotion { .. }
|
||||
| Event::DollarGesture { .. }
|
||||
| Event::DollarRecord { .. }
|
||||
| Event::MultiGesture { .. } => self.ignore_mouse,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, imgui: &mut imgui::Context, event: &Event) {
|
||||
use sdl2::keyboard;
|
||||
use sdl2::mouse::MouseButton;
|
||||
|
||||
fn set_mod(imgui: &mut imgui::Context, keymod: keyboard::Mod) {
|
||||
let ctrl = keymod.intersects(keyboard::Mod::RCTRLMOD | keyboard::Mod::LCTRLMOD);
|
||||
let alt = keymod.intersects(keyboard::Mod::RALTMOD | keyboard::Mod::LALTMOD);
|
||||
let shift = keymod.intersects(keyboard::Mod::RSHIFTMOD | keyboard::Mod::LSHIFTMOD);
|
||||
let super_ = keymod.intersects(keyboard::Mod::RGUIMOD | keyboard::Mod::LGUIMOD);
|
||||
|
||||
imgui.io_mut().key_ctrl = ctrl;
|
||||
imgui.io_mut().key_alt = alt;
|
||||
imgui.io_mut().key_shift = shift;
|
||||
imgui.io_mut().key_super = super_;
|
||||
}
|
||||
|
||||
match *event {
|
||||
Event::MouseWheel { y, .. } => {
|
||||
imgui.io_mut().mouse_wheel = y as f32;
|
||||
}
|
||||
Event::MouseButtonDown { mouse_btn, .. } => {
|
||||
if mouse_btn != MouseButton::Unknown {
|
||||
let index = match mouse_btn {
|
||||
MouseButton::Left => 0,
|
||||
MouseButton::Right => 1,
|
||||
MouseButton::Middle => 2,
|
||||
MouseButton::X1 => 3,
|
||||
MouseButton::X2 => 4,
|
||||
MouseButton::Unknown => unreachable!(),
|
||||
};
|
||||
self.mouse_press[index] = true;
|
||||
}
|
||||
}
|
||||
Event::TextInput { ref text, .. } => {
|
||||
for chr in text.chars() {
|
||||
imgui.io_mut().add_input_character(chr);
|
||||
}
|
||||
}
|
||||
Event::KeyDown {
|
||||
scancode, keymod, ..
|
||||
} => {
|
||||
set_mod(imgui, keymod);
|
||||
if let Some(scancode) = scancode {
|
||||
imgui.io_mut().keys_down[scancode as usize] = true;
|
||||
}
|
||||
}
|
||||
Event::KeyUp {
|
||||
scancode, keymod, ..
|
||||
} => {
|
||||
set_mod(imgui, keymod);
|
||||
if let Some(scancode) = scancode {
|
||||
imgui.io_mut().keys_down[scancode as usize] = false;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_frame(
|
||||
&mut self,
|
||||
io: &mut imgui::Io,
|
||||
window: &sdl2::video::Window,
|
||||
mouse_state: &sdl2::mouse::MouseState,
|
||||
) {
|
||||
let mouse_util = window.subsystem().sdl().mouse();
|
||||
|
||||
let (win_w, win_h) = window.size();
|
||||
let (draw_w, draw_h) = window.drawable_size();
|
||||
|
||||
io.display_size = [win_w as f32, win_h as f32];
|
||||
io.display_framebuffer_scale = [
|
||||
(draw_w as f32) / (win_w as f32),
|
||||
(draw_h as f32) / (win_h as f32),
|
||||
];
|
||||
|
||||
// Merging the mousedown events we received into the current state prevents us from missing
|
||||
// clicks that happen faster than a frame
|
||||
io.mouse_down = [
|
||||
self.mouse_press[0] || mouse_state.left(),
|
||||
self.mouse_press[1] || mouse_state.right(),
|
||||
self.mouse_press[2] || mouse_state.middle(),
|
||||
self.mouse_press[3] || mouse_state.x1(),
|
||||
self.mouse_press[4] || mouse_state.x2(),
|
||||
];
|
||||
self.mouse_press = [false; 5];
|
||||
|
||||
let any_mouse_down = io.mouse_down.iter().any(|&b| b);
|
||||
mouse_util.capture(any_mouse_down);
|
||||
|
||||
io.mouse_pos = [mouse_state.x() as f32, mouse_state.y() as f32];
|
||||
|
||||
self.ignore_keyboard = io.want_capture_keyboard;
|
||||
self.ignore_mouse = io.want_capture_mouse;
|
||||
}
|
||||
|
||||
pub fn prepare_render(&mut self, ui: &imgui::Ui, window: &sdl2::video::Window) {
|
||||
let io = ui.io();
|
||||
if !io
|
||||
.config_flags
|
||||
.contains(ConfigFlags::NO_MOUSE_CURSOR_CHANGE)
|
||||
{
|
||||
let mouse_util = window.subsystem().sdl().mouse();
|
||||
|
||||
match ui.mouse_cursor() {
|
||||
Some(mouse_cursor) if !io.mouse_draw_cursor => {
|
||||
mouse_util.show_cursor(true);
|
||||
|
||||
let sdl_cursor = match mouse_cursor {
|
||||
MouseCursor::Arrow => SystemCursor::Arrow,
|
||||
MouseCursor::TextInput => SystemCursor::IBeam,
|
||||
MouseCursor::ResizeAll => SystemCursor::SizeAll,
|
||||
MouseCursor::ResizeNS => SystemCursor::SizeNS,
|
||||
MouseCursor::ResizeEW => SystemCursor::SizeWE,
|
||||
MouseCursor::ResizeNESW => SystemCursor::SizeNESW,
|
||||
MouseCursor::ResizeNWSE => SystemCursor::SizeNWSE,
|
||||
MouseCursor::Hand => SystemCursor::Hand,
|
||||
MouseCursor::NotAllowed => SystemCursor::No,
|
||||
};
|
||||
|
||||
if self.cursor != Some(mouse_cursor) {
|
||||
let sdl_cursor = Cursor::from_system(sdl_cursor).unwrap();
|
||||
sdl_cursor.set();
|
||||
self.cursor = Some(mouse_cursor);
|
||||
self.sdl_cursor = Some(sdl_cursor);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.cursor = None;
|
||||
self.sdl_cursor = None;
|
||||
mouse_util.show_cursor(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::framework::backend::{Backend, init_backend, BackendRenderer};
|
||||
use crate::framework::backend::{init_backend, BackendRenderer};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem::Filesystem;
|
||||
use crate::Game;
|
||||
|
|
|
@ -71,7 +71,7 @@ impl Filesystem {
|
|||
// Set up VFS to merge resource path, root path, and zip path.
|
||||
let overlay = vfs::OverlayFS::new();
|
||||
// User data VFS.
|
||||
let mut user_overlay = vfs::OverlayFS::new();
|
||||
let user_overlay = vfs::OverlayFS::new();
|
||||
|
||||
Filesystem {
|
||||
vfs: overlay,
|
||||
|
|
50
src/lib.rs
50
src/lib.rs
|
@ -138,7 +138,7 @@ impl Game {
|
|||
let state_ref = unsafe { &mut *self.state.get() };
|
||||
|
||||
if state_ref.timing_mode != TimingMode::FrameSynchronized {
|
||||
let mut elapsed = self.start_time.elapsed().as_nanos();
|
||||
let elapsed = self.start_time.elapsed().as_nanos();
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
// Even with the non-monotonic Instant mitigation at the start of the event loop, there's still a chance of it not working.
|
||||
|
@ -177,31 +177,6 @@ impl Game {
|
|||
graphics::present(ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn key_down_event(&mut self, key_code: ScanCode, repeat: bool) {
|
||||
if repeat { return; }
|
||||
|
||||
let state = unsafe { &mut *self.state.get() };
|
||||
match key_code {
|
||||
ScanCode::F5 => { state.settings.subpixel_coords = !state.settings.subpixel_coords }
|
||||
ScanCode::F6 => { state.settings.motion_interpolation = !state.settings.motion_interpolation }
|
||||
ScanCode::F7 => { state.set_speed(1.0) }
|
||||
ScanCode::F8 => {
|
||||
if state.settings.speed > 0.2 {
|
||||
state.set_speed(state.settings.speed - 0.1);
|
||||
}
|
||||
}
|
||||
ScanCode::F9 => {
|
||||
if state.settings.speed < 3.0 {
|
||||
state.set_speed(state.settings.speed + 0.1);
|
||||
}
|
||||
}
|
||||
ScanCode::F10 => { state.settings.debug_outlines = !state.settings.debug_outlines }
|
||||
ScanCode::F11 => { state.settings.god_mode = !state.settings.god_mode }
|
||||
ScanCode::F12 => { state.settings.infinite_booster = !state.settings.infinite_booster }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
|
@ -321,28 +296,7 @@ pub fn init() -> GameResult {
|
|||
}
|
||||
|
||||
state_ref.next_scene = Some(Box::new(LoadingScene::new()));
|
||||
context.run(&mut game);
|
||||
|
||||
/* loop {
|
||||
game.update(&mut context)?;
|
||||
|
||||
if state_ref.shutdown {
|
||||
log::info!("Shutting down...");
|
||||
break;
|
||||
}
|
||||
|
||||
if state_ref.next_scene.is_some() {
|
||||
mem::swap(&mut game.scene, &mut state_ref.next_scene);
|
||||
state_ref.next_scene = None;
|
||||
|
||||
game.scene.as_mut().unwrap().init(state_ref, &mut context).unwrap();
|
||||
game.loops = 0;
|
||||
state_ref.frame_time = 0.0;
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
game.draw(&mut context)?;
|
||||
}*/
|
||||
context.run(&mut game)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ impl LiveDebugger {
|
|||
|
||||
Window::new(im_str!("Debugger"))
|
||||
.resizable(false)
|
||||
.collapsed(false, Condition::FirstUseEver)
|
||||
.collapsed(true, Condition::FirstUseEver)
|
||||
.position([5.0, 5.0], Condition::FirstUseEver)
|
||||
.size([400.0, 170.0], Condition::FirstUseEver)
|
||||
.build(ui, || {
|
||||
|
|
|
@ -1587,7 +1587,7 @@ impl NPC {
|
|||
npc.y = self.y - 0x1800;
|
||||
npc.tsc_direction = 10 * self.anim_num + 40;
|
||||
|
||||
npc_list.spawn(0, npc);
|
||||
let _ = npc_list.spawn(0, npc);
|
||||
self.cond.set_explode_die(true);
|
||||
}
|
||||
}
|
||||
|
@ -1630,7 +1630,7 @@ impl NPC {
|
|||
npc.direction = Direction::Right;
|
||||
npc.parent_id = self.id;
|
||||
|
||||
npc_list.spawn(0x100, npc);
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ impl NPC {
|
|||
}
|
||||
|
||||
pub(crate) fn tick_n049_skullhead(&mut self, state: &mut SharedGameState, players: [&mut Player; 2], npc_list: &NPCList) -> GameResult {
|
||||
let mut parent = self.get_parent_ref_mut(npc_list);
|
||||
let parent = self.get_parent_ref_mut(npc_list);
|
||||
|
||||
if self.action_num > 9 && parent.as_ref().map(|n| n.npc_type == 3).unwrap_or(false) {
|
||||
self.action_num = 3;
|
||||
|
|
|
@ -284,6 +284,8 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &BulletManager)> for NP
|
|||
216 => self.tick_n216_debug_cat(state),
|
||||
222 => self.tick_n222_prison_bars(state),
|
||||
227 => self.tick_n227_bucket(state),
|
||||
229 => self.tick_n229_red_flowers_sprouts(state),
|
||||
230 => self.tick_n230_red_flowers_blooming(state),
|
||||
234 => self.tick_n234_red_flowers_picked(state),
|
||||
239 => self.tick_n239_cage_bars(state),
|
||||
241 => self.tick_n241_critter_red(state, players),
|
||||
|
|
|
@ -73,7 +73,7 @@ impl Xoroshiro32PlusPlus {
|
|||
|
||||
pub fn next_u16(&self) -> u16 {
|
||||
let mut state = self.0.get();
|
||||
let mut result = (state.0.wrapping_add(state.1)).rotate_left(9).wrapping_add(state.0);
|
||||
let result = (state.0.wrapping_add(state.1)).rotate_left(9).wrapping_add(state.0);
|
||||
|
||||
state.1 ^= state.0;
|
||||
state.0 = state.0.rotate_left(13) ^ state.1 ^ (state.1 << 5);
|
||||
|
|
|
@ -434,13 +434,14 @@ impl GameScene {
|
|||
};
|
||||
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, tex_name)?;
|
||||
|
||||
// switch version uses +1000 face offset to display a flipped version
|
||||
// switch version uses 1xxx flag to show a flipped version of face
|
||||
let flip = state.textscript_vm.face > 1000;
|
||||
// x1xx flag shows a talking animation
|
||||
let talking = (state.textscript_vm.face % 1000) > 100;
|
||||
let face_num = state.textscript_vm.face % 100;
|
||||
let (scale_x, scale_y) = batch.scale();
|
||||
|
||||
batch.add_rect_scaled(left_pos + 14.0 + if flip { 48.0 } else { 0.0 }, top_pos + 8.0,
|
||||
scale_x * if flip { -1.0 } else { 1.0 }, scale_y,
|
||||
batch.add_rect_flip(left_pos + 14.0, top_pos + 8.0,
|
||||
flip, false,
|
||||
&Rect::new_size(
|
||||
(face_num as u16 % 6) * 48,
|
||||
(face_num as u16 / 6) * 48,
|
||||
|
|
|
@ -19,6 +19,7 @@ impl NoDataScene {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
static REL_URL: &str = "https://github.com/doukutsu-rs/game-data/releases";
|
||||
|
||||
impl Scene for NoDataScene {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use lua_ffi::ffi::luaL_Reg;
|
||||
use lua_ffi::{LuaObject, State, c_int};
|
||||
|
||||
use crate::scene::game_scene::GameScene;
|
||||
use crate::scripting::LuaScriptingState;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
|
||||
pub struct Doukutsu {
|
||||
pub ptr: *mut LuaScriptingState,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl Doukutsu {
|
||||
pub fn new(ptr: *mut LuaScriptingState) -> Doukutsu {
|
||||
Doukutsu {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::io::{Read, Seek};
|
||||
use std::io::Read;
|
||||
use std::ptr::null_mut;
|
||||
|
||||
|
||||
|
@ -6,8 +6,7 @@ use crate::framework::context::Context;
|
|||
use crate::framework::error::{GameResult, GameError};
|
||||
|
||||
|
||||
use lua_ffi::{c_int, LuaFunction, LuaObject, State, ThreadStatus};
|
||||
use lua_ffi::ffi::lua_pushcfunction;
|
||||
use lua_ffi::{c_int, State, ThreadStatus};
|
||||
|
||||
use crate::scene::game_scene::GameScene;
|
||||
use crate::scripting::doukutsu::Doukutsu;
|
||||
|
@ -117,7 +116,7 @@ impl LuaScriptingState {
|
|||
|
||||
if filesystem::exists(ctx, "/scripts/") {
|
||||
let mut script_count = 0;
|
||||
let mut files = filesystem::read_dir(ctx, "/scripts/")?
|
||||
let files = filesystem::read_dir(ctx, "/scripts/")?
|
||||
.filter(|f| f.to_string_lossy().to_lowercase().ends_with(".lua"));
|
||||
|
||||
for file in files {
|
||||
|
|
|
@ -12,6 +12,7 @@ pub struct LuaPlayer {
|
|||
inv_ptr: *mut Inventory,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl LuaPlayer {
|
||||
fn check_ref(&self, state: &mut State) -> bool {
|
||||
if !self.valid_reference {
|
||||
|
|
|
@ -28,7 +28,8 @@ use crate::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM};
|
|||
use crate::texture_set::TextureSet;
|
||||
use crate::framework::{filesystem, graphics};
|
||||
use crate::framework::backend::BackendTexture;
|
||||
use crate::framework::graphics::{create_texture, set_render_target, create_texture_mutable};
|
||||
use crate::framework::graphics::{set_render_target, create_texture_mutable};
|
||||
use crate::framework::keyboard::ScanCode;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub enum TimingMode {
|
||||
|
@ -103,6 +104,7 @@ pub struct SharedGameState {
|
|||
pub npc_super_pos: (i32, i32),
|
||||
pub stages: Vec<StageData>,
|
||||
pub frame_time: f64,
|
||||
pub debugger: bool,
|
||||
pub scale: f32,
|
||||
pub canvas_size: (f32, f32),
|
||||
pub screen_size: (f32, f32),
|
||||
|
@ -117,7 +119,7 @@ pub struct SharedGameState {
|
|||
pub lua: LuaScriptingState,
|
||||
pub sound_manager: SoundManager,
|
||||
pub settings: Settings,
|
||||
pub shutdown: bool,
|
||||
pub shutdown: bool
|
||||
}
|
||||
|
||||
impl SharedGameState {
|
||||
|
@ -168,6 +170,7 @@ impl SharedGameState {
|
|||
npc_super_pos: (0, 0),
|
||||
stages: Vec::with_capacity(96),
|
||||
frame_time: 0.0,
|
||||
debugger: false,
|
||||
scale: 2.0,
|
||||
screen_size: (640.0, 480.0),
|
||||
canvas_size: (320.0, 240.0),
|
||||
|
@ -186,6 +189,28 @@ impl SharedGameState {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn process_debug_keys(&mut self, key_code: ScanCode) {
|
||||
match key_code {
|
||||
ScanCode::F3 => { self.settings.god_mode = !self.settings.god_mode }
|
||||
ScanCode::F4 => { self.settings.infinite_booster = !self.settings.infinite_booster }
|
||||
ScanCode::F5 => { self.settings.subpixel_coords = !self.settings.subpixel_coords }
|
||||
ScanCode::F6 => { self.settings.motion_interpolation = !self.settings.motion_interpolation }
|
||||
ScanCode::F7 => { self.set_speed(1.0) }
|
||||
ScanCode::F8 => {
|
||||
if self.settings.speed > 0.2 {
|
||||
self.set_speed(self.settings.speed - 0.1);
|
||||
}
|
||||
}
|
||||
ScanCode::F9 => {
|
||||
if self.settings.speed < 3.0 {
|
||||
self.set_speed(self.settings.speed + 0.1);
|
||||
}
|
||||
}
|
||||
ScanCode::F10 => { self.settings.debug_outlines = !self.settings.debug_outlines }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reload_textures(&mut self) {
|
||||
let mut texture_set = TextureSet::new(self.base_path.as_str());
|
||||
|
||||
|
@ -307,10 +332,6 @@ impl SharedGameState {
|
|||
pub fn set_speed(&mut self, value: f64) {
|
||||
self.settings.speed = clamp(value, 0.1, 3.0);
|
||||
self.frame_time = 0.0;
|
||||
|
||||
if let Err(err) = self.sound_manager.set_speed(value as f32) {
|
||||
log::error!("Error while sending a message to sound manager: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_tps(&self) -> f64 {
|
||||
|
|
|
@ -8,7 +8,7 @@ use num_traits::clamp;
|
|||
|
||||
use crate::engine_constants::EngineConstants;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::{GameResult, GameError};
|
||||
use crate::framework::error::{GameResult};
|
||||
use crate::framework::filesystem;
|
||||
use crate::sound::organya::Song;
|
||||
use crate::sound::pixtone::PixTonePlayback;
|
||||
|
@ -16,7 +16,6 @@ use crate::sound::playback::{PlaybackEngine, SavedPlaybackState};
|
|||
use crate::sound::wave_bank::SoundBank;
|
||||
use crate::str;
|
||||
use crate::framework::error::GameError::{AudioError, ResourceLoadError, InvalidValue};
|
||||
use std::io::Error;
|
||||
|
||||
mod wave_bank;
|
||||
mod organya;
|
||||
|
|
|
@ -166,6 +166,7 @@ impl PlaybackEngine {
|
|||
self.play_pos = position;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn get_total_samples(&self) -> u32 {
|
||||
let ticks_intro = self.song.time.loop_range.start;
|
||||
let ticks_loop = self.song.time.loop_range.end - self.song.time.loop_range.start;
|
||||
|
|
|
@ -1751,6 +1751,7 @@ impl TextScript {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn read_varint<I: Iterator<Item=u8>>(iter: &mut I) -> GameResult<i32> {
|
||||
let mut result = 0u32;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use itertools::Itertools;
|
|||
use log::info;
|
||||
|
||||
use crate::common;
|
||||
use crate::common::{FILE_TYPES, Point, Rect};
|
||||
use crate::common::{FILE_TYPES, Rect};
|
||||
use crate::engine_constants::EngineConstants;
|
||||
use crate::framework::backend::{BackendTexture, SpriteBatchCommand};
|
||||
use crate::framework::context::Context;
|
||||
|
@ -94,12 +94,40 @@ impl SizedBatch {
|
|||
self.add_rect_scaled(x, y, 1.0, 1.0, rect)
|
||||
}
|
||||
|
||||
pub fn add_rect_flip(&mut self, mut x: f32, mut y: f32, flip_x: bool, flip_y: bool, rect: &common::Rect<u16>) {
|
||||
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
x = (x * G_MAG).round() / G_MAG;
|
||||
y = (y * G_MAG).round() / G_MAG;
|
||||
}
|
||||
let mag = unsafe { I_MAG };
|
||||
|
||||
self.batch.add(SpriteBatchCommand::DrawRectFlip(
|
||||
Rect {
|
||||
left: rect.left as f32 / self.scale_x,
|
||||
top: rect.top as f32 / self.scale_y,
|
||||
right: rect.right as f32 / self.scale_x,
|
||||
bottom: rect.bottom as f32 / self.scale_y,
|
||||
},
|
||||
Rect {
|
||||
left: x * mag,
|
||||
top: y * mag,
|
||||
right: (x + rect.width() as f32) * mag,
|
||||
bottom: (y + rect.height() as f32) * mag,
|
||||
},
|
||||
flip_x, flip_y
|
||||
));
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn add_rect_tinted(&mut self, x: f32, y: f32, color: (u8, u8, u8, u8), rect: &common::Rect<u16>) {
|
||||
self.add_rect_scaled_tinted(x, y, color, 1.0, 1.0, rect)
|
||||
}
|
||||
|
||||
pub fn add_rect_scaled(&mut self, mut x: f32, mut y: f32, mut scale_x: f32, mut scale_y: f32, rect: &common::Rect<u16>) {
|
||||
pub fn add_rect_scaled(&mut self, mut x: f32, mut y: f32, scale_x: f32, scale_y: f32, rect: &common::Rect<u16>) {
|
||||
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
||||
return;
|
||||
}
|
||||
|
@ -126,7 +154,7 @@ impl SizedBatch {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn add_rect_scaled_tinted(&mut self, mut x: f32, mut y: f32, color: (u8, u8, u8, u8), mut scale_x: f32, mut scale_y: f32, rect: &common::Rect<u16>) {
|
||||
pub fn add_rect_scaled_tinted(&mut self, mut x: f32, mut y: f32, color: (u8, u8, u8, u8), scale_x: f32, scale_y: f32, rect: &common::Rect<u16>) {
|
||||
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -384,7 +384,7 @@ impl Weapon {
|
|||
|
||||
fn tick_spur(&mut self, player: &mut Player, player_id: TargetPlayer, inventory: &mut Inventory, bullet_manager: &mut BulletManager, state: &mut SharedGameState) {
|
||||
let mut shoot = false;
|
||||
let mut btype = 0;
|
||||
let mut btype;
|
||||
|
||||
if player.controller.shoot() {
|
||||
inventory.add_xp(if player.equip.has_turbocharge() { 3 } else { 2 }, player, state);
|
||||
|
|
Loading…
Reference in a new issue