今回はジョイステックを使ったプログラムを組んでみました。


ゲームを作るにはゲームコントローラがないと話しなりません。



ジョイステックを操作するたび、コンソール画面に操作したジョイステックの情報が表示されるともいます。



ソースコードコンパイルする前に、サブシステムをコンソールにしておいてください。







ソースコードのダウンロードはこちらから

http://www.geocities.jp/finnissy/Joystick.zip


joystick.h

/********************************************/
/*          JoysticControll Header          */
/********************************************/
#ifndef JOYSTICK_H
#define JOYSTICK_H

int init_joystick(void);
void dest_joystick(void);
void read_joystick(Uint32 evtype);

#endif
/********************************************/
/*              End Joystic.h               */
/********************************************/





joystick.c

/********************************************/
/*          Joystic Controller              */
/********************************************/

#include <SDL/SDL.h>
#include "joystick.h"
#include "boolean.h"
#include "debug.h"
#include "err.h"


/********************************************/
/*              構造体宣言                  */
/********************************************/
typedef struct Joy_List {
    SDL_Joystick    *joystick;  /*  ジョイステック構造体    */
    Uint8           id;         /*  ジョイステック番号      */
    Sint16          Axes;       /*  ジョイステックの軸の数  */
    Sint16          Balls;      /*  トラックボールの数      */
    Sint16          Hats;       /*  ハットスイッチの数      */
    Sint16          Buttons;    /*  ジョイステックのボタン数*/
    struct Joy_List *next;      /*  次のジョイステック      */
}Joy_List;

/********************************************/
/*          フィールド変数宣言              */
/********************************************/
static Joy_List *top_joy = NULL;

/********************************************/
/*          関数プロトタイプ宣言            */
/********************************************/
static int create_joystick(int jnum);
static int joystick_list(int id);


/********************************************/
/*      概要:ジョイステックの生成          */
/*      詳細:ジョイステックの初期化と生成  */
/*      引数:無し                          */
/*      返却:TRUE:成功、FALSE:失敗       */
/********************************************/
int init_joystick(void)
{
    const Uint32 syscode = SDL_INIT_JOYSTICK;
    int joysticks = SDL_NumJoysticks();

    if(top_joy == NULL)
    {
        /************************************/
        /*  システムイベント初期化チェック  */
        /************************************/
        if( SDL_WasInit(syscode) )
        {
            SDL_InitSubSystem(syscode);
        }

        /************************************/
        /*  AutoUpdate Joystick State!!     */
        /************************************/
        SDL_JoystickEventState(SDL_ENABLE);

        /************************************/
        /*  ジョイステックのリストを生成    */
        /************************************/
        joysticks = create_joystick(joysticks);

        if( joysticks )
        {
            debug_log("\n%d本のジョイステックを生成\n",joysticks);
        } else {
            debug_log("\nジョイステックの生成に失敗\n");
            debug_log("\n%d本のジョイステックを生成\n",joysticks);

            return TRUE;
        }

    } else if( !joysticks )
    {
        return FALSE;
    }

    return TRUE;
}

/********************************************/
/*      概要:ジョイステックの破棄          */
/*      詳細:ジョイステックメモリの解放    */
/*      引数:無し                          */
/*      返却:無し                          */
/********************************************/
void dest_joystick(void)
{
    Joy_List *tmp;

    while(top_joy != NULL)
    {
        tmp = top_joy->next;
        SDL_JoystickClose(top_joy->joystick);
        free(top_joy);
        top_joy = tmp;
    }
}

