aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeffpk <[email protected]>2003-06-06 21:04:07 +0000
committerjeffpk <[email protected]>2003-06-06 21:04:07 +0000
commit454233e113a22a149fe45624ce3e405474ded053 (patch)
tree173b3916eff745d921bc22fc858f4bddcc966bde
parent4275dabe7f7cf2e427626550cb54f5e8ba104e44 (diff)
Initial check-in of the Java Games Initiative's game controller discovery and input library.
git-svn-id: file:///home/sven/projects/JOGL/git-svn/svn-server-sync/jinput/trunk@3 e343933a-64c8-49c5-92b1-88f2ce3e89e8
-rw-r--r--README.txt81
-rw-r--r--build.xml50
-rw-r--r--coreAPI/README.txt54
-rw-r--r--coreAPI/build.xml116
-rw-r--r--coreAPI/src/java/net/java/games/input/AbstractAxis.java153
-rw-r--r--coreAPI/src/java/net/java/games/input/AbstractController.java194
-rw-r--r--coreAPI/src/java/net/java/games/input/Axis.java349
-rw-r--r--coreAPI/src/java/net/java/games/input/Controller.java253
-rw-r--r--coreAPI/src/java/net/java/games/input/ControllerEnvironment.java140
-rw-r--r--coreAPI/src/java/net/java/games/input/ControllerEvent.java61
-rw-r--r--coreAPI/src/java/net/java/games/input/ControllerListener.java55
-rw-r--r--coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java232
-rw-r--r--coreAPI/src/java/net/java/games/input/Keyboard.java168
-rw-r--r--coreAPI/src/java/net/java/games/input/Mouse.java315
-rw-r--r--coreAPI/src/java/net/java/games/input/PluginClassLoader.java175
-rw-r--r--coreAPI/src/java/net/java/games/input/Rumbler.java52
-rw-r--r--coreAPI/src/java/net/java/games/input/StandardKeyboard.java261
-rw-r--r--coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java279
-rw-r--r--coreAPI/src/java/net/java/games/input/test/ControllerTextTest.java89
-rw-r--r--plugins/DX8/README.txt46
-rw-r--r--plugins/DX8/build.xml103
-rw-r--r--plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java211
-rw-r--r--plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java207
-rw-r--r--plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java183
-rw-r--r--plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java208
-rw-r--r--plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java311
-rw-r--r--plugins/DX8/src/native/input.cpp888
27 files changed, 5234 insertions, 0 deletions
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..3b191e3
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,81 @@
+Project: net.java.games.*
+Purpose: Open source game libraries
+Authors:
+ -- input API design:
+ Michael Martak, Sun Microsystems
+ Thomas Daniel, Sony Computer Entertainment
+ -- input API original author:
+ Michael Martak,Sun Microsystems
+ -- input API original release author:
+ Jeff Kesselman, Game Technology Architect,
+ Advanced Software Technologies Group,
+ Sun Microsystems.
+ -- this file updated on 06/06/2003 by Jeff Kesselman
+
+
+Introduction:
+
+This is the source tree for the Java Game Initiative (JGI) Open Source
+client game programming APIs.
+
+Build Requirements:
+
+This project has been built in the follwing environment.
+ -- Win32 (Win 2000 in the case of our machine)
+ -- Sun J2SDK 1.4 (available at java.sun.com)
+ -- MinGW 2.0.0 plus the following updates: (all available at www.mingw.org)
+ -- binutils 2.13.90
+ -- w32api-2.2
+ -- mingw-runtime-2.4
+ -- "Peter Puck's" directx8 binding
+ (http://www.urebelscum.speedhost.com/download.html, file: dx8libs.zip
+ -- ANT 1.4.1 (available at apache.org)
+
+
+Directory Organization:
+
+The root contains a master ANT build.xml and the following sub directories:
+ -- coreAPI: The actual API
+ -- plugins: Directories for bildign controlelr plugins.
+ (Currently the only plug in is the Win32 DX8 plugin.)
+
+Build instructions:
+
+To clean: ant clean
+To build: ant all (or just ant)
+To build docs: ant javadoc
+To test:
+ First cd to coreAPI. There are currently 2 tests there.
+ Textest: A simple discovery test that dumps
+ the data about the discovered controllers to stdout
+ To run: ant textest
+ Readtest: A test that creates a window for each discovered
+ controller (or sub-controller) which displays the
+ current state of all the controller's axiis.
+ (Note: The windows currrently all open at the same
+ place on the screen so yo uwill have to move them to
+ see them all.)
+ To run: ant readtest
+
+Release Info:
+ Initial Release: This release contains an implementation of the input
+ API designed by Mike Martak of Sun and Thomas (?) of Sony CEA for
+ the WIn32 platform. All the code in src/input is cross platform. The
+ Win32 code is segregated to the DirectX plugin (src/DXplugin) which
+ depends on DirectInput from DX7 (or later).
+
+ 05/09/2003: A number of bugs and problems with the DXPlugin are fixed in this
+ release. This release also brings the code up to date using the DI8
+ interface. This thus is the first release that requries Peter Puck's
+ DX8 bindings to compile with MinGW.
+
+ 05/09/2003 (second update):
+ This version adds a new standard value type to the API.
+ Axis.POV holds standard definitions for values for POV (hat) switches
+ -- Axis.POV.CENTER and Axis.POV.OFF are synonmous and are
+ the center position.
+ -- Axis.POV.UP, Axis.POV.DOWN, Axis.POV.LEFT and Axis.POV.RIGHT
+ should be self explainatory.
+ Any hat that claims to be "normalized" will return these values. (It is
+ recommended that all hats be normalized by the systemn specific plugins.)
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..a934222
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!-- Written to assume that classpath is rooted in the current directory. -->
+<!-- So this should be OK if you make this script in the root of a filesystem. -->
+<!-- If not, you may prefer to adjust the basedir, or move some directories around. -->
+<!-- The idea is that both Ant and NetBeans have to know what the package root is -->
+<!-- for the classes in your application. -->
+<project name="Sun Games Initiative Client Technologies" basedir="." default="all">
+
+ <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! -->
+ <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. -->
+
+ <target name="init">
+ <!-- You can set up any variables you want used throughout the script here. -->
+ <!-- <property name="hello" value="world"/ -->
+ <!-- To use e.g. Jikes, uncomment this line. -->
+ <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) -->
+ <!-- <property name="build.compiler" value="jikes"/> -->
+ <!-- You might like to set up some overridable paths, etc.: -->
+ <!-- <property name="mylib" value="../lib/mylib.jar"/> -->
+ </target>
+
+ <target name="compile" depends="init">
+ <!-- Both srcdir and destdir should be package roots. -->
+ <!-- They could be different of course; in that case NetBeans can also be set -->
+ <!-- up to compile to a different filesystem in the same way; see Compiler Types: -->
+ <ant dir="coreAPI" />
+ <ant dir="plugins/DX8" />
+ </target>
+
+ <target name="javadoc" depends="init">
+ <!-- Both srcdir and destdir should be package roots. -->
+ <!-- They could be different of course; in that case NetBeans can also be set -->
+ <!-- up to compile to a different filesystem in the same way; see Compiler Types: -->
+ <ant dir="coreAPI" target="javadoc"/>
+ <ant dir="plugins/DX8" target="javadoc"/>
+ </target>
+
+
+ <target name="all" depends="init,compile" description="Build everything.">
+ <echo message="Application built. Hello ${hello}!"/>
+ </target>
+
+ <target name="clean" depends="init" description="Clean all build products.">
+ <ant dir="plugins/DX8" target="clean"/>
+ <ant dir="coreAPI" target="clean"/>
+ </target>
+
+
+</project>
diff --git a/coreAPI/README.txt b/coreAPI/README.txt
new file mode 100644
index 0000000..90caf93
--- /dev/null
+++ b/coreAPI/README.txt
@@ -0,0 +1,54 @@
+This file modified last on 06/06/2003 by Jeff Kesselman
+
+This is the source tree for the core input API.
+
+Directory Organization:
+
+The root contains a master ANT build.xml.
+After a successful build of the project you will have the following sub directories:
+ -- apidocs Where the javadocs get built to
+ -- lib Where dependant libraries are kept.
+ -- bin Where the actual API is built to
+ -- src The source files.
+ -- src/test Execution directories and data for tests.
+
+Build instructions:
+
+To clean: ant clean
+To build: ant all (or just ant)
+To build docs: ant javadoc
+To test:
+ Textest: A simple discovery test that dumps
+ the data about the discovered controllers to stdout
+ To run: ant textest
+ Readtest: A test that creates a window for each discovered
+ controller (or sub-controller) which displays the
+ current state of all the controller's axiis.
+ (Note: The windows currrently all open at the same
+ place on the screen so yo uwill have to move them to
+ see them all.)
+ To run: ant readtest
+
+
+Release Info:
+ Initial Release: This release contains an implementation of the input
+ API designed by Mike Martak of Sun and Thomas (?) of Sony CEA for
+ the WIn32 platform. All the code in src/input is cross platform. The
+ Win32 code is segregated to the DirectX plugin (src/DXplugin) which
+ depends on DirectInput from DX7 (or later).
+
+ 05/09/2003: A number of bugs and problems with the DXPlugin are fixed in this
+ release. This release also brings the code up to date using the DI8
+ interface. This thus is the first release that requries Peter Puck's
+ DX8 bindings to compile with MinGW.
+
+ 05/09/2003 (second update):
+ This version adds a new standard value type to the API.
+ Axis.POV holds standard definitions for values for POV (hat) switches
+ -- Axis.POV.CENTER and Axis.POV.OFF are synonmous and are
+ the center position.
+ -- Axis.POV.UP, Axis.POV.DOWN, Axis.POV.LEFT and Axis.POV.RIGHT
+ should be self explainatory.
+ Any hat that claims to be "normalized" will return these values. (It is
+ recommended that all hats be normalized by the systemn specific plugins.)
+
diff --git a/coreAPI/build.xml b/coreAPI/build.xml
new file mode 100644
index 0000000..f2db003
--- /dev/null
+++ b/coreAPI/build.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0"?>
+
+<!-- Written to assume that classpath is rooted in the current directory. -->
+<!-- So this should be OK if you make this script in the root of a filesystem. -->
+<!-- If not, you may prefer to adjust the basedir, or move some directories around. -->
+<!-- The idea is that both Ant and NetBeans have to know what the package root is -->
+<!-- for the classes in your application. -->
+<project name="Game Input API" basedir="." default="all">
+
+ <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! -->
+ <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. -->
+
+ <target name="init">
+ <!-- You can set up any variables you want used throughout the script here. -->
+ <!-- property name="hello" value="world" -->
+ <!-- To use e.g. Jikes, uncomment this line. -->
+ <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) -->
+ <!-- <property name="build.compiler" value="jikes"/> -->
+ <!-- You might like to set up some overridable paths, etc.: -->
+ <property name="utils" value="lib/jutils.jar"/>
+ <mkdir dir="apidocs"/>
+ <mkdir dir="classes"/>
+ <mkdir dir="bin"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <!-- Both srcdir and destdir should be package roots. -->
+ <!-- They could be different of course; in that case NetBeans can also be set -->
+ <!-- up to compile to a different filesystem in the same way; see Compiler Types: -->
+ <javac srcdir="src/java" destdir="classes" debug="true" deprecation="true" source="1.4">
+ <include name="net/**"/>
+ <!-- To add something to the classpath: -->
+ <classpath>
+ <pathelement location="${utils}"/>
+ </classpath>
+ <!-- To exclude some files: -->
+ <!--
+ <exclude name="com/foo/SomeFile.java"/>
+ <exclude name="com/foo/somepackage/"/>
+ -->
+ </javac>
+ </target>
+
+ <target name="jar" depends="init,compile">
+ <!-- To make a standalone app: -->
+ <!-- 1. Create a myapp.mf manifest somewhere. -->
+ <!-- 2. Put in it: -->
+ <!-- Manifest-Version: 1.0 -->
+ <!-- Main-Class: com.foo.Main -->
+ <!-- 3. Pass to <jar>: manifest="myapp.mf" -->
+ <jar jarfile="bin/controller.jar" compress="true" basedir="classes">
+ <include name="net/**"/>
+ <exclude name="**/*.java"/>
+ <exclude name="**/*.form"/>
+ <exclude name="myapp.mf"/>
+ <exclude name="myapp.jar"/>
+ </jar>
+ <copy file="bin/controller.jar" todir="../plugins/DX8/lib" />
+ </target>
+
+ <target name="all" depends="init,jar" description="Build everything.">
+ <echo message="Application built. Hello ${hello}!"/>
+ </target>
+
+ <target name="texttest" depends="init,all" description="Try running it.">
+ <java classname="net.java.games.input.test.ControllerTextTest"
+ fork="true" failonerror="true" dir="src/tests">
+ <classpath>
+ <pathelement location="bin/controller.jar"/>
+ <pathelement location="${utils}"/>
+ </classpath>
+ <!-- Pass some args, perhaps: -->
+ <!-- <arg value="-myfile"/> -->
+ <!-- Will be given as an absolute path: -->
+ <!-- <arg file="myfile.txt"/> -->
+ </java>
+ </target>
+ <target name="readtest" depends="init,all" description="Try running it.">
+ <java classname="net.java.games.input.test.ControllerReadTest"
+ fork="true" failonerror="true" dir="src/tests">
+ <classpath>
+ <pathelement location="bin/controller.jar"/>
+ <pathelement location="${utils}"/>
+ </classpath>
+ <!-- Pass some args, perhaps: -->
+ <!-- <arg value="-myfile"/> -->
+ <!-- Will be given as an absolute path: -->
+ <!-- <arg file="myfile.txt"/> -->
+ </java>
+ </target>
+
+ <target name="javadoc" depends="init" description="Javadoc for my API.">
+ <javadoc packagenames="net.java.games.input.*"
+ destdir="apidocs"
+ additionalparam="-source 1.4">
+ <sourcepath>
+ <pathelement location="src/java"/>
+ </sourcepath>
+ <classpath>
+ <pathelement location="${utils}"/>
+ </classpath>
+ </javadoc>
+ </target>
+
+ <target name="clean" depends="init" description="Clean all build products.">
+ <delete>
+ <fileset dir="classes">
+ <include name="**/*.class"/>
+ </fileset>
+ </delete>
+ <delete file="bin/controller.jar"/>
+ <delete dir="apidocs"/>
+ <delete file="../plugins/DX8/lib/controller.jar" />
+ </target>
+
+</project>
diff --git a/coreAPI/src/java/net/java/games/input/AbstractAxis.java b/coreAPI/src/java/net/java/games/input/AbstractAxis.java
new file mode 100644
index 0000000..b0fa021
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/AbstractAxis.java
@@ -0,0 +1,153 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * Skeleton implementation of a named axis.
+ */
+public abstract class AbstractAxis implements Axis {
+
+ /**
+ * Human-readable name for this Axis
+ */
+ protected String name;
+
+ /**
+ * Identifier for the axis
+ */
+ protected Identifier id;
+
+ /**
+ * Whether this axis is ready to receive polling data
+ */
+ private boolean polling;
+
+ /**
+ * Protected constructor
+ * @param name A name for the axis
+ */
+ protected AbstractAxis(String name, Identifier id) {
+ this.name = name;
+ this.id = id;
+ this.polling = true;
+ }
+
+ /**
+ * Returns the type or identifier of the axis.
+ */
+ public Identifier getIdentifier() {
+ return id;
+ }
+
+ /**
+ * Returns whether or not the axis is analog, or false if it is digital.
+ * @return false by default, can be overridden
+ */
+ public boolean isAnalog() {
+ return false;
+ }
+
+ /**
+ * Returns whether or not data polled from this axis is normalized
+ * between the values of -1.0f and 1.0f.
+ * @return true by default, can be overridden
+ */
+ public boolean isNormalized() {
+ return true;
+ }
+
+ /**
+ * Returns whether or not this axis is ready to receive polling data.
+ * By default, an abstract axis is set to receive polling data.
+ */
+ public boolean isPolling() {
+ return polling;
+ }
+
+ /**
+ * Sets whether or not the axis should receive polling data.
+ */
+ public void setPolling(boolean polling) {
+ this.polling = polling;
+ }
+
+ /**
+ * Returns the suggested dead zone for this axis. Dead zone is the
+ * amount polled data can vary before considered a significant change
+ * in value. An application can safely ignore changes less than this
+ * value in the positive or negative direction.
+ * @return 0.0f by default, can be overridden
+ */
+ public float getDeadZone() {
+ return 0.0f;
+ }
+
+ /**
+ * Returns the data from the last time the control has been polled.
+ * If this axis is a button, the value returned will be either 0.0f or 1.0f.
+ * If this axis is normalized, the value returned will be between -1.0f and
+ * 1.0f.
+ * @return 0.0f by default, can be overridden
+ */
+ public float getPollData() {
+ return 0.0f;
+ }
+
+ /**
+ * Returns a human-readable name for this axis.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns a non-localized string description of this axis.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Changes the name of this Axis. This should be done only during
+ * initialization of the axis so that its name remains immutable.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+} // AbstractAxis
diff --git a/coreAPI/src/java/net/java/games/input/AbstractController.java b/coreAPI/src/java/net/java/games/input/AbstractController.java
new file mode 100644
index 0000000..99ee2da
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/AbstractController.java
@@ -0,0 +1,194 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * An AbstractController is a skeleton implementation of a controller that
+ * contains a fixed number of axes, controllers, and rumblers.
+ */
+public abstract class AbstractController implements Controller {
+
+ /**
+ * Null array representing no axes
+ */
+ protected static final Axis[] NO_AXES = {};
+
+ /**
+ * Null array representing no child controllers
+ */
+ protected static final Controller[] NO_CONTROLLERS = {};
+
+ /**
+ * Null array representing no rumblers
+ */
+ protected static final Rumbler[] NO_RUMBLERS = {};
+
+ /**
+ * Human-readable name for this Controller
+ */
+ private final String name;
+
+ /**
+ * Array of axes
+ */
+ protected Axis[] axes;
+
+ /**
+ * Array of child controllers
+ */
+ protected Controller[] children;
+
+ /**
+ * Array of rumblers
+ */
+ protected Rumbler[] rumblers;
+
+ /**
+ * Protected constructor for a controller; initially contains no axes,
+ * child controllers, or rumblers.
+ * @param name The name for the controller
+ */
+ protected AbstractController(String name) {
+ this(name, NO_AXES, NO_CONTROLLERS, NO_RUMBLERS);
+ }
+
+ /**
+ * Protected constructor for a controller containing the specified
+ * axes, child controllers, and rumblers
+ * @param name name for the controller
+ * @param axes axes for the controller
+ * @param children child controllers for the controller
+ * @param rumblers rumblers for the controller
+ */
+ protected AbstractController(String name, Axis[] axes,
+ Controller[] children, Rumbler[] rumblers) {
+ this.name = name;
+ this.axes = axes;
+ this.children = children;
+ this.rumblers = rumblers;
+ }
+
+ /**
+ * Returns the controllers connected to make up this controller, or
+ * an empty array if this controller contains no child controllers.
+ * The objects in the array are returned in order of assignment priority
+ * (primary stick, secondary buttons, etc.).
+ */
+ public Controller[] getControllers() {
+ return children;
+ }
+
+ /**
+ * Returns the axes on this controller, in order of assignment priority.
+ * For example, the button controller on a mouse returns an array containing
+ * the primary or leftmost mouse button, followed by the secondary or
+ * rightmost mouse button (if present), followed by the middle mouse button
+ * (if present).
+ * The array returned is an empty array if this controller contains no axes
+ * (such as a logical grouping of child controllers).
+ */
+ public Axis[] getAxes() {
+ return axes;
+ }
+
+ /**
+ * Returns a single axis based on its identifier, or null
+ * if no axis with the specified type could be found.
+ * By default, AbstractController calls getAxes in this method so that
+ * subclasses may lazily initialize the array of axes, if necessary.
+ */
+ public Axis getAxis(Axis.Identifier id) {
+ // Calls getAxes() so that subclasses may lazily set the array of axes.
+ Axis[] axes = getAxes();
+ if (axes.length == 0) {
+ return null;
+ }
+ for (int i = 0; i < axes.length; i++) {
+ if (axes[i].getIdentifier() == id) {
+ return axes[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the rumblers for sending feedback to this controller, or an
+ * empty array if there are no rumblers on this controller.
+ */
+ public Rumbler[] getRumblers() {
+ return rumblers;
+ }
+
+ /**
+ * Returns the port type for this Controller.
+ * @return PortType.UNKNOWN by default, can be overridden
+ */
+ public PortType getPortType() {
+ return PortType.UNKNOWN;
+ }
+
+ /**
+ * Returns the zero-based port number for this Controller.
+ * @return 0 by default, can be overridden
+ */
+ public int getPortNumber() {
+ return 0;
+ }
+
+ /**
+ * Returns a human-readable name for this Controller.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns a non-localized string description of this controller.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /** Returns the type of the Controller.
+ */
+ public Type getType() {
+ return Type.UNKNOWN;
+ }
+
+} // class AbstractController
diff --git a/coreAPI/src/java/net/java/games/input/Axis.java b/coreAPI/src/java/net/java/games/input/Axis.java
new file mode 100644
index 0000000..a4abced
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/Axis.java
@@ -0,0 +1,349 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * An axis is a single button, slider, or dial, which has a single range. An
+ * axis can hold information for motion (linear or rotational), velocity,
+ * force, or acceleration.
+ */
+public interface Axis {
+
+ /**
+ * Returns the identifier of the axis.
+ */
+ public abstract Identifier getIdentifier();
+
+ /**
+ * Returns <code>true</code> if data returned from <code>poll</code>
+ * is relative to the last call, or <code>false</code> if data
+ * is absolute.
+ */
+ public abstract boolean isRelative();
+
+ /**
+ * Returns whether or not the axis is analog, or false if it is digital.
+ */
+ public abstract boolean isAnalog();
+
+ /**
+ * Returns whether or not data polled from this axis is normalized
+ * between the values of -1.0f and 1.0f.
+ * @see #getPollData
+ */
+ public abstract boolean isNormalized();
+
+ /**
+ * Returns whether or not this axis is ready to receive polling data.
+ * @see #getPollData
+ * @see Controller#poll
+ * @see #setPolling
+ */
+ public abstract boolean isPolling();
+
+ /**
+ * Sets whether or not the axis should receive polling data.
+ * @see #getPollData
+ * @see Controller#poll
+ * @see #isPolling
+ */
+ public abstract void setPolling(boolean polling);
+
+ /**
+ * Returns the suggested dead zone for this axis. Dead zone is the
+ * amount polled data can vary before considered a significant change
+ * in value. An application can safely ignore changes less than this
+ * value in the positive or negative direction.
+ * @see #getPollData
+ */
+ public abstract float getDeadZone();
+
+ /**
+ * Returns the data from the last time the control has been polled.
+ * If this axis is a button, the value returned will be either 0.0f or 1.0f.
+ * If this axis is normalized, the value returned will be between -1.0f and
+ * 1.0f.
+ * @see Controller#poll
+ */
+ public abstract float getPollData();
+
+ /**
+ * Returns a human-readable name for this axis.
+ */
+ public abstract String getName();
+
+ /**
+ * Identifiers for different Axes.
+ */
+ public static class Identifier {
+
+ /**
+ * Name of axis type
+ */
+ private final String name;
+
+ /**
+ * Protected constructor
+ */
+ protected Identifier(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns a non-localized string description of this axis type.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns a non-localized string description of this axis type.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * An axis for specifying vertical data.
+ */
+ public static final Identifier X = new Identifier("x");
+
+ /**
+ * An axis for specifying horizontal data.
+ */
+ public static final Identifier Y = new Identifier("y");
+
+ /**
+ * An axis for specifying third dimensional up/down
+ * data, or linear data in any direction that is
+ * neither horizontal nor vertical.
+ */
+ public static final Identifier Z = new Identifier("z");
+
+ /**
+ * An axis for specifying left-right rotational data.
+ */
+ public static final Identifier RX = new Identifier("rx");
+
+ /**
+ * An axis for specifying forward-back rotational data.
+ */
+ public static final Identifier RY = new Identifier("ry");
+
+ /**
+ * An axis for specifying up-down rotational data
+ * (rudder control).
+ */
+ public static final Identifier RZ = new Identifier("rz");
+
+ /**
+ * An axis for a button or key.
+ */
+ public static final Identifier BUTTON = new Identifier("button");
+
+ /**
+ * An axis for a slider or mouse wheel.
+ */
+ public static final Identifier SLIDER = new Identifier("slider");
+
+ /**
+ * An axis for a point-of-view control.
+ */
+ public static final Identifier POV = new Identifier("pov");
+
+ /**
+ * An axis for specifying vertical velocity data.
+ */
+ public static final Identifier X_VELOCITY =
+ new Identifier("x-velocity");
+
+ /**
+ * An axis for specifying horizontal velocity data.
+ */
+ public static final Identifier Y_VELOCITY =
+ new Identifier("y-velocity");
+
+ /**
+ * An axis for specifying third dimensional up/down velocity
+ * data.
+ */
+ public static final Identifier Z_VELOCITY =
+ new Identifier("z-velocity");
+
+ /**
+ * An axis for specifying left-right angular velocity data.
+ */
+ public static final Identifier RX_VELOCITY =
+ new Identifier("rx-velocity");
+
+ /**
+ * An axis for specifying forward-back angular velocity data.
+ */
+ public static final Identifier RY_VELOCITY =
+ new Identifier("ry-velocity");
+
+ /**
+ * An axis for specifying up-down angular velocity data.
+ */
+ public static final Identifier RZ_VELOCITY =
+ new Identifier("rz-velocity");
+
+ /**
+ * An axis for slider or mouse wheel velocity data.
+ */
+ public static final Identifier SLIDER_VELOCITY =
+ new Identifier("slider-velocity");
+
+ /**
+ * An axis for specifying vertical acceleration data.
+ */
+ public static final Identifier X_ACCELERATION =
+ new Identifier("x-acceleration");
+
+ /**
+ * An axis for specifying horizontal acceleration data.
+ */
+ public static final Identifier Y_ACCELERATION =
+ new Identifier("y-acceleration");
+
+ /**
+ * An axis for specifying third dimensional up/down acceleration
+ * data.
+ */
+ public static final Identifier Z_ACCELERATION =
+ new Identifier("z-acceleration");
+
+ /**
+ * An axis for specifying left-right angular acceleration data.
+ */
+ public static final Identifier RX_ACCELERATION =
+ new Identifier("rx-acceleration");
+
+ /**
+ * An axis for specifying forward-back angular acceleration data.
+ */
+ public static final Identifier RY_ACCELERATION =
+ new Identifier("ry-acceleration");
+
+ /**
+ * An axis for specifying up-down angular acceleration data.
+ */
+ public static final Identifier RZ_ACCELERATION =
+ new Identifier("rz-acceleration");
+
+ /**
+ * An axis for slider or mouse wheel acceleration data.
+ */
+ public static final Identifier SLIDER_ACCELERATION =
+ new Identifier("slider-acceleration");
+
+ /**
+ * An axis for specifying vertical force data.
+ */
+ public static final Identifier X_FORCE =
+ new Identifier("x-force");
+
+ /**
+ * An axis for specifying horizontal force data.
+ */
+ public static final Identifier Y_FORCE =
+ new Identifier("y-force");
+
+ /**
+ * An axis for specifying third dimensional up/down force
+ * data.
+ */
+ public static final Identifier Z_FORCE =
+ new Identifier("z-force");
+
+ /**
+ * An axis for specifying left-right angular force (torque) data.
+ */
+ public static final Identifier RX_FORCE =
+ new Identifier("rx-force");
+
+ /**
+ * An axis for specifying forward-back angular force (torque) data.
+ */
+ public static final Identifier RY_FORCE =
+ new Identifier("ry-force");
+
+ /**
+ * An axis for specifying up-down angular force (torque) data.
+ */
+ public static final Identifier RZ_FORCE =
+ new Identifier("rz-force");
+
+ /**
+ * An axis for slider force data.
+ */
+ public static final Identifier SLIDER_FORCE =
+ new Identifier("slider-force");
+ } // class Axis.Identifier
+
+ /**
+ * POV enum for different positions.
+ */
+ public static class POV {
+ /**
+ * Standard value for center HAT position
+ */
+ public static final float OFF = 0.0f;
+ /**
+ * Synonmous with OFF
+ */
+ public static final float CENTER = OFF;
+ /**
+ * Standard value for up HAT position
+ */
+ public static final float UP = 0.25f;
+ /**
+ * Standard value for right HAT position
+ */
+ public static final float RIGHT = 0.50f;
+ /**
+ * Standard value for down HAT position
+ */
+ public static final float DOWN = 0.75f;
+ /**
+ * Standard value for left HAT position
+ */
+ public static final float LEFT = 1.0f;
+ } // class Axis.POV
+} // interface Axis
diff --git a/coreAPI/src/java/net/java/games/input/Controller.java b/coreAPI/src/java/net/java/games/input/Controller.java
new file mode 100644
index 0000000..ebf12ee
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/Controller.java
@@ -0,0 +1,253 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * A Controller represents a physical device, such as a keyboard, mouse,
+ * or joystick, or a logical grouping of related controls, such as a button
+ * pad or mouse ball. A controller can be composed of multiple controllers.
+ * For example, the ball of a mouse and its buttons are two separate
+ * controllers.
+ */
+public interface Controller {
+
+ /**
+ * Returns the controllers connected to make up this controller, or
+ * an empty array if this controller contains no child controllers.
+ * The objects in the array are returned in order of assignment priority
+ * (primary stick, secondary buttons, etc.).
+ */
+ public abstract Controller[] getControllers();
+
+ /**
+ * Returns the type of the Controller.
+ */
+ public abstract Type getType();
+
+ /**
+ * Returns the axes on this controller, in order of assignment priority.
+ * For example, the button controller on a mouse returns an array containing
+ * the primary or leftmost mouse button, followed by the secondary or
+ * rightmost mouse button (if present), followed by the middle mouse button
+ * (if present).
+ * The array returned is an empty array if this controller contains no axes
+ * (such as a logical grouping of child controllers).
+ */
+ public abstract Axis[] getAxes();
+
+ /**
+ * Returns a single axis based on its type, or null
+ * if no axis with the specified type could be found.
+ */
+ public abstract Axis getAxis(Axis.Identifier id);
+
+ /**
+ * Returns the rumblers for sending feedback to this controller, or an
+ * empty array if there are no rumblers on this controller.
+ */
+ public abstract Rumbler[] getRumblers();
+
+ /**
+ * Polls axes for data. Returns false if the controller is no longer valid.
+ * Polling reflects the current state of the device when polled.
+ */
+ public abstract boolean poll();
+
+ /**
+ * Returns the port type for this Controller.
+ */
+ public abstract PortType getPortType();
+
+ /**
+ * Returns the zero-based port number for this Controller.
+ */
+ public abstract int getPortNumber();
+
+ /**
+ * Returns a human-readable name for this Controller.
+ */
+ public abstract String getName();
+
+ /**
+ * Types of controller objects.
+ */
+ public static class Type {
+
+ /**
+ * Name of controller type
+ */
+ private final String name;
+
+ /**
+ * Protected constructor
+ */
+ protected Type(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns a non-localized string description of this controller type.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Mouse controller.
+ */
+ public static final Type UNKNOWN = new Type("unknown");
+
+ /**
+ * Mouse controller.
+ */
+ public static final Type MOUSE = new Type("mouse");
+
+ /**
+ * A mouse ball or the ball part of a trackball controller.
+ * Note that a mouse wheel is considered part of a ball controller.
+ */
+ public static final Type BALL = new Type("ball");
+
+ /**
+ * A group of buttons on a pad (mouse buttons, for
+ * example) or a keyboard.
+ */
+ public static final Type BUTTONS = new Type("buttons");
+ /**
+ * A keyboard controller (same as BUTTONS)
+ * @see #BUTTONS
+ */
+ public static final Type KEYBOARD = BUTTONS;
+
+ /**
+ * Fingerstick controller; note that this may be sometimes treated as a
+ * type of mouse or stick.
+ */
+ public static final Type FINGERSTICK = new Type("fingerstick");
+
+ /**
+ * Gamepad controller.
+ */
+ public static final Type GAMEPAD = new Type("gamepad");
+
+ /**
+ * Headtracker controller.
+ */
+ public static final Type HEADTRACKER = new Type("headtracker");
+
+ /**
+ * Rudder controller.
+ */
+ public static final Type RUDDER = new Type("rudder");
+
+ /**
+ * Stick controller, such as a joystick or flightstick.
+ */
+ public static final Type STICK = new Type("stick");
+
+ /**
+ * A trackball controller; note that this may sometimes be treated as a
+ * type of mouse.
+ */
+ public static final Type TRACKBALL = new Type("trackball");
+
+ /**
+ * A trackpad, such as a tablet, touchpad, or glidepad;
+ * note that this may sometimes be treated as a type of mouse.
+ */
+ public static final Type TRACKPAD = new Type("trackpad");
+
+ /**
+ * A wheel controller, such as a steering wheel (note
+ * that a mouse wheel is considered part of a ball control, not a
+ * wheel controller).
+ */
+ public static final Type WHEEL = new Type("wheel");
+ } // class Controller.Type
+
+ /**
+ * Common controller port types.
+ */
+ public static final class PortType {
+
+ /**
+ * Name of port type
+ */
+ private final String name;
+
+ /**
+ * Protected constructor
+ */
+ protected PortType(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns a non-localized string description of this port type.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Unknown port type
+ */
+ public static final PortType UNKNOWN = new PortType("Unknown");
+
+ /**
+ * USB port
+ */
+ public static final PortType USB = new PortType("USB port");
+
+ /**
+ * Standard game port
+ */
+ public static final PortType GAME = new PortType("Game port");
+
+ /**
+ * Network port
+ */
+ public static final PortType NETWORK = new PortType("Network port");
+
+ /**
+ * Serial port
+ */
+ public static final PortType SERIAL = new PortType("Serial port");
+ } // class Controller.PortType
+} // interface Controller
diff --git a/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java b/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java
new file mode 100644
index 0000000..d58ed4e
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/ControllerEnvironment.java
@@ -0,0 +1,140 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * A ControllerEnvironment represents a collection of controllers that are
+ * physically or logically linked. By default, this corresponds to the
+ * environment for the local machine.
+ * <p>
+ * In this reference implementation, this class can also be used to register
+ * controllers with the default environment as "plug-ins". A plug-in is
+ * created by subclassing ControllerEnvironment with a class that has a public
+ * no-argument constructor, implements the org.java.games.util.plugins.Plugin
+ * interface and has a name ending in "Plugin".
+ * (See org.java.games.input.DirectInputEnvironmentPlugin in the DXplugin
+ * part of the source tree for an example.)
+ *
+ * When the DefaultControllerEnvrionment is instanced it uses the plugin library
+ * to look for Plugins in both [java.home]/lib/controller and
+ * [user.dir]/controller. This allows controller plugins to be installed either
+ * globally for the entire Java environment or locally for just one particular
+ * Java app.
+ *
+ * For more information on the organization of plugins within the controller
+ * root directories, see org.java.games.util.plugins.Plugins (Note the
+ * plural -- "Plugins" not "Plugin" which is just a marker interface.)
+ *
+ */
+public abstract class ControllerEnvironment {
+
+ /**
+ * The default controller environment
+ */
+ private static ControllerEnvironment defaultEnvironment =
+ new DefaultControllerEnvironment();
+
+ /**
+ * List of controller listeners
+ */
+ protected final ArrayList controllerListeners = new ArrayList();
+
+ /**
+ * Protected constructor for subclassing.
+ */
+ protected ControllerEnvironment() {
+ }
+
+ /**
+ * Returns a list of all controllers available to this environment,
+ * or an empty array if there are no controllers in this environment.
+ */
+ public abstract Controller[] getControllers();
+
+ /**
+ * Adds a listener for controller state change events.
+ */
+ public void addControllerListener(ControllerListener l) {
+ assert l != null;
+ controllerListeners.add(l);
+ }
+
+ /**
+ * Removes a listener for controller state change events.
+ */
+ public void removeControllerListener(ControllerListener l) {
+ assert l != null;
+ controllerListeners.remove(l);
+ }
+
+ /**
+ * Creates and sends an event to the controller listeners that a controller
+ * has been added.
+ */
+ protected void fireControllerAdded(Controller c) {
+ ControllerEvent ev = new ControllerEvent(c);
+ Iterator it = controllerListeners.iterator();
+ while (it.hasNext()) {
+ ((ControllerListener)it.next()).controllerAdded(ev);
+ }
+ }
+
+ /**
+ * Creates and sends an event to the controller listeners that a controller
+ * has been lost.
+ */
+ protected void fireControllerRemoved(Controller c) {
+ ControllerEvent ev = new ControllerEvent(c);
+ Iterator it = controllerListeners.iterator();
+ while (it.hasNext()) {
+ ((ControllerListener)it.next()).controllerRemoved(ev);
+ }
+ }
+
+ /**
+ * Returns the default environment for input controllers.
+ * This usually corresponds to the environment for the local machine.
+ */
+ public static ControllerEnvironment getDefaultEnvironment() {
+ return defaultEnvironment;
+ }
+} // ControllerEnvironment
diff --git a/coreAPI/src/java/net/java/games/input/ControllerEvent.java b/coreAPI/src/java/net/java/games/input/ControllerEvent.java
new file mode 100644
index 0000000..14fbbcd
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/ControllerEvent.java
@@ -0,0 +1,61 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * An event that is fired when the state of a controller changes
+ */
+public class ControllerEvent {
+
+ private Controller controller;
+
+ /**
+ * Creates a controller event object.
+ */
+ public ControllerEvent(Controller c) {
+ controller = c;
+ }
+
+ /**
+ * Returns the controller for this event.
+ */
+ public Controller getController() {
+ return controller;
+ }
+} // class ControllerEvent
diff --git a/coreAPI/src/java/net/java/games/input/ControllerListener.java b/coreAPI/src/java/net/java/games/input/ControllerListener.java
new file mode 100644
index 0000000..8c58eff
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/ControllerListener.java
@@ -0,0 +1,55 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * A listener for changes in the state of controllers
+ */
+public interface ControllerListener {
+
+ /**
+ * Invoked when a controller is lost.
+ */
+ public abstract void controllerRemoved(ControllerEvent ev);
+
+ /**
+ * Invoked when a controller has been added.
+ */
+ public abstract void controllerAdded(ControllerEvent ev);
+} // interface ControllerListener
diff --git a/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java b/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java
new file mode 100644
index 0000000..e72aeae
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/DefaultControllerEnvironment.java
@@ -0,0 +1,232 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+import net.java.games.util.plugins.*;
+
+/**
+ * The default controller environment.
+ *
+ * @version %I% %G%
+ * @author Michael Martak
+ */
+class DefaultControllerEnvironment extends ControllerEnvironment {
+ static final boolean DEBUG =false;
+ /**
+ * The name of the properties file to find plugins.
+ */
+ private final static String PROPERTY_FILENAME =
+ "controller.properties";
+
+ /**
+ * The name of the property for identifying a plugin (used
+ * as the value, the key being the class name).
+ */
+ private final static String ID_PLUGIN =
+ "ControllerEnvironment";
+
+ /**
+ * Location of the LIB directory.
+ */
+ static String libPath;
+
+ /**
+ * List of all controllers in this environment
+ */
+ private ArrayList controllers;
+
+ /**
+ * Plug-in properties.
+ */
+ private Properties properties = new Properties();
+
+ /**
+ * Plug-in class loader.
+ */
+ private PluginClassLoader pluginLoader = new PluginClassLoader();
+
+ /**
+ * Public no-arg constructor.
+ */
+ public DefaultControllerEnvironment() {
+ }
+
+ /**
+ * Returns a list of all controllers available to this environment,
+ * or an empty array if there are no controllers in this environment.
+ */
+ public Controller[] getControllers() {
+ if (controllers == null) {
+ // Controller list has not been scanned.
+ controllers = new ArrayList();
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ scanControllers();
+ return DefaultControllerEnvironment.this;
+ }
+ });
+ }
+ Controller[] ret = new Controller[controllers.size()];
+ Iterator it = controllers.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ ret[i] = (Controller)it.next();
+ i++;
+ }
+ return ret;
+ }
+
+ /**
+ * Scans for controllers, placing them in the controllers list.
+ */
+ /* This is Mike's old plugin code.
+ private void scanControllers() {
+ // Load properties object.
+ try {
+ loadProperties();
+ } catch (IOException e) {
+ // Could not find or read file, simply return.
+ return;
+ }
+ // Create a list of ControllerEnvironment classes.
+ // For each ControllerEnvironment, locate the class
+ // using the plugin class loader.
+ Iterator it = properties.keySet().iterator();
+ while (it.hasNext()) {
+ Object key = it.next();
+ assert key != null;
+ Object value = properties.get(key);
+ assert value != null;
+ if (value.equals(ID_PLUGIN)) {
+ try {
+ ControllerEnvironment plugin =
+ newPlugin(key.toString());
+ addControllers(plugin.getControllers());
+ } catch (Throwable t) {
+ System.err.println(
+ "Warning : could not load plugin " +
+ key.toString() + ", received exeption " +
+ t.toString());
+ t.printStackTrace(System.err);
+ }
+ }
+ }
+ }*/
+
+ /* This is jeff's new plugin code using Jeff's Plugin manager */
+ private void scanControllers() {
+ scanControllersAt(System.getProperty("java.home") +
+ File.separator + "lib"+File.separator+"controller");
+ scanControllersAt(System.getProperty("user.dir")+
+ File.separator+ "controller");
+ }
+
+ private void scanControllersAt(String path) {
+ try {
+ Plugins plugins = new Plugins(new File(path));
+ Class[] envClasses = plugins.getExtends(ControllerEnvironment.class);
+ for(int i=0;i<envClasses.length;i++){
+ try {
+ if (DEBUG) {
+ System.out.println("ControllerEnvironment "+
+ envClasses[i].getName()
+ +" loaded by "+envClasses[i].getClassLoader());
+ }
+ ControllerEnvironment ce = (ControllerEnvironment)
+ envClasses[i].newInstance();
+ addControllers(ce.getControllers());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Retrieve the file "lib/control.properties" and
+ * load properties into properties object.
+ */
+ private void loadProperties() throws IOException {
+ if (libPath == null) {
+ libPath = System.getProperty("java.home") +
+ File.separator + "lib";
+ }
+ File file = new File(libPath + File.separator +
+ PROPERTY_FILENAME);
+ FileInputStream inputStream = new FileInputStream(file);
+ properties.load(inputStream);
+ inputStream.close();
+ }
+
+ /**
+ * Create a new plugin ControllerEnvironment object
+ */
+ /*
+ private ControllerEnvironment newPlugin(String name) throws
+ ClassNotFoundException, InstantiationException,
+ IllegalAccessException {
+ Class pluginClass = pluginLoader.loadClass(name);
+ if (!ControllerEnvironment.class.isAssignableFrom(pluginClass)) {
+ throw new ClassCastException(
+ "Plugin class must be assignable from " +
+ ControllerEnvironment.class.getName());
+ }
+ Object instance = pluginClass.newInstance();
+ return (ControllerEnvironment)instance;
+ }
+ */
+ /**
+ * Add the array of controllers to our list of controllers.
+ */
+ private void addControllers(Controller[] c) {
+ for (int i = 0; i < c.length; i++) {
+ controllers.add(c[i]);
+ }
+ }
+}
diff --git a/coreAPI/src/java/net/java/games/input/Keyboard.java b/coreAPI/src/java/net/java/games/input/Keyboard.java
new file mode 100644
index 0000000..92361af
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/Keyboard.java
@@ -0,0 +1,168 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * A Keyboard is a type of controller consisting of a single controller,
+ * they keypad, which contains several axes (the keys). By default, all keys
+ * are set to receive polling data.
+ */
+public abstract class Keyboard extends AbstractController {
+
+ /**
+ * Protected constructor.
+ * Subclasses should initialize the array of axes to an array of keys.
+ * @param name The name of the keyboard
+ */
+ protected Keyboard(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns the type of the Controller.
+ */
+ public Type getType() {
+ return Type.KEYBOARD;
+ }
+
+ /**
+ * Returns the axis corresponding to a particular key on the keypad,
+ * or null if a key with the specified ID could not be found.
+ */
+ public Axis getAxis(Axis.Identifier id) {
+ assert axes != null;
+ // Default implementation uses indices to lookup keys
+ // in the array of axes
+ if (id instanceof KeyID) {
+ KeyID kid = (KeyID)id;
+ int index = kid.getKeyIndex();
+ assert axes.length > index;
+ return axes[index];
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether or not the given key has been pressed since the last
+ * call to poll. This is called from a key's getPollData method.
+ */
+ protected abstract boolean isKeyPressed(Key key);
+
+ /**
+ * Axis representing a single key. By default, all keys are set to receive
+ * polling data.
+ */
+ public class Key extends AbstractAxis {
+
+ /**
+ * Key identifier
+ */
+ private final KeyID keyID;
+
+ /**
+ * Construct a new key object
+ */
+ public Key(KeyID keyID) {
+ super(keyID.toString(), keyID);
+ this.keyID = keyID;
+ }
+
+ /**
+ * Returns <code>true</code> if data returned from <code>poll</code>
+ * is relative to the last call, or <code>false</code> if data
+ * is absolute.
+ * @return false by default, can be overridden
+ */
+ public final boolean isRelative() {
+ return false;
+ }
+
+ /**
+ * Returns the data from the last time the control has been polled.
+ * The value returned will be either 0.0f or 1.0f. The result is always
+ * 0.0f if polling is turned off.
+ */
+ public float getPollData() {
+ if (!isPolling()) {
+ return 0.0f;
+ }
+ return (isKeyPressed(this) ? 1.0f : 0.0f);
+ }
+ } // class Keyboard.Key
+
+ /**
+ * Identifiers for physical keys.
+ */
+ public static class KeyID extends Axis.Identifier {
+
+ /**
+ * Key string
+ */
+ private static final String NAME_KEY = "key";
+
+ /**
+ * Index in the array of axes supplied to the keyboard contructor for
+ * this key.
+ */
+ protected final int keyIndex;
+
+ /**
+ * Protected constructor
+ * @param keyIndex the index for looking up the key in the array of axes
+ */
+ protected KeyID(int keyIndex) {
+ super(NAME_KEY);
+ this.keyIndex = keyIndex;
+ }
+
+ /**
+ * The index for this key for looking up the in the array of axes.
+ */
+ public int getKeyIndex() {
+ return keyIndex;
+ }
+
+ /**
+ * Returns a non-localized string description of this control type.
+ */
+ public String toString() {
+ return super.toString() + " " + Integer.toString(keyIndex);
+ }
+ } // class Keyboard.KeyID
+} // class Keyboard
diff --git a/coreAPI/src/java/net/java/games/input/Mouse.java b/coreAPI/src/java/net/java/games/input/Mouse.java
new file mode 100644
index 0000000..6029834
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/Mouse.java
@@ -0,0 +1,315 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * A Mouse is a type of controller consisting of two child controllers,
+ * a ball and a button pad. This includes devices such as touch pads,
+ * trackballs, and fingersticks.
+ */
+public abstract class Mouse extends AbstractController {
+
+ /**
+ * Mouse ball; should be initialized by subclasses
+ */
+ protected Ball ball;
+
+ /**
+ * Mouse buttons; should be initialized by subclasses
+ */
+ protected Buttons buttons;
+
+ /**
+ * Protected constructor;
+ * Subclasses should initialize the ball and buttons
+ */
+ protected Mouse(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns the controllers connected to make up this controller, or
+ * an empty array if this controller contains no child controllers.
+ * The objects in the array are returned in order of assignment priority
+ * (primary stick, secondary buttons, etc.).
+ */
+ public Controller[] getControllers() {
+ if (children.length == 0 && ball != null && buttons != null) {
+ children = new Controller[] { ball, buttons };
+ }
+ return children;
+ }
+
+ /**
+ * Returns the control for the ball of the mouse, never null.
+ */
+ public Ball getBall() {
+ return ball;
+ }
+
+ /**
+ * Returns the control for the buttons of the mouse, never null.
+ */
+ public Buttons getButtons() {
+ return buttons;
+ }
+
+ /**
+ * Returns the type of the Controller.
+ */
+ public Type getType() {
+ return Type.MOUSE;
+ }
+
+ /**
+ * Mouse ball controller
+ */
+ public abstract class Ball extends AbstractController {
+
+ /**
+ * X-axis; should be initialized by subclasses
+ */
+ protected Axis x;
+
+ /**
+ * Y-axis; should be initialized by subclasses
+ */
+ protected Axis y;
+
+ /**
+ * Mouse wheel; should be initialized by subclasses
+ */
+ protected Axis wheel;
+
+ /**
+ * Protected constructor
+ */
+ protected Ball(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns the type of Controller.
+ */
+ public Type getType() {
+ return Type.BALL;
+ }
+
+ /**
+ * Returns the x-axis for the mouse ball, never null.
+ */
+ public Axis getX() {
+ return x;
+ }
+
+ /**
+ * Returns the y-axis for the mouse ball, never null.
+ */
+ public Axis getY() {
+ return y;
+ }
+
+ /**
+ * Returns the mouse wheel, or null if no mouse wheel is present.
+ */
+ public Axis getWheel() {
+ return wheel;
+ }
+
+ /**
+ * Returns the axes on this controller, in order of assignment priority.
+ * Overridden to return the x-axis, followed by the y-axes, followed by
+ * the wheel (if present).
+ * The array returned is an empty array if this controller contains no
+ * axes (such as a logical grouping of child controllers).
+ */
+ public Axis[] getAxes() {
+ if (axes.length == 0 && x != null && y != null) {
+ if (wheel == null) {
+ axes = new Axis[] { x, y };
+ } else {
+ axes = new Axis[] { x, y, wheel };
+ }
+ }
+ return axes;
+ }
+
+ /**
+ * Polls axes for data. Returns false if the controller is no longer
+ * valid. Polling reflects the current state of the device when polled.
+ * By default, polling a mouse ball or button polls the entire mouse
+ * control.
+ */
+ public boolean poll() {
+ return Mouse.this.poll();
+ }
+ } // class Mouse.Ball
+
+ /**
+ * Mouse buttons controller
+ */
+ public abstract class Buttons extends AbstractController {
+
+ /**
+ * Left button; should be initialized by subclasses
+ */
+ protected Button left;
+
+ /**
+ * Right button; should be initialized by subclasses
+ */
+ protected Button right;
+
+ /**
+ * Middle button; should be initialized by subclasses
+ */
+ protected Button middle;
+
+ /**
+ * Protected constructor
+ */
+ protected Buttons(String name) {
+ super(name);
+ }
+
+ /**
+ * Returns the type or identifier of the Controller.
+ */
+ public Type getType() {
+ return Type.BUTTONS;
+ }
+
+ /**
+ * Returns the left or primary mouse button, never null.
+ */
+ public Button getLeft() {
+ return left;
+ }
+
+ /**
+ * Returns the right or secondary mouse button, null if the mouse is
+ * a single-button mouse.
+ */
+ public Button getRight() {
+ return right;
+ }
+
+ /**
+ * Returns the middle or tertiary mouse button, null if the mouse has
+ * fewer than three buttons.
+ */
+ public Button getMiddle() {
+ return middle;
+ }
+
+ /**
+ * Returns the axes on this controller, in order of assignment priority.
+ * Overridden to return the the primary or leftmost mouse button,
+ * followed by the secondary or rightmost mouse button (if present),
+ * followed by the middle mouse button (if present).
+ * The array returned is an empty array if this controller contains no
+ * axes (such as a logical grouping of child controllers).
+ */
+ public Axis[] getAxes() {
+ if (axes.length == 0 && left != null) {
+ if (right == null) {
+ axes = new Axis[] { left };
+ } else if (middle == null) {
+ axes = new Axis[] { left, right };
+ } else {
+ axes = new Axis[] { left, right, middle };
+ }
+ }
+ return axes;
+ }
+
+ /**
+ * Polls axes for data. Returns false if the controller is no longer
+ * valid. Polling reflects the current state of the device when polled.
+ * By default, polling a mouse ball or button polls the entire mouse
+ * control.
+ */
+ public boolean poll() {
+ return Mouse.this.poll();
+ }
+ } // class Mouse.Buttons
+
+ /**
+ * Mouse button axis
+ */
+ public abstract class Button extends AbstractAxis {
+
+ /**
+ * Protected constructor
+ */
+ protected Button(String name, ButtonID id) {
+ super(name, id);
+ }
+ } // class Mouse.Button
+
+ /**
+ * Identifier for types of mouse buttons
+ */
+ public static class ButtonID extends Axis.Identifier {
+
+ /**
+ * Protected constructor
+ */
+ protected ButtonID(String name) {
+ super(name);
+ }
+
+ /**
+ * The primary or leftmost mouse button.
+ */
+ public static final ButtonID LEFT = new ButtonID("left");
+
+ /**
+ * The secondary or rightmost mouse button, not present if
+ * the mouse is a single-button mouse.
+ */
+ public static final ButtonID RIGHT = new ButtonID("right");
+
+ /**
+ * Returns the middle mouse button, not present if the
+ * mouse has fewer than three buttons.
+ */
+ public static final ButtonID MIDDLE = new ButtonID("middle");
+ } // class Mouse.ButtonID
+} // class Mouse
diff --git a/coreAPI/src/java/net/java/games/input/PluginClassLoader.java b/coreAPI/src/java/net/java/games/input/PluginClassLoader.java
new file mode 100644
index 0000000..13c580f
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/PluginClassLoader.java
@@ -0,0 +1,175 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Loads all plugins.
+ *
+ * @version %I% %G%
+ * @author Michael Martak
+ */
+class PluginClassLoader extends ClassLoader {
+
+ /**
+ * Location of directory to look for plugins
+ */
+ private static String pluginDirectory;
+
+ /**
+ * File filter for JAR files
+ */
+ private static final FileFilter JAR_FILTER = new JarFileFilter();
+
+ /**
+ * Create a new class loader for loading plugins
+ */
+ public PluginClassLoader() {
+ super(Thread.currentThread().getContextClassLoader());
+ }
+
+ /**
+ * Overrides findClass to first look in the parent class loader,
+ * then try loading the class from the plugin file system.
+ */
+ protected Class findClass(String name)
+ throws ClassNotFoundException {
+ // Try loading the class from the file system.
+ byte[] b = loadClassData(name);
+ return defineClass(name, b, 0, b.length);
+ }
+
+ /**
+ * Load the class data from the file system
+ */
+ private byte[] loadClassData(String name)
+ throws ClassNotFoundException {
+ if (pluginDirectory == null) {
+ pluginDirectory = DefaultControllerEnvironment.libPath +
+ File.separator + "controller";
+ }
+ try {
+ return loadClassFromDirectory(name);
+ } catch (Exception e) {
+ try {
+ return loadClassFromJAR(name);
+ } catch (IOException e2) {
+ throw new ClassNotFoundException(name, e2);
+ }
+ }
+ }
+
+ /**
+ * Load the class data from the file system based on parsing
+ * the class name (packages).
+ */
+ private byte[] loadClassFromDirectory(String name)
+ throws ClassNotFoundException, IOException {
+ // Parse the class name into package directories.
+ // Look for the class in the plugin directory.
+ StringTokenizer tokenizer = new StringTokenizer(name, ".");
+ StringBuffer path = new StringBuffer(pluginDirectory);
+ while (tokenizer.hasMoreTokens()) {
+ path.append(File.separator);
+ path.append(tokenizer.nextToken());
+ }
+ path.append(".class");
+ File file = new File(path.toString());
+ if (!file.exists()) {
+ throw new ClassNotFoundException(name);
+ }
+ FileInputStream fileInputStream = new FileInputStream(file);
+ assert file.length() <= Integer.MAX_VALUE;
+ int length = (int)file.length();
+ byte[] bytes = new byte[length];
+ int length2 = fileInputStream.read(bytes);
+ assert length == length2;
+ return bytes;
+ }
+
+ /**
+ * Scans through the plugin directory for JAR files and
+ * attempts to load the class data from each JAR file.
+ */
+ private byte[] loadClassFromJAR(String name)
+ throws ClassNotFoundException, IOException {
+ File dir = new File(pluginDirectory);
+ File[] jarFiles = dir.listFiles(JAR_FILTER);
+ if (jarFiles == null) {
+ throw new ClassNotFoundException("Could not find class " + name);
+ }
+ for (int i = 0; i < jarFiles.length; i++) {
+ JarFile jarfile = new JarFile(jarFiles[i]);
+ JarEntry jarentry = jarfile.getJarEntry(name + ".class");
+ if (jarentry != null) {
+ InputStream jarInputStream = jarfile.getInputStream(jarentry);
+ assert jarentry.getSize() <= Integer.MAX_VALUE;
+ int length = (int)jarentry.getSize();
+ assert length >= 0;
+ byte[] bytes = new byte[length];
+ int length2 = jarInputStream.read(bytes);
+ assert length == length2;
+ return bytes;
+ }
+ }
+ throw new FileNotFoundException(name);
+ }
+
+ /**
+ * Filters out all non-JAR files, based on whether or not they
+ * end in ".JAR" (case-insensitive).
+ */
+ private static class JarFileFilter implements FileFilter {
+ public boolean accept(File file) {
+ return file.getName().toUpperCase().endsWith(".JAR");
+ }
+ }
+}
+
diff --git a/coreAPI/src/java/net/java/games/input/Rumbler.java b/coreAPI/src/java/net/java/games/input/Rumbler.java
new file mode 100644
index 0000000..2d4c8b8
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/Rumbler.java
@@ -0,0 +1,52 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * A Rumbler is a controller's mechanism for delivering feedback
+ * to the user through the device.
+ */
+public interface Rumbler {
+
+ /**
+ * Rumble with the specified intensity.
+ */
+ public abstract void rumble(float intensity);
+
+} // interface Rumbler
diff --git a/coreAPI/src/java/net/java/games/input/StandardKeyboard.java b/coreAPI/src/java/net/java/games/input/StandardKeyboard.java
new file mode 100644
index 0000000..5dc891a
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/StandardKeyboard.java
@@ -0,0 +1,261 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+/**
+ * Identifiers for physical keys for standard PC (LATIN-1) keyboards.
+ */
+public abstract class StandardKeyboard extends Keyboard {
+
+ private Key[] standardKeys = {
+ new Key(KeyID.VOID ), new Key(KeyID.ESCAPE ),
+ new Key(KeyID._1 ), new Key(KeyID._2 ),
+ new Key(KeyID._3 ), new Key(KeyID._4 ),
+ new Key(KeyID._5 ), new Key(KeyID._6 ),
+ new Key(KeyID._7 ), new Key(KeyID._8 ),
+ new Key(KeyID._9 ), new Key(KeyID._0 ),
+ new Key(KeyID.MINUS ), new Key(KeyID.EQUALS ),
+ new Key(KeyID.BACK ), new Key(KeyID.TAB ),
+ new Key(KeyID.Q ), new Key(KeyID.W ),
+ new Key(KeyID.E ), new Key(KeyID.R ),
+ new Key(KeyID.T ), new Key(KeyID.Y ),
+ new Key(KeyID.U ), new Key(KeyID.I ),
+ new Key(KeyID.O ), new Key(KeyID.P ),
+ new Key(KeyID.LBRACKET ), new Key(KeyID.RBRACKET ),
+ new Key(KeyID.RETURN ), new Key(KeyID.LCONTROL ),
+ new Key(KeyID.A ), new Key(KeyID.S ),
+ new Key(KeyID.D ), new Key(KeyID.F ),
+ new Key(KeyID.G ), new Key(KeyID.H ),
+ new Key(KeyID.J ), new Key(KeyID.K ),
+ new Key(KeyID.L ), new Key(KeyID.SEMICOLON ),
+ new Key(KeyID.APOSTROPHE ), new Key(KeyID.GRAVE ),
+ new Key(KeyID.LSHIFT ), new Key(KeyID.BACKSLASH ),
+ new Key(KeyID.Z ), new Key(KeyID.X ),
+ new Key(KeyID.C ), new Key(KeyID.V ),
+ new Key(KeyID.B ), new Key(KeyID.N ),
+ new Key(KeyID.M ), new Key(KeyID.COMMA ),
+ new Key(KeyID.PERIOD ), new Key(KeyID.SLASH ),
+ new Key(KeyID.RSHIFT ), new Key(KeyID.MULTIPLY ),
+ new Key(KeyID.LALT ), new Key(KeyID.SPACE ),
+ new Key(KeyID.CAPITAL ), new Key(KeyID.F1 ),
+ new Key(KeyID.F2 ), new Key(KeyID.F3 ),
+ new Key(KeyID.F4 ), new Key(KeyID.F5 ),
+ new Key(KeyID.F6 ), new Key(KeyID.F7 ),
+ new Key(KeyID.F8 ), new Key(KeyID.F9 ),
+ new Key(KeyID.F10 ), new Key(KeyID.NUMLOCK ),
+ new Key(KeyID.SCROLL ), new Key(KeyID.NUMPAD7 ),
+ new Key(KeyID.NUMPAD8 ), new Key(KeyID.NUMPAD9 ),
+ new Key(KeyID.SUBTRACT ), new Key(KeyID.NUMPAD4 ),
+ new Key(KeyID.NUMPAD5 ), new Key(KeyID.NUMPAD6 ),
+ new Key(KeyID.ADD ), new Key(KeyID.NUMPAD1 ),
+ new Key(KeyID.NUMPAD2 ), new Key(KeyID.NUMPAD3 ),
+ new Key(KeyID.NUMPAD0 ), new Key(KeyID.DECIMAL ),
+ new Key(KeyID.F11 ), new Key(KeyID.F12 ),
+ new Key(KeyID.F13 ), new Key(KeyID.F14 ),
+ new Key(KeyID.F15 ), new Key(KeyID.KANA ),
+ new Key(KeyID.CONVERT ), new Key(KeyID.NOCONVERT ),
+ new Key(KeyID.YEN ), new Key(KeyID.NUMPADEQUAL),
+ new Key(KeyID.CIRCUMFLEX ), new Key(KeyID.AT ),
+ new Key(KeyID.COLON ), new Key(KeyID.UNDERLINE ),
+ new Key(KeyID.KANJI ), new Key(KeyID.STOP ),
+ new Key(KeyID.AX ), new Key(KeyID.UNLABELED ),
+ new Key(KeyID.NUMPADENTER), new Key(KeyID.RCONTROL ),
+ new Key(KeyID.NUMPADCOMMA), new Key(KeyID.DIVIDE ),
+ new Key(KeyID.SYSRQ ), new Key(KeyID.RALT ),
+ new Key(KeyID.PAUSE ), new Key(KeyID.HOME ),
+ new Key(KeyID.UP ), new Key(KeyID.PRIOR ),
+ new Key(KeyID.LEFT ), new Key(KeyID.RIGHT ),
+ new Key(KeyID.END ), new Key(KeyID.DOWN ),
+ new Key(KeyID.NEXT ), new Key(KeyID.INSERT ),
+ new Key(KeyID.DELETE ), new Key(KeyID.LWIN ),
+ new Key(KeyID.RWIN ), new Key(KeyID.APPS ),
+ new Key(KeyID.POWER ), new Key(KeyID.SLEEP ),
+ };
+
+ /**
+ * Creates a new standard keyboard object with the default keys
+ * for a standard keyboard.
+ */
+ protected StandardKeyboard(String name) {
+ super(name);
+ axes = standardKeys;
+ }
+
+ /**
+ * KeyIDs for standard PC (LATIN-1) keyboards
+ */
+ public static class KeyID extends Keyboard.KeyID {
+ /**
+ * Protected constructor
+ */
+ protected KeyID(int keyID) {
+ super(keyID);
+ }
+ /**
+ * Standard keyboard (LATIN-1) keys
+ * UNIX X11 keysym values are listed to the right
+ */
+ public static final KeyID VOID = new KeyID(0); // MS 0x00 UNIX 0xFFFFFF
+ public static final KeyID ESCAPE = new KeyID(1); // MS 0x01 UNIX 0xFF1B
+ public static final KeyID _1 = new KeyID(2); // MS 0x02 UNIX 0x031 EXCLAM 0x021
+ public static final KeyID _2 = new KeyID(3); // MS 0x03 UNIX 0x032 AT 0x040
+ public static final KeyID _3 = new KeyID(4); // MS 0x04 UNIX 0x033 NUMBERSIGN 0x023
+ public static final KeyID _4 = new KeyID(5); // MS 0x05 UNIX 0x034 DOLLAR 0x024
+ public static final KeyID _5 = new KeyID(6); // MS 0x06 UNIX 0x035 PERCENT 0x025
+ public static final KeyID _6 = new KeyID(7); // MS 0x07 UNIX 0x036 CIRCUMFLEX 0x05e
+ public static final KeyID _7 = new KeyID(8); // MS 0x08 UNIX 0x037 AMPERSAND 0x026
+ public static final KeyID _8 = new KeyID(9); // MS 0x09 UNIX 0x038 ASTERISK 0x02a
+ public static final KeyID _9 = new KeyID(10); // MS 0x0A UNIX 0x039 PARENLEFT 0x028
+ public static final KeyID _0 = new KeyID(11); // MS 0x0B UNIX 0x030 PARENRIGHT 0x029
+ public static final KeyID MINUS = new KeyID(12); // MS 0x0C UNIX 0x02d UNDERSCORE 0x05f
+ public static final KeyID EQUALS = new KeyID(13); // MS 0x0D UNIX 0x03d PLUS 0x02b
+ public static final KeyID BACK = new KeyID(14); // MS 0x0E UNIX 0xFF08
+ public static final KeyID TAB = new KeyID(15); // MS 0x0F UNIX 0xFF09
+ public static final KeyID Q = new KeyID(16); // MS 0x10 UNIX 0x071 UPPER 0x051
+ public static final KeyID W = new KeyID(17); // MS 0x11 UNIX 0x077 UPPER 0x057
+ public static final KeyID E = new KeyID(18); // MS 0x12 UNIX 0x065 UPPER 0x045
+ public static final KeyID R = new KeyID(19); // MS 0x13 UNIX 0x072 UPPER 0x052
+ public static final KeyID T = new KeyID(20); // MS 0x14 UNIX 0x074 UPPER 0x054
+ public static final KeyID Y = new KeyID(21); // MS 0x15 UNIX 0x079 UPPER 0x059
+ public static final KeyID U = new KeyID(22); // MS 0x16 UNIX 0x075 UPPER 0x055
+ public static final KeyID I = new KeyID(23); // MS 0x17 UNIX 0x069 UPPER 0x049
+ public static final KeyID O = new KeyID(24); // MS 0x18 UNIX 0x06F UPPER 0x04F
+ public static final KeyID P = new KeyID(25); // MS 0x19 UNIX 0x070 UPPER 0x050
+ public static final KeyID LBRACKET = new KeyID(26); // MS 0x1A UNIX 0x05b BRACE 0x07b
+ public static final KeyID RBRACKET = new KeyID(27); // MS 0x1B UNIX 0x05d BRACE 0x07d
+ public static final KeyID RETURN = new KeyID(28); // MS 0x1C UNIX 0xFF0D
+ public static final KeyID LCONTROL = new KeyID(29); // MS 0x1D UNIX 0xFFE3
+ public static final KeyID A = new KeyID(30); // MS 0x1E UNIX 0x061 UPPER 0x041
+ public static final KeyID S = new KeyID(31); // MS 0x1F UNIX 0x073 UPPER 0x053
+ public static final KeyID D = new KeyID(32); // MS 0x20 UNIX 0x064 UPPER 0x044
+ public static final KeyID F = new KeyID(33); // MS 0x21 UNIX 0x066 UPPER 0x046
+ public static final KeyID G = new KeyID(34); // MS 0x22 UNIX 0x067 UPPER 0x047
+ public static final KeyID H = new KeyID(35); // MS 0x23 UNIX 0x068 UPPER 0x048
+ public static final KeyID J = new KeyID(36); // MS 0x24 UNIX 0x06A UPPER 0x04A
+ public static final KeyID K = new KeyID(37); // MS 0x25 UNIX 0x06B UPPER 0x04B
+ public static final KeyID L = new KeyID(38); // MS 0x26 UNIX 0x06C UPPER 0x04C
+ public static final KeyID SEMICOLON = new KeyID(39); // MS 0x27 UNIX 0x03b COLON 0x03a
+ public static final KeyID APOSTROPHE = new KeyID(40); // MS 0x28 UNIX 0x027 QUOTEDBL 0x022
+ public static final KeyID GRAVE = new KeyID(41); // MS 0x29 UNIX 0x060 TILDE 0x07e
+ public static final KeyID LSHIFT = new KeyID(42); // MS 0x2A UNIX 0xFFE1
+ public static final KeyID BACKSLASH = new KeyID(43); // MS 0x2B UNIX 0x05c BAR 0x07c
+ public static final KeyID Z = new KeyID(44); // MS 0x2C UNIX 0x07A UPPER 0x05A
+ public static final KeyID X = new KeyID(45); // MS 0x2D UNIX 0x078 UPPER 0x058
+ public static final KeyID C = new KeyID(46); // MS 0x2E UNIX 0x063 UPPER 0x043
+ public static final KeyID V = new KeyID(47); // MS 0x2F UNIX 0x076 UPPER 0x056
+ public static final KeyID B = new KeyID(48); // MS 0x30 UNIX 0x062 UPPER 0x042
+ public static final KeyID N = new KeyID(49); // MS 0x31 UNIX 0x06E UPPER 0x04E
+ public static final KeyID M = new KeyID(50); // MS 0x32 UNIX 0x06D UPPER 0x04D
+ public static final KeyID COMMA = new KeyID(51); // MS 0x33 UNIX 0x02c LESS 0x03c
+ public static final KeyID PERIOD = new KeyID(52); // MS 0x34 UNIX 0x02e GREATER 0x03e
+ public static final KeyID SLASH = new KeyID(53); // MS 0x35 UNIX 0x02f QUESTION 0x03f
+ public static final KeyID RSHIFT = new KeyID(54); // MS 0x36 UNIX 0xFFE2
+ public static final KeyID MULTIPLY = new KeyID(55); // MS 0x37 UNIX 0xFFAA
+ public static final KeyID LALT = new KeyID(56); // MS 0x38 UNIX 0xFFE9
+ public static final KeyID SPACE = new KeyID(57); // MS 0x39 UNIX 0x020
+ public static final KeyID CAPITAL = new KeyID(58); // MS 0x3A UNIX 0xFFE5 SHIFTLOCK 0xFFE6
+ public static final KeyID F1 = new KeyID(59); // MS 0x3B UNIX 0xFFBE
+ public static final KeyID F2 = new KeyID(60); // MS 0x3C UNIX 0xFFBF
+ public static final KeyID F3 = new KeyID(61); // MS 0x3D UNIX 0xFFC0
+ public static final KeyID F4 = new KeyID(62); // MS 0x3E UNIX 0xFFC1
+ public static final KeyID F5 = new KeyID(63); // MS 0x3F UNIX 0xFFC2
+ public static final KeyID F6 = new KeyID(64); // MS 0x40 UNIX 0xFFC3
+ public static final KeyID F7 = new KeyID(65); // MS 0x41 UNIX 0xFFC4
+ public static final KeyID F8 = new KeyID(66); // MS 0x42 UNIX 0xFFC5
+ public static final KeyID F9 = new KeyID(67); // MS 0x43 UNIX 0xFFC6
+ public static final KeyID F10 = new KeyID(68); // MS 0x44 UNIX 0xFFC7
+ public static final KeyID NUMLOCK = new KeyID(69); // MS 0x45 UNIX 0xFF7F
+ public static final KeyID SCROLL = new KeyID(70); // MS 0x46 UNIX 0xFF14
+ public static final KeyID NUMPAD7 = new KeyID(71); // MS 0x47 UNIX 0xFFB7 HOME 0xFF95
+ public static final KeyID NUMPAD8 = new KeyID(72); // MS 0x48 UNIX 0xFFB8 UP 0xFF97
+ public static final KeyID NUMPAD9 = new KeyID(73); // MS 0x49 UNIX 0xFFB9 PRIOR 0xFF9A
+ public static final KeyID SUBTRACT = new KeyID(74); // MS 0x4A UNIX 0xFFAD
+ public static final KeyID NUMPAD4 = new KeyID(75); // MS 0x4B UNIX 0xFFB4 LEFT 0xFF96
+ public static final KeyID NUMPAD5 = new KeyID(76); // MS 0x4C UNIX 0xFFB5
+ public static final KeyID NUMPAD6 = new KeyID(77); // MS 0x4D UNIX 0xFFB6 RIGHT 0xFF98
+ public static final KeyID ADD = new KeyID(78); // MS 0x4E UNIX 0xFFAB
+ public static final KeyID NUMPAD1 = new KeyID(79); // MS 0x4F UNIX 0xFFB1 END 0xFF9C
+ public static final KeyID NUMPAD2 = new KeyID(80); // MS 0x50 UNIX 0xFFB2 DOWN 0xFF99
+ public static final KeyID NUMPAD3 = new KeyID(81); // MS 0x51 UNIX 0xFFB3 NEXT 0xFF9B
+ public static final KeyID NUMPAD0 = new KeyID(82); // MS 0x52 UNIX 0xFFB0 INSERT 0xFF9E
+ public static final KeyID DECIMAL = new KeyID(83); // MS 0x53 UNIX 0xFFAE DELETE 0xFF9F
+ public static final KeyID F11 = new KeyID(84); // MS 0x57 UNIX 0xFFC8
+ public static final KeyID F12 = new KeyID(85); // MS 0x58 UNIX 0xFFC9
+ public static final KeyID F13 = new KeyID(86); // MS 0x64 UNIX 0xFFCA
+ public static final KeyID F14 = new KeyID(87); // MS 0x65 UNIX 0xFFCB
+ public static final KeyID F15 = new KeyID(88); // MS 0x66 UNIX 0xFFCC
+ public static final KeyID KANA = new KeyID(89); // MS 0x70 UNIX 0xFF2D
+ public static final KeyID CONVERT = new KeyID(90); // MS 0x79 Japanese keyboard
+ public static final KeyID NOCONVERT = new KeyID(91); // MS 0x7B Japanese keyboard
+ public static final KeyID YEN = new KeyID(92); // MS 0x7D UNIX 0x0a5
+ public static final KeyID NUMPADEQUAL = new KeyID(93); // MS 0x8D UNIX 0xFFBD
+ public static final KeyID CIRCUMFLEX = new KeyID(94); // MS 0x90 Japanese keyboard
+ public static final KeyID AT = new KeyID(95); // MS 0x91 UNIX 0x040
+ public static final KeyID COLON = new KeyID(96); // MS 0x92 UNIX 0x03a
+ public static final KeyID UNDERLINE = new KeyID(97); // MS 0x93 NEC PC98
+ public static final KeyID KANJI = new KeyID(98); // MS 0x94 UNIX 0xFF21
+ public static final KeyID STOP = new KeyID(99); // MS 0x95 UNIX 0xFF69
+ public static final KeyID AX = new KeyID(100); // MS 0x96 Japan AX
+ public static final KeyID UNLABELED = new KeyID(101); // MS 0x97 J3100
+ public static final KeyID NUMPADENTER = new KeyID(102); // MS 0x9C UNIX 0xFF8D
+ public static final KeyID RCONTROL = new KeyID(103); // MS 0x9D UNIX 0xFFE4
+ public static final KeyID NUMPADCOMMA = new KeyID(104); // MS 0xB3 UNIX 0xFFAC
+ public static final KeyID DIVIDE = new KeyID(105); // MS 0xB5 UNIX 0xFFAF
+ public static final KeyID SYSRQ = new KeyID(106); // MS 0xB7 UNIX 0xFF15 PRINT 0xFF61
+ public static final KeyID RALT = new KeyID(107); // MS 0xB8 UNIX 0xFFEA
+ public static final KeyID PAUSE = new KeyID(108); // MS 0xC5 UNIX 0xFF13 BREAK 0xFF6B
+ public static final KeyID HOME = new KeyID(109); // MS 0xC7 UNIX 0xFF50
+ public static final KeyID UP = new KeyID(110); // MS 0xC8 UNIX 0xFF52
+ public static final KeyID PRIOR = new KeyID(111); // MS 0xC9 UNIX 0xFF55
+ public static final KeyID LEFT = new KeyID(112); // MS 0xCB UNIX 0xFF51
+ public static final KeyID RIGHT = new KeyID(113); // MS 0xCD UNIX 0xFF53
+ public static final KeyID END = new KeyID(114); // MS 0xCF UNIX 0xFF57
+ public static final KeyID DOWN = new KeyID(115); // MS 0xD0 UNIX 0xFF54
+ public static final KeyID NEXT = new KeyID(116); // MS 0xD1 UNIX 0xFF56
+ public static final KeyID INSERT = new KeyID(117); // MS 0xD2 UNIX 0xFF63
+ public static final KeyID DELETE = new KeyID(118); // MS 0xD3 UNIX 0xFFFF
+ public static final KeyID LWIN = new KeyID(119); // MS 0xDB UNIX META 0xFFE7 SUPER 0xFFEB HYPER 0xFFED
+ public static final KeyID RWIN = new KeyID(120); // MS 0xDC UNIX META 0xFFE8 SUPER 0xFFEC HYPER 0xFFEE
+ public static final KeyID APPS = new KeyID(121); // MS 0xDD UNIX 0xFF67
+ public static final KeyID POWER = new KeyID(122); // MS 0xDE Sun 0x1005FF76 SHIFT 0x1005FF7D
+ public static final KeyID SLEEP = new KeyID(123); // MS 0xDF No UNIX keysym
+ protected static final KeyID FIRST = VOID;
+ protected static final KeyID LAST = SLEEP;
+ } // class StandardKeyboard.KeyID
+} // class StandardKeyboard
diff --git a/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java b/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java
new file mode 100644
index 0000000..15668bf
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/test/ControllerReadTest.java
@@ -0,0 +1,279 @@
+/*
+ * ConrtollerReadTest.java
+ *
+ * Created on May 5, 2003, 3:15 PM
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input.test;
+
+/**
+ *
+ * @author administrator
+ */
+
+import net.java.games.input.*;
+import javax.swing.*;
+import java.util.*;
+import java.util.List;
+import java.awt.*;
+
+abstract class AxisPanel extends JPanel{
+ Axis axis;
+ float data;
+
+ public AxisPanel(Axis ax){
+ axis = ax;
+ setLayout(new BorderLayout());
+ add(new JLabel(ax.getName()+"("+ax.getIdentifier()+")"),
+ BorderLayout.NORTH);
+ }
+
+ public void poll(){
+ data = axis.getPollData();
+ renderData();
+ }
+
+ protected abstract void renderData();
+}
+
+class DigitalAxisPanel extends AxisPanel {
+ JLabel digitalState = new JLabel("<unread>");
+
+ public DigitalAxisPanel(Axis ax) {
+ super(ax);
+ add(digitalState,BorderLayout.CENTER);
+ }
+
+ protected void renderData(){
+ if (data == 0.0f){
+ digitalState.setBackground(getBackground());
+ digitalState.setText("OFF");
+ } else if ( data == 1.0f) {
+ digitalState.setBackground(Color.green);
+ digitalState.setText("ON");
+ }else { // shoudl never happen
+ digitalState.setBackground(Color.red);
+ digitalState.setText("ERR:"+data);
+ }
+ digitalState.repaint();
+ }
+}
+
+class DigitalHatPanel extends AxisPanel {
+ JLabel digitalState = new JLabel("<unread>");
+
+ public DigitalHatPanel(Axis ax) {
+ super(ax);
+ add(digitalState,BorderLayout.CENTER);
+ }
+
+ protected void renderData(){
+ if (data == Axis.POV.OFF){
+ digitalState.setBackground(getBackground());
+ digitalState.setText("OFF");
+ } else if ( data == Axis.POV.UP) {
+ digitalState.setBackground(Color.green);
+ digitalState.setText("UP");
+ } else if ( data == Axis.POV.RIGHT) {
+ digitalState.setBackground(Color.green);
+ digitalState.setText("RIGHT");
+ } else if ( data == Axis.POV.DOWN) {
+ digitalState.setBackground(Color.green);
+ digitalState.setText("DOWN");
+ } else if ( data == Axis.POV.LEFT) {
+ digitalState.setBackground(Color.green);
+ digitalState.setText("LEFT");
+ }else { // shoudl never happen
+ digitalState.setBackground(Color.red);
+ digitalState.setText("ERR:"+data);
+ }
+ digitalState.repaint();
+ }
+}
+class AnalogAxisPanel extends AxisPanel {
+ JLabel analogState = new JLabel("<unread>");
+
+ public AnalogAxisPanel(Axis ax) {
+ super(ax);
+ add(analogState,BorderLayout.CENTER);
+ }
+
+ protected void renderData(){
+ analogState.setText(""+data);
+ analogState.repaint();
+ }
+}
+
+
+
+class ControllerWindow extends JFrame {
+ Controller ca;
+ List axisList = new ArrayList();
+ boolean disabled = false;
+
+ public ControllerWindow(JFrame frame,Controller ca){
+ super(ca.getName());
+ this.setName(ca.getName());
+ this.ca = ca;
+ Container c = this.getContentPane();
+ c.setLayout(new BorderLayout());
+ Axis[] axis = ca.getAxes();
+ System.out.println("Axis count = "+axis.length);
+ if (axis.length>0) {
+ int width = (int)Math.ceil(Math.sqrt(axis.length));
+ JPanel p = new JPanel();
+ p.setLayout(new GridLayout(width,0));
+ for(int j=0;j<axis.length;j++){
+ addAxis(p,axis[j]);
+ }
+ c.add(new JScrollPane(p),BorderLayout.CENTER);
+ }
+ setSize(400,400);
+ setLocation(50,50);
+ setVisible(true);
+ }
+
+ public boolean disabled() {
+ return disabled;
+ }
+
+ private void setDisabled(boolean b){
+ disabled = b;
+ if (!disabled){
+ this.setTitle(ca.getName());
+ System.out.println(ca.getName()+" enabled");
+ } else {
+ this.setTitle(ca.getName()+" DISABLED!");
+ System.out.println(ca.getName()+" disabled");
+ }
+ repaint();
+ }
+
+ private void addAxis(JPanel p, Axis ax){
+ JPanel p2;
+ if (ax.isAnalog()) {
+ p2 = new AnalogAxisPanel(ax);
+ } else {
+ if (ax.getIdentifier() == Axis.Identifier.POV) {
+ p2 = new DigitalHatPanel(ax);
+ } else {
+ p2 = new DigitalAxisPanel(ax);
+ }
+ }
+ p.add(p2);
+ axisList.add(p2);
+ ax.setPolling(true);
+ }
+
+ public void poll(){
+ if (!ca.poll()) {
+ if (!disabled()){
+ setDisabled(true);
+ }
+ return;
+ }
+ if (disabled()){
+ setDisabled(false);
+ }
+ //System.out.println("Polled "+ca.getName());
+ for(Iterator i =axisList.iterator();i.hasNext();){
+ try {
+ ((AxisPanel)i.next()).poll();
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
+
+public class ControllerReadTest extends JFrame{
+ static final long HEARTBEATMS =100; // 10th of a second
+ List controllers = new ArrayList();
+ /** Creates a new instance of ConrtollerReadTest */
+ public ControllerReadTest() {
+ super("Controller Read Test");
+ ControllerEnvironment ce = ControllerEnvironment.getDefaultEnvironment();
+ Controller[] ca = ce.getControllers();
+ for(int i =0;i<ca.length;i++){
+ makeController(ca[i]);
+ }
+
+ new Thread(new Runnable() {
+ public void run(){
+ try {
+ while(true){
+ for(Iterator i=controllers.iterator();i.hasNext();){
+ try {
+ ControllerWindow cw = (ControllerWindow)i.next();
+ cw.poll();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ Thread.sleep(HEARTBEATMS);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ pack();
+ setSize(400,400);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setVisible(true);
+ }
+
+ private void makeController(Controller c) {
+ Controller[] subControllers = c.getControllers();
+ if (subControllers.length == 0 ) {
+ createControllerWindow(c);
+ } else {
+ for(int i=0;i<subControllers.length;i++){
+ makeController(subControllers[i]);
+ }
+ }
+ }
+
+ private void createControllerWindow(Controller c){
+ controllers.add(new ControllerWindow(this,c));
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ new ControllerReadTest().setVisible(true);
+ }
+
+}
diff --git a/coreAPI/src/java/net/java/games/input/test/ControllerTextTest.java b/coreAPI/src/java/net/java/games/input/test/ControllerTextTest.java
new file mode 100644
index 0000000..8b59c8f
--- /dev/null
+++ b/coreAPI/src/java/net/java/games/input/test/ControllerTextTest.java
@@ -0,0 +1,89 @@
+/*
+ * ControllerScanner.java
+ *
+ * Created on April 14, 2003, 3:45 PM
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input.test;
+
+/**
+ *
+ * @author administrator
+ */
+import net.java.games.input.*;
+
+public class ControllerTextTest {
+ ControllerEnvironment ce;
+ /** Creates a new instance of ControllerScanner */
+ public ControllerTextTest() {
+ ce = ControllerEnvironment.getDefaultEnvironment();
+ System.out.println("Controller Env = "+ce.toString());
+
+
+ Controller[] ca = ce.getControllers();
+ for(int i =0;i<ca.length;i++){
+ System.out.println(ca[i].getName());
+ System.out.println("Type: "+ca[i].getType().toString());
+ Axis[] axis = ca[i].getAxes();
+ System.out.println("Axis Count: "+axis.length);
+ for(int j=0;j<axis.length;j++){
+ System.out.println("Axis "+j+": "+axis[j].getName());
+ System.out.println(" Identifier: "+
+ axis[j].getIdentifier().getName());
+ System.out.print(" AxisType: ");
+ if (axis[j].isRelative()) {
+ System.out.print("Relative");
+ } else {
+ System.out.print("Absolute");
+ }
+ if (axis[j].isAnalog()) {
+ System.out.print(" Analog");
+ } else {
+ System.out.print(" Digital");
+ }
+ System.out.println();
+ }
+ System.out.println("---------------------------------");
+ }
+
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ new ControllerTextTest();
+ }
+
+}
diff --git a/plugins/DX8/README.txt b/plugins/DX8/README.txt
new file mode 100644
index 0000000..12cd468
--- /dev/null
+++ b/plugins/DX8/README.txt
@@ -0,0 +1,46 @@
+This file modified last on 06/06/2003 by Jeff Kesselman
+
+This is the source tree for the core input API.
+
+Directory Organization:
+
+The root contains a master ANT build.xml.
+After a successful build you will have the following sub directories:
+ -- apidocs Where the javadocs get built to
+ -- lib Where dependant libraries are kept.
+ -- bin Where the plugin dll and jar files ar built to.
+ -- src The source files.
+
+
+Build instructions:
+
+To clean: ant clean
+To build: ant all (or just ant)
+To build docs: ant javadoc
+To test:
+ This build will install the plug-in into the coreAPI's test
+ directories.
+ Use the tests in the coreAPI build.xml to test.
+
+Release Info:
+ Initial Release: This release contains an implementation of the input
+ API designed by Mike Martak of Sun and Thomas (?) of Sony CEA for
+ the WIn32 platform. All the code in src/input is cross platform. The
+ Win32 code is segregated to the DirectX plugin (src/DXplugin) which
+ depends on DirectInput from DX7 (or later).
+
+ 05/09/2003: A number of bugs and problems with the DXPlugin are fixed in this
+ release. This release also brings the code up to date using the DI8
+ interface. This thus is the first release that requries Peter Puck's
+ DX8 bindings to compile with MinGW.
+
+ 05/09/2003 (second update):
+ This version adds a new standard value type to the API.
+ Axis.POV holds standard definitions for values for POV (hat) switches
+ -- Axis.POV.CENTER and Axis.POV.OFF are synonmous and are
+ the center position.
+ -- Axis.POV.UP, Axis.POV.DOWN, Axis.POV.LEFT and Axis.POV.RIGHT
+ should be self explainatory.
+ Any hat that claims to be "normalized" will return these values. (It is
+ recommended that all hats be normalized by the systemn specific plugins.)
+
diff --git a/plugins/DX8/build.xml b/plugins/DX8/build.xml
new file mode 100644
index 0000000..32001e1
--- /dev/null
+++ b/plugins/DX8/build.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+
+<!-- Written to assume that classpath is rooted in the current directory. -->
+<!-- So this should be OK if you make this script in the root of a filesystem. -->
+<!-- If not, you may prefer to adjust the basedir, or move some directories around. -->
+<!-- The idea is that both Ant and NetBeans have to know what the package root is -->
+<!-- for the classes in your application. -->
+<project name="Direct Input Plugin" basedir="." default="all">
+
+ <!-- Don't worry if you don't know the Ant syntax completely or need help on some tasks! -->
+ <!-- The standard Ant documentation is bundled. See Help | Help Sets | Ant 1.4.1 Manual. -->
+
+ <target name="init">
+ <!-- You can set up any variables you want used throughout the script here. -->
+ <property name="hello" value="world"/>
+ <mkdir dir="classes"/>
+ <mkdir dir="bin"/>
+ <!-- To use e.g. Jikes, uncomment this line. -->
+ <!-- (Or make the same change in Tools | Options | Ant Settings | Properties.) -->
+ <!-- <property name="build.compiler" value="jikes"/> -->
+ <!-- You might like to set up some overridable paths, etc.: -->
+ <!-- <property name="mylib" value="../lib/mylib.jar"/> -->
+ </target>
+
+ <target name="compile" depends="init">
+ <!-- Both srcdir and destdir should be package roots. -->
+ <!-- They could be different of course; in that case NetBeans can also be set -->
+ <!-- up to compile to a different filesystem in the same way; see Compiler Types: -->
+ <javac srcdir="src/java" destdir="classes" debug="true" deprecation="true" source="1.4">
+ <!-- To add something to the classpath: -->
+ <classpath>
+ <pathelement location="lib/controller.jar"/>
+ <pathelement location="lib/jutils.jar"/>
+ </classpath>
+ <!-- To exclude some files: -->
+ <!--
+ <exclude name="com/foo/SomeFile.java"/>
+ <exclude name="com/foo/somepackage/"/>
+ -->
+ </javac>
+ <exec dir="." executable="gcc" os="Windows 2000">
+ <arg line=" -D_STRICT_ANSI -D_JNI_IMPLEMENTATION_"/>
+ <arg line=" -I'${java.home}/../include' -I'${java.home}/../include/win32' -Ic:/dx9/include"/>
+ <arg line=" -o bin/dxinput.dll src/native/input.cpp -Wl,--export-all-symbols"/>
+ <arg line=" -shared -Wl,--kill-at -ldxguid -ldinput -ldinput8"/>
+ </exec>
+ <copy file="bin/dxinput.dll" todir="../../coreAPI/src/tests/controller" />
+ </target>
+
+ <target name="jar" depends="init,compile">
+ <!-- To make a standalone app: -->
+ <!-- 1. Create a myapp.mf manifest somewhere. -->
+ <!-- 2. Put in it: -->
+ <!-- Manifest-Version: 1.0 -->
+ <!-- Main-Class: com.foo.Main -->
+ <!-- 3. Pass to <jar>: manifest="myapp.mf" -->
+ <jar jarfile="bin/dxinput.jar" compress="true" basedir="classes">
+ <exclude name="**/*.java"/>
+ <exclude name="**/*.form"/>
+ <exclude name="dxinput.mf"/>
+ <exclude name="dxinput.jar"/>
+ <exclude name="apidoc"/>
+ </jar>
+ <copy file="bin/dxinput.jar" todir="../../coreAPI/src/tests/controller" />
+ </target>
+
+ <target name="all" depends="compile,jar" description="Build everything.">
+ <echo message="Application built. Hello ${hello}!"/>
+ </target>
+
+ <target name="test" depends="init,all" description="Try running it.">
+ <echo message="Test by running test on the build.xml for input"/>
+ </target>
+
+ <target name="javadoc" depends="init" description="Javadoc for my API.">
+ <mkdir dir="apidocs"/>
+ <javadoc packagenames="net.*"
+ destdir="apidocs"
+ additionalparam="-source 1.4">
+ <sourcepath>
+ <pathelement location="src/java"/>
+ </sourcepath>
+ <classpath>
+ <pathelement location="lib/controller.jar"/>
+ <pathelement location="lib/jutils.jar"/>
+ </classpath>
+ </javadoc>
+ </target>
+
+ <target name="clean" depends="init" description="Clean all build products.">
+ <delete>
+ <fileset dir="classes">
+ <include name="**/*.class"/>
+ </fileset>
+ </delete>
+ <delete file="bin/dxinput.jar" failonerror="no"/>
+ <delete file="bin/dxinput.dll" failonerror="no"/>
+ <delete file="../../coreAPI/src/tests/controller/dxinput.jar" failonerror="no" />
+ <delete file="../../coreAPI/src/test/controller/dxinput.dll" failonerror="no"/>
+ <delete dir="../../docs/input/win32/apidoc" failonerror="no"/>
+ </target>
+
+</project>
diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java b/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java
new file mode 100644
index 0000000..58df37d
--- /dev/null
+++ b/plugins/DX8/src/java/net/java/games/input/DirectInputAxis.java
@@ -0,0 +1,211 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import net.java.games.input.AbstractAxis;
+import net.java.games.input.Axis;
+
+/**
+ *
+ * @author martak
+ * @version
+ */
+class DirectInputAxis extends AbstractAxis {
+
+ /**
+ * DIDFT_ constants and macros defined in dinput.h
+ */
+ private static final int DIDFT_ALL = 0x00000000;
+ private static final int DIDFT_RELAXIS = 0x00000001;
+ private static final int DIDFT_ABSAXIS = 0x00000002;
+ private static final int DIDFT_AXIS = 0x00000003;
+ private static final int DIDFT_PSHBUTTON = 0x00000004;
+ private static final int DIDFT_TGLBUTTON = 0x00000008;
+ private static final int DIDFT_BUTTON = 0x0000000C;
+ private static final int DIDFT_POV = 0x00000010;
+ private static final int DIDFT_COLLECTION = 0x00000040;
+ private static final int DIDFT_NODATA = 0x00000080;
+ private static final int DIDFT_ANYINSTANCE = 0x00FFFF00;
+ private static final int DIDFT_INSTANCEMASK = DIDFT_ANYINSTANCE;
+ private static final int DIDFT_FFACTUATOR = 0x01000000;
+ private static final int DIDFT_FFEFFECTTRIGGER = 0x02000000;
+ private static final int DIDFT_OUTPUT = 0x10000000;
+ private static final int DIDFT_NOCOLLECTION = 0x00FFFF00;
+ private static int DIDFT_MAKEINSTANCE(int n) {
+ return ((n&0xffff) << 8);
+ }
+ private static int DIDFT_GETTYPE(int n) {
+ return (n&0xFF);
+ }
+ private static int DIDFT_GETINSTANCE(int n) {
+ return ((n >> 8)&0xffff);
+ }
+ private static int DIDFT_ENUMCOLLECTION(int n) {
+ return ((n&0xFFFF) << 8);
+ }
+
+ private DirectInputDevice device;
+ /**
+ * DIJOYSTATE structure defined in dinput.h:
+ *
+ * <pre>
+ * typedef struct DIJOYSTATE {
+ * LONG lX;
+ * LONG lY;
+ * LONG lZ;
+ * LONG lRx;
+ * LONG lRy;
+ * LONG lRz;
+ * LONG rglSlider[2];
+ * DWORD rgdwPOV[4];
+ * BYTE rgbButtons[32];
+ * } DIJOYSTATE, *LPDIJOYSTATE;
+ *
+ * 80 bytes total
+ * </pre>
+ */
+ private int offset;
+ private int type;
+ private int instance;
+ private int bitmask = 0xffffffff;
+ private int bitshift = 0;
+
+ private DirectInputAxis(DirectInputDevice device, Axis.Identifier id,
+ int didft, String name) {
+ super(name, id);
+ this.device = device;
+ this.type = DIDFT_GETTYPE(didft);
+ this.instance = DIDFT_GETINSTANCE(didft);
+ if (id == Axis.Identifier.X) {
+ offset = 0;
+ } else if (id == Axis.Identifier.Y) {
+ offset = 1;
+ } else if (id == Axis.Identifier.Z) {
+ offset = 2;
+ } else if (id == Axis.Identifier.RX) {
+ offset = 3;
+ } else if (id == Axis.Identifier.RY) {
+ offset = 4;
+ } else if (id == Axis.Identifier.RZ) {
+ offset = 5;
+ } else if (id == Axis.Identifier.SLIDER) {
+ //System.out.println("Slider on "+name+" instance = "+instance);
+ offset = 6 + (instance>>2);
+ } else if (id == Axis.Identifier.POV) {
+ //System.out.println("POV on "+name+" instance = "+instance);
+ offset = 8 + instance;
+ } else if (id == Axis.Identifier.BUTTON) {
+ //System.out.println("Button on "+name+" instance = "+instance);
+ offset = 12 + (instance/4);
+ bitshift = (instance%4)*8;
+ bitmask=0xff;
+ }
+ }
+
+ /** Returns the data from the last time the control has been polled.
+ * If this axis is a button, the value returned will be either 0.0f or 1.0f.
+ * If this axis is normalized, the value returned will be between -1.0f and
+ * 1.0f.
+ * @return A float between -1.0 and 1.0
+ */
+ public float getPollData() {
+ int data = ((device.data[offset] >> bitshift)&bitmask);
+ if ((type&DIDFT_BUTTON) != 0 ) {
+ return (float)((data&0x80)>>7);
+ } else if ((type&DIDFT_AXIS)!=0){ // all axes are set for -32768 to 32738
+ return ((float)data)/32768;
+ } else if ((type&DIDFT_POV)!=0) {
+ if (data == -1) {
+ return Axis.POV.OFF;
+ } else if (data == 0.0) {
+ return Axis.POV.UP;
+ } else if (data == 9000) {
+ return Axis.POV.RIGHT;
+ } else if (data == 18000) {
+ return Axis.POV.DOWN;
+ } else if (data == 27000) {
+ return Axis.POV.LEFT;
+ } else {
+ System.err.print("Unexpected value for DX8 HAT: "+data);
+ return Axis.POV.OFF;
+ }
+ } else { // return raw value
+ return (float)data;
+ }
+
+ }
+
+ /** Returns <code>true</code> if data returned from <code>poll</code>
+ * is relative to the last call, or <code>false</code> if data
+ * is absolute.
+ * @return true if data has chnaged since last poll, else false
+ */
+ public boolean isRelative() {
+ return (type & DIDFT_RELAXIS) != 0;
+ }
+
+ /** Returns whether or not the axis is analog, or false if it is digital.
+ * @return true if analog, false if digital
+ */
+ public boolean isAnalog() {
+ return (type & DIDFT_AXIS) != 0;
+ }
+
+ /** Returns whether or not data polled from this axis is normalized
+ * between the values of -1.0f and 1.0f.
+ * @return true if data is normalized, false if not.
+ */
+ public boolean isNormalized() {
+ return (type & (DIDFT_BUTTON|DIDFT_AXIS|DIDFT_POV)) != 0;
+ }
+
+ /** Creates a new DirectInputAxis (factory method).
+ * This is a function used internally during set up
+ * @return The new DirectInputAxis object.
+ * @param device The device to attach this axis to.
+ *
+ * @param didft The identifier for the axis as provided by DX8.
+ * @param name A name to give the new axis.
+ * @param id The identifier for the device
+ */
+ public static DirectInputAxis createAxis(DirectInputDevice device,
+ Axis.Identifier id, int didft, String name) {
+ return new DirectInputAxis(device, id, didft, name);
+ }
+}
diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java b/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java
new file mode 100644
index 0000000..f31c66e
--- /dev/null
+++ b/plugins/DX8/src/java/net/java/games/input/DirectInputDevice.java
@@ -0,0 +1,207 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import net.java.games.input.AbstractController;
+import net.java.games.input.Axis;
+import net.java.games.input.Controller;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ *
+ * @author martak
+ * @version
+ */
+class DirectInputDevice extends AbstractController {
+
+ /**
+ * DIDEVTYPE_ constants from dinput.h header file
+ ** JPK NOTE: This changed in DI8. In general this
+ * is fragile anda way shoudl be found to tie these mroe directly
+ * to the header files.
+ */
+ /* Mike's <=DX7 types
+ private static final int DIDEVTYPEJOYSTICK_UNKNOWN = 1;
+ private static final int DIDEVTYPEJOYSTICK_TRADITIONAL = 2;
+ private static final int DIDEVTYPEJOYSTICK_FLIGHTSTICK = 3;
+ private static final int DIDEVTYPEJOYSTICK_GAMEPAD = 4;
+ private static final int DIDEVTYPEJOYSTICK_RUDDER = 5;
+ private static final int DIDEVTYPEJOYSTICK_WHEEL = 6;
+ private static final int DIDEVTYPEJOYSTICK_HEADTRACKER = 7;
+ */
+
+ /**
+ * Pointer to the IDirectInputDevice for this device
+ */
+ private long lpDevice;
+
+ /**
+ * Type of device
+ */
+ private Type type;
+
+ /**
+ * Do we need to poll data?
+ */
+ private boolean polled = true;
+ /**
+ * Data when polling, as per the DIJOYSTATE structure in dinput.h;
+ * @see DirectInputAxis for a breakdown of this structure
+ */
+ int[] data = new int[32];
+
+ /**
+ * Private constructor
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of device, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the device
+ * @param instanceName The name of the device
+ */
+ private DirectInputDevice(long lpDevice, int subtype, String productName,
+ String instanceName,boolean polled) {
+ super(productName + " " + instanceName);
+ this.lpDevice = lpDevice;
+ this.polled = polled;
+ System.out.println("Creating "+productName+" polling = "+polled);
+ switch(subtype) {
+ /*
+ case DIDEVTYPEJOYSTICK_GAMEPAD:
+ type = Type.GAMEPAD; break;
+ case DIDEVTYPEJOYSTICK_RUDDER:
+ type = Type.RUDDER; break;
+ case DIDEVTYPEJOYSTICK_WHEEL:
+ type = Type.WHEEL; break;
+ case DIDEVTYPEJOYSTICK_HEADTRACKER:
+ type = Type.HEADTRACKER; break;
+ case DIDEVTYPEJOYSTICK_TRADITIONAL: // fall through
+ case DIDEVTYPEJOYSTICK_FLIGHTSTICK: // fall through
+ */
+ default:
+ type = Type.STICK; break;
+ }
+ axes = initDirectInputAxes();
+ }
+
+ /**
+ * Used instead of overriding initAxes because it needs the
+ * pointer to the IDirectInputDevice
+ */
+ private Axis[] initDirectInputAxes() {
+ ArrayList list = new ArrayList();
+ enumObjects(lpDevice, list);
+ Axis[] ret = new Axis[list.size()];
+ Iterator it = list.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ ret[i] = (Axis)it.next();
+ i++;
+ }
+ return ret;
+ }
+
+ /**
+ * Callback called by enumObjects to add a new axis into the list
+ * @param list This in which to add the new axis
+ * @param id The identifier for the axis, based on GUID
+ * @param didft The combination of DIDFT_ flags that make up the type and
+ * instance number of the axis.
+ * @param name The name to call the axis.
+ */
+ private void addAxis(ArrayList list, Axis.Identifier id, int didft,
+ String name) {
+ list.add(DirectInputAxis.createAxis(this, id, didft, name));
+ }
+
+ /** Polls axes for data. Returns false if the controller is no longer valid.
+ * Polling reflects the current state of the device when polled, and is
+ * unbuffered.
+ * @return False if the co troller is no longer valid, else true.
+ */
+ public boolean poll() {
+ return pollNative(lpDevice, data, polled);
+ }
+
+ /** Returns the type of Controller.
+ * @return The type of the controller.
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /** Returns the zero-based port number for this Controller.
+ * @return The port number.
+ */
+ public int getPortNumber() {
+ // REMIND : We may be able to parse this from the name string
+ return 0;
+ }
+
+ /**
+ * Polls the device; native method. The data from the poll is stored in
+ * the data array.
+ */
+ private native boolean pollNative(long lpDevice, int[] data,
+ boolean polled);
+
+ /**
+ * Enumerates the axes on the device
+ */
+ private native boolean enumObjects(long lpDevice, ArrayList list);
+
+ /** Creates a new DirectInputDevice (factory method)
+ * This is a function used internally during set up
+ * @param polled Whether this device's driver should actually be
+ * polled during a call to Poll or whether it is an
+ * interrupt driven device that should ignore poll
+ * requests.
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of device, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the device
+ * @param instanceName The name of the device
+ * @return The new DirectInputDevice object
+ */
+ public static DirectInputDevice createDevice(long lpDevice, int subtype,
+ String productName, String instanceName, boolean polled) {
+ return new DirectInputDevice(lpDevice, subtype, productName,
+ instanceName,polled);
+ }
+} // class DirectInputDevice
diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java b/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java
new file mode 100644
index 0000000..a406b09
--- /dev/null
+++ b/plugins/DX8/src/java/net/java/games/input/DirectInputEnvironmentPlugin.java
@@ -0,0 +1,183 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Iterator;
+import net.java.games.input.Controller;
+import net.java.games.input.ControllerEnvironment;
+//import sun.security.action.LoadLibraryAction;
+import net.java.games.util.plugins.Plugin;
+
+/** DirectInput implementation of controller environment
+ * @author martak
+ * @version 1.0
+ */
+public class DirectInputEnvironmentPlugin extends ControllerEnvironment
+ implements Plugin
+{
+
+ static {
+ /** Mikes old code, causes it to be laoded by wrong loader
+ java.security.AccessController.doPrivileged(
+ new LoadLibraryAction("jinput"));
+ */
+ System.loadLibrary("dxinput");
+ }
+
+ /**
+ * DIDEVTYPE_ constants from dinput.h header file
+ * JPK NOTE: changed in DX8 so had to be changed. This is
+ * fragile, we should find a way to set them from
+ * the C side sowe can stay up to date with header
+ */
+ /** DX7 and earlier
+ private static final int DIDEVTYPE_DEVICE = 1;
+ private static final int DIDEVTYPE_MOUSE = 2;
+ private static final int DIDEVTYPE_KEYBOARD = 3;
+ private static final int DIDEVTYPE_JOYSTICK = 4;
+ private static final int DIDEVTYPE_HID = 0x00010000;
+ private static int GET_DIDEVICE_TYPE(int dwDevType) {
+ return (int)((byte)dwDevType);
+ }
+ private static int GET_DIDEVICE_SUBTYPE(int dwDevType) {
+ return (int)((byte)((((short)dwDevType) >> 8) & 0xFF));
+ }
+ **/
+ /* DX8 and 9 */
+ private static final int DI8DEVTYPE_DEVICE = 0x11;
+ private static final int DI8DEVTYPE_MOUSE = 0x12;
+ private static final int DI8DEVTYPE_KEYBOARD = 0x13;
+ private static final int DI8DEVTYPE_JOYSTICK = 0x14;
+ private static final int DI8DEVTYPE_GAMEPAD = 0x15;
+ private static final int DI8DEVTYPE_DRIVING = 0x16;
+ private static final int DI8DEVTYPE_FLIGHT = 0x17;
+ private static final int DI8DEVTYPE_1STPERSON = 0x18;
+ private static final int DI8DEVTYPE_DEVICECTRL = 0x19;
+ private static final int DI8DEVTYPE_SCREENPOINTER = 0x1A;
+ private static final int DI8DEVTYPE_REMOTE = 0x1B;
+ private static final int DI8DEVTYPE_SUPPLEMENTAL = 0x1C;
+
+ private static int GET_DIDEVICE_TYPE(int dwDevType) {
+ return (dwDevType&0xFF);
+ }
+ private static int GET_DIDEVICE_SUBTYPE(int dwDevType) {
+ return (int)((byte)((((short)dwDevType) >> 8) & 0xFF));
+ }
+
+ // Pointer to DirectInput instance
+ private long lpDirectInput;
+ // Permanent array of controllers
+ private Controller[] controllers;
+
+ /** Creates new DirectInputEnvironment */
+ public DirectInputEnvironmentPlugin() {
+ lpDirectInput = directInputCreate();
+ enumControllers();
+ }
+
+ /** Returns a list of all controllers available to this environment,
+ * or an empty array if there are no controllers in this environment.
+ * @return An array of controllers that may be empty.
+ */
+ public Controller[] getControllers() {
+ return controllers;
+ }
+
+ private void enumControllers() {
+ // If direct input fails, create an empty array
+ if (lpDirectInput == 0) {
+ controllers = new Controller[] {};
+ return;
+ }
+ // Create temporary controller array
+ ArrayList tempDevices = new ArrayList();
+ // Eumerate devices
+ enumDevices(lpDirectInput, tempDevices);
+ // Set up permanent controller array
+ controllers = new Controller[tempDevices.size()];
+ Iterator it = tempDevices.iterator();
+ int i = 0;
+ while (it.hasNext()) {
+ controllers[i] = (Controller)it.next();
+ i++;
+ }
+ }
+
+ /**
+ * Creates a new device, adding it to the list supplied.
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param type The type of device to create, as defined by the constants
+ * in dinput.h (see DI8DEVTYPE constants above).
+ * @param productName The product name for the device
+ * @param instanceName The name of the device
+ */
+ private void addDevice(ArrayList list, long lpDevice,
+ int type, String productName, String instanceName, boolean polled) {
+ Controller c;
+ int category = GET_DIDEVICE_TYPE(type);
+ int subtype = GET_DIDEVICE_SUBTYPE(type);
+ //System.out.println("Category = "+category);
+ if (category == DI8DEVTYPE_MOUSE) {
+ c = DirectInputMouse.createMouse(lpDevice, subtype, productName,
+ instanceName);
+ } else if (category == DI8DEVTYPE_KEYBOARD) {
+ c = DirectInputKeyboard.createKeyboard(lpDevice, subtype,
+ productName, instanceName);
+ } else {
+ assert category == DI8DEVTYPE_JOYSTICK;
+ c = DirectInputDevice.createDevice(lpDevice, subtype, productName,
+ instanceName,polled);
+ }
+ if (c != null) {
+ list.add(c);
+ }
+ }
+
+ /**
+ * Returns the direct input instance, or 0 if failed to initialize
+ */
+ private native long directInputCreate();
+
+ /**
+ * Enumerates all devices, calling createDevice for each one
+ */
+ private native boolean enumDevices(long lpDirectInput, ArrayList list);
+} // class DirectInputEnvironment
diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java b/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java
new file mode 100644
index 0000000..6faf163
--- /dev/null
+++ b/plugins/DX8/src/java/net/java/games/input/DirectInputKeyboard.java
@@ -0,0 +1,208 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import net.java.games.input.AbstractAxis;
+import net.java.games.input.Axis;
+import net.java.games.input.StandardKeyboard;
+
+/**
+ * DirectInput keyboard implementation.
+ * @author martak
+ * @version
+ */
+class DirectInputKeyboard extends StandardKeyboard {
+
+ /**
+ * DIDEVTYPE_ constants from dinput.h header file
+ */
+ private static final int DIDEVTYPEKEYBOARD_UNKNOWN = 0;
+ private static final int DIDEVTYPEKEYBOARD_PCXT = 1;
+ private static final int DIDEVTYPEKEYBOARD_OLIVETTI = 2;
+ private static final int DIDEVTYPEKEYBOARD_PCAT = 3;
+ private static final int DIDEVTYPEKEYBOARD_PCENH = 4;
+ private static final int DIDEVTYPEKEYBOARD_NOKIA1050 = 5;
+ private static final int DIDEVTYPEKEYBOARD_NOKIA9140 = 6;
+ private static final int DIDEVTYPEKEYBOARD_NEC98 = 7;
+ private static final int DIDEVTYPEKEYBOARD_NEC98LAPTOP = 8;
+ private static final int DIDEVTYPEKEYBOARD_NEC98106 = 9;
+ private static final int DIDEVTYPEKEYBOARD_JAPAN106 = 10;
+ private static final int DIDEVTYPEKEYBOARD_JAPANAX = 11;
+ private static final int DIDEVTYPEKEYBOARD_J3100 = 12;
+
+ /**
+ * Key index crosstable; maps indices into the data array to virtual keys
+ * in the key array in StandardKeyboard.
+ * For example, the key F11 is at index 84 in the array of keys in
+ * StandardKeyboard, yet it is data element 87 (0x57) in our data array.
+ * <p>
+ * To access the data element of a particular key (F11), we use the
+ * crosstable as follows:
+ * <p><code>
+ * KeyID f11 = StandardKey.KeyID.F11;
+ * int keyIndex = f11.getKeyIndex(); // returns 84
+ * int crossIndex = CROSSTABLE[keyIndex]; // returns 0x57 (87)
+ * </code>
+ * To find a key given the data element index (87), we do a simple search
+ * through the crosstable starting at that index (index 87/0x57 = 0x65) and
+ * looking backwards until we find our key itself, or a lower number
+ * (meaning the key was not found). We can only take advantage of this
+ * algorithm only because on Windows, our crosstable is in increasing order.
+ */
+ private final static int[] CROSSTABLE = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, // _9
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // Y
+ 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // D
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, // BACKSLASH
+ 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, // RSHIFT
+ 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, // F7
+ 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, // NUMPAD5
+ 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x57, 0x58, 0x64, 0x65, // F14
+ 0x66, 0x70, 0x79, 0x7B, 0x7D, 0x8D, 0x90, 0x91, 0x92, 0x93, 0x94, // KANJI
+ 0x95, 0x96, 0x97, 0x9C, 0x9D, 0xB3, 0xB5, 0xB7, 0xB8, 0xC5, 0xC7, // HOME
+ 0xC8, 0xC9, 0xCB, 0xCD, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xDB, 0xDC, // RWIN
+ 0xDD, 0xDE, 0xDF // SLEEP
+ };
+
+ /**
+ * Pointer to the IDirectInputDevice for this device
+ */
+ private long lpDevice;
+
+ /**
+ * Subtype of keyboard, defined by DIDEVTYPE constants
+ */
+ private int subtype;
+
+ /**
+ * Polling key data
+ */
+ private byte[] keyData = new byte[256];
+
+ /**
+ * Private constructor
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of keyboard, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the device
+ * @param instanceName The name of the device
+ */
+ private DirectInputKeyboard(long lpDevice, int subtype, String productName,
+ String instanceName) {
+ super(productName + " (" + instanceName + ")");
+ this.lpDevice = lpDevice;
+ this.subtype = subtype;
+ }
+
+ /**
+ * Callback to rename a given key by index, name
+ * @param index the index in the data array
+ * @param name the name of the key
+ */
+ private void renameKey(int index, String name) {
+ int keyIndex = index;
+ if (keyIndex > CROSSTABLE.length) {
+ keyIndex = CROSSTABLE.length - 1;
+ }
+ for (; CROSSTABLE[keyIndex] > index; keyIndex--)
+ ;
+ if (CROSSTABLE[keyIndex] == index) {
+ Axis[] axes = getAxes();
+ AbstractAxis key = (AbstractAxis)axes[index];
+ if (name != null && name.length() > 0) {
+ //System.out.println("Renaming key " + key.getName() +
+ // " to " + name + " index=" +
+ // index + " keyIndex=" + keyIndex + " CROSSTAB=" +
+ // CROSSTABLE[keyIndex]);
+ key.setName(name);
+ }
+ } else {
+ //System.out.println("Key not found " + name + " index=" + index +
+ // " keyIndex=" + keyIndex + " CROSSTAB=" +
+ // CROSSTABLE[keyIndex]);
+ }
+ }
+
+ /** Polls axes for data. Returns false if the controller is no longer valid.
+ * Polling reflects the current state of the device when polled.
+ * @return False if the KB is no longer valid, true otherwise.
+ */
+ public boolean poll() {
+ return pollNative(lpDevice, keyData);
+ }
+
+ /** Returns whether or not the given key has been pressed since the last
+ * call to poll.
+ * @param key The key whose state to check.
+ * @return true if this key has changed state since last read of its state, false otherwise.
+ */
+ protected boolean isKeyPressed(Key key) {
+ KeyID id = (KeyID)key.getIdentifier();
+ int keyIndex = id.getKeyIndex();
+ int crossIndex = CROSSTABLE[keyIndex];
+ return ((keyData[crossIndex] & 0x80) != 0);
+ }
+
+ /**
+ * Polls the device; native method
+ */
+ private native boolean pollNative(long lpDevice, byte[] keyData);
+
+ /**
+ * Renames the keys with the name provided by DirectInput
+ */
+ private native boolean renameKeys(long lpDevice);
+
+ /** Creates a new DirectInputKeyboard (factory method)
+ * This is a function used internally during set up.
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of keyboard, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the keyboard
+ * @param instanceName The name of the keyboard
+ * @return The new DirectInputKeyboard object.
+ */
+ public static DirectInputKeyboard createKeyboard(long lpDevice,
+ int subtype, String productName, String instanceName) {
+ DirectInputKeyboard ret = new DirectInputKeyboard(lpDevice, subtype,
+ productName, instanceName);
+ ret.renameKeys(lpDevice);
+ return ret;
+ }
+} // class DirectInputKeyboard
diff --git a/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java b/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java
new file mode 100644
index 0000000..f706250
--- /dev/null
+++ b/plugins/DX8/src/java/net/java/games/input/DirectInputMouse.java
@@ -0,0 +1,311 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+/*****************************************************************************
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materails provided with the distribution.
+ *
+ * Neither the name Sun Microsystems, Inc. or the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANT OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMEN, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND
+ * ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS
+ * A RESULT OF USING, MODIFYING OR DESTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES. HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OUR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for us in
+ * the design, construction, operation or maintenance of any nuclear facility
+ *
+ *****************************************************************************/
+package net.java.games.input;
+
+import net.java.games.input.AbstractAxis;
+import net.java.games.input.Axis;
+import net.java.games.input.Mouse;
+
+/**
+ * DirectInput mouse implementation.
+ * @author martak
+ * @version
+ */
+class DirectInputMouse extends Mouse {
+
+ /**
+ * DIDEVTYPE_ constants from dinput.h header file
+ */
+ private static final int DIDEVTYPEMOUSE_UNKNOWN = 1;
+ private static final int DIDEVTYPEMOUSE_TRADITIONAL = 2;
+ private static final int DIDEVTYPEMOUSE_FINGERSTICK = 3;
+ private static final int DIDEVTYPEMOUSE_TOUCHPAD = 4;
+ private static final int DIDEVTYPEMOUSE_TRACKBALL = 5;
+
+ /**
+ * Pointer to the IDirectInputDevice for this device
+ */
+ private long lpDevice;
+
+ /**
+ * Type of mouse
+ */
+ private Type type;
+
+ /**
+ * Mouse data
+ */
+ private byte[] mouseData = new byte[16];
+
+ /**
+ * Private constructor
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of mouse, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the device
+ * @param instanceName The name of the device
+ */
+ private DirectInputMouse(long lpDevice, int subtype, String productName,
+ String instanceName) {
+ super(productName + " " + instanceName);
+ buttons = new ButtonsImpl();
+ ball = new BallImpl();
+ this.lpDevice = lpDevice;
+ switch(subtype) {
+ case DIDEVTYPEMOUSE_FINGERSTICK:
+ type = Type.FINGERSTICK; break;
+ case DIDEVTYPEMOUSE_TOUCHPAD:
+ type = Type.TRACKPAD; break;
+ case DIDEVTYPEMOUSE_TRACKBALL:
+ type = Type.TRACKBALL; break;
+ case DIDEVTYPEMOUSE_TRADITIONAL: // fall through
+ case DIDEVTYPEMOUSE_UNKNOWN: // fall through
+ default:
+ type = Type.MOUSE; break;
+ }
+ renameAxes(lpDevice);
+ }
+
+ /**
+ * Callback to rename a given axis by type, name
+ */
+ private void renameAxis(Axis.Identifier id, String name) {
+ AbstractAxis axis;
+ if (id instanceof ButtonID) {
+ axis = (AbstractAxis)getButtons().getAxis(id);
+ } else {
+ axis = (AbstractAxis)getBall().getAxis(id);
+ }
+ axis.setName(name);
+ //System.out.println("Renaming " + name);
+ }
+
+ /** Polls axes for data. Returns false if the controller is no longer valid.
+ * Polling reflects the current state of the device when polled.
+ * @return false if the mosue is no lonegr valid, true otherwise.
+ */
+ public boolean poll() {
+ return pollNative(lpDevice, mouseData);
+ }
+
+ /** Returns the type of the Controller.
+ * @return The device type of the controller (logically this
+ * shoudl be some form of "mouse" .)
+ */
+ public Type getType() {
+ return type;
+ }
+
+ /** Creates a new DirectInputMouse (factory method)
+ * This is a function used internally during set up.
+ * @param lpDevice A pointer to the IDirectInputDevice for the device.
+ * @param subtype The subtype of mouse, as defined in the DIDEVTYPE
+ * constants above
+ * @param productName The product name for the keyboard
+ * @param instanceName The name of the keyboard
+ * @return The new DirectInputMouse object.
+ */
+ public static DirectInputMouse createMouse(long lpDevice, int subtype,
+ String productName, String instanceName) {
+ return new DirectInputMouse(lpDevice, subtype, productName,
+ instanceName);
+ }
+
+ /**
+ * Implementation class representing the mouse ball
+ */
+ class BallImpl extends Ball {
+
+ /**
+ * Public constructor
+ */
+ public BallImpl() {
+ super(DirectInputMouse.this.getName() + " ball");
+ x = new BallAxis(Axis.Identifier.X);
+ y = new BallAxis(Axis.Identifier.Y);
+ wheel = new BallAxis(Axis.Identifier.SLIDER);
+ }
+ } // class DirectInputMouse.BallImpl
+
+ /**
+ * Implementation class representing the mouse buttons
+ */
+ class ButtonsImpl extends Buttons {
+
+ /**
+ * Public constructor
+ */
+ public ButtonsImpl() {
+ super(DirectInputMouse.this.getName() + " buttons");
+ left = new ButtonImpl(ButtonID.LEFT);
+ right = new ButtonImpl(ButtonID.RIGHT);
+ middle = new ButtonImpl(ButtonID.MIDDLE);
+ }
+ } // class DirectInputMouse.ButtonsImpl
+
+ /**
+ * Polls the device; native method
+ */
+ private native boolean pollNative(long lpDevice, byte[] mouseData);
+
+ /**
+ * Renames the axes with the name provided by DirectInput
+ */
+ private native boolean renameAxes(long lpDevice);
+
+ /**
+ * Mouse button axis implementation
+ */
+ class ButtonImpl extends Button {
+
+ /**
+ * Index into the mouseData array
+ */
+ private final int index;
+
+ /** Public constructor
+ * @param id An ID of a button to create an obejct to represent.
+ *
+ */
+ public ButtonImpl(ButtonID id) {
+ super(id.getName(), id);
+ if (id == ButtonID.LEFT) {
+ index = 12;
+ } else if (id == ButtonID.RIGHT) {
+ index = 13;
+ } else if (id == ButtonID.MIDDLE) {
+ index = 14;
+ } else {
+ throw new RuntimeException("Unknown button");
+ }
+ }
+
+ /** Returns the data from the last time the control has been polled.
+ * If this axis is a button, the value returned will be either 0.0f or 1.0f.
+ * If this axis is normalized, the value returned will be between -1.0f and
+ * 1.0f.
+ * @return state of controller. (Note: DX8 mice actually
+ * queue state so what is returned is the next state,
+ * not necessarily the most current one.)
+ */
+ public float getPollData() {
+ // Mouse button
+ byte data = mouseData[index];
+ if ((data & 0x80) != 0) {
+ return 1.0f;
+ } else {
+ return 0.0f;
+ }
+ }
+
+ /** Returns <code>true</code> if data returned from <code>poll</code>
+ * is relative to the last call, or <code>false</code> if data
+ * is absolute.
+ * @return true if data is relative, otherwise false.
+ */
+ public boolean isRelative() {
+ return false;
+ }
+ } // class DirectInputMouse.ButtonImpl
+
+ /**
+ * Mouse ball axis implementation
+ */
+ class BallAxis extends AbstractAxis {
+
+ /**
+ * Starting index into the mouseData array
+ */
+ private final int index;
+
+ /** Public constructor
+ * @param id An ID for a mouse axis to create an object to represent.
+ */
+ public BallAxis(Identifier id) {
+ super(id.getName(), id);
+ if (id == Identifier.X) {
+ index = 0;
+ } else if (id == Identifier.Y) {
+ index = 4;
+ } else if (id == Identifier.SLIDER) {
+ index = 8;
+ } else {
+ throw new RuntimeException("Unknown mouse axis");
+ }
+ }
+
+ /** Returns the data from the last time the control has been polled.
+ * If this axis is a button, the value returned will be either 0.0f or 1.0f.
+ * If this axis is normalized, the value returned will be between -1.0f and
+ * 1.0f.
+ * @return data. (Note that mice queue state in DX8 so what
+ * is returned is the next stae in the queue, not
+ * necessarily the most current one.)
+ */
+ public float getPollData() {
+ int data = ((int)mouseData[index] << 12) |
+ ((int)mouseData[index + 1] << 8) |
+ ((int)mouseData[index + 2] << 4) |
+ ((int)mouseData[index + 3]);
+ if (data == -1) {
+ return -1.0f;
+ } else if (data >= 1) {
+ return 1.0f;
+ } else {
+ return 0.0f;
+ }
+ }
+
+ /** Returns <code>true</code> if data returned from <code>poll</code>
+ * is relative to the last call, or <code>false</code> if data
+ * is absolute.
+ * @return true if relative, otherwise false.
+ */
+ public boolean isRelative() {
+ return true;
+ }
+
+ /** Returns whether or not the axis is analog, or false if it is digital.
+ * @return true if analog, false if digital
+ */
+ public boolean isAnalog() {
+ return true;
+ }
+ } // class DirectInputMouse.MouseBallAxis
+} // class DirectInputMouse
diff --git a/plugins/DX8/src/native/input.cpp b/plugins/DX8/src/native/input.cpp
new file mode 100644
index 0000000..ccfda2f
--- /dev/null
+++ b/plugins/DX8/src/native/input.cpp
@@ -0,0 +1,888 @@
+/*
+ * %W% %E%
+ *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+#ifndef WIN32
+ #error This is a Windows-only file
+#endif
+
+// hard define as DX7
+//#define DIRECTINPUT_VERSION 0x0800
+#include <windows.h>
+#include <jni.h>
+#include <dinput.h>
+
+
+/*
+ ******************************************************************************
+ * Global variables
+ ******************************************************************************
+ */
+jclass CLASS_AxisIdentifier = NULL;
+jclass CLASS_ButtonIdentifier = NULL;
+jclass CLASS_DirectInputEnvironmentPlugin = NULL;
+jclass CLASS_DirectInputDevice = NULL;
+jclass CLASS_DirectInputKeyboard = NULL;
+jclass CLASS_DirectInputMouse = NULL;
+jmethodID MID_AddDevice = NULL;
+jmethodID MID_AddAxis = NULL;
+jmethodID MID_RenameKey = NULL;
+jmethodID MID_RenameAxis = NULL;
+jfieldID FID_X = NULL;
+jfieldID FID_Y = NULL;
+jfieldID FID_Z = NULL;
+jfieldID FID_RX = NULL;
+jfieldID FID_RY = NULL;
+jfieldID FID_RZ = NULL;
+jfieldID FID_Slider = NULL;
+jfieldID FID_Button = NULL;
+jfieldID FID_POV = NULL;
+jfieldID FID_Left = NULL;
+jfieldID FID_Right = NULL;
+jfieldID FID_Middle = NULL;
+
+const char* FD_AxisIdentifier = "Lnet/java/games/input/Axis$Identifier;";
+const char* FD_ButtonIdentifier = "Lnet/java/games/input/Mouse$ButtonID;";
+// Dummy input window. This is needed because DirectX evidently needs a window
+// to do anything, such as setting the cooperative level for a device.
+const TCHAR* DUMMY_WINDOW_NAME = "InputControllerWindow";
+HWND hwndDummy = NULL;
+// Buffer size
+const DWORD BUFFER_SIZE = 16;
+
+// Class for handing device data to the callback for EnumDevices
+class DeviceParamData {
+public:
+ DeviceParamData(LPDIRECTINPUT8 lpdi, JNIEnv* e, jobject o, jobject l) :
+ lpDirectInput(lpdi), env(e), obj(o), list(l)
+ {
+ }
+ LPDIRECTINPUT8 lpDirectInput;
+ JNIEnv* env;
+ jobject obj;
+ jobject list;
+};
+
+// Class for handing device data to the callback for EnumObjects
+class ObjectParamData {
+public:
+ ObjectParamData(LPDIRECTINPUTDEVICE8 lpDev, JNIEnv* e, jobject o,
+ jobject l) :
+ lpDevice(lpDev), env(e), obj(o), list(l)
+ {
+ }
+ LPDIRECTINPUTDEVICE8 lpDevice;
+ JNIEnv* env;
+ jobject obj;
+ jobject list;
+};
+
+void PrintOutput(TCHAR* tszMessage) {
+ printf("%s\n", tszMessage);
+}
+
+void PrintDIError(TCHAR* tszOutput, HRESULT res) {
+ TCHAR tszMessage[256];
+#define CHECK_RESULT(r) case r: \
+sprintf(tszMessage, "%s : %s", tszOutput, #r); \
+break;
+ switch (res) {
+ CHECK_RESULT(DI_OK)
+ CHECK_RESULT(DI_NOTATTACHED)
+ CHECK_RESULT(DI_POLLEDDEVICE)
+ CHECK_RESULT(DI_DOWNLOADSKIPPED)
+ CHECK_RESULT(DI_EFFECTRESTARTED)
+ CHECK_RESULT(DI_TRUNCATED)
+ CHECK_RESULT(DI_TRUNCATEDANDRESTARTED)
+ CHECK_RESULT(DIERR_OLDDIRECTINPUTVERSION)
+ CHECK_RESULT(DIERR_BETADIRECTINPUTVERSION)
+ CHECK_RESULT(DIERR_BADDRIVERVER)
+ CHECK_RESULT(DIERR_DEVICENOTREG)
+ CHECK_RESULT(DIERR_NOTFOUND)
+ //CHECK_RESULT(DIERR_OBJECTNOTFOUND)
+ CHECK_RESULT(DIERR_INVALIDPARAM)
+ CHECK_RESULT(DIERR_NOINTERFACE)
+ CHECK_RESULT(DIERR_GENERIC)
+ CHECK_RESULT(DIERR_OUTOFMEMORY)
+ CHECK_RESULT(DIERR_UNSUPPORTED)
+ CHECK_RESULT(DIERR_NOTINITIALIZED)
+ CHECK_RESULT(DIERR_ALREADYINITIALIZED)
+ CHECK_RESULT(DIERR_NOAGGREGATION)
+ CHECK_RESULT(DIERR_OTHERAPPHASPRIO)
+ CHECK_RESULT(DIERR_INPUTLOST)
+ CHECK_RESULT(DIERR_ACQUIRED)
+ CHECK_RESULT(DIERR_NOTACQUIRED)
+ //CHECK_RESULT(DIERR_READONLY)
+ //CHECK_RESULT(DIERR_HANDLEEXISTS)
+ CHECK_RESULT(DIERR_INSUFFICIENTPRIVS)
+ CHECK_RESULT(DIERR_DEVICEFULL)
+ CHECK_RESULT(DIERR_MOREDATA)
+ CHECK_RESULT(DIERR_NOTDOWNLOADED)
+ CHECK_RESULT(DIERR_HASEFFECTS)
+ CHECK_RESULT(DIERR_NOTEXCLUSIVEACQUIRED)
+ CHECK_RESULT(DIERR_INCOMPLETEEFFECT)
+ CHECK_RESULT(DIERR_NOTBUFFERED)
+ CHECK_RESULT(DIERR_EFFECTPLAYING)
+ CHECK_RESULT(DIERR_UNPLUGGED)
+ CHECK_RESULT(DIERR_REPORTFULL)
+ default: sprintf(tszMessage, "Unknown"); break;
+ }
+ PrintOutput(tszMessage);
+}
+
+/*
+ ******************************************************************************
+ * DirectInputEnvironmentPlugin
+ ******************************************************************************
+ */
+
+/*
+ * Initialize all class, method, and field IDs
+ */
+BOOL InitIDs(JNIEnv* env) {
+ CLASS_AxisIdentifier =
+ env->FindClass("net/java/games/input/Axis$Identifier");
+ if (CLASS_AxisIdentifier == NULL) {
+ return FALSE;
+ }
+ FID_X = env->GetStaticFieldID(CLASS_AxisIdentifier, "X",
+ FD_AxisIdentifier);
+ if (FID_X == NULL) {
+ return FALSE;
+ }
+ FID_Y = env->GetStaticFieldID(CLASS_AxisIdentifier, "Y",
+ FD_AxisIdentifier);
+ if (FID_Y == NULL) {
+ return FALSE;
+ }
+ FID_Z = env->GetStaticFieldID(CLASS_AxisIdentifier, "Z",
+ FD_AxisIdentifier);
+ if (FID_Z == NULL) {
+ return FALSE;
+ }
+ FID_RX = env->GetStaticFieldID(CLASS_AxisIdentifier, "RX",
+ FD_AxisIdentifier);
+ if (FID_RX == NULL) {
+ return FALSE;
+ }
+ FID_RY = env->GetStaticFieldID(CLASS_AxisIdentifier, "RY",
+ FD_AxisIdentifier);
+ if (FID_RY == NULL) {
+ return FALSE;
+ }
+ FID_RZ = env->GetStaticFieldID(CLASS_AxisIdentifier, "RZ",
+ FD_AxisIdentifier);
+ if (FID_RZ == NULL) {
+ return FALSE;
+ }
+ FID_Slider = env->GetStaticFieldID(CLASS_AxisIdentifier, "SLIDER",
+ FD_AxisIdentifier);
+ if (FID_Slider == NULL) {
+ return FALSE;
+ }
+ FID_Button = env->GetStaticFieldID(CLASS_AxisIdentifier, "BUTTON",
+ FD_AxisIdentifier);
+ if (FID_Button == NULL) {
+ return FALSE;
+ }
+ FID_POV = env->GetStaticFieldID(CLASS_AxisIdentifier, "POV",
+ FD_AxisIdentifier);
+ if (FID_POV == NULL) {
+ return FALSE;
+ }
+ CLASS_ButtonIdentifier =
+ env->FindClass("net/java/games/input/Mouse$ButtonID");
+ if (CLASS_ButtonIdentifier == NULL) {
+ return FALSE;
+ }
+ FID_Left = env->GetStaticFieldID(CLASS_ButtonIdentifier, "LEFT",
+ FD_ButtonIdentifier);
+ if (FID_Left == NULL) {
+ return FALSE;
+ }
+ FID_Right = env->GetStaticFieldID(CLASS_ButtonIdentifier, "RIGHT",
+ FD_ButtonIdentifier);
+ if (FID_Right == NULL) {
+ return FALSE;
+ }
+ FID_Middle = env->GetStaticFieldID(CLASS_ButtonIdentifier, "MIDDLE",
+ FD_ButtonIdentifier);
+ if (FID_Middle == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputEnvironmentPlugin =
+ env->FindClass("net/java/games/input/DirectInputEnvironmentPlugin");
+ if (CLASS_DirectInputEnvironmentPlugin == NULL) {
+ return FALSE;
+ }
+ MID_AddDevice = env->GetMethodID(CLASS_DirectInputEnvironmentPlugin, "addDevice",
+ "(Ljava/util/ArrayList;JILjava/lang/String;Ljava/lang/String;Z)V");
+ if (MID_AddDevice == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputDevice =
+ env->FindClass("net/java/games/input/DirectInputDevice");
+ if (CLASS_DirectInputDevice == NULL) {
+ return FALSE;
+ }
+ MID_AddAxis = env->GetMethodID(CLASS_DirectInputDevice, "addAxis",
+ "(Ljava/util/ArrayList;Lnet/java/games/input/Axis$Identifier;ILjava/lang/String;)V");
+ if (MID_AddAxis == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputKeyboard =
+ env->FindClass("net/java/games/input/DirectInputKeyboard");
+ if (CLASS_DirectInputKeyboard == NULL) {
+ return FALSE;
+ }
+ MID_RenameKey = env->GetMethodID(CLASS_DirectInputKeyboard, "renameKey",
+ "(ILjava/lang/String;)V");
+ if (MID_RenameKey == NULL) {
+ return FALSE;
+ }
+ CLASS_DirectInputMouse =
+ env->FindClass("net/java/games/input/DirectInputMouse");
+ if (CLASS_DirectInputMouse == NULL) {
+ return FALSE;
+ }
+ MID_RenameAxis = env->GetMethodID(CLASS_DirectInputMouse, "renameAxis",
+ "(Lnet/java/games/input/Axis$Identifier;Ljava/lang/String;)V");
+ if (MID_RenameAxis == NULL) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * WndProc for our dummy input window
+ */
+LRESULT CALLBACK DummyWndProc(
+ HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/*
+ * Register the dummy input window class
+ */
+BOOL RegisterDummyWindow(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)DummyWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = NULL;
+ wcex.hCursor = NULL;
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = (LPCSTR)NULL;
+ wcex.lpszClassName = DUMMY_WINDOW_NAME;
+ wcex.hIconSm = NULL;
+ return RegisterClassEx(&wcex);
+}
+
+/*
+ * Class: org_java_games_input_DirectInputEnvironmentPlugin
+ * Method: directInputCreate
+ * Signature: ()J
+ */
+extern "C" JNIEXPORT jlong JNICALL
+Java_net_java_games_input_DirectInputEnvironmentPlugin_directInputCreate
+ (JNIEnv* env, jobject obj)
+{
+ // Get our module handle
+ HINSTANCE hInst = GetModuleHandle(NULL);
+
+ // Register the dummy input window
+ if (!RegisterDummyWindow(hInst)) {
+ return (jlong)0;
+ }
+
+ // Create the dummy input window
+ hwndDummy = CreateWindow(DUMMY_WINDOW_NAME, NULL,
+ WS_POPUP | WS_ICONIC,
+ 0, 0, 0, 0, NULL, NULL, hInst, NULL);
+ if (hwndDummy == NULL)
+ {
+ return (jlong)0;
+ }
+
+ // Create the IDirectInput object
+ DWORD dwVersion = DIRECTINPUT_VERSION;
+ LPDIRECTINPUT8 lpDirectInput = NULL;
+ HRESULT res;
+ if (FAILED(res = DirectInput8Create(hInst, DIRECTINPUT_VERSION,
+ IID_IDirectInput8,(VOID **)&lpDirectInput, NULL))){
+ PrintDIError("DirectInputCreate", res);
+ return (jlong)0;
+ }
+
+ // Initialize method, class, and field IDs
+ if (!InitIDs(env)) {
+ lpDirectInput->Release();
+ return (jlong)0;
+ }
+
+ return (jlong)(long)lpDirectInput;
+}
+
+/*
+ * Enumeration callback for devices
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+
+/** mikes old enum callback
+BOOL CALLBACK EnumDeviceCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+ DeviceParamData* pData = (DeviceParamData*)pvRef;
+ LPDIRECTINPUT8 lpDirectInput = pData->lpDirectInput;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ LPDIRECTINPUTDEVICE8 lpDevice = NULL;
+ LPUNKNOWN pUnknown = NULL;
+
+ // Create the device object
+ HRESULT res = lpDirectInput->CreateDevice(lpddi->guidInstance, &lpDevice,
+ pUnknown);
+ if (res != DI_OK) {
+ PrintDIError("CreateDevice", res);
+ return DIENUM_STOP;
+ }
+
+ LPDIRECTINPUTDEVICE8 lpDevice2 = NULL;
+ // Get the IDirectDrawDevice8 interface from the object
+ res = lpDevice->QueryInterface(IID_IDirectInputDevice8,
+ (void**)&lpDevice2);
+ if (res != DI_OK) {
+ PrintDIError("QueryInterface DID2", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the data format
+ DWORD category = GET_DIDEVICE_TYPE(lpddi->dwDevType);
+ LPCDIDATAFORMAT lpDataFormat = &c_dfDIJoystick;
+ if (category == DI8DEVTYPE_MOUSE) {
+ lpDataFormat = &c_dfDIMouse;
+ } else if (category == DI8DEVTYPE_KEYBOARD) {
+ lpDataFormat = &c_dfDIKeyboard;
+ }
+ res = lpDevice2->SetDataFormat(lpDataFormat);
+ if (res != DI_OK) {
+ PrintDIError("SetDataFormat", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // If we are the mouse, we have to buffer the data
+ if (category == DI8DEVTYPE_MOUSE) {
+ DIPROPDWORD dipropdw;
+ dipropdw.diph.dwSize = sizeof(DIPROPDWORD);
+ dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dipropdw.diph.dwObj = 0;
+ dipropdw.diph.dwHow = DIPH_DEVICE;
+ dipropdw.dwData = BUFFER_SIZE;
+ res = lpDevice2->SetProperty(DIPROP_BUFFERSIZE, &dipropdw.diph);
+ if (res != DI_OK) {
+ PrintDIError("SetProperty", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ }
+
+ // Set the cooperative level
+ res = lpDevice2->SetCooperativeLevel(hwndDummy,
+ DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
+ if (res != DI_OK) {
+ PrintDIError("SetCooperativeLevel", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Acquire the device
+ res = lpDevice2->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the variables for the Java callback
+ jint type = (jint)lpddi->dwDevType;
+ jstring productName = env->NewStringUTF(lpddi->tszProductName);
+ if (productName == NULL) {
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jstring instanceName = env->NewStringUTF(lpddi->tszInstanceName);
+ if (instanceName == NULL) {
+ lpDevice2->Release();
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Add the device into the list
+ env->CallVoidMethod(obj, MID_AddDevice, list, (jlong)(long)lpDevice2, type,
+ productName, instanceName);
+ return DIENUM_CONTINUE;
+}
+*/
+/** jeff's new enum callback */
+BOOL CALLBACK EnumDeviceCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+ DeviceParamData* pData = (DeviceParamData*)pvRef;
+ LPDIRECTINPUT8 lpDirectInput = pData->lpDirectInput;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ LPDIRECTINPUTDEVICE8 lpDevice = NULL;
+ LPUNKNOWN pUnknown = NULL;
+ HRESULT res;
+
+ // Create the device object
+ if (FAILED(res = lpDirectInput->CreateDevice(lpddi->guidInstance, &lpDevice,
+ pUnknown))){
+ PrintDIError("CreateDevice", res);
+ return DIENUM_STOP;
+ }
+
+ /*
+ LPDIRECTINPUTDEVICE8 lpDevice2 = NULL;
+ // Get the IDirectDrawDevice8 interface from the object
+ res = lpDevice->QueryInterface(IID_IDirectInputDevice8,
+ (void**)&lpDevice2);
+ if (res != DI_OK) {
+ PrintDIError("QueryInterface DID2", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ */
+
+ // Set the data format
+ LPCDIDATAFORMAT lpDataFormat;
+ DWORD category = GET_DIDEVICE_TYPE(lpddi->dwDevType)&0xFF;
+ switch (category){
+ case DI8DEVTYPE_KEYBOARD:
+ //printf("found Keyboard\n");
+ lpDataFormat = &c_dfDIKeyboard;
+ break;
+ case DI8DEVTYPE_MOUSE:
+ //printf("found mouse\n");
+ lpDataFormat = &c_dfDIMouse;
+ // set up buffering
+ DIPROPDWORD dipropdw;
+ dipropdw.diph.dwSize = sizeof(DIPROPDWORD);
+ dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ dipropdw.diph.dwObj = 0;
+ dipropdw.diph.dwHow = DIPH_DEVICE;
+ dipropdw.dwData = BUFFER_SIZE;
+ if (FAILED(
+ res = lpDevice->SetProperty(DIPROP_BUFFERSIZE,
+ &dipropdw.diph))) {
+ PrintDIError("SetProperty", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ break;
+ case DI8DEVTYPE_JOYSTICK:
+ default:
+ //printf("found stick\n");
+ lpDataFormat = &c_dfDIJoystick;
+ break;
+ }
+
+ if (FAILED(res = lpDevice->SetDataFormat(lpDataFormat))){
+ PrintDIError("SetDataFormat", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the cooperative level
+ if(FAILED(res = lpDevice->SetCooperativeLevel(hwndDummy,
+ DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))){
+ PrintDIError("SetCooperativeLevel", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // get polling
+ DIDEVCAPS didc;
+ // Allocate space for all the device's objects (axes, buttons, POVS)
+ ZeroMemory( &didc, sizeof(DIDEVCAPS) );
+ didc.dwSize = sizeof(DIDEVCAPS);
+ if (FAILED(res=lpDevice->GetCapabilities(&didc))){
+ PrintDIError("Get Device Capabilities", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jboolean polled = JNI_FALSE;
+ if ((didc.dwFlags)&DIDC_POLLEDDATAFORMAT) {
+ polled = JNI_TRUE;
+ }
+
+ // Acquire the device
+ if(FAILED(res = lpDevice->Acquire())){
+ PrintDIError("Acquire", res);
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Set the variables for the Java callback
+ jint type = (jint)lpddi->dwDevType&0xffff;
+ //printf("type == %x\n",type);
+ jstring productName = env->NewStringUTF(lpddi->tszProductName);
+ if (productName == NULL) {
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+ jstring instanceName = env->NewStringUTF(lpddi->tszInstanceName);
+ if (instanceName == NULL) {
+ lpDevice->Release();
+ return DIENUM_STOP;
+ }
+
+ // Add the device into the list
+ env->CallVoidMethod(obj, MID_AddDevice, list, (jlong)(long)lpDevice, type,
+ productName, instanceName,(jboolean)polled);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputEnvironmentPlugin
+ * Method: enumDevices
+ * Signature: (JLjava/util/ArrayList;)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputEnvironmentPlugin_enumDevices
+ (JNIEnv* env, jobject obj, jlong lDirectInput, jobject list)
+{
+ LPDIRECTINPUT8 lpDirectInput = (LPDIRECTINPUT8)(long)lDirectInput;
+ DWORD dwDevType = DI8DEVCLASS_ALL;
+ DeviceParamData data(lpDirectInput, env, obj, list);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIEDFL_ATTACHEDONLY;
+ HRESULT res;
+ if(FAILED(res=lpDirectInput->EnumDevices(dwDevType,
+ EnumDeviceCallback, pvRef, dwFlags))){
+ PrintDIError("EnumDevices", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputDevice
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputDevice
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputDevice_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jintArray baData,
+ jboolean pollme)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Poll the device
+ if (pollme == JNI_TRUE) {
+ res = lpDevice->Poll();
+ if (res != DI_OK) {
+ PrintDIError("Poll", res);
+ return JNI_FALSE;
+ }
+ }
+ // Get the device state (data)
+ DIJOYSTATE data;
+ res = lpDevice->GetDeviceState(sizeof(data), &data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ // Copy the data into the byte array
+ env->SetIntArrayRegion(baData, 0, (jsize)(sizeof(data)/4), (jint*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback for device objects
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK EnumObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject list = pData->list;
+ jobject identifier = NULL;
+ HRESULT res;
+ if (lpddoi->guidType == GUID_XAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_X);
+ } else if (lpddoi->guidType == GUID_YAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Y);
+ } else if (lpddoi->guidType == GUID_ZAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Z);
+ } else if (lpddoi->guidType == GUID_RxAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RX);
+ } else if (lpddoi->guidType == GUID_RyAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RY);
+ } else if (lpddoi->guidType == GUID_RzAxis) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_RZ);
+ } else if (lpddoi->guidType == GUID_Slider) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Slider);
+ } else if (lpddoi->guidType == GUID_Button) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_Button);
+ } else if (lpddoi->guidType == GUID_POV) {
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier, FID_POV);
+ } else {
+ // Do not add this axis into the list, since we don't know what it is
+ return DIENUM_CONTINUE;
+ }
+ if (identifier == NULL) {
+ return DIENUM_STOP;
+ }
+ if (DIDFT_GETTYPE(lpddoi->dwType)&DIDFT_AXIS){
+ // set axis range
+ DIPROPRANGE joy_axis_range;
+ joy_axis_range.lMin = -32768;
+ joy_axis_range.lMax = 32768;
+ joy_axis_range.diph.dwSize=sizeof(DIPROPRANGE);
+ joy_axis_range.diph.dwHeaderSize=sizeof(DIPROPHEADER);
+ joy_axis_range.diph.dwHow = DIPH_BYID;
+ joy_axis_range.diph.dwObj=lpddoi->dwType;
+ if (FAILED(
+ res=lpDevice->SetProperty(DIPROP_RANGE,&joy_axis_range.diph))){
+ PrintDIError("SetProperty", res);
+ }
+ }
+ jint didft = (jint)lpddoi->dwType;
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ // Add the axis into our list
+ env->CallVoidMethod(obj, MID_AddAxis, list, identifier, didft,
+ name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputDevice
+ * Method: enumObjects
+ * Signature: (JLjava/util/ArrayList;)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputDevice_enumObjects
+ (JNIEnv* env, jobject obj, jlong lDevice, jobject list)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, list);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(EnumObjectsCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputKeyboard
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputKeyboard
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputKeyboard_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Get the device state (data)
+ char data[256];
+ res = lpDevice->GetDeviceState(sizeof(data), data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback to rename keyboard keys
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK RenameKeysCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jint index = (jint)lpddoi->dwOfs;
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ env->CallVoidMethod(obj, MID_RenameKey, index, name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputKeyboard
+ * Method: renameKeys
+ * Signature: (J)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputKeyboard_renameKeys
+ (JNIEnv* env, jobject obj, jlong lDevice)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, NULL);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(RenameKeysCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/*
+ ******************************************************************************
+ * DirectInputMouse
+ ******************************************************************************
+ */
+
+/*
+ * Class: org_java_games_input_DirectInputMouse
+ * Method: pollNative
+ * Signature: (J[B)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputMouse_pollNative
+ (JNIEnv* env, jobject obj, jlong lDevice, jbyteArray baData)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ // Reacquire the device
+ HRESULT res = lpDevice->Acquire();
+ if (res != DI_OK && res != S_FALSE) {
+ PrintDIError("Acquire", res);
+ return JNI_FALSE;
+ }
+ // Get the data
+ DIMOUSESTATE data;
+ res = lpDevice->GetDeviceState(sizeof(data), &data);
+ if (res != DI_OK) {
+ PrintDIError("GetDeviceState", res);
+ return JNI_FALSE;
+ }
+ // Set the data in our array
+ env->SetByteArrayRegion(baData, 0, (jsize)sizeof(data), (jbyte*)&data);
+ return JNI_TRUE;
+}
+
+/*
+ * Enumeration callback to rename mouse axes
+ *
+ * returns DIENUM_CONTINUE or DIENUM_STOP
+ */
+BOOL CALLBACK RenameAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi,
+ LPVOID pvRef)
+{
+ ObjectParamData* pData = (ObjectParamData*)pvRef;
+ //LPDIRECTINPUTDEVICE8 lpDevice = pData->lpDevice;
+ JNIEnv* env = pData->env;
+ jobject obj = pData->obj;
+ jobject identifier;
+ switch (lpddoi->dwOfs) {
+ case DIMOFS_X:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_X);
+ break;
+ case DIMOFS_Y:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_Y);
+ break;
+ case DIMOFS_Z:
+ identifier = env->GetStaticObjectField(CLASS_AxisIdentifier,
+ FID_Slider);
+ break;
+ case DIMOFS_BUTTON0:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Left);
+ break;
+ case DIMOFS_BUTTON1:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Right);
+ break;
+ case DIMOFS_BUTTON2:
+ identifier = env->GetStaticObjectField(CLASS_ButtonIdentifier,
+ FID_Middle);
+ break;
+ case DIMOFS_BUTTON3:
+ default:
+ return DIENUM_CONTINUE; // Not an axis we know
+ }
+ jstring name = env->NewStringUTF(lpddoi->tszName);
+ env->CallVoidMethod(obj, MID_RenameAxis, identifier, name);
+ return DIENUM_CONTINUE;
+}
+
+/*
+ * Class: org_java_games_input_DirectInputMouse
+ * Method: renameAxes
+ * Signature: (J)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_net_java_games_input_DirectInputMouse_renameAxes
+ (JNIEnv* env, jobject obj, jlong lDevice)
+{
+ LPDIRECTINPUTDEVICE8 lpDevice = (LPDIRECTINPUTDEVICE8)(long)lDevice;
+ ObjectParamData data(lpDevice, env, obj, NULL);
+ LPVOID pvRef = (LPVOID)&data;
+ DWORD dwFlags = DIDFT_ALL;
+ // Enum objects
+ HRESULT res = lpDevice->EnumObjects(RenameAxesCallback, pvRef, dwFlags);
+ if (res != DI_OK) {
+ PrintDIError("EnumObjects", res);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+