SDL 2.0と1.2に関するメモ
Notes on SDL 2.0 and 1.2

戻る

g800bm2をSDLを1.2から2.0に変えたとき気づいたことをメモします. 「やってみたらこうだった」レベルなので正確ではないかもしれません.

「SDL 1.2から2.0への移行」も参考にしてください.


ウィンドウの表示

SDL 2.0では複数のウィンドウを扱えるようになった. それに伴いウィンドウの表示方法も変わっている. なお, 2.0にはSDL_GetVideoInfo関数はない.

SDL 1.2

	SDL_VideoInfo *v;
	SDL_Surface *s;

	v = SDL_GetVideoInfo();
	s = SDL_SetVideoMode(W, H, v->vfmt->BitsPerPixel, SDL_HWSURFACE);

SDL 2.0

	SDL_Window *w;
	SDL_Surface *s;

	w = SDL_CreateWindow("Title", X, Y, W, H, 0);
	s = SDL_GetWindowSurface(w);

表示の更新

SDL 1.2ではSDL_UpdateRect関数またはSDL_UpdateRects関数を使用したが, 2.0ではSDL_UpdateWindowSurface関数またはSDL_UpdateWindowSurfaceRects関数を使用する.

1.2では, ウィンドウを最小化したときや画面外に移動したときも表示を維持したが, 2.0では表示が消えてしまう. この場合SDL_UpdateWindowSurface関数で更新しなければならない.

なお, SDL_Surfaceはハードウェアアクセラレーションを使用しない. SDL_Textureを使えば有効になり, こちらが推奨されている.

SDL 1.2

	SDL_UpdateRect(s, X, Y, W, H);	/* X = Y = W = H = 0 ならウィンドウ全体 */
または
	SDL_Rect r[256];
	int n;

	/*
	.
	.
	.
	*/

	SDL_UpdateRects(s, n, r);

SDL 2.0

	SDL_UpdateWindowSurface(w); /* ウィンドウ全体 */
または
	SDL_UpdateWindowSurfaceRects(w, r, n);

タイトルバーの文字

タイトルバーの文字を変更する関数が変更された.

SDL 1.2

	SDL_WM_SetCaption("Title", NULL);

SDL 2.0

	SDL_SetWindowTitle(w, "Title")

タイトルバーのアイコン

タイトルバーのアイコンを変更する関数も変更されている. アイコンの透過部分の指定がなくなり, アルファチャンネルで透過を表すようになっている.

SDL 1.2

	SDL_Surface icon;
	Uint8 mask[32 * 32 / 8];

	/*
	.
	.
	.
	*/

	SDL_WM_SetIcon(icon, mask);

SDL 2.0

	SDL_SetWindowIcon(w, icon);

パレット

256色時のパレットも以下のように変わったようだが, 実際には試していない.

SDL 1.2

	SDL_Color c[256];

	/*
	.
	.
	.
	*/

	SDL_SetPalette(s, SDL_PHYSPAL, c, 0, 256);

SDL 2.0

	SDL_SetPaletteColors(s->format->palette, c, 0, 256);

キーコード

SDL 1.2のSDL_Keysym構造体のsymフィールドはSDLK_FIRSTからSDLK_LASTまでの連番になっていたが, 2.0ではそうではない. SDL 2.0ではsymフィールドは押されたキーの文字コード(UNICODE)となっている. キーを配列の添え字にするような場合はscancodeフィールドを使用する.

symフィールドの値はキーコード(SDLK_*), scancodeフィールドの値はスキャンコード(SDL_SCANCODE_*)と呼ばれている. キーコードはキーの文字を表し, スキャンコードはキーの位置を表している.

