#!/usr/bin/perl
#!/usr/bin/perl -d:ptkdb

###############################################################################
#
# libjoystick.pl -  Joystick controls
#
# Copyright (C) 2009  Rainer Walther  (rainerwalther-mail@web.de)
#
# Creative Commons Lizenz mit den Zusaetzen (by, nc, sa)
#
# Es ist Ihnen gestattet: 
#     * das Werk vervielfältigen, verbreiten und öffentlich zugänglich machen
#     * Abwandlungen bzw. Bearbeitungen des Inhaltes anfertigen
# 
# Zu den folgenden Bedingungen:
#     * Namensnennung.
#       Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
#     * Keine kommerzielle Nutzung.
#       Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden.
#     * Weitergabe unter gleichen Bedingungen.
#       Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten,
#       verändern oder als Grundlage für einen anderen Inhalt verwenden,
#       dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen
#       weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.
# 
# Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen, unter welche dieses
# Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden.
# 
# Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie die Einwilligung
# des Rechteinhabers dazu erhalten.
# 
# Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.
# 
# Weitere Details zur Lizenzbestimmung gibt es hier:
#   Kurzform: http://creativecommons.org/licenses/by-nc-sa/3.0/de/
#   Komplett: http://creativecommons.org/licenses/by-nc-sa/3.0/de/legalcode
#
###############################################################################
#
# 2009-12-06 0.0.1 rw created
# 2010-06-20 0.0.2 rw check hasPOV
#
###############################################################################

$Version{'libjoystick.pl'} = "0.0.2 - 2010-06-20";

# Packages
use threads;                # http://search.cpan.org/~jdhedden/threads-1.72/threads.pm
                            # http://perldoc.perl.org/threads.html
use threads::shared;        # http://search.cpan.org/~jdhedden/threads-shared-1.28/shared.pm
use Time::HiRes qw(usleep); # http://search.cpan.org/~jhi/Time-HiRes-1.9719/HiRes.pm
use Win32::MultiMedia::Joystick;  # http://aspn.activestate.com/ASPN/CodeDoc/Win32-MultiMedia/Joystick/Joystick.html

# Hashes exported to other threads and main-program
share (%Stick);

my $StickNum = "JOY1";
my $StickRange = 1024;      # global stick range

$Stick{'StickRange'} = $StickRange;
$Stick{'JoystickX'} = 512;
$Stick{'JoystickY'} = 512;
$Stick{'JoystickZ'} = 512;
$Stick{'JoystickR'} = 512;
$Stick{'JoystickU'} = 512;
$Stick{'JoystickV'} = 512;
$Stick{'JoystickButton'} = 0;
$Stick{'JoystickPov'} = 0xffff;
$Stick{'_JoystickTimestamp'} = time;

my $Joystick = Win32::MultiMedia::Joystick->new($StickNum);
if ( defined $Joystick )
   {
    $StickNumAxes = $Joystick->NumAxes;
    $StickNumButtons = $Joystick->NumButtons;

    $StickXmin = $Joystick->Xmin;
    $StickXmax = $Joystick->Xmax;
    $StickYmin = $Joystick->Ymin;
    $StickYmax = $Joystick->Ymax;
    $StickZmin = $Joystick->Zmin;
    $StickZmax = $Joystick->Zmax;

    $StickRmin = $Joystick->Rmin;
    $StickRmax = $Joystick->Rmax;
    $StickUmin = $Joystick->Umin;
    $StickUmax = $Joystick->Umax;
    $StickVmin = $Joystick->Vmin;
    $StickVmax = $Joystick->Vmax;

    $Stick{'JoystickAxes'}       = $StickNumAxes;
    $Stick{'JoystickNumButtons'} = $StickNumButtons;
    $Stick{'_JoystickTimestamp'} = time;
    }


sub Joystick()
    {
    while ( usleep (10000) )   # 10ms loop
        {
        if ( defined $Joystick  and  $Stick{'JoystickAxes'} > 0)
            {
            $Joystick->update;
    
            my $x = $Joystick->X;
            my $y = $Joystick->Y;
            my $z = $Joystick->Z;
            my $r = $Joystick->R;
            my $u = $Joystick->U;
            my $v = $Joystick->V;    
            my $Button = $Joystick->Buttons;
            my $Pov = $Joystick->POV;

            lock (%Stick);   # until end of block

            $Stick{'JoystickX'} = int ($x / ($StickXmax - $StickXmin) * $StickRange + 0.5);
            $Stick{'JoystickY'} = $StickRange - int ($y / ($StickYmax - $StickYmin) * $StickRange + 0.5);
            $Stick{'JoystickZ'} = $StickRange - int ($z / ($StickYmax - $StickYmin) * $StickRange + 0.5);
            $Stick{'JoystickR'} = int ($r / ($StickRmax - $StickRmin) * $StickRange + 0.5);
            $Stick{'JoystickU'} = int ($u / ($StickUmax - $StickUmin) * $StickRange + 0.5);
            $Stick{'JoystickV'} = int ($v / ($StickVmax - $StickVmin) * $StickRange + 0.5);
            $Stick{'JoystickButton'} = $Button;
            if ( $Joystick->hasPOV )
                {
                $Stick{'JoystickPov'} = $Pov;
                }
            $Stick{'_JoystickTimestamp'} = time;
            }
        }
    }

        
sub JoystickStop ()
    {
    # Nothing to do
    }


# check, if button "Num" pressed, Num = 0 .. n
sub JoystickButton()
    {
    my ($Num) = @_;

    return (($Stick{'JoystickButton'} >> $Num) & 1) == 1;
    }
	
1;

__END__
