SDL_Cursor()



今回はSDLのマウスカーソルを変更する関数を使って、

マウスカーソルのアイコンを変えてみようと思います。



SDLのリファレンスはこちら↓

http://www.tacoworks.jp/software/SDLdoc-jp/html/sdlcreatecursor.html



ダウンロードはこちらから↓

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





ソースコードです。

cursor.h

#ifndef CURSOR_H
#define CURSOR_H

#include "main.h"

typedef enum CursorType{
    CURSOR_DEFAULT,
    CURSOR_USER1,
    CURSOR_USER2,
    CURSOR_USER3,
    CURSOR_USER4,
    CURSOR_MAX,
}CursorType;

SDL_bool  initCursor(void);
void freeCursor(void);
void changeCursor(CursorType type);

#endif


cursor.c

/****************************************/
/*  概要:SDLリファレンスを参考に       */
/*        マウスカーソルを生成する      */
/****************************************/
#include <stdio.h>
#include "cursor.h"

#define CURSOR_WIDTH 32
#define CURSOR_HEIGHT 32
#define DATA_PARTITION 8
#define DATA_SIZE \
    ((CURSOR_WIDTH/DATA_PARTITION)*CURSOR_HEIGHT)

static SDL_Cursor *cursor[CURSOR_MAX];

static
SDL_Cursor *createCursor(const char *img[], SDL_bool inversion);

/****************************************/
/*          デフォルトのカーソル        */
/****************************************/
static const char *cursor_default[] =   {
/*   0---------------------------31     */
    "X                             ",/* 0*/
    "XX                            ",/* 1*/
    "X.X                           ",/* 2*/
    "X..X                          ",/* 3*/
    "X...X                         ",/* 4*/
    "X....X                        ",/* 5*/
    "X.....X                       ",/* 6*/
    "X......X                      ",/* 7*/
    "X.......X                     ",/* 8*/
    "X........X                    ",/* 9*/
    "X.........X                   ",/*10*/
    "X..........X                  ",/*11*/
    "X...........X                 ",/*12*/
    "X............X                ",/*13*/
    "X.............X               ",/*14*/
    "X..............X              ",/*15*/
    "X...............X             ",/*16*/
    "X................X            ",/*17*/
    "X.................X           ",/*18*/
    "X..................X          ",/*19*/
    "X.............XXXXX           ",/*20*/
    "X....XX......X                ",/*21*/
    "X..XX  X.....X                ",/*22*/
    "XXX    X.....X                ",/*23*/
    "X       X.....X               ",/*24*/
    "        X.....X               ",/*25*/
    "         X.....X              ",/*26*/
    "         X.....X              ",/*27*/
    "          X.....X             ",/*28*/
    "           X....X             ",/*29*/
    "            XXXX              ",/*30*/
    "                              ",/*31*/
    "0,0",/*カーソルの位置情報*/
};

/****************************************/
/*          オリジナルのカーソル1       */
/****************************************/
static const char *cursor_user1[]   =   {
/*   0---------------------------31     */
    "                              ",/* 0*/
    "                              ",/* 1*/
    "                              ",/* 2*/
    "                              ",/* 3*/
    "                              ",/* 4*/
    "                              ",/* 5*/
    "                              ",/* 6*/
    "     XXXX                     ",/* 7*/
    "    X....X                    ",/* 8*/
    "    X....X                    ",/* 9*/
    "    X....X                    ",/*10*/
    "    X....X                    ",/*11*/
    "    X....X                    ",/*12*/
    "    X....XXXXXX XXXXX         ",/*13*/
    "   XX....X....XX....XX        ",/*14*/
    "  XX.....X.....X.....XXXX     ",/*15*/
    " XXX.....X.....X.....X...X    ",/*16*/
    " X.X.................X...X    ",/*17*/
    " X.......................X    ",/*18*/
    " X.......................X    ",/*19*/
    "  X......................X    ",/*20*/
    "   X....................X     ",/*21*/
    "    X...................X     ",/*22*/
    "     XX................X      ",/*23*/
    "       XX.............X       ",/*24*/
    "        XXXXXXXX...XXX        ",/*25*/
    "       X..............X       ",/*26*/
    "       XX............XX       ",/*27*/
    "        XXXXXXXXXXXXX         ",/*28*/
    "                              ",/*29*/
    "                              ",/*30*/
    "                              ",/*31*/
    "4,7",/*カーソルの位置情報*/
};

