diff --git a/src/xenia/kernel/xam/xam_input.cc b/src/xenia/kernel/xam/xam_input.cc index 6179f7e5f..4a6d6cadb 100644 --- a/src/xenia/kernel/xam/xam_input.cc +++ b/src/xenia/kernel/xam/xam_input.cc @@ -16,6 +16,8 @@ #include "xenia/kernel/xam/xam_private.h" #include "xenia/xbox.h" +DECLARE_bool(allow_mic_initialization); + namespace xe { namespace kernel { namespace xam { @@ -238,7 +240,11 @@ X_HRESULT_result_t XamUserGetDeviceContext_entry(dword_t user_index, *out_ptr = 0; if (kernel_state()->xam_state()->IsUserSignedIn(user_index) || (user_index & XUserIndexAny) == XUserIndexAny) { - *out_ptr = (uint32_t)user_index; + if (device_type == 4 && cvars::allow_mic_initialization) { // Microphone + *out_ptr = 6 << 28; + } else { + *out_ptr = (uint32_t)user_index; + } return X_E_SUCCESS; } else { return X_E_DEVICE_NOT_CONNECTED; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc index 7222c5713..6347b6ccf 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_misc.cc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2022 Ben Vanik. All rights reserved. * + * Copyright 2026 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -12,10 +12,56 @@ #include "xenia/kernel/xthread.h" #include "xenia/xbox.h" +DEFINE_bool(allow_mic_initialization, false, + "Enable Mic Initialization\n" + " Only set true when testing mic related functions", + "Kernel"); + namespace xe { namespace kernel { namespace xboxkrnl { +enum class XMicRequestType : uint16_t { + MicGain = 0x0001, + MicIoPending = 0x0007, + MicGetCapabilities = 0x0009, + MicUnk = 0x000B, +}; + +enum class XMicState : uint32_t { + MicNotConnected = 0x00000000, + MicInitilizied = 0x00000005, +}; + +struct X_MIC_INFO { + xe::be request_type; + xe::be user_index; + xe::be state; // 8 + + xe::be unk1; // 16 + xe::be unk2; // 24 +}; + +struct X_MIC_CAPABILITIES { + xe::be features; + xe::be format_tag; + xe::be channels; + xe::be sample_rates; + xe::be bits_per_sample; + xe::be frame_length; // 0xE + xe::be mic_color; // 0x10 + xe::be vendor_id; + xe::be product_id; + xe::be revision; + xe::be device_id; +}; +static_assert_size(X_MIC_CAPABILITIES, 0x1C); + +struct X_MIC_DEVICE { + X_MIC_INFO info; + X_MIC_CAPABILITIES capabilities; +}; + void KeEnableFpuExceptions_entry( const ppc_context_t& ctx) { // dword_t enabled) { // TODO(benvanik): can we do anything about exceptions? @@ -59,6 +105,47 @@ static qword_result_t KeQueryInterruptTime_entry(const ppc_context_t& ctx) { return xe::load_and_swap(&bundle->interrupt_time); } DECLARE_XBOXKRNL_EXPORT1(KeQueryInterruptTime, kNone, kImplemented); + +dword_result_t MicDeviceRequest_entry(pointer_t device_ptr) { + if (!device_ptr) { + return X_STATUS_INVALID_PARAMETER; + } + XELOGE("MicDeviceRequest State: {:08X} Action: {:04X} USER: {:08X}", + static_cast(device_ptr->info.state.get()), + static_cast(device_ptr->info.request_type.get()), + device_ptr->info.user_index.get()); + if (device_ptr->info.user_index > XUserMaxUserCount) { + return X_STATUS_INVALID_PARAMETER; + } + + if (device_ptr->info.request_type > XMicRequestType::MicUnk) { + return X_STATUS_INVALID_DEVICE_REQUEST; + } + + device_ptr->info.state = cvars::allow_mic_initialization + ? XMicState::MicInitilizied + : XMicState::MicNotConnected; + + switch (device_ptr->info.request_type) { + case XMicRequestType::MicGain: + // GAIN + break; + case XMicRequestType::MicIoPending: + return X_STATUS_PENDING; + case XMicRequestType::MicGetCapabilities: + device_ptr->capabilities.features = 0x100; + device_ptr->capabilities.format_tag = 1; + device_ptr->capabilities.mic_color = 0; + break; + default: + // 0 Seems like initialization! + break; + } + + return X_ERROR_SUCCESS; +} +DECLARE_XBOXKRNL_EXPORT1(MicDeviceRequest, kNone, kStub); + } // namespace xboxkrnl } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc index 31289098c..8cb373da2 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_usbcam.cc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2022 Ben Vanik. All rights reserved. * + * Copyright 2026 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -29,11 +29,14 @@ dword_result_t XUsbcamCreate_entry(dword_t buffer, } DECLARE_XBOXKRNL_EXPORT1(XUsbcamCreate, kNone, kStub); +enum class XUsbCamState : uint32_t { + CamNotConnected = 0x00000000, + CamInitilizied = 0x00000001, + CamConnected = 0x00000002, +}; + dword_result_t XUsbcamGetState_entry() { - // 0 = not connected. - // 1 = initialized - // 2 = connected - return 0; + return static_cast(XUsbCamState::CamNotConnected); } DECLARE_XBOXKRNL_EXPORT1(XUsbcamGetState, kNone, kStub);