/********************************************/
/*      概要:ジョイステックの状態読み込み  */
/*      詳細:入力状態により入力イベント操作*/
/*      引数:ブロック操作命令構造体        */
/*      返却:無し                          */
/********************************************/
void read_joystick(Uint32 evt, Blk_Info *info)
{
    //SDL_JoystickUpdate();//auto evant update
    Sint16 axis, hat, button, ball;
    Joy_List *joy;
    SDL_Joystick *tmp;
    Uint8 i;

    for(joy = top_joy; joy != NULL; joy = joy->next)
    {
        axis    = joy->Axes;
        hat     = joy->Hats;
        button  = joy->Buttons;
        ball    = joy->Balls;
        tmp     = joy->joystick;
        
        switch( evt ){
        case SDL_JOYAXISMOTION:
            /************************************/
            /*      軸スイッチを処理            */
            /************************************/
            for(i = 0;i < axis;i++)
            {
                debug_log("\nAxis : %d = %d",i,
                    SDL_JoystickGetAxis(tmp,i));
            }
            debug_log("\n");
            break;
        case SDL_JOYHATMOTION:
            /************************************/
            /*      ハットスイッチを処理        */
            /************************************/
            for(i = 0;i < hat;i++)
            {
                debug_log("\nHat : %d = %X",i,
                    SDL_JoystickGetHat(tmp,i));
            }
            debug_log("\n");
            break;
        case SDL_JOYBUTTONDOWN:
            /************************************/
            /*      ボタンスイッチを処理        */
            /************************************/
            for(i = 0;i < button;i++)
            {
                debug_log("\nButton : %d = %d",i,
                    SDL_JoystickGetButton(tmp,i));
            }
            debug_log("\n");
            break;
        case SDL_JOYBUTTONUP:
            /************************************/
            /*      ボタンスイッチを処理        */
            /************************************/
#if 0
            for(i = 0;i < button;i++)
            {
                debug_log("\nButton : %d = %d",i,
                    SDL_JoystickGetButton(tmp,i));
            }
            debug_log("\n");
#endif
            break;
        case SDL_JOYBALLMOTION:
            /************************************/
            /*  トラックボールスイッチを処理    */
            /************************************/
            for(i = 0;i < ball;i++)
            {
                int dumy_x, dumy_y;

                SDL_JoystickGetBall(tmp,i,&dumy_x,&dumy_y);
                debug_log("\nBall : %d = %d, %d = %d",i,dumy_x,i,dumy_y);
            }
            debug_log("\n");
            break;
        default:
            break;
        }
        
    }
}

/********************************************/
/*      概要:ジョイステックのリストを生成  */
/*      詳細:リスト構造でメモリを割り当て  */
/*      引数:作成するジョイステックの数    */
/*      返却:作成されたジョイステックの数  */
/********************************************/
static int create_joystick(int jnum)
{
    int i;

    for(i = 0;i < jnum;i++)
    {
        if( !joystick_list(i) )
        {
            return i;
        }
    }

    return jnum;
}

/********************************************/
/*      概要:ジョイステックのリストを生成  */
/*      詳細:リスト構造でメモリを割り当て  */
/*      引数:作成するジョイステックの数    */
/*      返却:作成されたジョイステックの数  */
/********************************************/
static int joystick_list(int id)
{
    SDL_Joystick *tmp;
    Joy_List *new_joy = 
        (Joy_List*)malloc(sizeof(Joy_List));

    if(new_joy == NULL)
        return FALSE;

    tmp = SDL_JoystickOpen(id);
    if(tmp == NULL)
    {
        free(new_joy);
        return FALSE;
    }

    new_joy->id = SDL_JoystickIndex(tmp);
    new_joy->Axes = SDL_JoystickNumAxes(tmp);
    new_joy->Balls = SDL_JoystickNumBalls(tmp);
    new_joy->Hats = SDL_JoystickNumHats(tmp);
    new_joy->Buttons = SDL_JoystickNumButtons(tmp);
    new_joy->joystick = tmp;
    new_joy->next = NULL;

    if(top_joy != NULL)
    {
        Joy_List *tmp = top_joy->next;

        while(tmp != NULL)
            tmp = tmp->next;

        tmp = new_joy;
    } else {
        top_joy = new_joy;
    }

    return TRUE;
}

/********************************************/
/*          END Joystic Controller          */
/********************************************/




main.c

/************************************************/
/*  概要:SDLを使ったサンプルプログラム         */
/*  詳細:ジョイステックテストプログラム        */
/************************************************/

