/** * Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.ctdp.rfdynhud.input; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import net.ctdp.rfdynhud.gamedata.ByteUtil; import net.ctdp.rfdynhud.util.RFDHLog; /** * This manager keeps information about plugged in Joysticks (Wheels) and their buttons. * * @author Marvin Froehlich (CTDP) */ public class InputDeviceManager { private static final int MAX_JOYSTICK_NAME_LENGTH = 254; private static final int MAX_JOYSTICK_BUTTON_NAME_LENGTH = 64; private int numKeys = 0; private String[] keyNames = null; private int numJoysticks = 0; private String[] joystickNames = null; private int[] numButtons = null; private String[][] buttonNames = null; private int numComponents = 0; private int[] indexOffsets = null; public final int getNumKeys() { return ( numKeys ); } public final String getKeyName( int i ) { if ( keyNames == null ) return ( null ); if ( ( i < 0 ) || ( i >= keyNames.length ) ) return ( null ); return ( keyNames[i] ); } public final int getKeyIndex( String name ) { if ( keyNames == null ) return ( -1 ); for ( int i = 0; i < numKeys; i++ ) { if ( keyNames[i].equalsIgnoreCase( name ) ) return ( i ); } return ( -1 ); } private static HashMap<String, Integer> englishToIndex = new HashMap<String, Integer>(); private static HashMap<Integer, String> indexToEnglish = new HashMap<Integer, String>(); static { try { InputStream is = InputDeviceManager.class.getClassLoader().getResourceAsStream( InputDeviceManager.class.getPackage().getName().replace( '.', '/' ) + "/dinput.h" ); BufferedReader br = new BufferedReader( new InputStreamReader( is ) ); String line; while ( ( line = br.readLine() ) != null ) { line = line.trim(); if ( line.length() == 0 ) continue; if ( line.startsWith( "#define" ) ) { line = line.substring( 7 ).trim(); int p1 = line.indexOf( ' ' ); String name = line.substring( 0, p1 ); if ( name.startsWith( "DIK_" ) ) name = name.substring( 4 ); line = line.substring( p1 ).trim(); p1 = line.indexOf( ' ' ); String indexStr = ( p1 < 0 ) ? line : line.substring( 0, p1 ); int index = indexStr.startsWith( "0x" ) ? Integer.parseInt( indexStr.substring( 2 ), 16 ) : Integer.parseInt( indexStr, 16 ); if ( index >= 0 ) { englishToIndex.put( name, index ); indexToEnglish.put( index, name ); } } } } catch ( IOException e ) { e.printStackTrace(); } } public final String getEnglishKeyName( int i ) { return ( indexToEnglish.get( i ) ); } public final int getKeyIndexByEnglishName( String name ) { Integer index = englishToIndex.get( name ); if ( index == null ) return ( -1 ); return ( index.intValue() ); } public final int getNumJoysticks() { return ( numJoysticks ); } public final String getJoystickNameForIni( int i ) { return ( "Joystick" + ( i + 1 ) ); } public final String getJoystickButtonNameForIni( int i ) { return ( "Button" + ( i + 1 ) ); } public final String getJoystickName( int i ) { if ( joystickNames == null ) return ( null ); if ( ( i < 0 ) || ( i >= joystickNames.length ) ) return ( null ); return ( joystickNames[i] ); } public final int getJoystickIndex( String name ) { for ( int i = 1; i <= numJoysticks; i++ ) { if ( name.equals( "Joystick" + i ) ) return ( i - 1 ); } if ( joystickNames == null ) return ( -1 ); for ( int i = 0; i < numJoysticks; i++ ) { if ( joystickNames[i].equalsIgnoreCase( name ) ) return ( i ); } return ( -1 ); } public final int getNumJoystickButtons( int joystickIndex ) { return ( numButtons[joystickIndex] ); } public final String getJoystickButtonName( int joystickIndex, int i ) { return ( buttonNames[joystickIndex][i] ); } public final int getJoystickButtonIndex( int joystickIndex, String name ) { for ( int i = 1; i <= numButtons[joystickIndex]; i++ ) { if ( name.equalsIgnoreCase( "Button" + i ) ) return ( i - 1 ); } for ( int i = 0; i < numButtons[joystickIndex]; i++ ) { if ( buttonNames[joystickIndex][i].equalsIgnoreCase( name ) ) return ( i ); } return ( -1 ); } public final int getNumComponents() { return ( numComponents ); } public final int getJoystickButtonIndexOffset( int joystickIndex ) { return ( indexOffsets[joystickIndex] ); } public void decodeData( byte[] buffer ) { try { numComponents = 0; int bufferOffset = 0; numKeys = ByteUtil.readUnsignedShort( buffer, bufferOffset ); bufferOffset += ByteUtil.SIZE_SHORT; int maxKeyNameLength = ByteUtil.readUnsignedByte( buffer, bufferOffset ); bufferOffset += ByteUtil.SIZE_CHAR; keyNames = new String[ numKeys ]; for ( int i = 0; i < numKeys; i++ ) { keyNames[i] = ByteUtil.readString( buffer, bufferOffset, maxKeyNameLength ).trim(); bufferOffset += maxKeyNameLength + 1; } numComponents += numKeys; numComponents += 20; // reserved for Mouse buttons numJoysticks = ByteUtil.readUnsignedByte( buffer, bufferOffset ); bufferOffset += ByteUtil.SIZE_CHAR; joystickNames = new String[ numJoysticks ]; numButtons = new int[ numJoysticks ]; buttonNames = new String[ numJoysticks ][]; indexOffsets = new int[ numJoysticks ]; int buttonOffset = bufferOffset + numJoysticks * MAX_JOYSTICK_NAME_LENGTH; for ( int i = 0; i < numJoysticks; i++ ) { joystickNames[i] = ByteUtil.readString( buffer, bufferOffset + i * MAX_JOYSTICK_NAME_LENGTH, MAX_JOYSTICK_NAME_LENGTH ).trim(); numButtons[i] = ByteUtil.readUnsignedByte( buffer, buttonOffset ); buttonOffset++; indexOffsets[i] = numComponents; numComponents += numButtons[i]; buttonNames[i] = new String[ numButtons[i] ]; for ( int j = 0; j < numButtons[i]; j++ ) { buttonNames[i][j] = ByteUtil.readString( buffer, buttonOffset, MAX_JOYSTICK_BUTTON_NAME_LENGTH ).trim(); buttonOffset += MAX_JOYSTICK_BUTTON_NAME_LENGTH; } } /* Logger.log( "Num Keys: " + numKeys ); Logger.log( "Max Keyname length: " + maxKeyNameLength ); for ( int i = 0; i < numKeys; i++ ) { Logger.log( "Key Name[" + i + "]: " + keyNames[i] ); } Logger.log( "Num Joysticks: " + numJoysticks ); for ( int i = 0; i < numJoysticks; i++ ) { Logger.log( "Joystick-Name[" + i + "]: " + joystickNames[i] ); Logger.log( "Num Buttons[" + i + "]: " + numButtons[i] ); for ( int j = 0; j < numButtons[i]; j++ ) { Logger.log( "Button-Name[" + i + "][" + j + "]: " + buttonNames[i][j] ); } } */ } catch ( Throwable t ) { RFDHLog.exception( t ); } } public InputDeviceManager() { } }