void Xbox360Peripheral::MakeSettingsChanges() { if (controllerType == XboxOne) { if (pretend360) { controllerType = XboxOnePretend360; PadConnect(); } } else if (controllerType == XboxOnePretend360) { if (!pretend360) { controllerType = XboxOne; PadConnect(); } } noMapping = true; UInt8 normalMapping[15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15 }; for (int i = 0; i < 15; i++) { if (normalMapping[i] != mapping[i]) { noMapping = false; break; } } }
bool Xbox360Peripheral::start(IOService *provider) { const IOUSBConfigurationDescriptor *cd; IOUSBFindInterfaceRequest intf; IOUSBFindEndpointRequest pipe; XBOX360_OUT_LED led; IOWorkLoop *workloop = NULL; /* * Xbox One controller init packets. * The Rock Candy Xbox One controller requires more than just 0x05 * Minimum required packets unknown. */ UInt8 xoneInitFirst[] = { 0x02, 0x20, 0x01, 0x1C, 0x7E, 0xED, 0x8B, 0x11, 0x0F, 0xA8, 0x00, 0x00, 0x5E, 0x04, 0xD1, 0x02, 0x01, 0x00, 0x01, 0x00, 0x17, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; UInt8 xoneInitSecond[] = { 0x05, 0x20, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x53 }; UInt8 xoneInitThird[] = { 0x05, 0x20, 0x01, 0x01, 0x00 }; UInt8 xoneInitFourth[] = { 0x0A, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14 }; if (!super::start(provider)) return false; // Get device device=OSDynamicCast(IOUSBDevice,provider); if(device==NULL) { IOLog("start - invalid provider\n"); goto fail; } // Check for configurations if(device->GetNumConfigurations()<1) { device=NULL; IOLog("start - device has no configurations!\n"); goto fail; } // Set configuration cd=device->GetFullConfigurationDescriptor(0); if(cd==NULL) { device=NULL; IOLog("start - couldn't get configuration descriptor\n"); goto fail; } // Open if(!device->open(this)) { device=NULL; IOLog("start - unable to open device\n"); goto fail; } if(device->SetConfiguration(this,cd->bConfigurationValue,true)!=kIOReturnSuccess) { IOLog("start - unable to set configuration\n"); goto fail; } // Get release { UInt16 release = device->GetDeviceRelease(); switch (release) { default: IOLog("Unknown device release %.4x\n", release); // fall through case 0x0110: chatpadInit[0] = 0x01; chatpadInit[1] = 0x02; break; case 0x0114: chatpadInit[0] = 0x09; chatpadInit[1] = 0x00; break; } } // Find correct interface controllerType = Xbox360; intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=93; intf.bInterfaceProtocol=1; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox original intf.bInterfaceClass=kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass=66; intf.bInterfaceProtocol=0; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL,&intf); if(interface==NULL) { // Find correct interface, Xbox One intf.bInterfaceClass=255; intf.bInterfaceSubClass=71; intf.bInterfaceProtocol=208; intf.bAlternateSetting=kIOUSBFindInterfaceDontCare; interface=device->FindNextInterface(NULL, &intf); if(interface==NULL) { IOLog("start - unable to find the interface\n"); goto fail; } controllerType = XboxOne; goto interfacefound; } controllerType = XboxOriginal; goto interfacefound; } interfacefound: interface->open(this); // Find pipes pipe.direction=kUSBIn; pipe.interval=0; pipe.type=kUSBInterrupt; pipe.maxPacketSize=0; inPipe=interface->FindNextPipe(NULL,&pipe); if(inPipe==NULL) { IOLog("start - unable to find in pipe\n"); goto fail; } inPipe->retain(); pipe.direction=kUSBOut; outPipe=interface->FindNextPipe(NULL,&pipe); if(outPipe==NULL) { IOLog("start - unable to find out pipe\n"); goto fail; } outPipe->retain(); // Get a buffer inBuffer=IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,0,GetMaxPacketSize(inPipe)); if(inBuffer==NULL) { IOLog("start - failed to allocate input buffer\n"); goto fail; } // Find chatpad interface intf.bInterfaceClass = kIOUSBFindInterfaceDontCare; intf.bInterfaceSubClass = 93; intf.bInterfaceProtocol = 2; intf.bAlternateSetting = kIOUSBFindInterfaceDontCare; serialIn = device->FindNextInterface(NULL, &intf); if (serialIn == NULL) { IOLog("start - unable to find chatpad interface\n"); goto nochat; } serialIn->open(this); // Find chatpad pipe pipe.direction = kUSBIn; pipe.interval = 0; pipe.type = kUSBInterrupt; pipe.maxPacketSize = 0; serialInPipe = serialIn->FindNextPipe(NULL, &pipe); if (serialInPipe == NULL) { IOLog("start - unable to find chatpad in pipe\n"); goto fail; } serialInPipe->retain(); // Get a buffer for the chatpad serialInBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, 0, GetMaxPacketSize(serialInPipe)); if (serialInBuffer == NULL) { IOLog("start - failed to allocate input buffer for chatpad\n"); goto fail; } // Create timer for chatpad serialTimer = IOTimerEventSource::timerEventSource(this, ChatPadTimerActionWrapper); if (serialTimer == NULL) { IOLog("start - failed to create timer for chatpad\n"); goto fail; } workloop = getWorkLoop(); if ((workloop == NULL) || (workloop->addEventSource(serialTimer) != kIOReturnSuccess)) { IOLog("start - failed to connect timer for chatpad\n"); goto fail; } // Configure ChatPad // Send 'configuration' SendInit(0xa30c, 0x4423); SendInit(0x2344, 0x7f03); SendInit(0x5839, 0x6832); // Set 'switch' if ((!SendSwitch(false)) || (!SendSwitch(true)) || (!SendSwitch(false))) { // Commenting goto fail fixes the driver for the Hori Real Arcade Pro EX //goto fail; } // Begin toggle serialHeard = false; serialActive = false; serialToggle = false; serialResetCount = 0; serialTimerState = tsToggle; serialTimer->setTimeoutMS(1000); // Begin reading if (!QueueSerialRead()) goto fail; nochat: if (!QueueRead()) goto fail; if (controllerType == XboxOne) { QueueWrite(&xoneInitFirst, sizeof(xoneInitFirst)); QueueWrite(&xoneInitSecond, sizeof(xoneInitSecond)); QueueWrite(&xoneInitThird, sizeof(xoneInitThird)); QueueWrite(&xoneInitFourth, sizeof(xoneInitFourth)); } else { // Disable LED Xbox360_Prepare(led,outLed); led.pattern=ledOff; QueueWrite(&led,sizeof(led)); } // Done PadConnect(); registerService(); return true; fail: ReleaseAll(); return false; }
void Xbox360Peripheral::MakeSettingsChanges() { if (controllerType == XboxOne || controllerType == XboxOneElite) { if (pretend360) // Convert to a 360 controller { PadDisconnect(); previousType = controllerType; controllerType = XboxOnePretend360; PadConnect(); } for (UInt8 i = 0; i < 15; i++) // Change mappings to save time in remapping { switch (mapping[i]) { case 0: { mapping[i] = 8; } break; // Move to Up position case 1: { mapping[i] = 9; } break; // Move to Down position case 2: { mapping[i] = 10; } break; // Move to Left position case 3: { mapping[i] = 11; } break; // Move to Right position case 4: { mapping[i] = 2; } break; // Move to Start position case 5: { mapping[i] = 3; } break; // Move to Back position case 6: { mapping[i] = 14; } break; // Move to LB position case 7: { mapping[i] = 15; } break; // Move to RB position case 8: { mapping[i] = 12; } break; // Move to LSC position case 9: { mapping[i] = 13; } break; // Move to RSC position case 10: { mapping[i] = 0; } break; // Move to Guide position case 12: { mapping[i] = 4; } break; // Move to A position case 13: { mapping[i] = 5; } break; // Move to B position case 14: { mapping[i] = 6; } break; // Move to X position case 15: { mapping[i] = 7; } break; // Move to Y position } } } if (controllerType == XboxOnePretend360) { if (!pretend360) { PadDisconnect(); controllerType = previousType; PadConnect(); } for (UInt8 i = 0; i < 15; i++) // Change mappings to save time in remapping { switch (mapping[i]) { case 0: { mapping[i] = 8; } break; // Move to Up position case 1: { mapping[i] = 9; } break; // Move to Down position case 2: { mapping[i] = 10; } break; // Move to Left position case 3: { mapping[i] = 11; } break; // Move to Right position case 4: { mapping[i] = 2; } break; // Move to Start position case 5: { mapping[i] = 3; } break; // Move to Back position case 6: { mapping[i] = 14; } break; // Move to LB position case 7: { mapping[i] = 15; } break; // Move to RB position case 8: { mapping[i] = 12; } break; // Move to LSC position case 9: { mapping[i] = 13; } break; // Move to RSC position case 10: { mapping[i] = 0; } break; // Move to Guide position case 12: { mapping[i] = 4; } break; // Move to A position case 13: { mapping[i] = 5; } break; // Move to B position case 14: { mapping[i] = 6; } break; // Move to X position case 15: { mapping[i] = 7; } break; // Move to Y position } } } }