mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-11-30 08:08:18 +00:00
add gamepad input icons
This commit is contained in:
parent
0415f917f8
commit
fb4ac0dae8
BIN
src/builtin/builtin_data/buttons.png
Normal file
BIN
src/builtin/builtin_data/buttons.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 KiB |
|
|
@ -106,6 +106,10 @@ impl BuiltinFS {
|
||||||
include_bytes!("builtin/organya-wavetable-doukutsu.bin"),
|
include_bytes!("builtin/organya-wavetable-doukutsu.bin"),
|
||||||
),
|
),
|
||||||
FSNode::File("touch.png", include_bytes!("builtin/touch.png")),
|
FSNode::File("touch.png", include_bytes!("builtin/touch.png")),
|
||||||
|
FSNode::Directory(
|
||||||
|
"builtin_data",
|
||||||
|
vec![FSNode::File("buttons.png", include_bytes!("builtin/builtin_data/buttons.png"))],
|
||||||
|
),
|
||||||
FSNode::Directory(
|
FSNode::Directory(
|
||||||
"shaders",
|
"shaders",
|
||||||
vec![
|
vec![
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use crate::engine_constants::npcs::NPCConsts;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::framework::filesystem;
|
use crate::framework::filesystem;
|
||||||
|
use crate::framework::gamepad::{Axis, Button};
|
||||||
use crate::i18n::Locale;
|
use crate::i18n::Locale;
|
||||||
use crate::player::ControlMode;
|
use crate::player::ControlMode;
|
||||||
use crate::scripting::tsc::text_script::TextScriptEncoding;
|
use crate::scripting::tsc::text_script::TextScriptEncoding;
|
||||||
|
|
@ -287,6 +288,29 @@ impl Clone for TitleConsts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GamepadConsts {
|
||||||
|
pub button_rects: HashMap<Button, [Rect<u16>; 4]>,
|
||||||
|
pub axis_rects: HashMap<Axis, [Rect<u16>; 4]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for GamepadConsts {
|
||||||
|
fn clone(&self) -> GamepadConsts {
|
||||||
|
GamepadConsts { button_rects: self.button_rects.clone(), axis_rects: self.axis_rects.clone() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GamepadConsts {
|
||||||
|
fn rects(base: Rect<u16>) -> [Rect<u16>; 4] {
|
||||||
|
[
|
||||||
|
base,
|
||||||
|
Rect::new(base.left + 64, base.top, base.right + 64, base.bottom),
|
||||||
|
Rect::new(base.left + 128, base.top, base.right + 128, base.bottom),
|
||||||
|
Rect::new(base.left + 192, base.top, base.right + 192, base.bottom),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EngineConstants {
|
pub struct EngineConstants {
|
||||||
pub base_paths: Vec<String>,
|
pub base_paths: Vec<String>,
|
||||||
|
|
@ -315,6 +339,7 @@ pub struct EngineConstants {
|
||||||
pub string_table: HashMap<String, String>,
|
pub string_table: HashMap<String, String>,
|
||||||
pub missile_flags: Vec<u16>,
|
pub missile_flags: Vec<u16>,
|
||||||
pub locales: HashMap<String, Locale>,
|
pub locales: HashMap<String, Locale>,
|
||||||
|
pub gamepad: GamepadConsts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for EngineConstants {
|
impl Clone for EngineConstants {
|
||||||
|
|
@ -346,6 +371,7 @@ impl Clone for EngineConstants {
|
||||||
string_table: self.string_table.clone(),
|
string_table: self.string_table.clone(),
|
||||||
missile_flags: self.missile_flags.clone(),
|
missile_flags: self.missile_flags.clone(),
|
||||||
locales: self.locales.clone(),
|
locales: self.locales.clone(),
|
||||||
|
gamepad: self.gamepad.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1358,6 +1384,7 @@ impl EngineConstants {
|
||||||
"bkSunset" => (320, 240), // nxengine
|
"bkSunset" => (320, 240), // nxengine
|
||||||
"bkSunset480fix" => (480, 272), // nxengine
|
"bkSunset480fix" => (480, 272), // nxengine
|
||||||
"bkWater" => (32, 48),
|
"bkWater" => (32, 48),
|
||||||
|
"buttons" => (256, 256),
|
||||||
"Bullet" => (320, 176),
|
"Bullet" => (320, 176),
|
||||||
"Caret" => (320, 240),
|
"Caret" => (320, 240),
|
||||||
"casts" => (320, 240),
|
"casts" => (320, 240),
|
||||||
|
|
@ -1630,6 +1657,30 @@ impl EngineConstants {
|
||||||
string_table: HashMap::new(),
|
string_table: HashMap::new(),
|
||||||
missile_flags: vec![200, 201, 202, 218, 550, 766, 880, 920, 1551],
|
missile_flags: vec![200, 201, 202, 218, 550, 766, 880, 920, 1551],
|
||||||
locales: HashMap::new(),
|
locales: HashMap::new(),
|
||||||
|
gamepad: GamepadConsts {
|
||||||
|
button_rects: HashMap::from([
|
||||||
|
(Button::North, GamepadConsts::rects(Rect::new(0, 0, 32, 16))),
|
||||||
|
(Button::South, GamepadConsts::rects(Rect::new(0, 16, 32, 32))),
|
||||||
|
(Button::East, GamepadConsts::rects(Rect::new(0, 32, 32, 48))),
|
||||||
|
(Button::West, GamepadConsts::rects(Rect::new(0, 48, 32, 64))),
|
||||||
|
(Button::DPadDown, GamepadConsts::rects(Rect::new(0, 64, 32, 80))),
|
||||||
|
(Button::DPadUp, GamepadConsts::rects(Rect::new(0, 80, 32, 96))),
|
||||||
|
(Button::DPadRight, GamepadConsts::rects(Rect::new(0, 96, 32, 112))),
|
||||||
|
(Button::DPadLeft, GamepadConsts::rects(Rect::new(0, 112, 32, 128))),
|
||||||
|
(Button::LeftShoulder, GamepadConsts::rects(Rect::new(32, 32, 64, 48))),
|
||||||
|
(Button::RightShoulder, GamepadConsts::rects(Rect::new(32, 48, 64, 64))),
|
||||||
|
(Button::Start, GamepadConsts::rects(Rect::new(32, 96, 64, 112))),
|
||||||
|
(Button::Guide, GamepadConsts::rects(Rect::new(32, 112, 64, 128))),
|
||||||
|
]),
|
||||||
|
axis_rects: HashMap::from([
|
||||||
|
(Axis::LeftX, GamepadConsts::rects(Rect::new(32, 0, 64, 16))),
|
||||||
|
(Axis::LeftY, GamepadConsts::rects(Rect::new(32, 0, 64, 16))),
|
||||||
|
(Axis::RightX, GamepadConsts::rects(Rect::new(32, 16, 64, 32))),
|
||||||
|
(Axis::RightY, GamepadConsts::rects(Rect::new(32, 16, 64, 32))),
|
||||||
|
(Axis::TriggerLeft, GamepadConsts::rects(Rect::new(32, 64, 64, 80))),
|
||||||
|
(Axis::TriggerRight, GamepadConsts::rects(Rect::new(32, 80, 64, 96))),
|
||||||
|
]),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1709,6 +1760,7 @@ impl EngineConstants {
|
||||||
pub fn rebuild_path_list(&mut self, mod_path: Option<String>, season: Season, settings: &Settings) {
|
pub fn rebuild_path_list(&mut self, mod_path: Option<String>, season: Season, settings: &Settings) {
|
||||||
self.base_paths.clear();
|
self.base_paths.clear();
|
||||||
self.base_paths.push("/".to_owned());
|
self.base_paths.push("/".to_owned());
|
||||||
|
self.base_paths.push("/builtin/builtin_data/".to_owned());
|
||||||
|
|
||||||
if self.is_cs_plus {
|
if self.is_cs_plus {
|
||||||
self.base_paths.insert(0, "/base/".to_owned());
|
self.base_paths.insert(0, "/base/".to_owned());
|
||||||
|
|
|
||||||
|
|
@ -306,10 +306,17 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
|
|
||||||
if game_controller.is_game_controller(which) {
|
if game_controller.is_game_controller(which) {
|
||||||
let controller = game_controller.open(which).unwrap();
|
let controller = game_controller.open(which).unwrap();
|
||||||
log::info!("Connected gamepad: {} (ID: {})", controller.name(), controller.instance_id());
|
let id = controller.instance_id();
|
||||||
|
|
||||||
|
log::info!("Connected gamepad: {} (ID: {})", controller.name(), id);
|
||||||
|
|
||||||
let axis_sensitivity = state.settings.get_gamepad_axis_sensitivity(which);
|
let axis_sensitivity = state.settings.get_gamepad_axis_sensitivity(which);
|
||||||
ctx.gamepad_context.add_gamepad(controller, axis_sensitivity);
|
ctx.gamepad_context.add_gamepad(controller, axis_sensitivity);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let controller_type = sdl2_sys::SDL_GameControllerTypeForIndex(id as _);
|
||||||
|
ctx.gamepad_context.set_gamepad_type(id, controller_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::ControllerDeviceRemoved { which, .. } => {
|
Event::ControllerDeviceRemoved { which, .. } => {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
|
||||||
use sdl2::controller::GameController;
|
use sdl2::controller::GameController;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{framework::context::Context, settings::PlayerControllerInputType};
|
use crate::{common::Rect, engine_constants::EngineConstants, framework::context::Context};
|
||||||
|
|
||||||
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
|
|
@ -16,7 +16,13 @@ pub enum Axis {
|
||||||
TriggerRight,
|
TriggerRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
impl Axis {
|
||||||
|
pub fn get_rect(&self, offset: usize, constants: &EngineConstants) -> Rect<u16> {
|
||||||
|
constants.gamepad.axis_rects.get(self).unwrap()[offset]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
pub enum AxisDirection {
|
pub enum AxisDirection {
|
||||||
None,
|
None,
|
||||||
Either,
|
Either,
|
||||||
|
|
@ -58,8 +64,32 @@ pub enum Button {
|
||||||
DPadRight,
|
DPadRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Button {
|
||||||
|
pub fn get_rect(&self, offset: usize, constants: &EngineConstants) -> Rect<u16> {
|
||||||
|
constants.gamepad.button_rects.get(self).unwrap()[offset]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||||
|
pub enum PlayerControllerInputType {
|
||||||
|
ButtonInput(Button),
|
||||||
|
AxisInput(Axis, AxisDirection),
|
||||||
|
Either(Button, Axis, AxisDirection),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlayerControllerInputType {
|
||||||
|
pub fn get_rect(&self, offset: usize, constants: &EngineConstants) -> Rect<u16> {
|
||||||
|
match self {
|
||||||
|
PlayerControllerInputType::ButtonInput(button) => button.get_rect(offset, constants),
|
||||||
|
PlayerControllerInputType::AxisInput(axis, _) => axis.get_rect(offset, constants),
|
||||||
|
PlayerControllerInputType::Either(button, axis, _) => button.get_rect(offset, constants),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GamepadData {
|
pub struct GamepadData {
|
||||||
controller: GameController,
|
controller: GameController,
|
||||||
|
controller_type: Option<sdl2_sys::SDL_GameControllerType>,
|
||||||
|
|
||||||
left_x: f64,
|
left_x: f64,
|
||||||
left_y: f64,
|
left_y: f64,
|
||||||
|
|
@ -78,6 +108,7 @@ impl GamepadData {
|
||||||
pub(crate) fn new(game_controller: GameController, axis_sensitivity: f64) -> Self {
|
pub(crate) fn new(game_controller: GameController, axis_sensitivity: f64) -> Self {
|
||||||
GamepadData {
|
GamepadData {
|
||||||
controller: game_controller,
|
controller: game_controller,
|
||||||
|
controller_type: None,
|
||||||
|
|
||||||
left_x: 0.0,
|
left_x: 0.0,
|
||||||
left_y: 0.0,
|
left_y: 0.0,
|
||||||
|
|
@ -92,6 +123,26 @@ impl GamepadData {
|
||||||
axis_values: HashMap::with_capacity(8),
|
axis_values: HashMap::with_capacity(8),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_gamepad_type(&mut self, controller_type: sdl2_sys::SDL_GameControllerType) {
|
||||||
|
self.controller_type = Some(controller_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_gamepad_sprite_offset(&self) -> usize {
|
||||||
|
if let Some(controller_type) = self.controller_type {
|
||||||
|
return match controller_type {
|
||||||
|
sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_PS3
|
||||||
|
| sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_PS4
|
||||||
|
| sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_PS5 => 0,
|
||||||
|
sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_XBOX360
|
||||||
|
| sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_XBOXONE => 1,
|
||||||
|
sdl2_sys::SDL_GameControllerType::SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO => 3,
|
||||||
|
_ => 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GamepadContext {
|
pub struct GamepadContext {
|
||||||
|
|
@ -123,6 +174,20 @@ impl GamepadContext {
|
||||||
self.gamepads.retain(|data| data.controller.instance_id() != gamepad_id);
|
self.gamepads.retain(|data| data.controller.instance_id() != gamepad_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_gamepad_type(&mut self, gamepad_id: u32, controller_type: sdl2_sys::SDL_GameControllerType) {
|
||||||
|
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
|
||||||
|
gamepad.set_gamepad_type(controller_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_gamepad_sprite_offset(&self, gamepad_index: usize) -> usize {
|
||||||
|
if let Some(gamepad) = self.get_gamepad_by_index(gamepad_index) {
|
||||||
|
return gamepad.get_gamepad_sprite_offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn set_button(&mut self, gamepad_id: u32, button: Button, pressed: bool) {
|
pub(crate) fn set_button(&mut self, gamepad_id: u32, button: Button, pressed: bool) {
|
||||||
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
|
if let Some(gamepad) = self.get_gamepad_mut(gamepad_id) {
|
||||||
if pressed {
|
if pressed {
|
||||||
|
|
@ -139,18 +204,15 @@ impl GamepadContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_active(
|
pub(crate) fn is_active(&self, gamepad_index: u32, input_type: &PlayerControllerInputType) -> bool {
|
||||||
&self,
|
|
||||||
gamepad_index: u32,
|
|
||||||
input_type: &PlayerControllerInputType,
|
|
||||||
axis_direction: AxisDirection,
|
|
||||||
) -> bool {
|
|
||||||
match input_type {
|
match input_type {
|
||||||
PlayerControllerInputType::ButtonInput(button) => self.is_button_active(gamepad_index, *button),
|
PlayerControllerInputType::ButtonInput(button) => self.is_button_active(gamepad_index, *button),
|
||||||
PlayerControllerInputType::AxisInput(axis) => self.is_axis_active(gamepad_index, *axis, axis_direction),
|
PlayerControllerInputType::AxisInput(axis, axis_direction) => {
|
||||||
PlayerControllerInputType::Either(button, axis) => {
|
self.is_axis_active(gamepad_index, *axis, *axis_direction)
|
||||||
|
}
|
||||||
|
PlayerControllerInputType::Either(button, axis, axis_direction) => {
|
||||||
self.is_button_active(gamepad_index, *button)
|
self.is_button_active(gamepad_index, *button)
|
||||||
|| self.is_axis_active(gamepad_index, *axis, axis_direction)
|
|| self.is_axis_active(gamepad_index, *axis, *axis_direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,13 +274,16 @@ pub fn remove_gamepad(context: &mut Context, gamepad_id: u32) {
|
||||||
context.gamepad_context.remove_gamepad(gamepad_id);
|
context.gamepad_context.remove_gamepad(gamepad_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_active(
|
pub fn set_gamepad_type(context: &mut Context, gamepad_id: u32, controller_type: sdl2_sys::SDL_GameControllerType) {
|
||||||
ctx: &Context,
|
context.gamepad_context.set_gamepad_type(gamepad_id, controller_type);
|
||||||
gamepad_index: u32,
|
}
|
||||||
input_type: &PlayerControllerInputType,
|
|
||||||
axis_direction: AxisDirection,
|
pub fn get_gamepad_sprite_offset(context: &Context, gamepad_index: usize) -> usize {
|
||||||
) -> bool {
|
context.gamepad_context.get_gamepad_sprite_offset(gamepad_index)
|
||||||
ctx.gamepad_context.is_active(gamepad_index, input_type, axis_direction)
|
}
|
||||||
|
|
||||||
|
pub fn is_active(ctx: &Context, gamepad_index: u32, input_type: &PlayerControllerInputType) -> bool {
|
||||||
|
ctx.gamepad_context.is_active(gamepad_index, input_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_button_active(ctx: &Context, gamepad_index: u32, button: Button) -> bool {
|
pub fn is_button_active(ctx: &Context, gamepad_index: u32, button: Button) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
use crate::bitfield;
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::framework::gamepad::{self, AxisDirection, Button};
|
use crate::framework::gamepad::{self, Button, PlayerControllerInputType};
|
||||||
use crate::input::player_controller::PlayerController;
|
use crate::input::player_controller::PlayerController;
|
||||||
use crate::player::TargetPlayer;
|
use crate::player::TargetPlayer;
|
||||||
use crate::shared_game_state::SharedGameState;
|
use crate::shared_game_state::SharedGameState;
|
||||||
use crate::{bitfield, settings::PlayerControllerInputType};
|
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|
@ -49,35 +49,24 @@ impl PlayerController for GamepadController {
|
||||||
TargetPlayer::Player2 => &state.settings.player2_controller_button_map,
|
TargetPlayer::Player2 => &state.settings.player2_controller_button_map,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.state.set_up(gamepad::is_active(ctx, self.gamepad_id, &button_map.up, AxisDirection::Up));
|
self.state.set_up(gamepad::is_active(ctx, self.gamepad_id, &button_map.up));
|
||||||
self.state.set_down(gamepad::is_active(ctx, self.gamepad_id, &button_map.down, AxisDirection::Down));
|
self.state.set_down(gamepad::is_active(ctx, self.gamepad_id, &button_map.down));
|
||||||
self.state.set_left(gamepad::is_active(ctx, self.gamepad_id, &button_map.left, AxisDirection::Left));
|
self.state.set_left(gamepad::is_active(ctx, self.gamepad_id, &button_map.left));
|
||||||
self.state.set_right(gamepad::is_active(ctx, self.gamepad_id, &button_map.right, AxisDirection::Right));
|
self.state.set_right(gamepad::is_active(ctx, self.gamepad_id, &button_map.right));
|
||||||
self.state.set_map(gamepad::is_active(ctx, self.gamepad_id, &button_map.map, AxisDirection::None));
|
self.state.set_map(gamepad::is_active(ctx, self.gamepad_id, &button_map.map));
|
||||||
self.state.set_inventory(gamepad::is_active(ctx, self.gamepad_id, &button_map.inventory, AxisDirection::None));
|
self.state.set_inventory(gamepad::is_active(ctx, self.gamepad_id, &button_map.inventory));
|
||||||
self.state.set_jump(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump, AxisDirection::None));
|
self.state.set_jump(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump));
|
||||||
self.state.set_shoot(gamepad::is_active(ctx, self.gamepad_id, &button_map.shoot, AxisDirection::None));
|
self.state.set_shoot(gamepad::is_active(ctx, self.gamepad_id, &button_map.shoot));
|
||||||
self.state.set_next_weapon(gamepad::is_active(
|
self.state.set_next_weapon(gamepad::is_active(ctx, self.gamepad_id, &button_map.next_weapon));
|
||||||
ctx,
|
self.state.set_prev_weapon(gamepad::is_active(ctx, self.gamepad_id, &button_map.prev_weapon));
|
||||||
self.gamepad_id,
|
|
||||||
&button_map.next_weapon,
|
|
||||||
AxisDirection::None,
|
|
||||||
));
|
|
||||||
self.state.set_prev_weapon(gamepad::is_active(
|
|
||||||
ctx,
|
|
||||||
self.gamepad_id,
|
|
||||||
&button_map.prev_weapon,
|
|
||||||
AxisDirection::None,
|
|
||||||
));
|
|
||||||
self.state.set_escape(gamepad::is_active(
|
self.state.set_escape(gamepad::is_active(
|
||||||
ctx,
|
ctx,
|
||||||
self.gamepad_id,
|
self.gamepad_id,
|
||||||
&PlayerControllerInputType::ButtonInput(Button::Start),
|
&PlayerControllerInputType::ButtonInput(Button::Start),
|
||||||
AxisDirection::None,
|
|
||||||
));
|
));
|
||||||
self.state.set_enter(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump, AxisDirection::None));
|
self.state.set_enter(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump));
|
||||||
self.state.set_skip(gamepad::is_active(ctx, self.gamepad_id, &button_map.skip, AxisDirection::Either));
|
self.state.set_skip(gamepad::is_active(ctx, self.gamepad_id, &button_map.skip));
|
||||||
self.state.set_strafe(gamepad::is_active(ctx, self.gamepad_id, &button_map.strafe, AxisDirection::Either));
|
self.state.set_strafe(gamepad::is_active(ctx, self.gamepad_id, &button_map.strafe));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ use crate::scene::title_scene::TitleScene;
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
use crate::scripting::tsc::credit_script::CreditScriptVM;
|
use crate::scripting::tsc::credit_script::CreditScriptVM;
|
||||||
use crate::scripting::tsc::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM};
|
use crate::scripting::tsc::text_script::{ScriptMode, TextScriptExecutionState, TextScriptVM};
|
||||||
|
use crate::settings::ControllerType;
|
||||||
use crate::shared_game_state::{Language, PlayerCount, ReplayState, SharedGameState, TileSize};
|
use crate::shared_game_state::{Language, PlayerCount, ReplayState, SharedGameState, TileSize};
|
||||||
use crate::stage::{BackgroundType, Stage, StageTexturePaths};
|
use crate::stage::{BackgroundType, Stage, StageTexturePaths};
|
||||||
use crate::texture_set::SpriteBatch;
|
use crate::texture_set::SpriteBatch;
|
||||||
|
|
@ -2170,15 +2171,30 @@ impl Scene for GameScene {
|
||||||
self.text_boxes.draw(state, ctx, &self.frame)?;
|
self.text_boxes.draw(state, ctx, &self.frame)?;
|
||||||
|
|
||||||
if self.skip_counter > 1 || state.tutorial_counter > 0 {
|
if self.skip_counter > 1 || state.tutorial_counter > 0 {
|
||||||
let text = state.tt(
|
let key = {
|
||||||
"game.cutscene_skip",
|
if state.settings.touch_controls {
|
||||||
HashMap::from(if !state.settings.touch_controls {
|
">>".to_owned()
|
||||||
[("key".to_owned(), format!("{:?}", state.settings.player1_key_map.inventory))]
|
|
||||||
} else {
|
} else {
|
||||||
[("key".to_owned(), ">>".to_owned())]
|
match state.settings.player1_controller_type {
|
||||||
}),
|
ControllerType::Keyboard => format!("{:?}", state.settings.player1_key_map.skip),
|
||||||
);
|
ControllerType::Gamepad(_) => "=".to_owned(),
|
||||||
let width = state.font.text_width(text.chars(), &state.constants);
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let text = state.tt("game.cutscene_skip", HashMap::from([("key".to_owned(), key)]));
|
||||||
|
|
||||||
|
let gamepad_sprite_offset = match state.settings.player1_controller_type {
|
||||||
|
ControllerType::Keyboard => 1,
|
||||||
|
ControllerType::Gamepad(index) => ctx.gamepad_context.get_gamepad_sprite_offset(index as usize),
|
||||||
|
};
|
||||||
|
|
||||||
|
let rect_map = HashMap::from([(
|
||||||
|
'=',
|
||||||
|
state.settings.player1_controller_button_map.skip.get_rect(gamepad_sprite_offset, &state.constants),
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let width = state.font.text_width_with_rects(text.chars(), &rect_map, &state.constants);
|
||||||
let pos_x = state.canvas_size.0 - width - 20.0;
|
let pos_x = state.canvas_size.0 - width - 20.0;
|
||||||
let pos_y = 0.0;
|
let pos_y = 0.0;
|
||||||
let line_height = state.font.line_height(&state.constants);
|
let line_height = state.font.line_height(&state.constants);
|
||||||
|
|
@ -2199,12 +2215,14 @@ impl Scene for GameScene {
|
||||||
rect.right = rect.left + (w * state.scale).ceil() as isize;
|
rect.right = rect.left + (w * state.scale).ceil() as isize;
|
||||||
draw_rect(ctx, rect, Color::from_rgb(128, 128, 160))?;
|
draw_rect(ctx, rect, Color::from_rgb(128, 128, 160))?;
|
||||||
|
|
||||||
state.font.draw_text_with_shadow(
|
state.font.draw_text_with_shadow_and_rects(
|
||||||
text.chars(),
|
text.chars(),
|
||||||
pos_x + 10.0,
|
pos_x + 10.0,
|
||||||
pos_y + 5.0,
|
pos_y + 5.0,
|
||||||
&state.constants,
|
&state.constants,
|
||||||
&mut state.texture_set,
|
&mut state.texture_set,
|
||||||
|
&rect_map,
|
||||||
|
Some("buttons".into()),
|
||||||
ctx,
|
ctx,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::framework::context::Context;
|
use crate::framework::context::Context;
|
||||||
use crate::framework::error::GameResult;
|
use crate::framework::error::GameResult;
|
||||||
use crate::framework::filesystem::{user_create, user_open};
|
use crate::framework::filesystem::{user_create, user_open};
|
||||||
use crate::framework::gamepad::{Axis, Button};
|
use crate::framework::gamepad::{Axis, AxisDirection, Button, PlayerControllerInputType};
|
||||||
use crate::framework::keyboard::ScanCode;
|
use crate::framework::keyboard::ScanCode;
|
||||||
use crate::graphics::VSyncMode;
|
use crate::graphics::VSyncMode;
|
||||||
use crate::input::gamepad_player_controller::GamepadController;
|
use crate::input::gamepad_player_controller::GamepadController;
|
||||||
|
|
@ -79,7 +79,7 @@ fn default_true() -> bool {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn current_version() -> u32 {
|
fn current_version() -> u32 {
|
||||||
13
|
14
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
@ -215,6 +215,14 @@ impl Settings {
|
||||||
self.player2_controller_button_map = player_default_controller_button_map();
|
self.player2_controller_button_map = player_default_controller_button_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.version == 13 {
|
||||||
|
self.version = 14;
|
||||||
|
|
||||||
|
// reset controller mappings again since we have new enums
|
||||||
|
self.player1_controller_button_map = player_default_controller_button_map();
|
||||||
|
self.player2_controller_button_map = player_default_controller_button_map();
|
||||||
|
}
|
||||||
|
|
||||||
if self.version != initial_version {
|
if self.version != initial_version {
|
||||||
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
|
||||||
}
|
}
|
||||||
|
|
@ -355,13 +363,6 @@ pub enum ControllerType {
|
||||||
Gamepad(u32),
|
Gamepad(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
|
||||||
pub enum PlayerControllerInputType {
|
|
||||||
ButtonInput(Button),
|
|
||||||
AxisInput(Axis),
|
|
||||||
Either(Button, Axis),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct PlayerControllerButtonMap {
|
pub struct PlayerControllerButtonMap {
|
||||||
pub left: PlayerControllerInputType,
|
pub left: PlayerControllerInputType,
|
||||||
|
|
@ -381,16 +382,16 @@ pub struct PlayerControllerButtonMap {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
|
pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
|
||||||
PlayerControllerButtonMap {
|
PlayerControllerButtonMap {
|
||||||
left: PlayerControllerInputType::Either(Button::DPadLeft, Axis::LeftX),
|
left: PlayerControllerInputType::Either(Button::DPadLeft, Axis::LeftX, AxisDirection::Left),
|
||||||
up: PlayerControllerInputType::Either(Button::DPadUp, Axis::LeftY),
|
up: PlayerControllerInputType::Either(Button::DPadUp, Axis::LeftY, AxisDirection::Up),
|
||||||
right: PlayerControllerInputType::Either(Button::DPadRight, Axis::LeftX),
|
right: PlayerControllerInputType::Either(Button::DPadRight, Axis::LeftX, AxisDirection::Right),
|
||||||
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftY),
|
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftY, AxisDirection::Down),
|
||||||
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftShoulder),
|
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftShoulder),
|
||||||
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightShoulder),
|
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightShoulder),
|
||||||
jump: PlayerControllerInputType::ButtonInput(Button::South),
|
jump: PlayerControllerInputType::ButtonInput(Button::South),
|
||||||
shoot: PlayerControllerInputType::ButtonInput(Button::East),
|
shoot: PlayerControllerInputType::ButtonInput(Button::East),
|
||||||
skip: PlayerControllerInputType::AxisInput(Axis::TriggerLeft),
|
skip: PlayerControllerInputType::AxisInput(Axis::TriggerLeft, AxisDirection::Either),
|
||||||
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight),
|
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight, AxisDirection::Either),
|
||||||
inventory: PlayerControllerInputType::ButtonInput(Button::North),
|
inventory: PlayerControllerInputType::ButtonInput(Button::North),
|
||||||
map: PlayerControllerInputType::ButtonInput(Button::West),
|
map: PlayerControllerInputType::ButtonInput(Button::West),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue