doukutsu-rs/src/settings.rs

387 lines
12 KiB
Rust
Raw Normal View History

2021-01-27 18:20:47 +00:00
use crate::framework::context::Context;
use crate::framework::error::GameResult;
2021-02-12 10:05:28 +00:00
use crate::framework::filesystem::{user_create, user_open};
use crate::framework::gamepad::{Axis, Button};
2021-01-27 18:20:47 +00:00
use crate::framework::keyboard::ScanCode;
2022-04-15 00:51:48 +00:00
use crate::graphics::VSyncMode;
2022-07-20 13:07:24 +00:00
use crate::input::gamepad_player_controller::GamepadController;
2020-11-28 19:25:51 +00:00
use crate::input::keyboard_player_controller::KeyboardController;
use crate::input::player_controller::PlayerController;
2020-12-20 20:57:17 +00:00
use crate::input::touch_player_controller::TouchPlayerController;
2021-01-27 18:20:47 +00:00
use crate::player::TargetPlayer;
2022-07-13 14:03:17 +00:00
use crate::shared_game_state::{Language, ScreenShakeIntensity, TimingMode, WindowMode};
2021-08-16 07:47:11 +00:00
use crate::sound::InterpolationMode;
2020-11-28 19:25:51 +00:00
2021-08-16 07:47:11 +00:00
#[derive(serde::Serialize, serde::Deserialize)]
2020-11-28 19:25:51 +00:00
pub struct Settings {
2021-08-16 07:47:11 +00:00
#[serde(default = "current_version")]
pub version: u32,
2021-10-10 00:31:07 +00:00
#[serde(default = "default_true")]
2020-11-28 19:25:51 +00:00
pub seasonal_textures: bool,
pub original_textures: bool,
pub shader_effects: bool,
2021-10-10 00:31:07 +00:00
#[serde(default = "default_true")]
pub light_cone: bool,
#[serde(default = "default_true")]
pub subpixel_coords: bool,
2021-10-10 00:31:07 +00:00
#[serde(default = "default_true")]
2020-11-28 19:25:51 +00:00
pub motion_interpolation: bool,
pub touch_controls: bool,
2021-02-12 10:05:28 +00:00
pub soundtrack: String,
2022-02-03 03:09:29 +00:00
#[serde(default = "default_vol")]
pub bgm_volume: f32,
#[serde(default = "default_vol")]
pub sfx_volume: f32,
2021-10-14 07:43:17 +00:00
#[serde(default = "default_timing")]
pub timing_mode: TimingMode,
2021-08-16 07:47:11 +00:00
#[serde(default = "default_interpolation")]
pub organya_interpolation: InterpolationMode,
2022-07-20 13:07:24 +00:00
#[serde(default = "default_controller_type")]
pub player1_controller_type: ControllerType,
#[serde(default = "default_controller_type")]
pub player2_controller_type: ControllerType,
2021-02-12 10:05:28 +00:00
#[serde(default = "p1_default_keymap")]
2020-11-28 19:25:51 +00:00
pub player1_key_map: PlayerKeyMap,
2021-02-12 10:05:28 +00:00
#[serde(default = "p2_default_keymap")]
2020-11-28 19:25:51 +00:00
pub player2_key_map: PlayerKeyMap,
2022-07-20 13:07:24 +00:00
#[serde(default = "player_default_controller_button_map")]
pub player1_controller_button_map: PlayerControllerButtonMap,
#[serde(default = "player_default_controller_button_map")]
pub player2_controller_button_map: PlayerControllerButtonMap,
#[serde(default = "default_controller_axis_sensitivity")]
pub player1_controller_axis_sensitivity: f64,
#[serde(default = "default_controller_axis_sensitivity")]
pub player2_controller_axis_sensitivity: f64,
2021-02-12 10:05:28 +00:00
#[serde(skip, default = "default_speed")]
2020-11-28 19:25:51 +00:00
pub speed: f64,
#[serde(skip)]
pub god_mode: bool,
#[serde(skip)]
pub infinite_booster: bool,
#[serde(skip)]
pub debug_outlines: bool,
2022-01-26 01:37:45 +00:00
pub fps_counter: bool,
2022-03-15 01:54:03 +00:00
pub locale: Language,
2022-07-13 14:03:17 +00:00
#[serde(default = "default_window_mode")]
pub window_mode: WindowMode,
2022-04-15 00:51:48 +00:00
#[serde(default = "default_vsync")]
pub vsync_mode: VSyncMode,
#[serde(default = "default_screen_shake_intensity")]
pub screen_shake_intensity: ScreenShakeIntensity,
2022-04-19 22:50:04 +00:00
pub debug_mode: bool,
2022-04-27 03:23:14 +00:00
#[serde(skip)]
2022-04-24 15:01:31 +00:00
pub noclip: bool,
2020-11-28 19:25:51 +00:00
}
2022-02-03 03:09:29 +00:00
fn default_true() -> bool {
true
}
2021-10-10 00:31:07 +00:00
2021-08-16 07:47:11 +00:00
#[inline(always)]
2022-02-03 03:09:29 +00:00
fn current_version() -> u32 {
2022-07-20 13:07:24 +00:00
12
2022-02-03 03:09:29 +00:00
}
2021-10-14 07:43:17 +00:00
#[inline(always)]
2022-02-03 03:09:29 +00:00
fn default_timing() -> TimingMode {
TimingMode::_50Hz
}
2021-08-16 07:47:11 +00:00
2022-07-13 14:03:17 +00:00
#[inline(always)]
fn default_window_mode() -> WindowMode {
WindowMode::Windowed
}
2021-08-16 07:47:11 +00:00
#[inline(always)]
2022-02-03 03:09:29 +00:00
fn default_interpolation() -> InterpolationMode {
InterpolationMode::Linear
}
2021-08-16 07:47:11 +00:00
#[inline(always)]
2021-02-12 10:05:28 +00:00
fn default_speed() -> f64 {
1.0
}
2022-02-03 03:09:29 +00:00
#[inline(always)]
fn default_vol() -> f32 {
1.0
}
2022-03-15 01:54:03 +00:00
#[inline(always)]
fn default_locale() -> Language {
Language::English
}
2022-04-15 00:51:48 +00:00
#[inline(always)]
fn default_vsync() -> VSyncMode {
VSyncMode::VSync
}
#[inline(always)]
fn default_screen_shake_intensity() -> ScreenShakeIntensity {
ScreenShakeIntensity::Full
}
2022-07-20 13:07:24 +00:00
#[inline(always)]
fn default_controller_type() -> ControllerType {
ControllerType::Keyboard
}
2020-11-28 19:25:51 +00:00
impl Settings {
2021-02-12 10:05:28 +00:00
pub fn load(ctx: &Context) -> GameResult<Settings> {
2021-10-14 04:54:11 +00:00
if let Ok(file) = user_open(ctx, "/settings.json") {
match serde_json::from_reader::<_, Settings>(file) {
Ok(settings) => return Ok(settings.upgrade()),
2021-02-12 10:05:28 +00:00
Err(err) => log::warn!("Failed to deserialize settings: {}", err),
}
}
2020-11-28 19:25:51 +00:00
Ok(Settings::default())
}
2021-10-14 04:54:11 +00:00
fn upgrade(mut self) -> Self {
let initial_version = self.version;
if self.version == 2 {
self.version = 3;
self.light_cone = true;
}
2021-10-14 07:43:17 +00:00
if self.version == 3 {
self.version = 4;
self.timing_mode = default_timing();
}
2022-02-03 03:09:29 +00:00
if self.version == 4 {
self.version = 5;
self.bgm_volume = default_vol();
self.sfx_volume = default_vol();
}
2022-02-26 01:51:10 +00:00
if self.version == 5 {
self.version = 6;
self.player1_key_map.strafe = ScanCode::LShift;
self.player2_key_map.strafe = ScanCode::RShift;
}
2022-03-15 01:54:03 +00:00
if self.version == 6 {
self.version = 7;
self.locale = default_locale();
}
2022-04-15 00:51:48 +00:00
if self.version == 7 {
self.version = 8;
self.vsync_mode = default_vsync();
}
2022-04-19 22:50:04 +00:00
if self.version == 8 {
self.version = 9;
self.debug_mode = false;
}
if self.version == 9 {
self.version = 10;
self.screen_shake_intensity = default_screen_shake_intensity();
}
2022-07-13 14:03:17 +00:00
if self.version == 10 {
self.version = 11;
self.window_mode = default_window_mode();
}
2022-07-20 13:07:24 +00:00
if self.version == 11 {
self.version = 12;
self.player1_controller_type = default_controller_type();
self.player2_controller_type = default_controller_type();
self.player1_controller_button_map = player_default_controller_button_map();
self.player2_controller_button_map = player_default_controller_button_map();
self.player1_controller_axis_sensitivity = default_controller_axis_sensitivity();
self.player2_controller_axis_sensitivity = default_controller_axis_sensitivity();
}
2021-10-14 04:54:11 +00:00
if self.version != initial_version {
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
}
self
}
2021-02-12 10:05:28 +00:00
pub fn save(&self, ctx: &Context) -> GameResult {
2021-10-14 04:54:11 +00:00
let file = user_create(ctx, "/settings.json")?;
2022-01-06 18:49:20 +00:00
serde_json::to_writer_pretty(file, self)?;
2021-10-14 04:54:11 +00:00
2021-02-12 10:05:28 +00:00
Ok(())
}
2020-11-28 19:25:51 +00:00
pub fn create_player1_controller(&self) -> Box<dyn PlayerController> {
2020-12-20 20:57:17 +00:00
if self.touch_controls {
return Box::new(TouchPlayerController::new());
}
2022-07-20 13:07:24 +00:00
match self.player1_controller_type {
ControllerType::Keyboard => Box::new(KeyboardController::new(TargetPlayer::Player1)),
ControllerType::Gamepad(id) => Box::new(GamepadController::new(id, TargetPlayer::Player1)),
}
2020-11-28 19:25:51 +00:00
}
pub fn create_player2_controller(&self) -> Box<dyn PlayerController> {
2022-07-20 13:07:24 +00:00
match self.player2_controller_type {
ControllerType::Keyboard => Box::new(KeyboardController::new(TargetPlayer::Player2)),
ControllerType::Gamepad(id) => Box::new(GamepadController::new(id, TargetPlayer::Player2)),
}
}
pub fn get_gamepad_axis_sensitivity(&self, id: u32) -> f64 {
2022-07-20 13:07:24 +00:00
if self.player1_controller_type == ControllerType::Gamepad(id) {
self.player1_controller_axis_sensitivity
} else if self.player2_controller_type == ControllerType::Gamepad(id) {
self.player2_controller_axis_sensitivity
} else {
default_controller_axis_sensitivity()
}
2020-11-28 19:25:51 +00:00
}
}
impl Default for Settings {
fn default() -> Self {
Settings {
2021-10-14 04:54:11 +00:00
version: current_version(),
2020-11-28 19:25:51 +00:00
seasonal_textures: true,
original_textures: false,
2022-02-25 05:01:58 +00:00
shader_effects: false,
2021-10-10 00:31:07 +00:00
light_cone: true,
subpixel_coords: true,
2020-11-28 19:25:51 +00:00
motion_interpolation: true,
touch_controls: cfg!(target_os = "android"),
2022-02-25 05:01:58 +00:00
soundtrack: "Organya".to_string(),
2022-02-03 03:09:29 +00:00
bgm_volume: 1.0,
sfx_volume: 1.0,
2021-10-14 07:43:17 +00:00
timing_mode: default_timing(),
2021-08-16 07:47:11 +00:00
organya_interpolation: InterpolationMode::Linear,
2022-07-20 13:07:24 +00:00
player1_controller_type: default_controller_type(),
player2_controller_type: default_controller_type(),
2020-11-28 19:25:51 +00:00
player1_key_map: p1_default_keymap(),
player2_key_map: p2_default_keymap(),
2022-07-20 13:07:24 +00:00
player1_controller_button_map: player_default_controller_button_map(),
player2_controller_button_map: player_default_controller_button_map(),
player1_controller_axis_sensitivity: default_controller_axis_sensitivity(),
player2_controller_axis_sensitivity: default_controller_axis_sensitivity(),
2020-11-28 19:25:51 +00:00
speed: 1.0,
god_mode: false,
infinite_booster: false,
debug_outlines: false,
2022-02-25 05:01:58 +00:00
fps_counter: false,
2022-03-15 01:54:03 +00:00
locale: Language::English,
2022-07-13 14:03:17 +00:00
window_mode: WindowMode::Windowed,
2022-04-15 00:51:48 +00:00
vsync_mode: VSyncMode::VSync,
screen_shake_intensity: ScreenShakeIntensity::Full,
2022-04-19 22:50:04 +00:00
debug_mode: false,
2022-04-24 15:01:31 +00:00
noclip: false,
2020-11-28 19:25:51 +00:00
}
}
}
2021-08-16 07:47:11 +00:00
#[derive(serde::Serialize, serde::Deserialize)]
2020-11-28 19:25:51 +00:00
pub struct PlayerKeyMap {
2021-01-27 18:20:47 +00:00
pub left: ScanCode,
pub up: ScanCode,
pub right: ScanCode,
pub down: ScanCode,
pub prev_weapon: ScanCode,
pub next_weapon: ScanCode,
pub jump: ScanCode,
pub shoot: ScanCode,
pub skip: ScanCode,
pub inventory: ScanCode,
pub map: ScanCode,
2022-02-26 01:51:10 +00:00
pub strafe: ScanCode,
2020-11-28 19:25:51 +00:00
}
2021-08-16 07:47:11 +00:00
#[inline(always)]
2020-11-28 19:25:51 +00:00
fn p1_default_keymap() -> PlayerKeyMap {
PlayerKeyMap {
2021-01-27 18:20:47 +00:00
left: ScanCode::Left,
up: ScanCode::Up,
right: ScanCode::Right,
down: ScanCode::Down,
prev_weapon: ScanCode::A,
next_weapon: ScanCode::S,
jump: ScanCode::Z,
shoot: ScanCode::X,
2021-02-12 10:05:28 +00:00
skip: ScanCode::E,
2021-01-27 18:20:47 +00:00
inventory: ScanCode::Q,
map: ScanCode::W,
2022-02-26 01:51:10 +00:00
strafe: ScanCode::LShift,
2020-11-28 19:25:51 +00:00
}
}
2021-08-16 07:47:11 +00:00
#[inline(always)]
2020-11-28 19:25:51 +00:00
fn p2_default_keymap() -> PlayerKeyMap {
PlayerKeyMap {
2021-01-27 18:20:47 +00:00
left: ScanCode::Comma,
up: ScanCode::L,
right: ScanCode::Slash,
down: ScanCode::Period,
prev_weapon: ScanCode::G,
next_weapon: ScanCode::H,
jump: ScanCode::B,
shoot: ScanCode::N,
skip: ScanCode::U,
inventory: ScanCode::T,
map: ScanCode::Y,
2022-02-26 01:51:10 +00:00
strafe: ScanCode::RShift,
2020-11-28 19:25:51 +00:00
}
}
2022-07-20 13:07:24 +00:00
#[derive(serde::Serialize, serde::Deserialize, Eq, PartialEq)]
pub enum ControllerType {
Keyboard,
Gamepad(u32),
2022-07-20 13:07:24 +00:00
}
#[derive(serde::Serialize, serde::Deserialize)]
pub enum PlayerControllerInputType {
ButtonInput(Button),
AxisInput(Axis),
Either(Button, Axis),
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct PlayerControllerButtonMap {
pub left: PlayerControllerInputType,
pub up: PlayerControllerInputType,
pub right: PlayerControllerInputType,
pub down: PlayerControllerInputType,
pub prev_weapon: PlayerControllerInputType,
pub next_weapon: PlayerControllerInputType,
pub jump: PlayerControllerInputType,
pub shoot: PlayerControllerInputType,
pub skip: PlayerControllerInputType,
pub inventory: PlayerControllerInputType,
pub map: PlayerControllerInputType,
pub strafe: PlayerControllerInputType,
}
#[inline(always)]
pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
PlayerControllerButtonMap {
left: PlayerControllerInputType::Either(Button::DPadLeft, Axis::LeftX),
up: PlayerControllerInputType::Either(Button::DPadUp, Axis::LeftY),
right: PlayerControllerInputType::Either(Button::DPadRight, Axis::LeftX),
down: PlayerControllerInputType::Either(Button::DPadDown, Axis::LeftY),
prev_weapon: PlayerControllerInputType::ButtonInput(Button::LeftShoulder),
next_weapon: PlayerControllerInputType::ButtonInput(Button::RightShoulder),
jump: PlayerControllerInputType::ButtonInput(Button::South),
shoot: PlayerControllerInputType::ButtonInput(Button::East),
skip: PlayerControllerInputType::AxisInput(Axis::TriggerLeft),
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight),
2022-07-20 13:07:24 +00:00
inventory: PlayerControllerInputType::ButtonInput(Button::North),
map: PlayerControllerInputType::ButtonInput(Button::West),
}
}
#[inline(always)]
pub fn default_controller_axis_sensitivity() -> f64 {
0.3
}