The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
PS3 Sixaxis controller
Ninjaboi


Joined: 11 Feb 2012
Posts: 14
I've been trying to use a PS3 Sixaxis controller for joystick input, yet it seems that I can't get it to do more than recognize that a controller is plugged in. I've tested the controller in device properties and can move the axis and press the buttons without a problem while getting input. The problem is that my program doesn't seem to get the input. I tried Lazy Foo's sample tutorial code to see if it would work. It compiled perfectly, but it still didn't get the input. Here is the tutorial in case someone wants it:

http://lazyfoo.net/SDL_tutorials/lesson25/index.php

The code is here:

Code:
/*This source code copyrighted by Lazy Foo' Productions (2004-2012)
and may not be redestributed without written permission.*/

//The headers
#include "SDL.h"
#include "SDL_image.h"
#include <string>

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 20;

//The dot dimensions
const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 20;

//The surfaces
SDL_Surface *dot = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

//The joystick that will be used
SDL_Joystick *stick = NULL;

//The dot
class Dot
{
    private:
    //The offsets of the dot
    int x, y;

    //The velocity of the dot
    int xVel, yVel;

    public:
    //Initializes
    Dot();

    //Handles joystick
    void handle_input();

    //Moves the dot
    void move();

    //Shows the dot
    void show();
};

//The timer
class Timer
{
    private:
    //The clock time when the timer started
    int startTicks;

    //The ticks stored when the timer was paused
    int pausedTicks;

    //The timer status
    bool paused;
    bool started;

    public:
    //Initializes variables
    Timer();

    //The various clock actions
    void start();
    void stop();
    void pause();
    void unpause();

    //Gets the timer's time
    int get_ticks();

    //Checks the status of the timer
    bool is_started();
    bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
    //The image that's loaded
    SDL_Surface* loadedImage = NULL;

    //The optimized surface that will be used
    SDL_Surface* optimizedImage = NULL;

    //Load the image
    loadedImage = IMG_Load( filename.c_str() );

    //If the image loaded
    if( loadedImage != NULL )
    {
        //Create an optimized surface
        optimizedImage = SDL_DisplayFormat( loadedImage );

        //Free the old surface
        SDL_FreeSurface( loadedImage );

        //If the surface was optimized
        if( optimizedImage != NULL )
        {
            //Color key surface
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
        }
    }

    //Return the optimized surface
    return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    //Holds offsets
    SDL_Rect offset;

    //Get offsets
    offset.x = x;
    offset.y = y;

    //Blit
    SDL_BlitSurface( source, clip, destination, &offset );
}

bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    //Set up the screen
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was an error in setting up the screen
    if( screen == NULL )
    {
        return false;
    }

    //Check if there's any joysticks
    if( SDL_NumJoysticks() < 1 )
    {
        return false;
    }

    //Open the joystick
    stick = SDL_JoystickOpen( 0 );

    //If there's a problem opening the joystick
    if( stick == NULL )
    {
        return false;
    }

    //Set the window caption
    SDL_WM_SetCaption( "Move the Dot", NULL );

    //If everything initialized fine
    return true;
}

bool load_files()
{
    //Load the dot image
    dot = load_image( "dot.bmp" );

    //If there was a problem in loading the dot
    if( dot == NULL )
    {
        return false;
    }

    //If everything loaded fine
    return true;
}

void clean_up()
{
    //Free the surface
    SDL_FreeSurface( dot );

    //Close the joystick
    SDL_JoystickClose( stick );

    //Quit SDL
    SDL_Quit();
}

Dot::Dot()
{
    //Initialize the offsets
    x = 0;
    y = 0;

    //Initialize the velocity
    xVel = 0;
    yVel = 0;
}