またキーコードの定義(#define)も, なくなったり追加されたものや, 名前が変わったものがある.

なくなったキーの定義

	SDLK_RMETA
	SDLK_LMETA
	SDLK_COMPOSE
	SDLK_EURO

名前の変わったキーの定義

	SDLK_KP0 → SDLK_KP_0
	SDLK_KP1 → SDLK_KP_1
	SDLK_KP2 → SDLK_KP_2
	SDLK_KP3 → SDLK_KP_3
	SDLK_KP4 → SDLK_KP_4
	SDLK_KP5 → SDLK_KP_5
	SDLK_KP6 → SDLK_KP_6
	SDLK_KP7 → SDLK_KP_7
	SDLK_KP8 → SDLK_KP_8
	SDLK_KP9 → SDLK_KP_9
	SDLK_NUMLOCK → SDLK_NUMLOCKCLEAR
	SDLK_SCROLLOCK → SDLK_SCROLLLOCK
	SDLK_PRINT → SDLK_PRINTSCREEN
	SDLK_BREAK → SDLK_STOP
	SDLK_RSUPER → SDLK_RGUI
	SDLK_LSUPER → SDLK_LGUI

キーリピート

SDL 1.2にはキーリピートの有無と速さを設定するSDL_EnableKeyRepeat関数があったが, 2.0ではなくなっている. SDL 2.0では何も指定しなくてもキーリピートする. キーリピート時にはSDL_KeyboardEvent構造体のrepeatフィールドの値が真になっているので, 必要ならばこれを見ればよい.


音声の初期化

SDL_OpenAudio関数で初期化するとき, フォーマットをAUDIO_U8(8bit符号なし)とすると音が出力されなかった. AUDIO_S8(8bit符号あり)とすると正常に出力された. 原因は不明である.
(このあたりはよくわからない...)

SDL_OpenAudioは旧バージョンとの互換性のためにある関数で, 新しくSDL_OpenAudioDevice関数が追加されているが試していない.


音声のコールバック関数

SDL 2.0では音声出力のコールバック関数でミックスされる元のバッファ(第2引数)を0で初期化しないとエコーがかかったようになった.

SDL 1.2

Uint8 *soundBuffer;

/*
.
.
.
*/

static void SDLCALL audioCallbackFunc(void *unused, Uint8 *stream, int len)
{
	SDL_MixAudio(stream, soundBuffer, len, SDL_MIX_MAXVOLUME);
}

SDL 2.0

static void SDLCALL audioCallbackFunc(void *unused, Uint8 *stream, int len)
{
	memset(stream, 0, len);
	SDL_MixAudio(stream, soundBuffer, len, SDL_MIX_MAXVOLUME);
}

音声バッファ

1つのバッファの音声を出力中に別のバッファに音声を書き込み, 出力し終えたらバッファを交換するようにした場合, SDL 1.2ではポインタを交換すればよかったが, SDL 2.0ではできない. バッファの値を出力側に書き込まなければならないようである.
(このあたりはよくわからない...)

SDL 1.2


int soundBufferSize;
Uint8 *soundWriteBuffer;

void flipSoundBuffer()
{
	Uint8 *p;

	p = soundBuffer;
	soundBuffer = soundWriteBuffer;
	soundWriteBuffer = p;

	memset(soundWriteBuffer, 0, soundBufferSize);
}

SDL 2.0


void flipSoundBuffer()
{
	memcpy(soundBuffer, soundWriteBuffer, soundBufferSize);
	memset(soundWriteBuffer, 0, soundBufferSize);
}


静的リンク

SDL 1.2はLGPLなので静的リンクすると場合によってはライセンス違反となる. SDL 2.0はzlibライセンスに変更されたため静的リンクできる.

しかし筆者の環境ではリンクのオプションを sdl2-config --static-libs としても静的リンクできなかった. (win32ではリンクエラー, Linuxでは動的リンクとなった.) /usr/local/bin/sdl2-config の --static-libs の下の echo を編集することで静的リンクできた.

win32

-lSDL2main -lSDL2
の部分を
-Wl,-Bstatic -lSDL2main -lSDL2 -Wl,-Bdynamic
として
-XCClinker -static-libgcc
を削除する.

Linux

-lSDL2
の部分を
-Wl,-Bstatic -lSDL2 -Wl,-Bdynamic
とする.


文字コード

SDL 1.2では文字コードはその環境のロケール(例えば日本語WindowsならばShift-JIS)だったが, SDL 2.0ではUTF-8になっている. 日本語Windowsの場合, int main(int argc, char *argv[])のargvはShift-JISなので注意すること.

SDL 2.0はSDL 1.2と同様に文字コードはUTF-8である. 日本語Windowsの場合, SDL 1.2ではint main(int argc, char *argv[])のargvはSHIFT-JISだったが, SDL 2.0ではUTF-8になっている.


戻る [転載可・改変可]