/****************************************/
/*          オリジナルのカーソル2       */
/****************************************/
static const char *cursor_user2[]   =   {
/*   0---------------------------31     */
    "                              ",/* 0*/
    "                              ",/* 1*/
    "                              ",/* 2*/
    "                              ",/* 3*/
    "                              ",/* 4*/
    "                              ",/* 5*/
    "                              ",/* 6*/
    "                              ",/* 7*/
    "                              ",/* 8*/
    "                              ",/* 9*/
    "                              ",/*10*/
    "                              ",/*11*/
    "                              ",/*12*/
    "     XXXXXXXXXXXXXXXX         ",/*13*/
    "    XX...XX....XX...XXX       ",/*14*/
    "  XXX....X.....X.....XXXX     ",/*15*/
    " X..X....X.....X.....X..XX    ",/*16*/
    " X..X................X...X    ",/*17*/
    " X.......................X    ",/*18*/
    " X.......................X    ",/*19*/
    "  X......................X    ",/*20*/
    "   X....................X     ",/*21*/
    "    X...................X     ",/*22*/
    "     XX................X      ",/*23*/
    "       XX.............X       ",/*24*/
    "        XXXXXXXX...XXX        ",/*25*/
    "       X..............X       ",/*26*/
    "       XX............XX       ",/*27*/
    "        XXXXXXXXXXXXX         ",/*28*/
    "                              ",/*29*/
    "                              ",/*30*/
    "                              ",/*31*/
    "4,13"/*カーソルの位置情報*/
};

/****************************************/
/*          オリジナルのカーソル3       */
/****************************************/
static const char *cursor_user3[]   =   {
/*   0---------------------------31     */
    "                              ",/* 0*/
    "                              ",/* 1*/
    "                              ",/* 2*/
    "                              ",/* 3*/
    "          XXXXXXXXXX          ",/* 4*/
    "       XXX..........XXX       ",/* 5*/
    "     XX................XX     ",/* 6*/
    "    X....................X    ",/* 7*/
    "   X......................X   ",/* 8*/
    "  X........................X  ",/* 9*/
    " X..........................X ",/*10*/
    " X.....XXXX........XXXX.....X ",/*11*/
    "X............................X",/*12*/
    "X............................X",/*13*/
    "X............................X",/*14*/
    "X............................X",/*15*/
    "X............................X",/*16*/
    "X............................X",/*17*/
    "X............................X",/*18*/
    " X..........................X ",/*19*/
    " X......XXXXXXXXXXXXXX......X ",/*20*/
    "  X........................X  ",/*21*/
    "   X......................X   ",/*22*/
    "    X....................X    ",/*23*/
    "     XX................XX     ",/*24*/
    "       XXX..........XXX       ",/*25*/
    "          XXXXXXXXXX          ",/*26*/
    "                              ",/*27*/
    "                              ",/*28*/
    "                              ",/*29*/
    "                              ",/*30*/
    "                              ",/*31*/
    "15,15",/*カーソルの位置情報*/
};

/****************************************/
/*          オリジナルのカーソル3       */
/****************************************/
static const char *cursor_user4[]   =   {
/*   0---------------------------31     */
    "                              ",/* 0*/
    "                              ",/* 1*/
    "                              ",/* 2*/
    "                              ",/* 3*/
    "          XXXXXXXXXX          ",/* 4*/
    "       XXX..........XXX       ",/* 5*/
    "     XX................XX     ",/* 6*/
    "    X....................X    ",/* 7*/
    "   X......................X   ",/* 8*/
    "  X....XXXXXX....XXXXXX....X  ",/* 9*/
    " X....X..XX..X..X..XX..X....X ",/*10*/
    " X...X.......X..X.......X...X ",/*11*/
    "X....X..XXXXXX..XXXXXX..X....X",/*12*/
    "X....XXX..............XXX....X",/*13*/
    "X............................X",/*14*/
    "X............................X",/*15*/
    "X............................X",/*16*/
    "X............................X",/*17*/
    "X.....XXX............XXX.....X",/*18*/
    " X...X...XXXXXXXXXXXX...X...X ",/*19*/
    " X...X..................X...X ",/*20*/
    "  X..X..................X..X  ",/*21*/
    "   X..XX..............XX..X   ",/*22*/
    "    X...XXXXXXXXXXXXXX...X    ",/*23*/
    "     XX................XX     ",/*24*/
    "       XXX..........XXX       ",/*25*/
    "          XXXXXXXXXX          ",/*26*/
    "                              ",/*27*/
    "                              ",/*28*/
    "                              ",/*29*/
    "                              ",/*30*/
    "                              ",/*31*/
    "15,15",/*カーソルの位置情報*/
};

/****************************************/
/*          カーソルの雛形              */
/****************************************/
#if 0
static const char *cursor_tmp[] =   {
/*   0---------------------------31     */
    "                              ",/* 0*/
    "                              ",/* 1*/
    "                              ",/* 2*/
    "                              ",/* 3*/
    "                              ",/* 4*/
    "                              ",/* 5*/
    "                              ",/* 6*/
    "                              ",/* 7*/
    "                              ",/* 8*/
    "                              ",/* 9*/
    "                              ",/*10*/
    "                              ",/*11*/
    "                              ",/*12*/
    "                              ",/*13*/
    "                              ",/*14*/
    "                              ",/*15*/
    "                              ",/*16*/
    "                              ",/*17*/
    "                              ",/*18*/
    "                              ",/*19*/
    "                              ",/*20*/
    "                              ",/*21*/
    "                              ",/*22*/
    "                              ",/*23*/
    "                              ",/*24*/
    "                              ",/*25*/
    "                              ",/*26*/
    "                              ",/*27*/
    "                              ",/*28*/
    "                              ",/*29*/
    "                              ",/*30*/
    "                              ",/*31*/
};
#endif

