mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-07-27 15:31:49 +00:00
Compare commits
5 commits
9e21838a9d
...
ad4fc4b481
Author | SHA1 | Date | |
---|---|---|---|
|
ad4fc4b481 | ||
|
035b2c2848 | ||
|
20be51bb72 | ||
|
203a4a1180 | ||
|
5f259b572e |
|
@ -35,6 +35,7 @@ cache:
|
|||
# - cargo test --verbose --all --no-fail-fast
|
||||
|
||||
build_script:
|
||||
- set DRS_BUILD_VERSION_OVERRIDE=%APPVEYOR_BUILD_VERSION%
|
||||
- cargo build --release --bin doukutsu-rs
|
||||
- mkdir release
|
||||
- copy target\release\doukutsu-rs.exe release
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
authors = ["Alula <julekonopinska@gmail.com>"]
|
||||
authors = ["Alula"]
|
||||
edition = "2018"
|
||||
name = "doukutsu-rs"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -11,16 +11,18 @@ layout (std140) uniform Globals {
|
|||
|
||||
layout (std140) uniform WaterShaderParams {
|
||||
vec2 u_Resolution;
|
||||
vec2 u_FramePos;
|
||||
float u_Tick;
|
||||
};
|
||||
|
||||
void main() {
|
||||
vec2 wave = v_Uv;
|
||||
wave.x += sin(v_Uv.x * 40.0 + u_Tick / 20.0) * (sin(u_Tick / 10.0) * 0.01);
|
||||
wave.y -= cos(v_Uv.y * 20.0 + u_Tick / 5.0) * (sin(u_Tick / 20.0) * 0.01);
|
||||
wave.x += sin((-u_FramePos.y / u_Resolution.y + v_Uv.x * 16.0) + u_Tick / 20.0) * 2.0 / u_Resolution.x;
|
||||
wave.y -= cos((-u_FramePos.x / u_Resolution.x + v_Uv.y * 16.0) + u_Tick / 5.0) * 2.0 / u_Resolution.y;
|
||||
float off = 0.4 / u_Resolution.y;
|
||||
vec4 color = texture(t_Texture, wave);
|
||||
color.r = texture(t_Texture, wave + off).r;
|
||||
color.b = texture(t_Texture, wave - off).b;
|
||||
Target0 = vec4(0.7, 0.8, 1.2, 1.0) * color * v_Color;
|
||||
|
||||
Target0 = (vec4(0.4, 0.6, 0.8, 1.0) * 0.3) + (color * v_Color * 0.7);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use num_traits::{AsPrimitive, Num};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::{SeqAccess, Visitor};
|
||||
use serde::ser::SerializeTupleStruct;
|
||||
|
||||
use crate::bitfield;
|
||||
|
||||
/// Multiply cave story degrees (0-255, which corresponds to 0°-360°) with this to get
|
||||
/// respective value in radians.
|
||||
pub const CDEG_RAD: f64 = std::f64::consts::PI / 128.0;
|
||||
lazy_static! {
|
||||
pub static ref VERSION_BANNER: String = {
|
||||
let version = option_env!("DRS_BUILD_VERSION_OVERRIDE").unwrap_or(env!("CARGO_PKG_VERSION"));
|
||||
format!("doukutsu-rs {}", version)
|
||||
};
|
||||
}
|
||||
|
||||
bitfield! {
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -217,7 +227,7 @@ impl Direction {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Rect<T: Num + PartialOrd + Copy = isize> {
|
||||
pub left: T,
|
||||
pub top: T,
|
||||
|
@ -279,6 +289,63 @@ impl<T: Num + PartialOrd + Copy + AsPrimitive<f32>> Into<ggez::graphics::Rect> f
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Num + PartialOrd + Copy + Serialize> Serialize for Rect<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_tuple_struct("Rect", 4)?;
|
||||
state.serialize_field(&self.left)?;
|
||||
state.serialize_field(&self.top)?;
|
||||
state.serialize_field(&self.right)?;
|
||||
state.serialize_field(&self.bottom)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
macro_rules! rect_deserialze {
|
||||
($num_type: ident) => {
|
||||
impl<'de> Deserialize<'de> for Rect<$num_type> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Rect<$num_type>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct RectVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for RectVisitor {
|
||||
type Value = Rect<$num_type>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("Expected Rect structure.")
|
||||
}
|
||||
|
||||
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
||||
where
|
||||
V: SeqAccess<'de>
|
||||
{
|
||||
let invalid_length = || {
|
||||
de::Error::invalid_length(0, &self)
|
||||
};
|
||||
|
||||
let left = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
let top = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
let right = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
let bottom = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
|
||||
Ok(Rect { left, top, right, bottom })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_tuple_struct("Rect", 4, RectVisitor)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
rect_deserialze!(u8);
|
||||
rect_deserialze!(u16);
|
||||
rect_deserialze!(isize);
|
||||
rect_deserialze!(usize);
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fix9_scale(val: isize, scale: f32) -> f32 {
|
||||
(val as f64 * scale as f64 / 512.0).floor() as f32 / scale
|
||||
|
|
|
@ -163,7 +163,6 @@ impl Game {
|
|||
fn key_down_event(&mut self, key_code: KeyCode, _key_mod: KeyMods, repeat: bool) {
|
||||
if repeat { return; }
|
||||
|
||||
// todo: proper keymaps?
|
||||
let state = &mut self.state;
|
||||
match key_code {
|
||||
KeyCode::F7 => { state.set_speed(1.0) }
|
||||
|
|
|
@ -318,6 +318,10 @@ impl Player {
|
|||
}
|
||||
|
||||
pub fn tick_npc_collisions(&mut self, id: TargetPlayer, state: &mut SharedGameState, npc_map: &mut NPCMap, inventory: &mut Inventory) {
|
||||
if !self.cond.alive() {
|
||||
return;
|
||||
}
|
||||
|
||||
for npc_cell in npc_map.npcs.values() {
|
||||
let mut npc = npc_cell.borrow_mut();
|
||||
if !npc.cond.alive() { continue; }
|
||||
|
|
|
@ -649,8 +649,11 @@ impl GameScene {
|
|||
}
|
||||
|
||||
fn draw_water(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||
let (frame_x, frame_y) = self.frame.xy_interpolated(state.frame_time, state.scale);
|
||||
|
||||
{
|
||||
state.shaders.water_shader_params.resolution = [state.canvas_size.0, state.canvas_size.1];
|
||||
state.shaders.water_shader_params.frame_pos = [frame_x, frame_y];
|
||||
state.shaders.water_shader_params.t = self.tick as f32;
|
||||
let _lock = graphics::use_shader(ctx, &state.shaders.water_shader);
|
||||
state.shaders.water_shader.send(ctx, state.shaders.water_shader_params)?;
|
||||
|
@ -666,8 +669,6 @@ impl GameScene {
|
|||
// cheap, clones a reference underneath
|
||||
let mut tmp_batch = SpriteBatch::new(state.tmp_canvas.image().clone());
|
||||
|
||||
let (frame_x, frame_y) = self.frame.xy_interpolated(state.frame_time, state.scale);
|
||||
|
||||
let tile_start_x = clamp(self.frame.x / 0x200 / 16, 0, self.stage.map.width as isize) as usize;
|
||||
let tile_start_y = clamp(self.frame.y / 0x200 / 16, 0, self.stage.map.height as isize) as usize;
|
||||
let tile_end_x = clamp((self.frame.x / 0x200 + 8 + state.canvas_size.0 as isize) / 16 + 1, 0, self.stage.map.width as isize) as usize;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use ggez::{Context, GameResult, graphics};
|
||||
use ggez::graphics::Color;
|
||||
|
||||
use crate::common::Rect;
|
||||
use crate::common::{Rect, VERSION_BANNER};
|
||||
use crate::menu::{Menu, MenuEntry, MenuSelectionResult};
|
||||
use crate::scene::Scene;
|
||||
use crate::shared_game_state::{SharedGameState, TimingMode};
|
||||
|
@ -75,7 +75,6 @@ impl TitleScene {
|
|||
}
|
||||
}
|
||||
|
||||
static ENGINE_VERSION: &str = "doukutsu-rs 0.1.0";
|
||||
// asset copyright for freeware version
|
||||
static COPYRIGHT_PIXEL: &str = "2004.12 Studio Pixel";
|
||||
// asset copyright for Nicalis
|
||||
|
@ -235,7 +234,7 @@ impl Scene for TitleScene {
|
|||
batch.draw(ctx)?;
|
||||
}
|
||||
|
||||
self.draw_text_centered(ENGINE_VERSION, state.canvas_size.1 - 15.0, state, ctx)?;
|
||||
self.draw_text_centered(VERSION_BANNER.as_str(), state.canvas_size.1 - 15.0, state, ctx)?;
|
||||
|
||||
if state.constants.is_switch {
|
||||
self.draw_text_centered(COPYRIGHT_NICALIS_SWITCH, state.canvas_size.1 - 30.0, state, ctx)?;
|
||||
|
|
|
@ -5,6 +5,7 @@ use ggez::{Context, GameResult};
|
|||
gfx_defines! {
|
||||
constant WaterShaderParams {
|
||||
resolution: [f32; 2] = "u_Resolution",
|
||||
frame_pos: [f32; 2] = "u_FramePos",
|
||||
t: f32 = "u_Tick",
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +20,7 @@ impl Shaders {
|
|||
let water_shader_params = WaterShaderParams {
|
||||
t: 0.0,
|
||||
resolution: [0.0, 0.0],
|
||||
frame_pos: [0.0, 0.0],
|
||||
};
|
||||
|
||||
Ok(Shaders {
|
||||
|
|
Loading…
Reference in a new issue