mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-07-30 09:02:17 +00:00
Compare commits
No commits in common. "a17d3afe2dc406f874356dbfbd6cc75830a48442" and "318d94d84345071baeef560b24e0912b1e663828" have entirely different histories.
a17d3afe2d
...
318d94d843
16
Cargo.toml
16
Cargo.toml
|
@ -4,8 +4,8 @@ edition = "2018"
|
||||||
name = "doukutsu-rs"
|
name = "doukutsu-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
#[lib]
|
[lib]
|
||||||
#crate-type = ["lib", "cdylib"]
|
crate-type = ["lib", "cdylib"]
|
||||||
|
|
||||||
[package.metadata.android]
|
[package.metadata.android]
|
||||||
android_version = 29
|
android_version = 29
|
||||||
|
@ -41,7 +41,7 @@ opt-level = 1
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["scripting", "backend-sdl"]
|
default = ["scripting", "backend-sdl"]
|
||||||
backend-sdl = ["sdl2"]
|
backend-sdl = ["sdl2", "sdl2-sys", "imgui-sdl2"]
|
||||||
backend-gfx = ["winit", "imgui-gfx-renderer", "imgui-winit-support"]
|
backend-gfx = ["winit", "imgui-gfx-renderer", "imgui-winit-support"]
|
||||||
scripting = ["lua-ffi"]
|
scripting = ["lua-ffi"]
|
||||||
editor = []
|
editor = []
|
||||||
|
@ -53,9 +53,10 @@ case_insensitive_hashmap = "1.0.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
cpal = { git = "https://github.com/doukutsu-rs/cpal.git", branch = "android-support" }
|
cpal = { git = "https://github.com/doukutsu-rs/cpal.git", branch = "android-support" }
|
||||||
directories = "3"
|
directories = "3"
|
||||||
imgui = "0.7.0"
|
imgui = "0.6.0"
|
||||||
imgui-gfx-renderer = { version = "0.7.0", optional = true }
|
imgui-gfx-renderer = { version = "0.6.0", optional = true }
|
||||||
imgui-winit-support = { version = "0.7.0", default-features = false, features = ["winit-23"], 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 }
|
||||||
image = { version = "0.22", default-features = false, features = ["png_codec", "pnm", "bmp"] }
|
image = { version = "0.22", default-features = false, features = ["png_codec", "pnm", "bmp"] }
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
@ -66,7 +67,8 @@ num-derive = "0.3.2"
|
||||||
num-traits = "0.2.12"
|
num-traits = "0.2.12"
|
||||||
paste = "1.0.0"
|
paste = "1.0.0"
|
||||||
pretty_env_logger = "0.4.0"
|
pretty_env_logger = "0.4.0"
|
||||||
sdl2 = { version = "0.34", optional = true, features = ["unsafe_textures", "bundled", "static-link"] }
|
sdl2 = { version = "0.34.3", optional = true, features = ["unsafe_textures", "bundled", "gfx"] }
|
||||||
|
sdl2-sys = { version = "0.34", optional = true, features = ["bundled", "gfx"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_derive = "1"
|
serde_derive = "1"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
|
|
|
@ -388,6 +388,22 @@ pub struct Color {
|
||||||
pub a: f32,
|
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 {
|
impl Color {
|
||||||
/// Create a new `Color` from four `f32`'s in the range `[0.0-1.0]`
|
/// 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 {
|
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
|
||||||
|
|
|
@ -52,6 +52,5 @@ pub fn init_backend() -> GameResult<Box<dyn Backend>> {
|
||||||
|
|
||||||
pub enum SpriteBatchCommand {
|
pub enum SpriteBatchCommand {
|
||||||
DrawRect(Rect<f32>, Rect<f32>),
|
DrawRect(Rect<f32>, Rect<f32>),
|
||||||
DrawRectFlip(Rect<f32>, Rect<f32>, bool, bool),
|
|
||||||
DrawRectTinted(Rect<f32>, Rect<f32>, Color),
|
DrawRectTinted(Rect<f32>, Rect<f32>, Color),
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,22 @@ use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use imgui::{DrawCmd, DrawData, ImString, TextureId, Ui};
|
||||||
use imgui::internal::RawWrapper;
|
use imgui::internal::RawWrapper;
|
||||||
use imgui::{ConfigFlags, DrawCmd, DrawData, ImString, Key, MouseCursor, TextureId, Ui};
|
use sdl2::{EventPump, keyboard, pixels, Sdl};
|
||||||
use sdl2::event::{Event, WindowEvent};
|
use sdl2::event::{Event, WindowEvent};
|
||||||
|
use sdl2::gfx::primitives::DrawRenderer;
|
||||||
use sdl2::keyboard::Scancode;
|
use sdl2::keyboard::Scancode;
|
||||||
use sdl2::mouse::{Cursor, SystemCursor};
|
|
||||||
use sdl2::pixels::PixelFormatEnum;
|
use sdl2::pixels::PixelFormatEnum;
|
||||||
use sdl2::render::{Texture, TextureCreator, WindowCanvas};
|
use sdl2::render::{Texture, TextureCreator, WindowCanvas};
|
||||||
|
use sdl2::surface::Surface;
|
||||||
use sdl2::video::WindowContext;
|
use sdl2::video::WindowContext;
|
||||||
use sdl2::{keyboard, pixels, EventPump, Sdl};
|
|
||||||
|
|
||||||
use crate::common::Color;
|
use crate::common::Color;
|
||||||
use crate::framework::backend::{
|
use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand};
|
||||||
Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand,
|
|
||||||
};
|
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::{GameError, GameResult};
|
use crate::framework::error::{GameError, GameResult};
|
||||||
use crate::framework::graphics::{imgui_context, BlendMode};
|
use crate::framework::graphics::{BlendMode, imgui_context};
|
||||||
use crate::framework::keyboard::ScanCode;
|
use crate::framework::keyboard::ScanCode;
|
||||||
use crate::framework::ui::init_imgui;
|
use crate::framework::ui::init_imgui;
|
||||||
use crate::Game;
|
use crate::Game;
|
||||||
|
@ -32,7 +31,9 @@ impl SDL2Backend {
|
||||||
pub fn new() -> GameResult<Box<dyn Backend>> {
|
pub fn new() -> GameResult<Box<dyn Backend>> {
|
||||||
let context = sdl2::init().map_err(|e| GameError::WindowError(e))?;
|
let context = sdl2::init().map_err(|e| GameError::WindowError(e))?;
|
||||||
|
|
||||||
let backend = SDL2Backend { context };
|
let backend = SDL2Backend {
|
||||||
|
context,
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Box::new(backend))
|
Ok(Box::new(backend))
|
||||||
}
|
}
|
||||||
|
@ -61,15 +62,13 @@ impl SDL2EventLoop {
|
||||||
|
|
||||||
let event_pump = sdl.event_pump().map_err(|e| GameError::WindowError(e))?;
|
let event_pump = sdl.event_pump().map_err(|e| GameError::WindowError(e))?;
|
||||||
let video = sdl.video().map_err(|e| GameError::WindowError(e))?;
|
let video = sdl.video().map_err(|e| GameError::WindowError(e))?;
|
||||||
let window = video
|
let window = video.window("Cave Story (doukutsu-rs)", 640, 480)
|
||||||
.window("Cave Story (doukutsu-rs)", 640, 480)
|
|
||||||
.position_centered()
|
.position_centered()
|
||||||
.resizable()
|
.resizable()
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| GameError::WindowError(e.to_string()))?;
|
.map_err(|e| GameError::WindowError(e.to_string()))?;
|
||||||
|
|
||||||
let canvas = window
|
let canvas = window.into_canvas()
|
||||||
.into_canvas()
|
|
||||||
.accelerated()
|
.accelerated()
|
||||||
.present_vsync()
|
.present_vsync()
|
||||||
.build()
|
.build()
|
||||||
|
@ -97,10 +96,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
let (imgui, imgui_sdl2) = unsafe {
|
let (imgui, imgui_sdl2) = unsafe {
|
||||||
let renderer: &Box<SDL2Renderer> = std::mem::transmute(ctx.renderer.as_ref().unwrap());
|
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(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -119,30 +115,27 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
Event::Quit { .. } => {
|
Event::Quit { .. } => {
|
||||||
state.shutdown();
|
state.shutdown();
|
||||||
}
|
}
|
||||||
Event::Window { win_event, .. } => match win_event {
|
Event::Window { win_event, .. } => {
|
||||||
WindowEvent::Shown => {}
|
match win_event {
|
||||||
WindowEvent::Hidden => {}
|
WindowEvent::Shown => {}
|
||||||
WindowEvent::SizeChanged(width, height) => {
|
WindowEvent::Hidden => {}
|
||||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
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 Some(renderer) = ctx.renderer.as_ref() {
|
||||||
if let Ok(imgui) = renderer.imgui() {
|
if let Ok(imgui) = renderer.imgui() {
|
||||||
imgui.io_mut().display_size =
|
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||||
[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(scancode) = scancode {
|
||||||
if let Some(drs_scan) = conv_scancode(scancode) {
|
if let Some(drs_scan) = conv_scancode(scancode) {
|
||||||
if !repeat {
|
game.key_down_event(drs_scan, repeat);
|
||||||
state.process_debug_keys(drs_scan);
|
|
||||||
}
|
|
||||||
ctx.keyboard_context.set_key(drs_scan, true);
|
ctx.keyboard_context.set_key(drs_scan, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,11 +167,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
state.frame_time = 0.0;
|
state.frame_time = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui_sdl2.prepare_frame(
|
imgui_sdl2.prepare_frame(imgui.io_mut(), self.refs.borrow().canvas.window(), &self.event_pump.mouse_state());
|
||||||
imgui.io_mut(),
|
|
||||||
self.refs.borrow().canvas.window(),
|
|
||||||
&self.event_pump.mouse_state(),
|
|
||||||
);
|
|
||||||
game.draw(ctx).unwrap();
|
game.draw(ctx).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +180,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
struct SDL2Renderer {
|
struct SDL2Renderer {
|
||||||
refs: Rc<RefCell<SDL2Context>>,
|
refs: Rc<RefCell<SDL2Context>>,
|
||||||
imgui: Rc<RefCell<imgui::Context>>,
|
imgui: Rc<RefCell<imgui::Context>>,
|
||||||
imgui_event: Rc<RefCell<ImguiSdl2>>,
|
imgui_event: Rc<RefCell<imgui_sdl2::ImguiSdl2>>,
|
||||||
imgui_textures: HashMap<TextureId, SDL2Texture>,
|
imgui_textures: HashMap<TextureId, SDL2Texture>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,49 +192,42 @@ impl SDL2Renderer {
|
||||||
|
|
||||||
imgui.set_renderer_name(ImString::new("SDL2Renderer"));
|
imgui.set_renderer_name(ImString::new("SDL2Renderer"));
|
||||||
{
|
{
|
||||||
let refs = refs.clone();
|
let mut refs = refs.clone();
|
||||||
let mut fonts = imgui.fonts();
|
let mut fonts = imgui.fonts();
|
||||||
let id = fonts.tex_id;
|
let id = fonts.tex_id;
|
||||||
let font_tex = fonts.build_rgba32_texture();
|
let font_tex = fonts.build_rgba32_texture();
|
||||||
|
|
||||||
let mut texture = refs
|
let mut texture = refs.borrow_mut().texture_creator
|
||||||
.borrow_mut()
|
|
||||||
.texture_creator
|
|
||||||
.create_texture_streaming(PixelFormatEnum::RGBA32, font_tex.width, font_tex.height)
|
.create_texture_streaming(PixelFormatEnum::RGBA32, font_tex.width, font_tex.height)
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
|
|
||||||
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
||||||
texture
|
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||||
.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
for y in 0..(font_tex.height as usize) {
|
||||||
for y in 0..(font_tex.height as usize) {
|
for x in 0..(font_tex.width as usize) {
|
||||||
for x in 0..(font_tex.width as usize) {
|
let offset = y * pitch + x * 4;
|
||||||
let offset = y * pitch + x * 4;
|
let data_offset = (y * font_tex.width as usize + x) * 4;
|
||||||
let data_offset = (y * font_tex.width as usize + x) * 4;
|
|
||||||
|
|
||||||
buffer[offset] = font_tex.data[data_offset];
|
buffer[offset] = font_tex.data[data_offset];
|
||||||
buffer[offset + 1] = font_tex.data[data_offset + 1];
|
buffer[offset + 1] = font_tex.data[data_offset + 1];
|
||||||
buffer[offset + 2] = font_tex.data[data_offset + 2];
|
buffer[offset + 2] = font_tex.data[data_offset + 2];
|
||||||
buffer[offset + 3] = font_tex.data[data_offset + 3];
|
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(
|
imgui_textures.insert(id, SDL2Texture {
|
||||||
id,
|
refs: refs.clone(),
|
||||||
SDL2Texture {
|
texture: Some(texture),
|
||||||
refs: refs.clone(),
|
width: font_tex.width as u16,
|
||||||
texture: Some(texture),
|
height: font_tex.height as u16,
|
||||||
width: font_tex.width as u16,
|
commands: vec![],
|
||||||
height: font_tex.height as u16,
|
});
|
||||||
commands: vec![],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let imgui_sdl2 = unsafe {
|
let imgui_sdl2 = unsafe {
|
||||||
let refs = &mut *refs.as_ptr();
|
let refs = &mut *refs.as_ptr();
|
||||||
ImguiSdl2::new(&mut imgui, refs.canvas.window())
|
imgui_sdl2::ImguiSdl2::new(&mut imgui, refs.canvas.window())
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Box::new(SDL2Renderer {
|
Ok(Box::new(SDL2Renderer {
|
||||||
|
@ -262,10 +244,7 @@ fn to_sdl(color: Color) -> pixels::Color {
|
||||||
pixels::Color::RGBA(r, g, b, a)
|
pixels::Color::RGBA(r, g, b, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_raw_target(
|
unsafe fn set_raw_target(renderer: *mut sdl2::sys::SDL_Renderer, raw_texture: *mut sdl2::sys::SDL_Texture) -> GameResult {
|
||||||
renderer: *mut sdl2::sys::SDL_Renderer,
|
|
||||||
raw_texture: *mut sdl2::sys::SDL_Texture,
|
|
||||||
) -> GameResult {
|
|
||||||
if sdl2::sys::SDL_SetRenderTarget(renderer, raw_texture) == 0 {
|
if sdl2::sys::SDL_SetRenderTarget(renderer, raw_texture) == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
@ -274,23 +253,11 @@ unsafe fn set_raw_target(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min3(x: f32, y: f32, z: f32) -> f32 {
|
fn min3(x: f32, y: f32, z: f32) -> f32 {
|
||||||
if x < y && x < z {
|
if x < y && x < z { x } else if y < z { y } else { z }
|
||||||
x
|
|
||||||
} else if y < z {
|
|
||||||
y
|
|
||||||
} else {
|
|
||||||
z
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max3(x: f32, y: f32, z: f32) -> f32 {
|
fn max3(x: f32, y: f32, z: f32) -> f32 {
|
||||||
if x > y && x > z {
|
if x > y && x > z { x } else if y > z { y } else { z }
|
||||||
x
|
|
||||||
} else if y > z {
|
|
||||||
y
|
|
||||||
} else {
|
|
||||||
z
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackendRenderer for SDL2Renderer {
|
impl BackendRenderer for SDL2Renderer {
|
||||||
|
@ -309,15 +276,10 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_texture_mutable(
|
fn create_texture_mutable(&mut self, width: u16, height: u16) -> GameResult<Box<dyn BackendTexture>> {
|
||||||
&mut self,
|
let mut refs = self.refs.borrow_mut();
|
||||||
width: u16,
|
|
||||||
height: u16,
|
|
||||||
) -> GameResult<Box<dyn BackendTexture>> {
|
|
||||||
let refs = self.refs.borrow_mut();
|
|
||||||
|
|
||||||
let texture = refs
|
let mut texture = refs.texture_creator
|
||||||
.texture_creator
|
|
||||||
.create_texture_target(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
.create_texture_target(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
|
|
||||||
|
@ -330,35 +292,27 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_texture(
|
fn create_texture(&mut self, width: u16, height: u16, data: &[u8]) -> GameResult<Box<dyn BackendTexture>> {
|
||||||
&mut self,
|
let mut refs = self.refs.borrow_mut();
|
||||||
width: u16,
|
|
||||||
height: u16,
|
|
||||||
data: &[u8],
|
|
||||||
) -> GameResult<Box<dyn BackendTexture>> {
|
|
||||||
let refs = self.refs.borrow_mut();
|
|
||||||
|
|
||||||
let mut texture = refs
|
let mut texture = refs.texture_creator
|
||||||
.texture_creator
|
|
||||||
.create_texture_streaming(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
.create_texture_streaming(PixelFormatEnum::RGBA32, width as u32, height as u32)
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
|
|
||||||
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
texture.set_blend_mode(sdl2::render::BlendMode::Blend);
|
||||||
texture
|
texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
||||||
.with_lock(None, |buffer: &mut [u8], pitch: usize| {
|
for y in 0..(height as usize) {
|
||||||
for y in 0..(height as usize) {
|
for x in 0..(width as usize) {
|
||||||
for x in 0..(width as usize) {
|
let offset = y * pitch + x * 4;
|
||||||
let offset = y * pitch + x * 4;
|
let data_offset = (y * width as usize + x) * 4;
|
||||||
let data_offset = (y * width as usize + x) * 4;
|
|
||||||
|
|
||||||
buffer[offset] = data[data_offset];
|
buffer[offset] = data[data_offset];
|
||||||
buffer[offset + 1] = data[data_offset + 1];
|
buffer[offset + 1] = data[data_offset + 1];
|
||||||
buffer[offset + 2] = data[data_offset + 2];
|
buffer[offset + 2] = data[data_offset + 2];
|
||||||
buffer[offset + 3] = data[data_offset + 3];
|
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 {
|
Ok(Box::new(SDL2Texture {
|
||||||
refs: self.refs.clone(),
|
refs: self.refs.clone(),
|
||||||
|
@ -390,21 +344,23 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
let sdl2_texture: &Box<SDL2Texture> = std::mem::transmute(texture);
|
let sdl2_texture: &Box<SDL2Texture> = std::mem::transmute(texture);
|
||||||
|
|
||||||
if let Some(target) = sdl2_texture.texture.as_ref() {
|
if let Some(target) = sdl2_texture.texture.as_ref() {
|
||||||
set_raw_target(renderer, target.raw())?;
|
set_raw_target(renderer, target.raw());
|
||||||
} else {
|
} else {
|
||||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
set_raw_target(renderer, std::ptr::null_mut());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => unsafe {
|
None => unsafe {
|
||||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
set_raw_target(renderer, std::ptr::null_mut());
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
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 {
|
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
||||||
|
@ -435,12 +391,9 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let v1 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
let v1 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i] as usize];
|
||||||
+ 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 v2 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
let v3 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 2] as usize];
|
||||||
+ 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_x[0] = (v1.pos[0] - 0.5) as i16;
|
||||||
vert_y[0] = (v1.pos[1] - 0.5) as i16;
|
vert_y[0] = (v1.pos[1] - 0.5) as i16;
|
||||||
|
@ -451,30 +404,27 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
|
|
||||||
#[allow(clippy::float_cmp)]
|
#[allow(clippy::float_cmp)]
|
||||||
if i < count - 3 {
|
if i < count - 3 {
|
||||||
let v4 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
let v4 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 3] as usize];
|
||||||
+ 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 v5 = draw_list.vtx_buffer()[cmd_params.vtx_offset
|
let v6 = draw_list.vtx_buffer()[cmd_params.vtx_offset + idx_buffer[cmd_params.idx_offset + i + 5] as usize];
|
||||||
+ 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[0] = min3(v1.pos[0], v2.pos[0], v3.pos[0]);
|
||||||
min[1] = min3(v1.pos[1], v2.pos[1], v3.pos[1]);
|
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[0] = max3(v1.pos[0], v2.pos[0], v3.pos[0]);
|
||||||
max[1] = max3(v1.pos[1], v2.pos[1], v3.pos[1]);
|
max[1] = max3(v1.pos[1], v2.pos[1], v3.pos[1]);
|
||||||
|
|
||||||
is_rect = (v1.pos[0] == min[0] || v1.pos[0] == max[0])
|
is_rect = (v1.pos[0] == min[0] || v1.pos[0] == max[0]) &&
|
||||||
&& (v1.pos[1] == min[1] || v1.pos[1] == max[1])
|
(v1.pos[1] == min[1] || v1.pos[1] == max[1]) &&
|
||||||
&& (v2.pos[0] == min[0] || v2.pos[0] == max[0])
|
(v2.pos[0] == min[0] || v2.pos[0] == max[0]) &&
|
||||||
&& (v2.pos[1] == min[1] || v2.pos[1] == max[1])
|
(v2.pos[1] == min[1] || v2.pos[1] == max[1]) &&
|
||||||
&& (v3.pos[0] == min[0] || v3.pos[0] == max[0])
|
(v3.pos[0] == min[0] || v3.pos[0] == max[0]) &&
|
||||||
&& (v3.pos[1] == min[1] || v3.pos[1] == max[1])
|
(v3.pos[1] == min[1] || v3.pos[1] == max[1]) &&
|
||||||
&& (v4.pos[0] == min[0] || v4.pos[0] == max[0])
|
(v4.pos[0] == min[0] || v4.pos[0] == max[0]) &&
|
||||||
&& (v4.pos[1] == min[1] || v4.pos[1] == max[1])
|
(v4.pos[1] == min[1] || v4.pos[1] == max[1]) &&
|
||||||
&& (v5.pos[0] == min[0] || v5.pos[0] == max[0])
|
(v5.pos[0] == min[0] || v5.pos[0] == max[0]) &&
|
||||||
&& (v5.pos[1] == min[1] || v5.pos[1] == max[1])
|
(v5.pos[1] == min[1] || v5.pos[1] == max[1]) &&
|
||||||
&& (v6.pos[0] == min[0] || v6.pos[0] == max[0])
|
(v6.pos[0] == min[0] || v6.pos[0] == max[0]) &&
|
||||||
&& (v6.pos[1] == min[1] || v6.pos[1] == max[1]);
|
(v6.pos[1] == min[1] || v6.pos[1] == max[1]);
|
||||||
|
|
||||||
if is_rect {
|
if is_rect {
|
||||||
tex_pos[0] = min3(v1.uv[0], v2.uv[0], v3.uv[0]);
|
tex_pos[0] = min3(v1.uv[0], v2.uv[0], v3.uv[0]);
|
||||||
|
@ -484,40 +434,35 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surf) = self.imgui_textures.get_mut(&cmd_params.texture_id)
|
if let Some(surf) = self.imgui_textures.get_mut(&cmd_params.texture_id) {
|
||||||
{
|
unsafe {
|
||||||
if is_rect {
|
if is_rect {
|
||||||
let src = sdl2::rect::Rect::new(
|
let src = sdl2::rect::Rect::new((tex_pos[0] * surf.width as f32) as i32,
|
||||||
(tex_pos[0] * surf.width as f32) as i32,
|
(tex_pos[1] * surf.height 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[2] - tex_pos[0]) * surf.width as f32) as u32,
|
((tex_pos[3] - tex_pos[1]) * surf.height 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,
|
||||||
let dest = sdl2::rect::Rect::new(
|
(max[0] - min[0]) as u32,
|
||||||
min[0] as i32,
|
(max[1] - min[1]) as u32);
|
||||||
min[1] as i32,
|
|
||||||
(max[0] - min[0]) as u32,
|
|
||||||
(max[1] - min[1]) as u32,
|
|
||||||
);
|
|
||||||
|
|
||||||
let tex = surf.texture.as_mut().unwrap();
|
let tex = surf.texture.as_mut().unwrap();
|
||||||
tex.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
tex.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
||||||
tex.set_alpha_mod(v1.col[3]);
|
tex.set_alpha_mod(v1.col[3]);
|
||||||
|
|
||||||
refs.canvas
|
refs.canvas.copy(tex, src, dest);
|
||||||
.copy(tex, src, dest)
|
} else {
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
||||||
} else {
|
refs.canvas.raw(),
|
||||||
/*sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
vert_x.as_ptr(),
|
||||||
refs.canvas.raw(),
|
vert_y.as_ptr(),
|
||||||
vert_x.as_ptr(),
|
3,
|
||||||
vert_y.as_ptr(),
|
v1.col[0],
|
||||||
3,
|
v1.col[1],
|
||||||
v1.col[0],
|
v1.col[2],
|
||||||
v1.col[1],
|
v1.col[3],
|
||||||
v1.col[2],
|
);
|
||||||
v1.col[3],
|
}
|
||||||
);*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,7 +472,7 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
DrawCmd::ResetRenderState => {}
|
DrawCmd::ResetRenderState => {}
|
||||||
DrawCmd::RawCallback { callback, raw_cmd } => unsafe {
|
DrawCmd::RawCallback { callback, raw_cmd } => unsafe {
|
||||||
callback(draw_list.raw(), raw_cmd)
|
callback(draw_list.raw(), raw_cmd)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,7 +480,7 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_frame<'ui>(&self, _ui: &Ui<'ui>) -> GameResult {
|
fn prepare_frame<'ui>(&self, ui: &Ui<'ui>) -> GameResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,22 +520,9 @@ impl BackendTexture for SDL2Texture {
|
||||||
texture.set_alpha_mod(255);
|
texture.set_alpha_mod(255);
|
||||||
texture.set_blend_mode(refs.blend_mode);
|
texture.set_blend_mode(refs.blend_mode);
|
||||||
|
|
||||||
refs.canvas
|
refs.canvas.copy(texture,
|
||||||
.copy(
|
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)),
|
||||||
texture,
|
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)))
|
||||||
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()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
}
|
}
|
||||||
SpriteBatchCommand::DrawRectTinted(src, dest, color) => {
|
SpriteBatchCommand::DrawRectTinted(src, dest, color) => {
|
||||||
|
@ -599,49 +531,9 @@ impl BackendTexture for SDL2Texture {
|
||||||
texture.set_alpha_mod(a);
|
texture.set_alpha_mod(a);
|
||||||
texture.set_blend_mode(refs.blend_mode);
|
texture.set_blend_mode(refs.blend_mode);
|
||||||
|
|
||||||
refs.canvas
|
refs.canvas.copy(texture,
|
||||||
.copy(
|
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)),
|
||||||
texture,
|
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)))
|
||||||
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()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,9 +551,7 @@ impl Drop for SDL2Texture {
|
||||||
mem::swap(&mut self.texture, &mut texture_opt);
|
mem::swap(&mut self.texture, &mut texture_opt);
|
||||||
|
|
||||||
if let Some(texture) = texture_opt {
|
if let Some(texture) = texture_opt {
|
||||||
unsafe {
|
unsafe { texture.destroy(); }
|
||||||
texture.destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,219 +699,3 @@ fn conv_scancode(code: keyboard::Scancode) -> Option<ScanCode> {
|
||||||
_ => None,
|
_ => 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::{init_backend, BackendRenderer};
|
use crate::framework::backend::{Backend, init_backend, BackendRenderer};
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::framework::filesystem::Filesystem;
|
use crate::framework::filesystem::Filesystem;
|
||||||
use crate::Game;
|
use crate::Game;
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl Filesystem {
|
||||||
// Set up VFS to merge resource path, root path, and zip path.
|
// Set up VFS to merge resource path, root path, and zip path.
|
||||||
let overlay = vfs::OverlayFS::new();
|
let overlay = vfs::OverlayFS::new();
|
||||||
// User data VFS.
|
// User data VFS.
|
||||||
let user_overlay = vfs::OverlayFS::new();
|
let mut user_overlay = vfs::OverlayFS::new();
|
||||||
|
|
||||||
Filesystem {
|
Filesystem {
|
||||||
vfs: overlay,
|
vfs: overlay,
|
||||||
|
|
48
src/lib.rs
48
src/lib.rs
|
@ -177,6 +177,31 @@ impl Game {
|
||||||
graphics::present(ctx)?;
|
graphics::present(ctx)?;
|
||||||
Ok(())
|
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")]
|
#[cfg(target_os = "android")]
|
||||||
|
@ -296,7 +321,28 @@ pub fn init() -> GameResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
state_ref.next_scene = Some(Box::new(LoadingScene::new()));
|
state_ref.next_scene = Some(Box::new(LoadingScene::new()));
|
||||||
context.run(&mut game)?;
|
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)?;
|
||||||
|
}*/
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl LiveDebugger {
|
||||||
|
|
||||||
Window::new(im_str!("Debugger"))
|
Window::new(im_str!("Debugger"))
|
||||||
.resizable(false)
|
.resizable(false)
|
||||||
.collapsed(true, Condition::FirstUseEver)
|
.collapsed(false, Condition::FirstUseEver)
|
||||||
.position([5.0, 5.0], Condition::FirstUseEver)
|
.position([5.0, 5.0], Condition::FirstUseEver)
|
||||||
.size([400.0, 170.0], Condition::FirstUseEver)
|
.size([400.0, 170.0], Condition::FirstUseEver)
|
||||||
.build(ui, || {
|
.build(ui, || {
|
||||||
|
|
|
@ -1587,7 +1587,7 @@ impl NPC {
|
||||||
npc.y = self.y - 0x1800;
|
npc.y = self.y - 0x1800;
|
||||||
npc.tsc_direction = 10 * self.anim_num + 40;
|
npc.tsc_direction = 10 * self.anim_num + 40;
|
||||||
|
|
||||||
let _ = npc_list.spawn(0, npc);
|
npc_list.spawn(0, npc);
|
||||||
self.cond.set_explode_die(true);
|
self.cond.set_explode_die(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1630,7 +1630,7 @@ impl NPC {
|
||||||
npc.direction = Direction::Right;
|
npc.direction = Direction::Right;
|
||||||
npc.parent_id = self.id;
|
npc.parent_id = self.id;
|
||||||
|
|
||||||
let _ = npc_list.spawn(0x100, npc);
|
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 {
|
pub(crate) fn tick_n049_skullhead(&mut self, state: &mut SharedGameState, players: [&mut Player; 2], npc_list: &NPCList) -> GameResult {
|
||||||
let parent = self.get_parent_ref_mut(npc_list);
|
let mut 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) {
|
if self.action_num > 9 && parent.as_ref().map(|n| n.npc_type == 3).unwrap_or(false) {
|
||||||
self.action_num = 3;
|
self.action_num = 3;
|
||||||
|
|
|
@ -284,8 +284,6 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &BulletManager)> for NP
|
||||||
216 => self.tick_n216_debug_cat(state),
|
216 => self.tick_n216_debug_cat(state),
|
||||||
222 => self.tick_n222_prison_bars(state),
|
222 => self.tick_n222_prison_bars(state),
|
||||||
227 => self.tick_n227_bucket(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),
|
234 => self.tick_n234_red_flowers_picked(state),
|
||||||
239 => self.tick_n239_cage_bars(state),
|
239 => self.tick_n239_cage_bars(state),
|
||||||
241 => self.tick_n241_critter_red(state, players),
|
241 => self.tick_n241_critter_red(state, players),
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl Xoroshiro32PlusPlus {
|
||||||
|
|
||||||
pub fn next_u16(&self) -> u16 {
|
pub fn next_u16(&self) -> u16 {
|
||||||
let mut state = self.0.get();
|
let mut state = self.0.get();
|
||||||
let result = (state.0.wrapping_add(state.1)).rotate_left(9).wrapping_add(state.0);
|
let mut result = (state.0.wrapping_add(state.1)).rotate_left(9).wrapping_add(state.0);
|
||||||
|
|
||||||
state.1 ^= state.0;
|
state.1 ^= state.0;
|
||||||
state.0 = state.0.rotate_left(13) ^ state.1 ^ (state.1 << 5);
|
state.0 = state.0.rotate_left(13) ^ state.1 ^ (state.1 << 5);
|
||||||
|
|
|
@ -434,14 +434,13 @@ impl GameScene {
|
||||||
};
|
};
|
||||||
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, tex_name)?;
|
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, tex_name)?;
|
||||||
|
|
||||||
// switch version uses 1xxx flag to show a flipped version of face
|
// switch version uses +1000 face offset to display a flipped version
|
||||||
let flip = state.textscript_vm.face > 1000;
|
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 face_num = state.textscript_vm.face % 100;
|
||||||
|
let (scale_x, scale_y) = batch.scale();
|
||||||
|
|
||||||
batch.add_rect_flip(left_pos + 14.0, top_pos + 8.0,
|
batch.add_rect_scaled(left_pos + 14.0 + if flip { 48.0 } else { 0.0 }, top_pos + 8.0,
|
||||||
flip, false,
|
scale_x * if flip { -1.0 } else { 1.0 }, scale_y,
|
||||||
&Rect::new_size(
|
&Rect::new_size(
|
||||||
(face_num as u16 % 6) * 48,
|
(face_num as u16 % 6) * 48,
|
||||||
(face_num as u16 / 6) * 48,
|
(face_num as u16 / 6) * 48,
|
||||||
|
|
|
@ -19,11 +19,11 @@ impl NoDataScene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
static REL_URL: &str = "https://github.com/doukutsu-rs/game-data/releases";
|
static REL_URL: &str = "https://github.com/doukutsu-rs/game-data/releases";
|
||||||
|
|
||||||
impl Scene for NoDataScene {
|
impl Scene for NoDataScene {
|
||||||
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
{
|
{
|
||||||
if !self.flag {
|
if !self.flag {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
use lua_ffi::ffi::luaL_Reg;
|
use lua_ffi::ffi::luaL_Reg;
|
||||||
use lua_ffi::{LuaObject, State, c_int};
|
use lua_ffi::{LuaObject, State, c_int};
|
||||||
|
|
||||||
|
use crate::scene::game_scene::GameScene;
|
||||||
use crate::scripting::LuaScriptingState;
|
use crate::scripting::LuaScriptingState;
|
||||||
|
use crate::shared_game_state::SharedGameState;
|
||||||
|
|
||||||
pub struct Doukutsu {
|
pub struct Doukutsu {
|
||||||
pub ptr: *mut LuaScriptingState,
|
pub ptr: *mut LuaScriptingState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
impl Doukutsu {
|
impl Doukutsu {
|
||||||
pub fn new(ptr: *mut LuaScriptingState) -> Doukutsu {
|
pub fn new(ptr: *mut LuaScriptingState) -> Doukutsu {
|
||||||
Doukutsu {
|
Doukutsu {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::io::Read;
|
use std::io::{Read, Seek};
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ use crate::framework::context::Context;
|
||||||
use crate::framework::error::{GameResult, GameError};
|
use crate::framework::error::{GameResult, GameError};
|
||||||
|
|
||||||
|
|
||||||
use lua_ffi::{c_int, State, ThreadStatus};
|
use lua_ffi::{c_int, LuaFunction, LuaObject, State, ThreadStatus};
|
||||||
|
use lua_ffi::ffi::lua_pushcfunction;
|
||||||
|
|
||||||
use crate::scene::game_scene::GameScene;
|
use crate::scene::game_scene::GameScene;
|
||||||
use crate::scripting::doukutsu::Doukutsu;
|
use crate::scripting::doukutsu::Doukutsu;
|
||||||
|
@ -116,7 +117,7 @@ impl LuaScriptingState {
|
||||||
|
|
||||||
if filesystem::exists(ctx, "/scripts/") {
|
if filesystem::exists(ctx, "/scripts/") {
|
||||||
let mut script_count = 0;
|
let mut script_count = 0;
|
||||||
let files = filesystem::read_dir(ctx, "/scripts/")?
|
let mut files = filesystem::read_dir(ctx, "/scripts/")?
|
||||||
.filter(|f| f.to_string_lossy().to_lowercase().ends_with(".lua"));
|
.filter(|f| f.to_string_lossy().to_lowercase().ends_with(".lua"));
|
||||||
|
|
||||||
for file in files {
|
for file in files {
|
||||||
|
|
|
@ -12,7 +12,6 @@ pub struct LuaPlayer {
|
||||||
inv_ptr: *mut Inventory,
|
inv_ptr: *mut Inventory,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
impl LuaPlayer {
|
impl LuaPlayer {
|
||||||
fn check_ref(&self, state: &mut State) -> bool {
|
fn check_ref(&self, state: &mut State) -> bool {
|
||||||
if !self.valid_reference {
|
if !self.valid_reference {
|
||||||
|
|
|
@ -28,8 +28,7 @@ use crate::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM};
|
||||||
use crate::texture_set::TextureSet;
|
use crate::texture_set::TextureSet;
|
||||||
use crate::framework::{filesystem, graphics};
|
use crate::framework::{filesystem, graphics};
|
||||||
use crate::framework::backend::BackendTexture;
|
use crate::framework::backend::BackendTexture;
|
||||||
use crate::framework::graphics::{set_render_target, create_texture_mutable};
|
use crate::framework::graphics::{create_texture, set_render_target, create_texture_mutable};
|
||||||
use crate::framework::keyboard::ScanCode;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum TimingMode {
|
pub enum TimingMode {
|
||||||
|
@ -104,7 +103,6 @@ pub struct SharedGameState {
|
||||||
pub npc_super_pos: (i32, i32),
|
pub npc_super_pos: (i32, i32),
|
||||||
pub stages: Vec<StageData>,
|
pub stages: Vec<StageData>,
|
||||||
pub frame_time: f64,
|
pub frame_time: f64,
|
||||||
pub debugger: bool,
|
|
||||||
pub scale: f32,
|
pub scale: f32,
|
||||||
pub canvas_size: (f32, f32),
|
pub canvas_size: (f32, f32),
|
||||||
pub screen_size: (f32, f32),
|
pub screen_size: (f32, f32),
|
||||||
|
@ -119,7 +117,7 @@ pub struct SharedGameState {
|
||||||
pub lua: LuaScriptingState,
|
pub lua: LuaScriptingState,
|
||||||
pub sound_manager: SoundManager,
|
pub sound_manager: SoundManager,
|
||||||
pub settings: Settings,
|
pub settings: Settings,
|
||||||
pub shutdown: bool
|
pub shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedGameState {
|
impl SharedGameState {
|
||||||
|
@ -170,7 +168,6 @@ impl SharedGameState {
|
||||||
npc_super_pos: (0, 0),
|
npc_super_pos: (0, 0),
|
||||||
stages: Vec::with_capacity(96),
|
stages: Vec::with_capacity(96),
|
||||||
frame_time: 0.0,
|
frame_time: 0.0,
|
||||||
debugger: false,
|
|
||||||
scale: 2.0,
|
scale: 2.0,
|
||||||
screen_size: (640.0, 480.0),
|
screen_size: (640.0, 480.0),
|
||||||
canvas_size: (320.0, 240.0),
|
canvas_size: (320.0, 240.0),
|
||||||
|
@ -189,28 +186,6 @@ 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) {
|
pub fn reload_textures(&mut self) {
|
||||||
let mut texture_set = TextureSet::new(self.base_path.as_str());
|
let mut texture_set = TextureSet::new(self.base_path.as_str());
|
||||||
|
|
||||||
|
@ -332,6 +307,10 @@ impl SharedGameState {
|
||||||
pub fn set_speed(&mut self, value: f64) {
|
pub fn set_speed(&mut self, value: f64) {
|
||||||
self.settings.speed = clamp(value, 0.1, 3.0);
|
self.settings.speed = clamp(value, 0.1, 3.0);
|
||||||
self.frame_time = 0.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 {
|
pub fn current_tps(&self) -> f64 {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use num_traits::clamp;
|
||||||
|
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::{GameResult};
|
use crate::framework::error::{GameResult, GameError};
|
||||||
use crate::framework::filesystem;
|
use crate::framework::filesystem;
|
||||||
use crate::sound::organya::Song;
|
use crate::sound::organya::Song;
|
||||||
use crate::sound::pixtone::PixTonePlayback;
|
use crate::sound::pixtone::PixTonePlayback;
|
||||||
|
@ -16,6 +16,7 @@ use crate::sound::playback::{PlaybackEngine, SavedPlaybackState};
|
||||||
use crate::sound::wave_bank::SoundBank;
|
use crate::sound::wave_bank::SoundBank;
|
||||||
use crate::str;
|
use crate::str;
|
||||||
use crate::framework::error::GameError::{AudioError, ResourceLoadError, InvalidValue};
|
use crate::framework::error::GameError::{AudioError, ResourceLoadError, InvalidValue};
|
||||||
|
use std::io::Error;
|
||||||
|
|
||||||
mod wave_bank;
|
mod wave_bank;
|
||||||
mod organya;
|
mod organya;
|
||||||
|
|
|
@ -166,7 +166,6 @@ impl PlaybackEngine {
|
||||||
self.play_pos = position;
|
self.play_pos = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn get_total_samples(&self) -> u32 {
|
pub fn get_total_samples(&self) -> u32 {
|
||||||
let ticks_intro = self.song.time.loop_range.start;
|
let ticks_intro = self.song.time.loop_range.start;
|
||||||
let ticks_loop = self.song.time.loop_range.end - self.song.time.loop_range.start;
|
let ticks_loop = self.song.time.loop_range.end - self.song.time.loop_range.start;
|
||||||
|
|
|
@ -1751,7 +1751,6 @@ impl TextScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
fn read_varint<I: Iterator<Item=u8>>(iter: &mut I) -> GameResult<i32> {
|
fn read_varint<I: Iterator<Item=u8>>(iter: &mut I) -> GameResult<i32> {
|
||||||
let mut result = 0u32;
|
let mut result = 0u32;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use itertools::Itertools;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::common::{FILE_TYPES, Rect};
|
use crate::common::{FILE_TYPES, Point, Rect};
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::framework::backend::{BackendTexture, SpriteBatchCommand};
|
use crate::framework::backend::{BackendTexture, SpriteBatchCommand};
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
|
@ -94,40 +94,12 @@ impl SizedBatch {
|
||||||
self.add_rect_scaled(x, y, 1.0, 1.0, rect)
|
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)]
|
#[inline(always)]
|
||||||
pub fn add_rect_tinted(&mut self, x: f32, y: f32, color: (u8, u8, u8, u8), rect: &common::Rect<u16>) {
|
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)
|
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, scale_x: f32, scale_y: f32, rect: &common::Rect<u16>) {
|
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>) {
|
||||||
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +126,7 @@ impl SizedBatch {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
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>) {
|
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>) {
|
||||||
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 {
|
||||||
return;
|
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) {
|
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 shoot = false;
|
||||||
let mut btype;
|
let mut btype = 0;
|
||||||
|
|
||||||
if player.controller.shoot() {
|
if player.controller.shoot() {
|
||||||
inventory.add_xp(if player.equip.has_turbocharge() { 3 } else { 2 }, player, state);
|
inventory.add_xp(if player.equip.has_turbocharge() { 3 } else { 2 }, player, state);
|
||||||
|
|
Loading…
Reference in a new issue