/****************************************/
/*          カーソル初期化処理          */
/****************************************/
SDL_bool initCursor(void)
{
    int idx;
    int flg = 0;

    cursor[CURSOR_DEFAULT] = 
        createCursor( cursor_default ,flg);
    
    cursor[CURSOR_USER1] = 
        createCursor( cursor_user1 ,flg);
    
    cursor[CURSOR_USER2] = 
        createCursor( cursor_user2 ,flg);
    
    cursor[CURSOR_USER3] = 
        createCursor( cursor_user3 ,flg);

    cursor[CURSOR_USER4] = 
        createCursor( cursor_user4 ,flg);
    
    for(idx = 0;idx < CURSOR_MAX;idx++)
    {
        if(cursor[idx] == NULL)
            return SDL_FALSE;
    }
    return SDL_TRUE;
}

/****************************************/
/*          カーソルの変更              */
/****************************************/
void changeCursor(CursorType type)
{
    if( cursor[type] != NULL)
    {
        SDL_SetCursor( cursor[type] );
    }
}

/****************************************/
/*          カーソルの作成              */
/****************************************/
static
SDL_Cursor *createCursor(const char *img[], SDL_bool inversion)
{
    int i,x,y;
    int hot_x,hot_y;
    Uint8 drw_white;
    Uint8 drw_black;
    Uint8 data[DATA_SIZE];
    Uint8 mask[DATA_SIZE];

    i = -1;
    drw_white = (inversion) ? 0x01 : 0x00;
    drw_black = (inversion) ? 0x00 : 0x01;
    for(y = 0;y < CURSOR_HEIGHT;y++)
    {
        for(x = 0;x < CURSOR_WIDTH;x++)
        {
            if(x%DATA_PARTITION)/*8ビット区切りで色を生成*/
            {
                data[i] <<= 1;
                mask[i] <<= 1;
            } else {
                ++i;
                data[i] = mask[i] = 0;
            }
            switch(img[y][x]){
            case 'X':
                data[i] |= drw_black;
                mask[i] |= 0x01;
                break;
            case '.':
                data[i] |= drw_white;
                mask[i] |= 0x01;
                break;
            case 'o':
                data[i] |= 0x01;
                break;
            default:
                break;
            }
        }
    }
    sscanf_s(img[CURSOR_HEIGHT], "%d,%d",&hot_x,&hot_y);
    return SDL_CreateCursor(
        data, mask,CURSOR_WIDTH,CURSOR_HEIGHT,hot_x, hot_y);
}

/****************************************/
/*          カーソルの後片付け          */
/****************************************/
void freeCursor(void)
{
    int idx = 0;

    for(idx = 0;idx < CURSOR_MAX; idx++)
    {
        if(cursor[idx] != NULL)
        {
            SDL_FreeCursor(cursor[idx]);
            cursor[idx] = NULL;
        }
    }
}

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)
#define INIT_FLAG_VIDEO (SDL_SWSURFACE)

typedef SDL_bool Bool;
#define False   (SDL_FALSE)
#define True    (SDL_TRUE)

#endif

main.c

/************************************************/
/*  概要:SDLを使ったサンプルプログラム         */
/*  詳細:マウスボタンを押下するたび            */
/*        マウスアイコンを変更するプログラム    */
/************************************************/

#include <SDL/SDL.h>
#include <stdio.h>
#include "main.h"
#include "cursor.h"

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

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


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

    quit();
    
    return 0;
}

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

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

    if( screen == NULL) {
        printf("VideoInitialize Error");
        return SDL_FALSE;
    }

    /*  カーソルの初期化    */
    initCursor();

    return SDL_TRUE;
}

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

    /****************************************/
    /*  次のイベントが来るまで無限に待機    */
    /****************************************/
    while( SDL_WaitEvent(&ev) )
    {
        switch(ev.type)
        {
        /*ウィンドウの×ボタン*/
        case SDL_QUIT:
            printf("QUIT\n");
            return;
        /*キーダウン*/
        case SDL_KEYDOWN:
            printf("KeyDonw\n");
            break;
        /*マウス押下*/
        case SDL_MOUSEBUTTONDOWN:
            printf("MouseDown\n");
            mouseAction(type++);
            break;
        default:
            break;
        }

    }
}

/********************************/
/*      マウスイベント処理      */
/********************************/
void mouseAction(Uint8 type)
{
    changeCursor(type%CURSOR_MAX);
}

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