Ejemplo n.º 1
0
void Song::addController( Controller * controller )
{
	if( controller && !m_controllers.contains( controller ) )
	{
		m_controllers.append( controller );
		emit controllerAdded( controller );

		this->setModified();
	}
}
Ejemplo n.º 2
0
void Remapper::commandIn( Command command, QVariant data, qint64 timeStamp ) {
    switch( command ) {
        case Command::Stop:
        case Command::Load:
        case Command::Pause:
        case Command::Unload:
        case Command::Reset: {
            emit commandOut( command, data, timeStamp );
            playing = false;
            break;
        }

        case Command::Play: {
            emit commandOut( command, data, timeStamp );
            playing = true;
            break;
        }

        case Command::HandleGlobalPipelineReady: {
            emit commandOut( command, data, timeStamp );
            emit controllerAdded( "", "Keyboard", 0, 0, 0 );

            // TODO: Read keyboard setting from disk too
            dpadToAnalogKeyboard = true;

            // Give the model friendly names for all the keys set
            for( int physicalKey : keyboardKeyToSDLButton.keys() ) {
                int virtualButton = keyboardKeyToSDLButton[ physicalKey ];

                // This prints garbage as-is, so change it to something that doesn't
                // Confirmed on Windows but looks okay in OS X?
                // https://bugreports.qt.io/browse/QTBUG-40030
                if( physicalKey == Qt::Key_Shift ) {
                    physicalKey = Qt::ShiftModifier;
                }

                if( physicalKey == Qt::Key_Control ) {
                    physicalKey = Qt::ControlModifier;
                }

                if( physicalKey == Qt::Key_Meta ) {
                    physicalKey = Qt::MetaModifier;
                }

                if( physicalKey == Qt::Key_Alt ) {
                    physicalKey = Qt::AltModifier;
                }

                if( physicalKey == Qt::Key_AltGr ) {
                    physicalKey = Qt::AltModifier;
                }

                QString keyString = QKeySequence( physicalKey ).toString( QKeySequence::NativeText );

                // Strip out trailing + in the corrected keys
                if( keyString.length() > 1 ) {
                    keyString = keyString.section( '+', 0, 0 );
                }

                emit setMapping( "",  keyString, gameControllerIDToMappingString( virtualButton ) );
            }

            break;
        }

        case Command::SetUserDataPath: {
            userDataPath = data.toString();
            qDebug() << "Using path" << userDataPath;
            break;
        }

        case Command::Heartbeat: {
            emit commandOut( command, data, timeStamp );

            // Tell the model to clear its stored states
            emit heartbeat();

            // Send out per-GUID OR'd states to RemapperModel then clear stored pressed states
            for( QString GUID : pressed.keys() ) {
                emit buttonUpdate( GUID, pressed[ GUID ] );
                pressed[ GUID ] = false;
            }

            // Do the same for the keyboard
            emit buttonUpdate( "", keyboardKeyPressed );
            keyboardKeyPressed = false;

            // If in remap mode, make sure the GUID in question still exists, exit remap mode if not
            if( remapMode && !GUIDCount.contains( remapModeGUID ) ) {
                qCWarning( phxInput ) << "No controllers with GUID" << remapModeGUID << "remaining, exiting remap mode!";
                remapMode = false;
                emit remappingEnded();
            }

            break;
        }

        case Command::AddController: {
            emit commandOut( command, data, timeStamp );
            GamepadState gamepad = data.value<GamepadState>();
            int instanceID = gamepad.instanceID;
            QString GUID( QByteArray( reinterpret_cast<const char *>( gamepad.GUID.data ), 16 ).toHex() );

            // Add to map if it hasn't been encountered yet
            // Otherwise, just increment the count
            if( !GUIDCount.contains( GUID ) ) {
                GUIDCount[ GUID ] = 1;
                emit controllerAdded( GUID, gamepad.friendlyName, gamepad.joystickNumButtons, gamepad.joystickNumHats, gamepad.joystickNumAxes );
            } else {
                GUIDCount[ GUID ]++;
            }

            // Initialize mappings with invalid values
            for( int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) {
                Key key = Key( BUTTON, i );
                Val val = Val( INVALID, VHat( -1, -1 ) );
                gameControllerToJoystick[ GUID ][ key ] = val;
                emit setMapping( GUID, keyToMappingString( key ), valToFriendlyString( val ) );
            }

            // Grab gamepad handle
            gameControllerHandles[ instanceID ] = gamepad.gamecontrollerHandle;

            for( int i = 0; i < SDL_CONTROLLER_AXIS_MAX; i++ ) {
                Key key = Key( AXIS, i );
                Val val = Val( INVALID, VHat( -1, -1 ) );
                gameControllerToJoystick[ GUID ][ key ] = val;
                emit setMapping( GUID, keyToMappingString( key ), valToFriendlyString( val ) );
            }

            // TODO: Read value from disk
            analogToDpad[ GUID ] = false;
            dpadToAnalog[ GUID ] = false;

            // Set calibration flag, analog values will be read and deadzone values will be calculated the first time
            // we get data
            deadzoneFlag[ GUID ] = true;

            QString mappingString = gamepad.mappingString;

            if( mappingString.isEmpty() ) {
                return;
            }

            // Parse mapping string
            {
                QStringList mappings = mappingString.split( ',', QString::SkipEmptyParts );

                // No one likes QList asserts failing
                if( mappings.isEmpty() ) {
                    return;
                }

                /*QString gamepadGUID =*/ mappings.takeFirst();

                if( mappings.isEmpty() ) {
                    return;
                }

                QString friendlyName = mappings.takeFirst();

                if( mappings.isEmpty() ) {
                    return;
                }

                QString platform;

                // Parse the main part of the remapping string
                for( QString mapping : mappings ) {
                    if( mapping.contains( "platform" ) ) {
                        platform = mapping;
                        continue;
                    }

                    QString keyString = mapping.section( ':', 0, 0 );
                    QString valueString = mapping.section( ':', 1, 1 );

                    // Give up if there's nothing parsed
                    if( keyString.isEmpty() || valueString.isEmpty() ) {
                        continue;
                    }

                    Type valueType;

                    // Parse the key
                    Key key = Key( BUTTON, SDL_CONTROLLER_BUTTON_INVALID );
                    {
                        bool okay;
                        key = mappingStringToKey( keyString, &okay );

                        if( !okay ) {
                            continue;
                        }
                    }

                    // Parse the value
                    int value = -1;
                    int hatValue = -1;
                    {
                        // Button, format: bX
                        if( valueString.startsWith( "b" ) ) {
                            valueType = BUTTON;
                            bool okay;
                            value = valueString.right( valueString.size() - 1 ).toInt( &okay );

                            if( !okay ) {
                                continue;
                            }
                        }
                        // Hat, format: hX.Y
                        else if( valueString.startsWith( "h" ) ) {
                            valueType = HAT;
                            bool okay;
                            value = valueString.right( valueString.size() - 1 ).split( '.' )[ 0 ].toInt( &okay );

                            if( !okay ) {
                                continue;
                            }

                            hatValue = valueString.split( '.' )[ 1 ].toInt( &okay );

                            if( !okay ) {
                                continue;
                            }
                        }

                        // Axis, format aX
                        else if( valueString.startsWith( "a" ) ) {
                            valueType = AXIS;
                            bool okay;
                            value = valueString.right( valueString.size() - 1 ).toInt( &okay );

                            if( !okay ) {
                                continue;
                            }
                        } else {
                            continue;
                        }
                    }

                    //qDebug() << keyString << valueString << key << keyType << value << hatValue << valueType;
                    gameControllerToJoystick[ GUID ][ key ] = Val( valueType, VHat( value, hatValue ) );
                    emit setMapping( GUID, keyToMappingString( key ), valToFriendlyString( Val( valueType, VHat( value, hatValue ) ) ) );
                }
            }

            break;
        }

        case Command::RemoveController: {
            GamepadState gamepad = data.value<GamepadState>();
            int instanceID = gamepad.instanceID;
            QString GUID( QByteArray( reinterpret_cast<const char *>( gamepad.GUID.data ), 16 ).toHex() );
            GUIDCount[ GUID ]--;

            // Remove from map if no longer there
            if( GUIDCount[ GUID ] == 0 ) {
                GUIDCount.remove( GUID );
                emit controllerRemoved( GUID );
            }

            // If we opened an SDL2 Game controller handle from this class, keep it and inject it into all gamepads we send out
            if( gameControllerHandles[ instanceID ] ) {
                gamepad.gamecontrollerHandle = gameControllerHandles[ instanceID ];
            }

            gameControllerHandles.remove( instanceID );

            emit commandOut( Command::RemoveController, QVariant::fromValue( gamepad ), nodeCurrentTime() );
            break;
        }

        default: {
            emit commandOut( command, data, timeStamp );
            break;
        }
    }
}