void Dot::handle_input()
{
    //If a axis was changed
    if( event.type == SDL_JOYAXISMOTION )
    {
        //If joystick 0 has moved
        if( event.jaxis.which == 0 )
        {
            //If the X axis changed
            if( event.jaxis.axis == 0 )
            {
                //If the X axis is neutral
                if( ( event.jaxis.value > -8000 ) && ( event.jaxis.value < 8000 ) )
                {
                    xVel = 0;
                }
                //If not
                else
                {
                    //Adjust the velocity
                    if( event.jaxis.value < 0 )
                    {
                        xVel = -DOT_WIDTH / 2;
                    }
                    else
                    {
                        xVel = DOT_WIDTH / 2;
                    }
                }
            }
            //If the Y axis changed
            else if( event.jaxis.axis == 1 )
            {
                //If the Y axis is neutral
                if( ( event.jaxis.value > -8000 ) && ( event.jaxis.value < 8000 ) )
                {
                    yVel = 0;
                }
                //If not
                else
                {
                    //Adjust the velocity
                    if( event.jaxis.value < 0 )
                    {
                        yVel = -DOT_HEIGHT / 2;
                    }
                    else
                    {
                        yVel = DOT_HEIGHT / 2;
                    }
                }
            }
        }
    }
}

void Dot::move()
{
    //Move the dot left or right
    x += xVel;

    //If the dot went too far to the left or right
    if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) )
    {
        //move back
        x -= xVel;
    }

    //Move the dot up or down
    y += yVel;

    //If the dot went too far up or down
    if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
    {
        //move back
        y -= yVel;
    }
}

void Dot::show()
{
    //Show the dot
    apply_surface( x, y, dot, screen );
}

Timer::Timer()
{
    //Initialize the variables
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;
}

void Timer::start()
{
    //Start the timer
    started = true;

    //Unpause the timer
    paused = false;

    //Get the current clock time
    startTicks = SDL_GetTicks();
}

void Timer::stop()
{
    //Stop the timer
    started = false;

    //Unpause the timer
    paused = false;
}

void Timer::pause()
{
    //If the timer is running and isn't already paused
    if( ( started == true ) && ( paused == false ) )
    {
        //Pause the timer
        paused = true;

        //Calculate the paused ticks
        pausedTicks = SDL_GetTicks() - startTicks;
    }
}

void Timer::unpause()
{
    //If the timer is paused
    if( paused == true )
    {
        //Unpause the timer
        paused = false;

        //Reset the starting ticks
        startTicks = SDL_GetTicks() - pausedTicks;

        //Reset the paused ticks
        pausedTicks = 0;
    }
}

int Timer::get_ticks()
{
    //If the timer is running
    if( started == true )
    {
        //If the timer is paused
        if( paused == true )
        {
            //Return the number of ticks when the timer was paused
            return pausedTicks;
        }
        else
        {
            //Return the current time minus the start time
            return SDL_GetTicks() - startTicks;
        }
    }

    //If the timer isn't running
    return 0;
}

bool Timer::is_started()
{
    return started;
}

bool Timer::is_paused()
{
    return paused;
}

int main( int argc, char* args[] )
{
    //Quit flag
    bool quit = false;

    //Make the dot
    Dot myDot;

    //The frame rate regulator
    Timer fps;

    //Initialize
    if( init() == false )
    {
        return 1;
    }

    //Load the files
    if( load_files() == false )
    {
        return 1;
    }

    //While the user hasn't quit
    while( quit == false )
    {
        //Start the frame timer
        fps.start();

        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //Handle events for the dot
            myDot.handle_input();

            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

        //Move the dot
        myDot.move();

        //Fill the screen white
        SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );

        //Show the dot on the screen
        myDot.show();

        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        //Cap the frame rate
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        {
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
        }
    }

    //Clean up
    clean_up();

    return 0;
}


I'm using SDL 1.2.14 on a Windows XP SP3 machine. My IDE is Visual Studio 2008 ( Non-Express Edition ). Again, no compiler errors or warnings, and the controller itself tests perfectly on games I play it with on the PC as well as testing it via device manager.
PS3 Sixaxis controller
Bl0ckeduser
Guest

Ninjaboi <dannymcgill <at> hotmail.com> writes:

Quote:
I've been trying to use a PS3 Sixaxis controller for joystick input, yet it
seems that I can't get it to do more than recognize that a controller is plugged
in. I've tested the controller in device properties and can move the axis and
press the buttons without a problem while getting input. The problem is that my
program doesn't seem to get the input. I tried Lazy Foo's sample tutorial code
to see if it would work. It compiled perfectly, but it still didn't get the
input. Here is the tutorial in case someone wants
it:http://lazyfoo.net/SDL_tutorials/lesson25/index.php

