Skip to content

Commit

Permalink
Volume: added logic for changing sound volume (Windows Cliend and Ser…
Browse files Browse the repository at this point in the history
…ver)
  • Loading branch information
DvaMishkiLapa committed Nov 30, 2024
1 parent 2813efe commit 0dcb987
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 13 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ This allows to support a large number of Windows games without any fixes.
| Battery || PS Vita's battery status is sent to the emulated DualShock 4 |
| Any configuration || You can choose from [ready-made configurations](#33-configurations) |
| DS4Windows support || Virtual Controller Support[*] requires activation |
| Sound || Probably will never be realized |
| Changing the sound volume || Volume Up = Select + R1, Volume Down = Select + L1 |
| Sound sending || Probably will never be realized |

[*] - Virtual Controller Support can be found in the [schmaldeo DS4Windows fork](https://github.com/schmaldeo/DS4Windows).
This option can be found in `Settings -> Device Options -> Virtual Controller Support`.
Expand All @@ -166,7 +167,8 @@ The behavior is close to how the DualShock 4 (`vendor: 0x054C`, `product: 0x9CC`
| DualShock 4 digitizer button || Works as a quick tap on the digitizer. Supports front and rear digitizer. Linux itself determines the behaviour |
| Battery || - |
| Any configuration || You can choose from [ready-made configurations](#33-configurations) |
| Sound || Probably will never be realized |
| Changing the sound volume || - |
| Sound sending || Probably will never be realized |

You can also use a convenient input signal remapper, such as [antimicrox](https://github.com/AntiMicroX/antimicrox/)
or [input-remapper](https://github.com/sezanzeb/input-remapper).
Expand Down
79 changes: 72 additions & 7 deletions client/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/packages/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ flatbuffers_structs = { version = "0.1.0", path = "../flatbuffers_structs" }
protocol = { version = "0.1.0", path = "../protocol" }
vita_reports = { version = "0.1.0", path = "../vita_reports" }
vita_virtual_device = { version = "0.1.0", path = "../vita_virtual_device" }
serde = { version = "1.0.214", features = ["derive"] }
serde = { version = "1.0.215", features = ["derive"] }
config = "0.14.1"
toml = "0.8.19"
home = "0.5.9"
Expand Down
2 changes: 1 addition & 1 deletion client/packages/protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ flatbuffers_structs = { path = "../flatbuffers_structs" }
thiserror = "2.0.3"
vita_reports = { path = "../vita_reports" }
tokio-util = { version = "0.7.12", optional = true, features = ["codec"] }
bytes = { version = "1.8.0", optional = true }
bytes = { version = "1.9.0", optional = true }

[features]
codec = ["dep:tokio-util", "dep:bytes"]
4 changes: 4 additions & 0 deletions client/packages/vita_reports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub struct ButtonsData {
pub circle: bool,
pub cross: bool,
pub square: bool,
pub vol_up: bool,
pub vol_down: bool,
// timestamp: u64;
}

Expand All @@ -30,6 +32,8 @@ impl From<flatbuffers_structs::net_protocol::ButtonsData> for ButtonsData {
circle: buttons.circle(),
cross: buttons.cross(),
square: buttons.square(),
vol_up: buttons.vol_up(),
vol_down: buttons.vol_down(),
// timestamp: buttons.timestamp(),
}
}
Expand Down
9 changes: 8 additions & 1 deletion client/packages/vita_virtual_device/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ edition = "2021"
cfg-if = "1.0.0"
derive_builder = "0.20.2"
rstar = { version = "0.12.2", features = ["serde"] }
serde = { version = "1.0.214", features = ["serde_derive"] }
serde = { version = "1.0.215", features = ["serde_derive"] }
thiserror = "2.0.3"
vita_reports = { version = "0.1.0", path = "../vita_reports" }

Expand All @@ -18,3 +18,10 @@ input-linux = "0.7.1"

[target.'cfg(windows)'.dependencies]
vigem-client = { git = "https://github.com/santarl/vigem_client_rust/" }
windows = { version = "0.58", features = [
"Win32_Foundation",
"Win32_Media_Audio",
"Win32_Media_Audio_Endpoints",
"Win32_System_Com",
"Win32_UI_Input_KeyboardAndMouse",
] }
63 changes: 63 additions & 0 deletions client/packages/vita_virtual_device/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,69 @@ use vigem_client::{
DS4TouchPoint, DS4TouchReport, DpadDirection as VigemDpadDirection, DualShock4Wired, TargetId,
};

use windows::Win32::{
Media::Audio::Endpoints::IAudioEndpointVolume,
Media::Audio::{eMultimedia, eRender, IMMDevice, IMMDeviceEnumerator, MMDeviceEnumerator},
System::Com::{CoCreateInstance, CoInitializeEx, CLSCTX_ALL, COINIT_MULTITHREADED},
UI::Input::KeyboardAndMouse::{
SendInput, INPUT, INPUT_0, INPUT_KEYBOARD, KEYBDINPUT, KEYBD_EVENT_FLAGS, KEYEVENTF_KEYUP,
VIRTUAL_KEY, VK_VOLUME_DOWN, VK_VOLUME_UP,
},
};

use crate::virtual_button::{Button, DpadDirection};
use crate::virtual_config::{Config, ConfigBuilder, TouchConfig, TriggerConfig};
use crate::virtual_touch::{Point, TouchAction};
use crate::virtual_utils::{compute_dpad_direction, get_pressed_buttons};
use crate::{f32_to_i16, VitaVirtualDevice, FRONT_TOUCHPAD_RECT, REAR_TOUCHPAD_RECT};

unsafe fn simulate_key_press(vk: VIRTUAL_KEY) -> windows::core::Result<()> {
let inputs = &mut [
INPUT {
r#type: INPUT_KEYBOARD,
Anonymous: INPUT_0 {
ki: KEYBDINPUT {
wVk: vk,
wScan: 0,
dwFlags: KEYBD_EVENT_FLAGS(0),
time: 0,
dwExtraInfo: 0,
},
},
},
INPUT {
r#type: INPUT_KEYBOARD,
Anonymous: INPUT_0 {
ki: KEYBDINPUT {
wVk: vk,
wScan: 0,
dwFlags: KEYEVENTF_KEYUP,
time: 0,
dwExtraInfo: 0,
},
},
},
];

let result = SendInput(inputs, std::mem::size_of::<INPUT>() as i32);
if result == 0 {
Err(windows::core::Error::from_win32())
} else {
Ok(())
}
}

fn change_volume_by_key(delta: f32) -> windows::core::Result<()> {
unsafe {
if delta > 0.0 {
simulate_key_press(VK_VOLUME_UP)?;
} else if delta < 0.0 {
simulate_key_press(VK_VOLUME_DOWN)?;
}
Ok(())
}
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Failed to connect to the client")]
Expand Down Expand Up @@ -197,6 +254,12 @@ impl VitaVirtualDevice<&ConfigBuilder> for VitaDevice {

// Get the pressed buttons
let pressed_buttons = get_pressed_buttons(&report.buttons, self.config.trigger_config);
if report.buttons.vol_up {
change_volume_by_key(0.02).expect("Failed to increase volume");
}
if report.buttons.vol_down {
change_volume_by_key(-0.02).expect("Failed to increase volume");
}

// Create DS4Buttons object
let mut buttons = DS4Buttons::new().dpad(ds4_dpad);
Expand Down
2 changes: 2 additions & 0 deletions common/netprotocol.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct ButtonsData
circle: bool;
cross: bool;
square: bool;
vol_up: bool;
vol_down: bool;
}

struct Vector3
Expand Down
13 changes: 12 additions & 1 deletion server/src/ctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ NetProtocol::ButtonsData convert_pad_data(const SceCtrlData &data) {
(data.buttons & SCE_CTRL_DOWN) > 0, (data.buttons & SCE_CTRL_LEFT) > 0,
(data.buttons & SCE_CTRL_LTRIGGER) > 0, (data.buttons & SCE_CTRL_RTRIGGER) > 0,
(data.buttons & SCE_CTRL_TRIANGLE) > 0, (data.buttons & SCE_CTRL_CIRCLE) > 0,
(data.buttons & SCE_CTRL_CROSS) > 0, (data.buttons & SCE_CTRL_SQUARE) > 0);
(data.buttons & SCE_CTRL_CROSS) > 0, (data.buttons & SCE_CTRL_SQUARE) > 0,
(data.buttons & SCE_CTRL_VOLUP) > 0, (data.buttons & SCE_CTRL_VOLDOWN) > 0
);
}

flatbuffers::Offset<NetProtocol::TouchData>
Expand All @@ -38,6 +40,15 @@ void get_ctrl_as_netprotocol(flatbuffers::FlatBufferBuilder &builder, SharedData
while (pad.timeStamp <= last_ts) {
sceCtrlPeekBufferPositive(0, &pad, 1);
}
if (pad.buttons & SCE_CTRL_SELECT && pad.buttons & SCE_CTRL_LTRIGGER){
sceKernelDelayThread(20 * 1000);
pad.buttons |= SCE_CTRL_VOLDOWN;
}
if (pad.buttons & SCE_CTRL_SELECT && pad.buttons & SCE_CTRL_RTRIGGER){
sceKernelDelayThread(20 * 1000);
pad.buttons |= SCE_CTRL_VOLUP;
}

auto buttons = convert_pad_data(pad);

sceTouchPeek(SCE_TOUCH_PORT_FRONT, &touch_data_front, 1);
Expand Down
1 change: 1 addition & 0 deletions server/src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ int net_thread(__attribute__((unused)) unsigned int arglen, void *argp) {
}

timeout = client->remaining_polling_time();
sceKernelDelayThread(10 * 1000);
}

sceNetCtlInetUnregisterCallback(cbid);
Expand Down

0 comments on commit 0dcb987

Please sign in to comment.