http://homepage.mac.com/kijibato/macreatefan/letssdl02.html

 MacでSDLを使おう(その2) その1,その3

SDLのAPIを使ってみる。
(コントローラ、グラフィック、サウンド)



最終更新 2004.11.22

※ここのページで紹介されているソフトウェアのバージョン等は2004年11月現在のものです



★目的

できるだけ数少ないAPIだけでやりたいものです。(笑)


1.コントローラを使う

 SDLでは、コントローラの状態が変化した場合に生じるイベントと、コントローラの状態を得る関数の2つの方法で、ユーザの意志を得ることが可能です。


A.イベントによるコントローラの状態の取得

 mainLoopにあるイベント処理ルーチンに、ブレークポイントを仕掛けてeventストラクチャの中身の変化を検証してみてください。

・マウスを動かしてみる
・マウスボタンを押してみる。
・キーを押してみる。

それぞれを行った際、eventの中身がどう変化するでしょうか。


デバッガを使えばストラクチャの構造を把握するのも簡単ですね。

イベントが発生したら、必要な情報をeventのメンバにアクセスして取得してください。





B.現在のコントローラの状態の取得

 ゲーム等ではイベントよりも、それぞれの処理ルーチン内でコントローラの状態を知りたい場合が多いと思います。

 SDLには各コントローラの現在の状態を取得する機能があります。

キーボードの場合

SDL_GetKeyStateという関数を利用します。

例:現在スペースキーが押されているか?
int myPressSpace( void ){
 
Uint8 *keys = SDL_GetKeyState (NULL);

 
SDL_PumpEvents (); //キーボードの状態を更新する(繰り返し見る場合必要)
 return ( keys[SDLK_SPACE]==SDL_PRESSED );

}

こんな感じのファンクションを定義すればよいでしょう。

SDLK_SPACEはスペースキーを表す定数です。各種定数はFrameworks内のヘッダファイルに記載されています。(Webで検索したり、デバッガで確認する方が早いかも。)

注意:複数のキーを押す場合、組み合わせによっては、後に押されたキーが検出されない場合があります。(キーマトリクスによる物理的な限界)



ジョイスティック(パッド)の場合

1度初期化を行う。

SDL_Joystick *joy0; //参照値(リファレンス)グローバル

 if( SDL_Init (SDL_INIT_JOYSTICK) < 0 ){
  //joy0 = null; //ジョイスティックは接続されていない。
 
}else{
  joy0 =
SDL_JoystickOpen (0);
   //joy0は、後で0番のスティックを識別するための参照値、複数接続されてるなら云々〜
 }

(※編集の都合でインデントに全角スペースが使用されています)

ジョイスティックの状態を得る
 SDL_JoystickUpdate (); //全ジョイスティックの状態を更新する。
 xaxis
=
SDL_JoystickGetAxis ( joy0, 0); // joy0スティックのX方向への傾きを得る
 yaxis
=
SDL_JoystickGetAxis ( joy0, 1); // joy0スティックのY方向への傾きを得る
 pressedF
=
SDL_JoystickGetButton ( joy0, 0 ); // joy0スティックのボタン0の状態




2.イメージ(画像)を扱う

 SDLではサーフェイス(Surface)と呼ばれる、画素を格納する2次元配列と、縦横ドット数等の情報をパックした構造体でイメージを管理しているようです。ユーザはサーフェイスの配列にアクセスすることもできますし、この配列をOpenGLのテクスチャ作成時に直接渡すこともできます。(Macのオフスクリーンと違い、縦横ドット数と配列のサイズは一致している!)

画像の読み込みの注意

 MacとWindowsではエンディアンが異なりますので、他のサイトを参考にしたイメージの読み処理を流用する場合にはちょっとした注意が必要です。(32ビットカラーイメージの場合)

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 #define rmask
0xff000000
 #define gmask
0x00ff0000
 #define bmask
0x0000ff00
 #define amask
0x000000ff
#else
 #define rmask
0x000000ff
 #define gmask
0x0000ff00
 #define bmask
0x00ff0000
 #define amask
0xff000000
#endif

 SDL_Surface *Image = IMG_Load ( "samplepic.png" );  //ファイル読込
 
SDL_Surface *tmpImage = SDL_CreateRGBSurface ( SDL_SWSURFACE, 0, 0, 32, rmask, gmask, bmask, amask );
 // ↑イメージ変換フィルタの作成
 Image =
SDL_ConvertSurface ( Image, tmpImage->format, SDL_SWSURFACE );
 
SDL_FreeSurface ( tmpImage ); //イメージの変換

 // "Image->pixels"(画素配列の実体)をglTexImage2Dに渡せばOpenGLテクスチャが完成します。

このようにしておけば、MacでもWindowsでも同じ表示になります。

※SDL基本セットではBMP画像以外( jpg、png等)読み込むことができないので、SDL_image-devel.pkg(SDLのサイトにあります)をインストールしてSDL_image Frameworkをプロジェクトに追加してください。(#include "SDL_image.h"#include "SDL_endian.h"もソースに追加。)


3.サウンドを鳴らす

主なサウンド機能

・音声データを鳴らす
・各種音楽フォーマットのデータを演奏する
・様々な演出効果

等々

使用方法

 SDL_mixer-devel.pkgをインストールすれば、簡単なコマンドで各種音声データを再生・演奏することができます。


4.ファイルパスについて

 SDL並びに各種フレームワークのアクセスパスは、アプリケーションパッケージと同階層が基本ディレクトリに相当するようです。

 例えばパッケージと同階層にimageというフォルダを作成し、その中にsamplepic.pngを入れておけば、"image/samplepic.png"でファイルを指定できます。(※SDLの文字列はC型です。)


参考・関連サイト

SDL Guide

各種APIや構造体、定数等が日本語で解説されています。

SDL / OpenGL 分科会(1〜4回)

SDLによる簡単な入出力関連の解説を

Durandal Home Page

開発日誌にOpenGLとSDLを使用したネタがあります。
(SDLを使う動機を作ってくださいました;;)


履歴

041122版 初版


戻る