Example #1
0
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;
}
Example #3
0
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
            }
        }
    }
}