[XBOXKNRL/MISC] - Stub MicDeviceRequest

- Stub MicDeviceRequest
- Games:
  - Rock Band 2 now exits game instead of being stuck on boot when mic set to false
  - Guitar Hero World Tour now properly responds when you tell it mic is connected
This commit is contained in:
The-Little-Wolf
2026-02-10 16:37:54 -08:00
committed by Radosław Gliński
parent 12f5084b93
commit 367d22d269
3 changed files with 103 additions and 7 deletions

View File

@@ -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;

View File

@@ -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<XMicRequestType> request_type;
xe::be<uint16_t> user_index;
xe::be<XMicState> state; // 8
xe::be<uint64_t> unk1; // 16
xe::be<uint64_t> unk2; // 24
};
struct X_MIC_CAPABILITIES {
xe::be<uint32_t> features;
xe::be<uint16_t> format_tag;
xe::be<uint16_t> channels;
xe::be<uint32_t> sample_rates;
xe::be<uint16_t> bits_per_sample;
xe::be<uint16_t> frame_length; // 0xE
xe::be<uint8_t> mic_color; // 0x10
xe::be<uint16_t> vendor_id;
xe::be<uint16_t> product_id;
xe::be<uint16_t> revision;
xe::be<uint32_t> 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<uint64_t>(&bundle->interrupt_time);
}
DECLARE_XBOXKRNL_EXPORT1(KeQueryInterruptTime, kNone, kImplemented);
dword_result_t MicDeviceRequest_entry(pointer_t<X_MIC_DEVICE> device_ptr) {
if (!device_ptr) {
return X_STATUS_INVALID_PARAMETER;
}
XELOGE("MicDeviceRequest State: {:08X} Action: {:04X} USER: {:08X}",
static_cast<uint32_t>(device_ptr->info.state.get()),
static_cast<uint16_t>(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

View File

@@ -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<uint32_t>(XUsbCamState::CamNotConnected);
}
DECLARE_XBOXKRNL_EXPORT1(XUsbcamGetState, kNone, kStub);