#!/usr/bin/perl

use strict;
use Win32::API;

my $VERSION = 0.2;

=head1 NAME

win32_joystick.pl - demo showing how to read joystick data from perl under windows

=head1 SYNOPSIS

    win32_joystick.pl [joynumber]

=head1 DESCRIPTION

This B<win32_joystick.pl> demo continuously prints out the
attached joystick data until you press CTRL-C.

It displays joystick 0 by default.  If you've got more 
than 1 joystick, run the program with a numeric paramater;
eg:  win32_joystick.pl 1

=head1 OPTIONS

=over

=item B<none>

this demo has no options

=back

=head1 README

Needs Win32::API installed

=head1 PREREQUISITES

This script requires C<Win32::API 0.20>.

=pod OSNAMES

MSWin32

=pod SCRIPT CATEGORIES

Win32

=head1 AUTHOR

Written by Chris Drake.

=head1 SEE ALSO

MSDN - I'd put some URL in here, but they change almost weekly
so it would end up giving 404's by the time you read this :-)
Search joyGetPosEx or something...

=head1 COPYRIGHT

Copyright �� 2011 The Chris Drake Team.

This is Free Software; this software is licensed under the GPL version 2, as published by the Free Software Foundation.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

=cut


use strict;


# How many joysticks does the driver support?
my $joyGetNumDevs=Win32::API->new('WinMM', 'int joyGetNumDevs()');
print "joyGetNumDevs=";
print $joyGetNumDevs->Call();
print "\n";


# Define the structure we need to get all this info (might already be defined in Win32::API - I didn't look)
  typedef Win32::API::Struct JOYINFOEX => (
    'LONG', 'dwSize',		# size of structure        
    'LONG', 'dwFlags',		# flags to indicate what to return        
    'LONG', 'dwXpos',		# x position        
    'LONG', 'dwYpos',		# y position        
    'LONG', 'dwZpos',		# z position        
    'LONG', 'dwRpos',		# rudder/4th axis position        
    'LONG', 'dwUpos',		# 5th axis position        
    'LONG', 'dwVpos',		# 6th axis position        
    'LONG', 'dwButtons',	# button states        
    'LONG', 'dwButtonNumber',	# current button number pressed        
    'LONG', 'dwPOV',		# point of view state        
    'LONG', 'dwReserved1',	# reserved for communication between winmm driver        
    'LONG', 'dwReserved2',	# reserved for future expansion
  );

my $joyinfoex=Win32::API::Struct->new( 'JOYINFOEX' ); # Register the structure

# Windows wants us to fill in some parts of the structure before we use it:
$joyinfoex->{dwSize}=Win32::API::Struct::sizeof($joyinfoex);
$joyinfoex->{dwFlags}= 0x01 |  0x02 |  0x04 |  0x08 |  0x10 |  0x20 |  0x40 |  0x80; # JOY_RETURNX JOY_RETURNY JOY_RETURNZ JOY_RETURNR JOY_RETURNU JOY_RETURNV JOY_RETURNPOV JOY_RETURNBUTTONS

# "import" the call we need to get the joystick data.
my $joyGetPosEx=Win32::API->new('WinMM', 'int joyGetPosEx(int a, JOYINFOEX *p)');

# Show a demo return value;
print "joyGetPosEx=";
my $ret=$joyGetPosEx->Call($ARGV[0] || 0,$joyinfoex);
print "$ret\n";

if($ret!=0) {
  print "non-zero return code means some kind of error.\n";
  print "if it's 165 - your joystick is probably off or not connected/detected?\n";
  print "sleeping 5 seonnds...\n";sleep(5);
}

# Show demo first results
print "dwSize=" . $joyinfoex->{ 'dwSize' } . "\n";
print "dwFlags=" . $joyinfoex->{ 'dwFlags' } . "\n";
print "dwXpos=" . $joyinfoex->{ 'dwXpos' } . "\n";
print "dwYpos=" . $joyinfoex->{ 'dwYpos' } . "\n";
print "dwZpos=" . $joyinfoex->{ 'dwZpos' } . "\n";
print "dwRpos=" . $joyinfoex->{ 'dwRpos' } . "\n";
print "dwUpos=" . $joyinfoex->{ 'dwUpos' } . "\n";
print "dwVpos=" . $joyinfoex->{ 'dwVpos' } . "\n";
print "dwButtons=" . $joyinfoex->{ 'dwButtons' } . "\n";
print "dwButtonNumber=" . $joyinfoex->{ 'dwButtonNumber' } . "\n";
print "dwPOV=" . $joyinfoex->{ 'dwPOV' } . "\n";
print "dwReserved1=" . $joyinfoex->{ 'dwReserved1' } . "\n";
print "dwReserved2=" . $joyinfoex->{ 'dwReserved2' } . "\n";

print "If you don't see numbers above, your joystick isn't connected or turned on...\n";
print "looping in 2 seconds...\n";
sleep(2);

while(1) {
  print $joyGetPosEx->Call($ARGV[0],$joyinfoex) . ' ';
  foreach my $i (qw( dwSize dwFlags dwXpos dwYpos dwZpos dwRpos dwUpos dwVpos dwButtons dwButtonNumber dwPOV dwReserved1 dwReserved2 )) {
    print $joyinfoex->{$i} . ' ';
  }
  print "\n";
}

# The end.