Implemented MU support to xapi functions
This commit is contained in:
parent
4cf90a6170
commit
88a786b700
|
@ -117,18 +117,19 @@ void InputDeviceManager::Initialize(bool is_gui, HWND hwnd)
|
||||||
for (unsigned i = 0; i < 4; ++i) {
|
for (unsigned i = 0; i < 4; ++i) {
|
||||||
int type;
|
int type;
|
||||||
g_EmuShared->GetInputDevTypeSettings(&type, i);
|
g_EmuShared->GetInputDevTypeSettings(&type, i);
|
||||||
std::string port = std::to_string(i);
|
|
||||||
if (type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
if (type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||||
|
std::string port = std::to_string(i);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
|
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE):
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
case to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S): {
|
||||||
ConstructHleInputDevice(&g_devs[CTRL_OFFSET + i], nullptr, type, port);
|
ConstructHleInputDevice(&g_devs[CTRL_OFFSET + i], nullptr, type, port);
|
||||||
|
BindHostDevice(type, port);
|
||||||
for (unsigned slot = 0; slot < XBOX_CTRL_NUM_SLOTS; ++slot) {
|
for (unsigned slot = 0; slot < XBOX_CTRL_NUM_SLOTS; ++slot) {
|
||||||
g_EmuShared->GetInputSlotTypeSettings(&type, i, slot);
|
g_EmuShared->GetInputSlotTypeSettings(&type, i, slot);
|
||||||
if (type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
if (type != to_underlying(XBOX_INPUT_DEVICE::DEVICE_INVALID)) {
|
||||||
assert(type == to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT));
|
assert(type == to_underlying(XBOX_INPUT_DEVICE::MEMORY_UNIT));
|
||||||
ConstructHleInputDevice(&g_devs[MU_OFFSET + slot], &g_devs[CTRL_OFFSET + i], type, port + std::to_string(slot));
|
ConstructHleInputDevice(&g_devs[MU_OFFSET + slot], &g_devs[CTRL_OFFSET + i], type, port + "." + std::to_string(slot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +138,7 @@ void InputDeviceManager::Initialize(bool is_gui, HWND hwnd)
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK):
|
case to_underlying(XBOX_INPUT_DEVICE::ARCADE_STICK):
|
||||||
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
|
case to_underlying(XBOX_INPUT_DEVICE::STEEL_BATTALION_CONTROLLER):
|
||||||
ConstructHleInputDevice(&g_devs[CTRL_OFFSET + i], nullptr, type, port);
|
ConstructHleInputDevice(&g_devs[CTRL_OFFSET + i], nullptr, type, port);
|
||||||
|
BindHostDevice(type, port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -224,8 +226,8 @@ void InputDeviceManager::UpdateDevices(std::string_view port, bool ack)
|
||||||
{
|
{
|
||||||
DeviceState *dev, *upstream;
|
DeviceState *dev, *upstream;
|
||||||
int port1, type, slot;
|
int port1, type, slot;
|
||||||
dev = &g_devs[port1];
|
|
||||||
PortStr2Int(port, &port1, &slot);
|
PortStr2Int(port, &port1, &slot);
|
||||||
|
dev = &g_devs[port1];
|
||||||
|
|
||||||
if (slot == PORT_INVALID) { // Port references a device attached to an xbox port
|
if (slot == PORT_INVALID) { // Port references a device attached to an xbox port
|
||||||
upstream = nullptr;
|
upstream = nullptr;
|
||||||
|
|
|
@ -59,10 +59,38 @@ std::atomic<bool> g_bIsDevicesEmulating = false;
|
||||||
// Protects access to xpp types
|
// Protects access to xpp types
|
||||||
std::atomic<bool> g_bXppGuard = false;
|
std::atomic<bool> g_bXppGuard = false;
|
||||||
|
|
||||||
// allocate enough memory for the max number of devices we can support simultaneously
|
// Allocate enough memory for the max number of devices we can support simultaneously
|
||||||
// 4 duke / S / sbc / arcade joystick (mutually exclusive) + 8 memory units
|
// 4 duke / S / sbc / arcade joystick (mutually exclusive) + 8 memory units
|
||||||
DeviceState g_devs[4 + 8];
|
DeviceState g_devs[4 + 8];
|
||||||
|
|
||||||
|
xbox::ulong_xt g_Mounted_MUs = 0; // fallback if XapiMountedMUs is not found
|
||||||
|
xbox::ulong_xt *g_XapiMountedMUs = &g_Mounted_MUs;
|
||||||
|
std::mutex g_MuLock;
|
||||||
|
|
||||||
|
static inline xbox::char_xt MuPort2Lett(xbox::dword_xt port, xbox::dword_xt slot)
|
||||||
|
{
|
||||||
|
return 'F' + (XBOX_CTRL_NUM_SLOTS * port) + slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int MuPort2Idx(xbox::dword_xt port, xbox::dword_xt slot)
|
||||||
|
{
|
||||||
|
return (port << 1) + slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool MuIsMounted(xbox::char_xt lett)
|
||||||
|
{
|
||||||
|
return *g_XapiMountedMUs & (1 << (lett - 'F'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void MuSetMounted(xbox::char_xt lett)
|
||||||
|
{
|
||||||
|
*g_XapiMountedMUs |= (1 << (lett - 'F'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void MuClearMounted(xbox::char_xt lett)
|
||||||
|
{
|
||||||
|
*g_XapiMountedMUs &= ~(1 << (lett - 'F'));
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +131,7 @@ bool operator==(xbox::PXPP_DEVICE_TYPE XppType, XBOX_INPUT_DEVICE XidType)
|
||||||
|
|
||||||
void UpdateXppState(DeviceState *dev, XBOX_INPUT_DEVICE type, std::string_view port)
|
void UpdateXppState(DeviceState *dev, XBOX_INPUT_DEVICE type, std::string_view port)
|
||||||
{
|
{
|
||||||
xbox::PXPP_DEVICE_TYPE xpp;
|
xbox::PXPP_DEVICE_TYPE xpp = nullptr;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
case XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE:
|
||||||
|
@ -121,44 +149,38 @@ void UpdateXppState(DeviceState *dev, XBOX_INPUT_DEVICE type, std::string_view p
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
xpp = nullptr;
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(xpp != nullptr);
|
if (xpp == nullptr) {
|
||||||
|
// This will happen with xbes that act like launchers, and don't link against the xinput libraries, which results in all the global
|
||||||
|
// xpp types being nullptr. Test case: Innocent Tears
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int port1, slot;
|
int port1, slot;
|
||||||
PortStr2Int(port, &port1, &slot);
|
PortStr2Int(port, &port1, &slot);
|
||||||
xbox::ulong_xt port_mask = 1 << port1;
|
xbox::ulong_xt port_mask = 1 << port1;
|
||||||
|
xbox::ulong_xt slot_mask = 0;
|
||||||
|
|
||||||
// Guard against the unfortunate case where XGetDevices or XGetDeviceChanges have already checked for g_bIsDevicesInitializing
|
// Guard against the unfortunate case where XGetDevices or XGetDeviceChanges have already checked for g_bIsDevicesInitializing
|
||||||
// and g_bIsDevicesEmulating and a thread switch happens to this function
|
// and g_bIsDevicesEmulating and a thread switch happens to this function
|
||||||
while (g_bXppGuard) {}
|
while (g_bXppGuard) {}
|
||||||
|
|
||||||
if (xpp == g_DeviceType_MU) {
|
if (xpp == g_DeviceType_MU) {
|
||||||
if ((dev->upstream->type != XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE) ||
|
assert((dev->upstream->type == XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE) ||
|
||||||
(dev->upstream->type != XBOX_INPUT_DEVICE::MS_CONTROLLER_S) ||
|
(dev->upstream->type == XBOX_INPUT_DEVICE::MS_CONTROLLER_S));
|
||||||
dev->upstream->bPendingRemoval) {
|
assert(slot != PORT_INVALID);
|
||||||
xpp->CurrentConnected &= ~port_mask;
|
if (slot == 1) {
|
||||||
xpp->CurrentConnected &= ~(port_mask << 16);
|
slot_mask = 16;
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (unsigned i = 0, j = 0; i < XBOX_CTRL_NUM_SLOTS; ++i, j += 16) {
|
|
||||||
if (xpp == dev->type && !dev->bPendingRemoval) {
|
|
||||||
xpp->CurrentConnected |= (port_mask << j);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xpp->CurrentConnected &= ~(port_mask << j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xpp == dev->type && !dev->bPendingRemoval) {
|
||||||
|
xpp->CurrentConnected |= (port_mask << slot_mask);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (xpp == dev->type && !dev->bPendingRemoval) {
|
xpp->CurrentConnected &= ~(port_mask << slot_mask);
|
||||||
xpp->CurrentConnected |= port_mask;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xpp->CurrentConnected &= ~port_mask;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xpp->ChangeConnected = xpp->PreviousConnected ^ xpp->CurrentConnected;
|
xpp->ChangeConnected = xpp->PreviousConnected ^ xpp->CurrentConnected;
|
||||||
|
@ -425,6 +447,34 @@ void SetupXboxDeviceTypes()
|
||||||
else {
|
else {
|
||||||
EmuLog(LOG_LEVEL::INFO, "XDEVICE_TYPE_MEMORY_UNIT was not found because MU_Init could not be found");
|
EmuLog(LOG_LEVEL::INFO, "XDEVICE_TYPE_MEMORY_UNIT was not found because MU_Init could not be found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporary code until XapiMountedMUs is derived by XbSymbolDatabase
|
||||||
|
Xbe::LibraryVersion *pLibraryVersion = reinterpret_cast<Xbe::LibraryVersion *>(CxbxKrnl_Xbe->m_Header.dwLibraryVersionsAddr);
|
||||||
|
if (pLibraryVersion != nullptr) {
|
||||||
|
if (uint8_t *start = reinterpret_cast<uint8_t *>(g_SymbolAddresses["XUnmountMU"])) {
|
||||||
|
uint32_t offset = 0;
|
||||||
|
for (unsigned v = 0; v < CxbxKrnl_Xbe->m_Header.dwLibraryVersions; ++v) {
|
||||||
|
if (std::strcmp(pLibraryVersion[v].szName, "XAPILIB") == 0) {
|
||||||
|
if (pLibraryVersion[v].wBuildVersion < 4242) {
|
||||||
|
offset = 0x1D;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset = 0x2A;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// skip 2 because the address is hard-coded inside a test instruction
|
||||||
|
g_XapiMountedMUs = reinterpret_cast<xbox::ulong_xt *>(*reinterpret_cast<uint32_t *>((g_SymbolAddresses["XUnmountMU"] + offset + 2)));
|
||||||
|
EmuLog(LOG_LEVEL::INFO, "XapiMountedMUs found at 0x%08X", reinterpret_cast<uintptr_t>(g_XapiMountedMUs));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EmuLog(LOG_LEVEL::WARNING, "XapiMountedMUs was not found because XUnmountMU could not be found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EmuLog(LOG_LEVEL::WARNING, "XapiMountedMUs was not found because this xbe does not have a library version address");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool IsXInputPoll>
|
template<bool IsXInputPoll>
|
||||||
|
@ -1318,18 +1368,28 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XMountMUA)
|
||||||
PCHAR pchDrive
|
PCHAR pchDrive
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
LOG_FUNC_BEGIN
|
LOG_FUNC_BEGIN
|
||||||
LOG_FUNC_ARG(dwPort)
|
LOG_FUNC_ARG(dwPort)
|
||||||
LOG_FUNC_ARG(dwSlot)
|
LOG_FUNC_ARG(dwSlot)
|
||||||
LOG_FUNC_ARG(pchDrive)
|
LOG_FUNC_ARG(pchDrive)
|
||||||
LOG_FUNC_END;
|
LOG_FUNC_END;
|
||||||
|
|
||||||
// TODO: Actually allow memory card emulation? This might make transferring
|
std::lock_guard lock(g_MuLock);
|
||||||
// game saves a bit easier if the memory card directory was configurable. =]
|
|
||||||
|
|
||||||
RETURN(E_FAIL);
|
char lett = MuPort2Lett(dwPort, dwSlot);
|
||||||
|
if (MuIsMounted(lett)) {
|
||||||
|
if (pchDrive != zeroptr) {
|
||||||
|
*pchDrive = lett;
|
||||||
|
}
|
||||||
|
RETURN(ERROR_ALREADY_ASSIGNED);
|
||||||
|
}
|
||||||
|
|
||||||
|
MuSetMounted(lett);
|
||||||
|
if (pchDrive != zeroptr) {
|
||||||
|
*pchDrive = lett;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -1378,16 +1438,41 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XMountMURootA)
|
||||||
PCHAR pchDrive
|
PCHAR pchDrive
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
LOG_FUNC_BEGIN
|
LOG_FUNC_BEGIN
|
||||||
LOG_FUNC_ARG(dwPort)
|
LOG_FUNC_ARG(dwPort)
|
||||||
LOG_FUNC_ARG(dwSlot)
|
LOG_FUNC_ARG(dwSlot)
|
||||||
LOG_FUNC_ARG(pchDrive)
|
LOG_FUNC_ARG(pchDrive)
|
||||||
LOG_FUNC_END;
|
LOG_FUNC_END;
|
||||||
|
|
||||||
// TODO: The params are probably wrong...
|
std::lock_guard lock(g_MuLock);
|
||||||
LOG_UNIMPLEMENTED();
|
|
||||||
|
char_xt lett = MuPort2Lett(dwPort, dwSlot);
|
||||||
|
if (MuIsMounted(lett)) {
|
||||||
|
if (pchDrive != zeroptr) {
|
||||||
|
*pchDrive = lett;
|
||||||
|
}
|
||||||
|
RETURN(ERROR_ALREADY_ASSIGNED);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mu_path_str(DrivePrefix + lett + ":");
|
||||||
|
std::string mu_dev_str(DeviceMU + std::to_string(MuPort2Idx(dwPort, dwSlot)));
|
||||||
|
ANSI_STRING mu_dev, mu_path;
|
||||||
|
RtlInitAnsiString(&mu_path, mu_path_str.data());
|
||||||
|
RtlInitAnsiString(&mu_dev, mu_dev_str.data());
|
||||||
|
ntstatus_xt status = IoCreateSymbolicLink(&mu_path, &mu_dev);
|
||||||
|
|
||||||
|
if (!nt_success(status)) {
|
||||||
|
if (pchDrive != zeroptr) {
|
||||||
|
*pchDrive = 0;
|
||||||
|
}
|
||||||
|
RtlNtStatusToDosError(status);
|
||||||
|
RETURN(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
MuSetMounted(lett);
|
||||||
|
if (pchDrive != zeroptr) {
|
||||||
|
*pchDrive = lett;
|
||||||
|
}
|
||||||
|
|
||||||
RETURN(ERROR_SUCCESS);
|
RETURN(ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -1401,14 +1486,29 @@ xbox::dword_xt WINAPI xbox::EMUPATCH(XUnmountMU)
|
||||||
dword_xt dwSlot
|
dword_xt dwSlot
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
LOG_FUNC_BEGIN
|
LOG_FUNC_BEGIN
|
||||||
LOG_FUNC_ARG(dwPort)
|
LOG_FUNC_ARG(dwPort)
|
||||||
LOG_FUNC_ARG(dwSlot)
|
LOG_FUNC_ARG(dwSlot)
|
||||||
LOG_FUNC_END;
|
LOG_FUNC_END;
|
||||||
|
|
||||||
LOG_UNIMPLEMENTED();
|
std::lock_guard lock(g_MuLock);
|
||||||
|
|
||||||
|
char_xt lett = MuPort2Lett(dwPort, dwSlot);
|
||||||
|
if (!MuIsMounted(lett)) {
|
||||||
|
RETURN(ERROR_INVALID_DRIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mu_path_str(DrivePrefix + lett + ":");
|
||||||
|
ANSI_STRING mu_path;
|
||||||
|
RtlInitAnsiString(&mu_path, mu_path_str.data());
|
||||||
|
ntstatus_xt status = IoDeleteSymbolicLink(&mu_path);
|
||||||
|
|
||||||
|
if (!nt_success(status)) {
|
||||||
|
RtlNtStatusToDosError(status);
|
||||||
|
RETURN(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
MuClearMounted(lett);
|
||||||
|
|
||||||
RETURN(ERROR_SUCCESS);
|
RETURN(ERROR_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1501,25 +1501,48 @@ XBSYSAPI EXPORTNUM(218) xbox::ntstatus_xt NTAPI xbox::NtQueryVolumeInformationFi
|
||||||
if ((DWORD)FileInformationClass == FileFsSizeInformation) {
|
if ((DWORD)FileInformationClass == FileFsSizeInformation) {
|
||||||
PFILE_FS_SIZE_INFORMATION XboxSizeInfo = (PFILE_FS_SIZE_INFORMATION)FileInformation;
|
PFILE_FS_SIZE_INFORMATION XboxSizeInfo = (PFILE_FS_SIZE_INFORMATION)FileInformation;
|
||||||
|
|
||||||
XboxPartitionTable partitionTable = CxbxGetPartitionTable();
|
// This might access the HDD or a MU, so we need to figure out the correct one first
|
||||||
int partitionNumber = CxbxGetPartitionNumberFromHandle(FileHandle);
|
const std::wstring path = CxbxGetFinalPathNameByHandle(FileHandle);
|
||||||
FATX_SUPERBLOCK superBlock = CxbxGetFatXSuperBlock(partitionNumber);
|
size_t pos = path.rfind(L"\\EmuDisk\\Partition");
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
// We are accessing a disk partition
|
||||||
|
|
||||||
XboxSizeInfo->BytesPerSector = 512;
|
XboxPartitionTable partitionTable = CxbxGetPartitionTable();
|
||||||
|
int partitionNumber = CxbxGetPartitionNumberFromPath(path);
|
||||||
|
FATX_SUPERBLOCK superBlock = CxbxGetFatXSuperBlock(partitionNumber);
|
||||||
|
|
||||||
// In some cases, the emulated partition hasn't been formatted yet, as these are forwarded to a real folder, this doesn't actually matter.
|
XboxSizeInfo->BytesPerSector = 512;
|
||||||
// We just pretend they are valid by defaulting the SectorsPerAllocationUnit value to the most common for system partitions
|
|
||||||
XboxSizeInfo->SectorsPerAllocationUnit = 32;
|
|
||||||
|
|
||||||
// If there is a valid cluster size, we calculate SectorsPerAllocationUnit from that instead
|
// In some cases, the emulated partition hasn't been formatted yet, as these are forwarded to a real folder, this doesn't actually matter.
|
||||||
if (superBlock.ClusterSize > 0) {
|
// We just pretend they are valid by defaulting the SectorsPerAllocationUnit value to the most common for system partitions
|
||||||
XboxSizeInfo->SectorsPerAllocationUnit = superBlock.ClusterSize;
|
XboxSizeInfo->SectorsPerAllocationUnit = 32;
|
||||||
|
|
||||||
|
// If there is a valid cluster size, we calculate SectorsPerAllocationUnit from that instead
|
||||||
|
if (superBlock.ClusterSize > 0) {
|
||||||
|
XboxSizeInfo->SectorsPerAllocationUnit = superBlock.ClusterSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
XboxSizeInfo->TotalAllocationUnits.QuadPart = partitionTable.TableEntries[partitionNumber - 1].LBASize / XboxSizeInfo->SectorsPerAllocationUnit;
|
||||||
|
XboxSizeInfo->AvailableAllocationUnits.QuadPart = partitionTable.TableEntries[partitionNumber - 1].LBASize / XboxSizeInfo->SectorsPerAllocationUnit;
|
||||||
|
|
||||||
|
RETURN(xbox::status_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
XboxSizeInfo->TotalAllocationUnits.QuadPart = partitionTable.TableEntries[partitionNumber - 1].LBASize / XboxSizeInfo->SectorsPerAllocationUnit;
|
pos = path.rfind(L"\\EmuMu");
|
||||||
XboxSizeInfo->AvailableAllocationUnits.QuadPart = partitionTable.TableEntries[partitionNumber - 1].LBASize / XboxSizeInfo->SectorsPerAllocationUnit;
|
if (pos != std::string::npos) {
|
||||||
|
// We are accessing a MU
|
||||||
|
|
||||||
RETURN(xbox::status_success);
|
XboxSizeInfo->BytesPerSector = 512;
|
||||||
|
XboxSizeInfo->SectorsPerAllocationUnit = 32;
|
||||||
|
XboxSizeInfo->TotalAllocationUnits.QuadPart = 512; // 8MB -> ((1024)^2 * 8) / (BytesPerSector * SectorsPerAllocationUnit)
|
||||||
|
XboxSizeInfo->AvailableAllocationUnits.QuadPart = 512; // constant, so there's always free space available to write stuff
|
||||||
|
|
||||||
|
RETURN(xbox::status_success);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmuLog(LOG_LEVEL::WARNING, "%s: Unrecongnized handle 0x%X with class FileFsSizeInformation", __func__, FileHandle);
|
||||||
|
|
||||||
|
RETURN(xbox::status_invalid_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the required size for the host buffer
|
// Get the required size for the host buffer
|
||||||
|
|
|
@ -1509,16 +1509,15 @@ __declspec(noreturn) void CxbxKrnlInit
|
||||||
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition7, CxbxBasePath + "Partition7");
|
CxbxRegisterDeviceHostPath(DeviceHarddisk0Partition7, CxbxBasePath + "Partition7");
|
||||||
CxbxRegisterDeviceHostPath(DevicePrefix + "\\Chihiro", CxbxBasePath + "Chihiro");
|
CxbxRegisterDeviceHostPath(DevicePrefix + "\\Chihiro", CxbxBasePath + "Chihiro");
|
||||||
|
|
||||||
// Create MU directories
|
// Create the MU directories
|
||||||
for (unsigned i = 0; i < 8; ++i) {
|
CxbxRegisterDeviceHostPath(DeviceMU0, MuBasePath + "F");
|
||||||
std::error_code error;
|
CxbxRegisterDeviceHostPath(DeviceMU1, MuBasePath + "G");
|
||||||
static char mu_letter = 'F';
|
CxbxRegisterDeviceHostPath(DeviceMU2, MuBasePath + "H");
|
||||||
std::string mu_path = MuBasePath + mu_letter;
|
CxbxRegisterDeviceHostPath(DeviceMU3, MuBasePath + "I");
|
||||||
if (!(std::filesystem::exists(mu_path) || std::filesystem::create_directory(mu_path, error))) {
|
CxbxRegisterDeviceHostPath(DeviceMU4, MuBasePath + "J");
|
||||||
CxbxKrnlCleanup("Failed to create memory unit directories");
|
CxbxRegisterDeviceHostPath(DeviceMU5, MuBasePath + "K");
|
||||||
}
|
CxbxRegisterDeviceHostPath(DeviceMU6, MuBasePath + "L");
|
||||||
++mu_letter;
|
CxbxRegisterDeviceHostPath(DeviceMU7, MuBasePath + "M");
|
||||||
}
|
|
||||||
|
|
||||||
// Create default symbolic links :
|
// Create default symbolic links :
|
||||||
EmuLogInit(LOG_LEVEL::DEBUG, "Creating default symbolic links.");
|
EmuLogInit(LOG_LEVEL::DEBUG, "Creating default symbolic links.");
|
||||||
|
|
|
@ -139,7 +139,7 @@ FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber)
|
||||||
return superblock;
|
return superblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::wstring CxbxGetFinalPathNameByHandle(HANDLE hFile)
|
std::wstring CxbxGetFinalPathNameByHandle(HANDLE hFile)
|
||||||
{
|
{
|
||||||
constexpr size_t INITIAL_BUF_SIZE = MAX_PATH;
|
constexpr size_t INITIAL_BUF_SIZE = MAX_PATH;
|
||||||
std::wstring path(INITIAL_BUF_SIZE, '\0');
|
std::wstring path(INITIAL_BUF_SIZE, '\0');
|
||||||
|
@ -173,20 +173,30 @@ static bool CxbxIsPathInsideEmuDisk(const std::filesystem::path& path)
|
||||||
return match.first == rootPath.end();
|
return match.first == rootPath.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CxbxGetPartitionNumberFromHandle(HANDLE hFile)
|
static int CxbxGetPartitionNumber(const std::wstring_view path)
|
||||||
{
|
{
|
||||||
// Get which partition number is being accessed, by parsing the filename and extracting the last portion
|
|
||||||
const std::wstring path = CxbxGetFinalPathNameByHandle(hFile);
|
|
||||||
|
|
||||||
const std::wstring_view partitionString = L"\\EmuDisk\\Partition";
|
const std::wstring_view partitionString = L"\\EmuDisk\\Partition";
|
||||||
const size_t pos = path.rfind(partitionString);
|
const size_t pos = path.rfind(partitionString);
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const std::wstring partitionNumberString = path.substr(pos + partitionString.length(), 1);
|
const std::wstring_view partitionNumberString = path.substr(pos + partitionString.length(), 1);
|
||||||
|
|
||||||
// wcstol returns 0 on non-numeric characters, so we don't need to error check here
|
// wcstol returns 0 on non-numeric characters, so we don't need to error check here
|
||||||
return wcstol(partitionNumberString.c_str(), nullptr, 0);
|
return wcstol(partitionNumberString.data(), nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CxbxGetPartitionNumberFromPath(const std::wstring_view path)
|
||||||
|
{
|
||||||
|
return CxbxGetPartitionNumber(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CxbxGetPartitionNumberFromHandle(HANDLE hFile)
|
||||||
|
{
|
||||||
|
// Get which partition number is being accessed, by parsing the filename and extracting the last portion
|
||||||
|
const std::wstring path = CxbxGetFinalPathNameByHandle(hFile);
|
||||||
|
|
||||||
|
return CxbxGetPartitionNumber(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path CxbxGetPartitionDataPathFromHandle(HANDLE hFile)
|
std::filesystem::path CxbxGetPartitionDataPathFromHandle(HANDLE hFile)
|
||||||
|
@ -267,6 +277,7 @@ const std::string DriveZ = DrivePrefix + "Z:"; // Z: is Title utility data regio
|
||||||
const std::string DevicePrefix = "\\Device";
|
const std::string DevicePrefix = "\\Device";
|
||||||
const std::string DeviceCdrom0 = DevicePrefix + "\\CdRom0";
|
const std::string DeviceCdrom0 = DevicePrefix + "\\CdRom0";
|
||||||
const std::string DeviceHarddisk0 = DevicePrefix + "\\Harddisk0";
|
const std::string DeviceHarddisk0 = DevicePrefix + "\\Harddisk0";
|
||||||
|
const std::string DeviceMU = DevicePrefix + "\\MU_";
|
||||||
const std::string DeviceHarddisk0PartitionPrefix = DevicePrefix + "\\Harddisk0\\partition";
|
const std::string DeviceHarddisk0PartitionPrefix = DevicePrefix + "\\Harddisk0\\partition";
|
||||||
const std::string DeviceHarddisk0Partition0 = DeviceHarddisk0PartitionPrefix + "0"; // Contains raw config sectors (like XBOX_REFURB_INFO) + entire hard disk
|
const std::string DeviceHarddisk0Partition0 = DeviceHarddisk0PartitionPrefix + "0"; // Contains raw config sectors (like XBOX_REFURB_INFO) + entire hard disk
|
||||||
const std::string DeviceHarddisk0Partition1 = DeviceHarddisk0PartitionPrefix + "1"; // Data partition. Contains TDATA and UDATA folders.
|
const std::string DeviceHarddisk0Partition1 = DeviceHarddisk0PartitionPrefix + "1"; // Data partition. Contains TDATA and UDATA folders.
|
||||||
|
@ -289,6 +300,14 @@ const std::string DeviceHarddisk0Partition17 = DeviceHarddisk0PartitionPrefix +
|
||||||
const std::string DeviceHarddisk0Partition18 = DeviceHarddisk0PartitionPrefix + "18";
|
const std::string DeviceHarddisk0Partition18 = DeviceHarddisk0PartitionPrefix + "18";
|
||||||
const std::string DeviceHarddisk0Partition19 = DeviceHarddisk0PartitionPrefix + "19";
|
const std::string DeviceHarddisk0Partition19 = DeviceHarddisk0PartitionPrefix + "19";
|
||||||
const std::string DeviceHarddisk0Partition20 = DeviceHarddisk0PartitionPrefix + "20"; // 20 = Largest possible partition number
|
const std::string DeviceHarddisk0Partition20 = DeviceHarddisk0PartitionPrefix + "20"; // 20 = Largest possible partition number
|
||||||
|
const std::string DeviceMU0 = DeviceMU + "0";
|
||||||
|
const std::string DeviceMU1 = DeviceMU + "1";
|
||||||
|
const std::string DeviceMU2 = DeviceMU + "2";
|
||||||
|
const std::string DeviceMU3 = DeviceMU + "3";
|
||||||
|
const std::string DeviceMU4 = DeviceMU + "4";
|
||||||
|
const std::string DeviceMU5 = DeviceMU + "5";
|
||||||
|
const std::string DeviceMU6 = DeviceMU + "6";
|
||||||
|
const std::string DeviceMU7 = DeviceMU + "7"; // 7 = Largest possible mu number
|
||||||
|
|
||||||
EmuNtSymbolicLinkObject* NtSymbolicLinkObjects['Z' - 'A' + 1];
|
EmuNtSymbolicLinkObject* NtSymbolicLinkObjects['Z' - 'A' + 1];
|
||||||
std::vector<XboxDevice> Devices;
|
std::vector<XboxDevice> Devices;
|
||||||
|
|
|
@ -73,6 +73,7 @@ extern const std::string DriveZ;
|
||||||
extern const std::string DevicePrefix;
|
extern const std::string DevicePrefix;
|
||||||
extern const std::string DeviceCdrom0;
|
extern const std::string DeviceCdrom0;
|
||||||
extern const std::string DeviceHarddisk0;
|
extern const std::string DeviceHarddisk0;
|
||||||
|
extern const std::string DeviceMU;
|
||||||
extern const std::string DeviceHarddisk0PartitionPrefix;
|
extern const std::string DeviceHarddisk0PartitionPrefix;
|
||||||
extern const std::string DeviceHarddisk0Partition0;
|
extern const std::string DeviceHarddisk0Partition0;
|
||||||
extern const std::string DeviceHarddisk0Partition1;
|
extern const std::string DeviceHarddisk0Partition1;
|
||||||
|
@ -95,6 +96,14 @@ extern const std::string DeviceHarddisk0Partition17;
|
||||||
extern const std::string DeviceHarddisk0Partition18;
|
extern const std::string DeviceHarddisk0Partition18;
|
||||||
extern const std::string DeviceHarddisk0Partition19;
|
extern const std::string DeviceHarddisk0Partition19;
|
||||||
extern const std::string DeviceHarddisk0Partition20;
|
extern const std::string DeviceHarddisk0Partition20;
|
||||||
|
extern const std::string DeviceMU0;
|
||||||
|
extern const std::string DeviceMU1;
|
||||||
|
extern const std::string DeviceMU2;
|
||||||
|
extern const std::string DeviceMU3;
|
||||||
|
extern const std::string DeviceMU4;
|
||||||
|
extern const std::string DeviceMU5;
|
||||||
|
extern const std::string DeviceMU6;
|
||||||
|
extern const std::string DeviceMU7;
|
||||||
constexpr char CxbxAutoMountDriveLetter = 'D';
|
constexpr char CxbxAutoMountDriveLetter = 'D';
|
||||||
|
|
||||||
extern std::string CxbxBasePath;
|
extern std::string CxbxBasePath;
|
||||||
|
@ -318,6 +327,8 @@ typedef struct _FATX_SUPERBLOCK
|
||||||
XboxPartitionTable CxbxGetPartitionTable();
|
XboxPartitionTable CxbxGetPartitionTable();
|
||||||
FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber);
|
FATX_SUPERBLOCK CxbxGetFatXSuperBlock(int partitionNumber);
|
||||||
int CxbxGetPartitionNumberFromHandle(HANDLE hFile);
|
int CxbxGetPartitionNumberFromHandle(HANDLE hFile);
|
||||||
|
int CxbxGetPartitionNumberFromPath(const std::wstring_view path);
|
||||||
|
std::wstring CxbxGetFinalPathNameByHandle(HANDLE hFile);
|
||||||
std::filesystem::path CxbxGetPartitionDataPathFromHandle(HANDLE hFile);
|
std::filesystem::path CxbxGetPartitionDataPathFromHandle(HANDLE hFile);
|
||||||
void CxbxFormatPartitionByHandle(HANDLE hFile);
|
void CxbxFormatPartitionByHandle(HANDLE hFile);
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ INT_PTR CALLBACK DlgInputConfigProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPAR
|
||||||
HWND hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + port);
|
HWND hHandle = GetDlgItem(hWndDlg, IDC_DEVICE_PORT1 + port);
|
||||||
int DeviceType = SendMessage(hHandle, CB_GETITEMDATA, SendMessage(hHandle, CB_GETCURSEL, 0, 0), 0);
|
int DeviceType = SendMessage(hHandle, CB_GETITEMDATA, SendMessage(hHandle, CB_GETCURSEL, 0, 0), 0);
|
||||||
g_Settings->m_input_port[port].Type = DeviceType;
|
g_Settings->m_input_port[port].Type = DeviceType;
|
||||||
if (DeviceType != to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE) ||
|
if (DeviceType != to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_DUKE) &&
|
||||||
DeviceType != to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S)) {
|
DeviceType != to_underlying(XBOX_INPUT_DEVICE::MS_CONTROLLER_S)) {
|
||||||
// Forcefully set the child devices to none. This will happen if the user sets MUs in the controller dialog but
|
// Forcefully set the child devices to none. This will happen if the user sets MUs in the controller dialog but
|
||||||
// then they set the parent device to a device that cannot support them in the input dialog
|
// then they set the parent device to a device that cannot support them in the input dialog
|
||||||
|
|
Loading…
Reference in New Issue