From e07207b40ce4ce1ef391b2b94e12218f88304c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sallai=20J=C3=B3zsef?= Date: Tue, 16 Aug 2022 14:47:11 +0300 Subject: [PATCH] more rust crab headband sprites by @RedCoder09 --- src/builtin/builtin_data/crab_band.png | Bin 0 -> 943 bytes src/builtin_fs.rs | 1 + src/components/text_boxes.rs | 17 +++--- src/framework/backend.rs | 1 + src/framework/backend_sdl2.rs | 28 +++++++++ src/framework/render_opengl.rs | 47 ++++++++++++++- src/live_debugger.rs | 1 + src/npc/mod.rs | 36 ++++++++---- src/settings.rs | 9 ++- src/shared_game_state.rs | 5 ++ src/texture_set.rs | 76 ++++++++++++++++++++++++- 11 files changed, 200 insertions(+), 21 deletions(-) create mode 100644 src/builtin/builtin_data/crab_band.png diff --git a/src/builtin/builtin_data/crab_band.png b/src/builtin/builtin_data/crab_band.png new file mode 100644 index 0000000000000000000000000000000000000000..2834ea2d4f1d2d8a5ed37aca071d2a66eb7cf391 GIT binary patch literal 943 zcmV;g15o^lP)5Qe3qdvu6AXP$P8WQ=5wY|*@Ci7vrHs?^Xl6_Ix*@d$k%KnMhUBu)ObsPk_R zDItXaWysX`(8m9MdYWDvrfaT#bi5TW%X@!W+Dq#m`(5U0Nak)hbMCbInQ0-S5S2d< z57UH)>6)v@#VX#Cwe62(0X{bB*5i=$8;AMg&G843)(? zzPfDAW3*ViWq)aksO~rFTNInLk)uYCl8uyWq+1ag#f!(ETMWrKG-&2P8oM?A8bRK~ zRBoV^F>a)mQ4u@Doj0cU@q1&Q&yq9jII1)>CRYG6Y6OV@;qnY@1Yg{o^TzS64tc&Y zFMfD`exAp&bp>#XNqXtRaF238@zeZD^i&Us*ae#O5&!@I0H|?!w9@8FTjyJ2+vBfH z{VXiT(L?S!n4*bMYQ@dmX&TOM zi&Z~p5c^3fH;W>$b()~DlL}*Z$6xc~i1^DL@t>q4MqNo4<7{tnYd^76kV#C{23lkJ zvcm|>IG-#^DiPGE@uaV@-vzM%H5#*jaRMR+bI!geA!0}19hO0g%@H2{FQZ2gu>&M| zTKI(Qgb|wCeZ|xK3Wtjb&cuE|mqHM+15mFH&cx6?h#0zu zAJsTo=B`VvoQT+nIEP!}={>Ul+Hrj4P%Ft@-;6`xA>N{T16|!psV)sX#5e2b#7`{! zgZA78+Ou-rH*$3m>P39Ihj>o}XZndH9^%aS@e{Y?>INN&hd2{o1%6^U0`X49PYlgz zc^^W=&WVqCc#QLqVsj22<9!gZGqicyD?)a{2&-E=-eLd%00000xE8}O`~?kpA*#da RDd7MB002ovPDHLkV1l@V#OeS5 literal 0 HcmV?d00001 diff --git a/src/builtin_fs.rs b/src/builtin_fs.rs index b1a544e..90b5ff5 100644 --- a/src/builtin_fs.rs +++ b/src/builtin_fs.rs @@ -111,6 +111,7 @@ impl BuiltinFS { "builtin_data", vec![ FSNode::File("buttons.png", include_bytes!("builtin/builtin_data/buttons.png")), + FSNode::File("crab_band.png", include_bytes!("builtin/builtin_data/crab_band.png")), FSNode::File("triangles.png", include_bytes!("builtin/builtin_data/triangles.png")), ], ), diff --git a/src/components/text_boxes.rs b/src/components/text_boxes.rs index 505a57a..6d532f6 100644 --- a/src/components/text_boxes.rs +++ b/src/components/text_boxes.rs @@ -164,13 +164,16 @@ impl GameEntity<()> for TextBoxes { let face_x = (4.0 + (6 - self.slide_in) as f32 * 8.0) - 52.0; - batch.add_rect_flip( - left_pos + 14.0 + face_x, - top_pos + 8.0, - flip, - false, - &Rect::new_size((face_num as u16 % 6) * 48, (face_num as u16 / 6) * 48, 48, 48), - ); + let final_x = left_pos + 14.0 + face_x; + let final_y = top_pos + 8.0; + let rect = Rect::new_size((face_num as u16 % 6) * 48, (face_num as u16 / 6) * 48, 48, 48); + + if face_num >= 1 && face_num <= 4 && state.more_rust { + // sue + batch.add_rect_flip_tinted(final_x, final_y, flip, false, (200, 200, 255, 255), &rect); + } else { + batch.add_rect_flip(final_x, final_y, flip, false, &rect); + } batch.draw(ctx)?; graphics::set_clip_rect(ctx, None)?; diff --git a/src/framework/backend.rs b/src/framework/backend.rs index 0160406..fe7808a 100644 --- a/src/framework/backend.rs +++ b/src/framework/backend.rs @@ -119,4 +119,5 @@ pub enum SpriteBatchCommand { DrawRect(Rect, Rect), DrawRectFlip(Rect, Rect, bool, bool), DrawRectTinted(Rect, Rect, Color), + DrawRectFlipTinted(Rect, Rect, bool, bool, Color), } diff --git a/src/framework/backend_sdl2.rs b/src/framework/backend_sdl2.rs index 7c30ac1..6e091d7 100644 --- a/src/framework/backend_sdl2.rs +++ b/src/framework/backend_sdl2.rs @@ -965,6 +965,34 @@ impl BackendTexture for SDL2Texture { texture.set_alpha_mod(255); texture.set_blend_mode(blend); + 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()))?; + } + SpriteBatchCommand::DrawRectFlipTinted(src, dest, flip_x, flip_y, color) => { + let (r, g, b, a) = color.to_rgba(); + texture.set_color_mod(r, g, b); + texture.set_alpha_mod(a); + texture.set_blend_mode(blend); + canvas .copy_ex( texture, diff --git a/src/framework/render_opengl.rs b/src/framework/render_opengl.rs index cc2f882..c1edb72 100644 --- a/src/framework/render_opengl.rs +++ b/src/framework/render_opengl.rs @@ -164,6 +164,51 @@ impl BackendTexture for OpenGLTexture { ]; self.vertices.extend_from_slice(&vertices); } + SpriteBatchCommand::DrawRectFlipTinted(mut src, dest, flip_x, flip_y, color) => { + if flip_x { + std::mem::swap(&mut src.left, &mut src.right); + } + + if flip_y { + std::mem::swap(&mut src.top, &mut src.bottom); + } + + let color = color.to_rgba(); + + let vertices = [ + VertexData { + position: (dest.left, dest.bottom), + uv: (src.left * tex_scale_x, src.bottom * tex_scale_y), + color, + }, + VertexData { + position: (dest.left, dest.top), + uv: (src.left * tex_scale_x, src.top * tex_scale_y), + color, + }, + VertexData { + position: (dest.right, dest.top), + uv: (src.right * tex_scale_x, src.top * tex_scale_y), + color, + }, + VertexData { + position: (dest.left, dest.bottom), + uv: (src.left * tex_scale_x, src.bottom * tex_scale_y), + color, + }, + VertexData { + position: (dest.right, dest.top), + uv: (src.right * tex_scale_x, src.top * tex_scale_y), + color, + }, + VertexData { + position: (dest.right, dest.bottom), + uv: (src.right * tex_scale_x, src.bottom * tex_scale_y), + color, + }, + ]; + self.vertices.extend_from_slice(&vertices); + } } } @@ -787,7 +832,7 @@ impl BackendRenderer for OpenGLRenderer { match mode { VSyncMode::Uncapped => { sdl2_sys::SDL_GL_SetSwapInterval(0); - }, + } VSyncMode::VSync => { sdl2_sys::SDL_GL_SetSwapInterval(1); } diff --git a/src/live_debugger.rs b/src/live_debugger.rs index 1ed2618..280d189 100644 --- a/src/live_debugger.rs +++ b/src/live_debugger.rs @@ -163,6 +163,7 @@ impl LiveDebugger { self.hotkey_list_visible = !self.hotkey_list_visible; } ui.checkbox("noclip", &mut state.settings.noclip); + ui.checkbox("more rust", &mut state.more_rust); }); if self.map_selector_visible { diff --git a/src/npc/mod.rs b/src/npc/mod.rs index d089460..90da326 100644 --- a/src/npc/mod.rs +++ b/src/npc/mod.rs @@ -218,6 +218,10 @@ impl NPC { Ok(()) } + + fn is_sue(&self) -> bool { + [42, 92, 280, 284].contains(&self.npc_type) + } } impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &mut BulletManager, &mut Flash, &mut BossNPC)> for NPC { @@ -658,16 +662,28 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &mut BulletManager, &mu let (frame_x, frame_y) = frame.xy_interpolated(state.frame_time); - batch.add_rect( - interpolate_fix9_scale(self.prev_x - off_x, self.x - off_x, state.frame_time) + shock - frame_x, - interpolate_fix9_scale( - self.prev_y - self.display_bounds.top as i32, - self.y - self.display_bounds.top as i32, - state.frame_time, - ) - frame_y, - &self.anim_rect, - ); - batch.draw(ctx)?; + let final_x = interpolate_fix9_scale(self.prev_x - off_x, self.x - off_x, state.frame_time) + shock - frame_x; + let final_y = interpolate_fix9_scale( + self.prev_y - self.display_bounds.top as i32, + self.y - self.display_bounds.top as i32, + state.frame_time, + ) - frame_y; + + if self.is_sue() && state.more_rust { + // tint sue blue + batch.add_rect_tinted(final_x, final_y, (200, 200, 255, 255), &self.anim_rect); + batch.draw(ctx)?; + } else { + batch.add_rect(final_x, final_y, &self.anim_rect); + batch.draw(ctx)?; + } + + if self.npc_type == 42 && state.more_rust { + // draw crab headband + let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "crab_band")?; + batch.add_rect(final_x, final_y, &self.anim_rect); + batch.draw(ctx)?; + } Ok(()) } diff --git a/src/settings.rs b/src/settings.rs index c14981a..71b30f7 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -78,6 +78,7 @@ pub struct Settings { pub debug_mode: bool, #[serde(skip)] pub noclip: bool, + pub more_rust: bool, } fn default_true() -> bool { @@ -86,7 +87,7 @@ fn default_true() -> bool { #[inline(always)] fn current_version() -> u32 { - 18 + 19 } #[inline(always)] @@ -285,6 +286,11 @@ impl Settings { self.player2_rumble = default_rumble(); } + if self.version == 18 { + self.version = 19; + self.more_rust = false; + } + if self.version != initial_version { log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version); } @@ -388,6 +394,7 @@ impl Default for Settings { screen_shake_intensity: ScreenShakeIntensity::Full, debug_mode: false, noclip: false, + more_rust: false, } } } diff --git a/src/shared_game_state.rs b/src/shared_game_state.rs index 81080b0..a546389 100644 --- a/src/shared_game_state.rs +++ b/src/shared_game_state.rs @@ -339,6 +339,7 @@ pub struct SharedGameState { pub replay_state: ReplayState, pub mod_requirements: ModRequirements, pub tutorial_counter: u16, + pub more_rust: bool, pub shutdown: bool, } @@ -427,6 +428,9 @@ impl SharedGameState { sound_manager.set_song_volume(settings.bgm_volume); sound_manager.set_sfx_volume(settings.sfx_volume); + let current_time = Local::now(); + let more_rust = (current_time.month() == 7 && current_time.day() == 7) || settings.more_rust; + #[cfg(feature = "hooks")] init_hooks(); @@ -480,6 +484,7 @@ impl SharedGameState { replay_state: ReplayState::None, mod_requirements, tutorial_counter: 0, + more_rust, shutdown: false, }) } diff --git a/src/texture_set.rs b/src/texture_set.rs index 8ee073c..3226673 100644 --- a/src/texture_set.rs +++ b/src/texture_set.rs @@ -52,6 +52,16 @@ pub trait SpriteBatch { fn add_rect_tinted(&mut self, x: f32, y: f32, color: (u8, u8, u8, u8), rect: &common::Rect); + fn add_rect_flip_tinted( + &mut self, + x: f32, + y: f32, + flip_x: bool, + flip_y: bool, + color: (u8, u8, u8, u8), + rect: &common::Rect, + ); + fn add_rect_scaled(&mut self, x: f32, y: f32, scale_x: f32, scale_y: f32, rect: &common::Rect); fn add_rect_scaled_tinted( @@ -116,6 +126,17 @@ impl SpriteBatch for DummyBatch { fn add_rect_tinted(&mut self, _x: f32, _y: f32, _color: (u8, u8, u8, u8), _rect: &Rect) {} + fn add_rect_flip_tinted( + &mut self, + _x: f32, + _y: f32, + _flip_x: bool, + _flip_y: bool, + _color: (u8, u8, u8, u8), + _rect: &Rect, + ) { + } + fn add_rect_scaled(&mut self, _x: f32, _y: f32, _scale_x: f32, _scale_y: f32, _rect: &Rect) {} fn add_rect_scaled_tinted( @@ -284,14 +305,19 @@ impl SpriteBatch for SubBatch { scale_y: f32, rect: &common::Rect, ) { - if (rect.right - rect.left) == 0 || (rect.bottom - rect.top) == 0 { + if (rect.right.saturating_sub(rect.left)) == 0 || (rect.bottom.saturating_sub(rect.top)) == 0 { return; } let mag = unsafe { I_MAG }; self.batch.add(SpriteBatchCommand::DrawRectTinted( - Rect { left: rect.left as f32, top: rect.top as f32, right: rect.right as f32, bottom: rect.bottom as f32 }, + 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, @@ -302,6 +328,40 @@ impl SpriteBatch for SubBatch { )); } + fn add_rect_flip_tinted( + &mut self, + x: f32, + y: f32, + flip_x: bool, + flip_y: bool, + color: (u8, u8, u8, u8), + rect: &common::Rect, + ) { + if (rect.right.saturating_sub(rect.left)) == 0 || (rect.bottom.saturating_sub(rect.top)) == 0 { + return; + } + + let mag = unsafe { I_MAG }; + + self.batch.add(SpriteBatchCommand::DrawRectFlipTinted( + 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, + color.into(), + )); + } + #[inline(always)] fn draw(&mut self, ctx: &mut Context) -> GameResult { self.draw_filtered(FilterMode::Nearest, ctx) @@ -392,6 +452,18 @@ impl SpriteBatch for CombinedBatch { self.main_batch.add_rect_scaled_tinted(x, y, color, scale_x, scale_y, rect) } + fn add_rect_flip_tinted( + &mut self, + x: f32, + y: f32, + flip_x: bool, + flip_y: bool, + color: (u8, u8, u8, u8), + rect: &common::Rect, + ) { + self.main_batch.add_rect_flip_tinted(x, y, flip_x, flip_y, color, rect) + } + fn draw(&mut self, ctx: &mut Context) -> GameResult { self.main_batch.draw(ctx) }