#include <SDL/SDL.h>
#include <stdio.h>
#include "main.h"
#include "joystick.h"
#include "debug.h"

#ifdef  DEBUG_LOGGER
//#undef    DEBUG_LOGGER
#endif
#ifdef  DEBUG_PRINT
#undef  DEBUG_PRINT
#endif

/********************************/
/*      フィールド変数          */
/********************************/
static SDL_Surface  *screen;

/********************************/
/*      プロトタイプ宣言        */
/********************************/
static Bool init();
static void run();
static void quit();


/********************************/
/*      プログラム開始位置      */
/********************************/
int main(int argc, char *argv[])
{
    if( init() )
        run();

    quit();
    
    return 0;
}

/********************************/
/*          初期化処理          */
/********************************/
static
Bool init(void)
{
    /*  ライブラリを初期化する  */
    if(SDL_Init(INIT_FLAG_SUBSYSTEM) < 0) {
        debug_log("初期化に失敗");
        return FALSE;
    }

    /*    ビデオモードを設定する    */
    screen = SDL_SetVideoMode(
        FRAME_WIDTH,    FRAME_HEIGHT,
        FRAME_BPP,      INIT_FLAG_VIDEO
    );

    if( screen == NULL) {
        debug_log("VideoInitialize Error");
        return FALSE;
    }

    /*  ジョイステックの初期化  */
    if( !init_joystick() )
    {
        debug_log("Joystick Open Error\n");
        return FALSE;
    }

    return TRUE;
}

/********************************/
/*      ゲームイベント処理      */
/********************************/
static
void run(void)
{
    SDL_Event ev;
    Bool flg = FALSE;
    Uint8 type = 0;

    /****************************************/
    /*  次のイベントが来るまで無限に待機    */
    /****************************************/
    while( SDL_WaitEvent(&ev) )
    {
        switch(ev.type)
        {
        /*ウィンドウの×ボタン*/
        case SDL_QUIT:
            debug_log("QUIT\n");
            return;
        /*キーダウン*/
        case SDL_KEYDOWN:
            debug_log("KeyDonw\n");
            break;
        /*ジョイステック*/
        case SDL_JOYAXISMOTION:
        case SDL_JOYHATMOTION:
        case SDL_JOYBUTTONDOWN:
        case SDL_JOYBALLMOTION:
            read_joystick(ev.type);
            break;
        case SDL_JOYBUTTONUP:
            break;
        default:
            break;
        }

    }
}

/********************************/
/*      プログラム終了処理      */
/********************************/
static
void quit(void)
{
    if(screen != NULL)
    {
        SDL_FreeSurface( screen );
    }
    dest_joystick();
    SDL_Quit();
}

main.h

#ifndef MAIN_H
#define MAIN_H

#include <SDL/SDL.h>

/* ライブラリのインポート   */
#pragma comment(lib,"SDL.lib")
#pragma comment(lib,"SDLmain.lib")

#define FRAME_WIDTH 320
#define FRAME_HEIGHT 280
#define FRAME_BPP   32

#define INIT_FLAG_SUBSYSTEM (SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)
#define INIT_FLAG_VIDEO (SDL_SWSURFACE)

typedef SDL_bool Bool;

#define FALSE   (SDL_FALSE)
#define TRUE   (SDL_TRUE)

#endif







debug.h

#ifndef DEBUG_H
#define DEBUG_H

#define DEBUG_PRINT
#define DEBUG_LOGGER



void logger(const char *log,...);
void debug_log(const char *log,...);

#endif


debug.h



#include "debug.h"
#include <stdarg.h>
#include <stdio.h>

void logger(const char *log,...)
{
#ifdef DEBUG_PRINT
    va_list argp;
    va_start(argp,log);
    vprintf(log, argp);
    va_end(argp);
#endif
}

void debug_log(const char *log,...)
{
#ifdef  DEBUG_LOGGER
    va_list argp;
    va_start(argp,log);
    vprintf(log, argp);
    va_end(argp);
#endif
}