2

I need to capture joystick input using C or Java (whichever is easier).

There are answers to similar questions but they all use C++ or C#.

The program only needs to get the direction and amount by which the joystick is tilted. I'm using Windows7, so I'll probably need to use winmm.dll as is explained here.
I would appreciate if someone could explain how to do so in C or Java.

Community
  • 1
  • 1
Richard
  • 162
  • 1
  • 4
  • 11
  • 1
    Did you realize that the function pointed to in the accepted answer you link to is a C function? – Mat Jan 28 '12 at 10:03

5 Answers5

2

There are premade libraries for both languages. The more important question would be the language you have to use or which one you'd prefer primarily. It doesn't necessarily make sense to add C code just to add such functionality to a Java program. In a similar way, you wouldn't want to call Java from C, just to get joystick input.

First hit on Google for "java joystick" has been this one. Haven't tried it yet.

As for C++ code (and most likely C# too) you should be able to use the same code in C, assuming it's pure Windows API code (cause that one is in C too). So you shouldn't have any issues adapting these.

Edit: Regarding the answer you linked: You should be able to use this solution 1:1 in C (in Java you'd have to write code essentially doing the same). But instead of declaring everything yourself, just #include <windows.h> and you should be ready to go (in C).

Mario
  • 35,726
  • 5
  • 62
  • 78
1

I recommend the Simple Directmedia Layer library for a pure C solution. The library is pleasant to use, and their documentation and code examples are great:

SDL_Joystick *joy;

// Initialize the joystick subsystem
SDL_InitSubSystem(SDL_INIT_JOYSTICK);

// Check for joystick
if(SDL_NumJoysticks()>0){
  // Open joystick
  joy=SDL_JoystickOpen(0);
  ...
blahdiblah
  • 33,069
  • 21
  • 98
  • 152
1

The C# solution is indeed pure Windows API code! In C just #include <windows.h> and instead of [DllImport("winmm.dll")] you link to winmm.lib. The following example should make it clear:

void printJoystickData()
{
   // The captured data will be written to the following struct:
   //typedef struct joyinfo_tag {
   //   UINT wXpos;
   //   UINT wYpos;
   //   UINT wZpos;
   //   UINT wButtons;
   //} JOYINFO,*PJOYINFO,*LPJOYINFO;
   JOYINFO joystickInfo;

   // The ID of the joystick you are using. If there is only one joystick use JOYSTICKID1.
   UINT joystickId = JOYSTICKID1;

   MMRESULT errorCode = joyGetPos(joystickId, &joystickInfo);
   switch(errorCode)
   {
       case JOYERR_NOERROR: // No error. joystickInfo now contains contains the captured data.
       {
           printf("The X position (left/right tilt) is %u\n", joystickInfo.wXpos);
           printf("The Y position (up/down tilt) is %u\n", joystickInfo.wYpos);
           printf("The Z position (usually the throttle) is %u\n", joystickInfo.wZpos);
           // These values range from 0 to 65536. 32768 is the centre position.

           // Test button 1. You can do the same for JOY_BUTTON2, JOY_BUTTON3 etc.
           // wButtons is a UNINT that is the OR of all pressed button flags.
           if(joystickInfo.wButtons & JOY_BUTTON1)
               printf("Button 1 was pressed.");

           break;
       }
       case JOYERR_PARMS: fprintf(stderr, "Invalid parameters to joyGetPos."); break;
       case JOYERR_NOCANDO: fprintf(stderr, " Failed to capture joystick input."); break;
       case JOYERR_UNPLUGGED: fprintf(stderr, "The joystick identified by joystickId isn't plugged in."); break;
       case MMSYSERR_NODRIVER: fprintf(stderr, "No (active) joystick driver available."); break;
   }
}

The Simple Directmedia Layer library (suggested by blahdiblah) also looks promising but for what I needed to do I think the code above is simpler.

For Java use the Central Nexus Device API as suggested by Mario. The download includes documentation.

Community
  • 1
  • 1
Richard
  • 162
  • 1
  • 4
  • 11
0

Refer this url for Gamepad.c and Gamepad.h files. https://github.com/elanthis/gamepad

Open the joystick using

STATE.fd = open(STATE.device, O_RDWR|O_NONBLOCK);

Structure Definition:

STATE is a structure object. //It is in Gamepad.h file

open returns -1 on failure. Set the flag value (defined while declaring variables for joystick) if opened successfully.

Read the joystick input using

     (read(STATE[gamepad].fd, &je, sizeof(je)) > 0) 

Structure Definition: je is a structure object //It is in joystick.h

je is updated now. je.type is one among the three things mentioned in the joystick.h header file If a button is pressed , then je.number is an int that denotes the button number as specified by the manufacturer. If a stick is moved , then je.number denotes the axis specification by the manufacturer. The magnitude is present in the je.value which is assigned to the stick's corresponding variable accordingly.

0

The sample you have linked to doesn't actually use anything object-oriented, which means you can quite easily port it to C.

C supports structs the same as C# (which are allocated on the stack), so that's basically copy-paste.

The one thing that might trip you up is the [DllImport] attribute. The purpose of this attribute is to p/invoke (platform invoke) an unmanaged DLL from within managed C# code. Here you would use extern to access the Windows API.

ose
  • 4,065
  • 2
  • 24
  • 40