According to the SDL docs, "Ideally joysticks should be read using the event
system. To enable this, you must set the joystick event processing state with
SDL_JoystickEventState."

So, unless I'm mistaken, you probably want to add this line to your code:

SDL_JoystickEventState(SDL_ENABLE);


Bl0ckeduser

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Ninjaboi


Joined: 11 Feb 2012
Posts: 14
Thanks, though I looked at the documentation to see where I should put that line ( I followed what it said by putting it right above the line that assigns the joystick ) yet came to the same problem: Joystick events won't register. I tried looking for an example or some manner of description of a PS3 controller being used in an SDL program, yet found none.
PS3 Sixaxis controller
D B
Guest

Hi,

We recently added support for the PS3 controller in our little game
bitfighter (bitfighter.org)

One thing we noticed was that it behaved strangely under Linux. To
solve this we implemented the old Linux device system just for it.
See our source (with comments) at:

https://code.google.com/p/bitfighter/source/browse/zap/Joystick.cpp#89

Maybe it will help a bit,
D


On Wed, Feb 15, 2012 at 11:05 PM, Ninjaboi wrote:
Quote:
Thanks, though I looked at the documentation to see where I should put that
line ( I followed what it said by putting it right above the line that
assigns the joystick ) yet came to the same problem: Joystick events won't
register. I tried looking for an example or some manner of description of a
PS3 controller being used in an SDL program, yet found none.

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
riksweeney


Joined: 17 Jan 2012
Posts: 38
Have you stuck in any debug to see if the motion event is being picked up?
Code:

if( event.type == SDL_JOYAXISMOTION )
{
    printf("Joystick is %d\n", event.jaxis.which);
    printf("Axis is %d\n", event.jaxis.axis);
    printf("Value is %d\n", event.jaxis.value);
}


I've never used the event.jaxis.which, I just assume there will only ever be 1 joystick plugged in Smile
Ninjaboi


Joined: 11 Feb 2012
Posts: 14
Thanks for all the help, though I got it fixed. The problem wasn't the code or the controller per say, but that SDL wasn't able to treat the PS3 Sixaxis controller like a generic joystick. I got another PS3 controller ( not Sixaxis ) made by MadCatz and it worked perfectly as it should. So, it seems to me that only Sixaxis controllers have the issue ( as I tried two other Sixaxis controllers and they didn't work ). Not sure if this is a problem that has never been recognized until now, but that's what I'm getting out of this experience.

Thanks for the link to that source by the way, as it did help me think of a slightly different way to approach my event handling for the joystick.
RodrigoCard


Joined: 23 Apr 2011
Posts: 113
Location: Brazil
Which OS are you using? You may get your SIXAXIS working by installing custom drivers.
I tested it right now with a DUALSHOCK3 (it have SIXAXIS written on it too =P) in OSX 10.7 and it works.

Ninjaboi wrote:
Thanks for all the help, though I got it fixed. The problem wasn't the code or the controller per say, but that SDL wasn't able to treat the PS3 Sixaxis controller like a generic joystick. I got another PS3 controller ( not Sixaxis ) made by MadCatz and it worked perfectly as it should. So, it seems to me that only Sixaxis controllers have the issue ( as I tried two other Sixaxis controllers and they didn't work ). Not sure if this is a problem that has never been recognized until now, but that's what I'm getting out of this experience.

Thanks for the link to that source by the way, as it did help me think of a slightly different way to approach my event handling for the joystick.
Ninjaboi


Joined: 11 Feb 2012
Posts: 14
I'm running Windows XP SP3 using custom drivers for the SixAxis controllers. I also tried installing and using PPJoy to make Windows treat the controller like a generic joystick with no luck. I've also tried the application on Window Vista SP1 and Windows 7 SP1 with no luck until I used a joystick that wasn't SixAxis.

Quote:
Which OS are you using? You may get your SIXAXIS working by installing custom drivers.
I tested it right now with a DUALSHOCK3 (it have SIXAXIS written on it too =P) in OSX 10.7 and it works.