/* vim: ts=4 sw=4 sts=4 :
* =============================================================================
* SDL sample for D
* =============================================================================
*/
import std.conv;
import std.stdio;
import std.string;
import sdl.c.sdl;
import sdl.c.sdl_image;
/**
* MAIN.
*
* Params:
* args = 起動引数
*/
int main(char[][] args)
{
SDLImage sdlimg = new SDLImage();
sdlimg.showImages();
eventLoop();
return 0;
}
/**
* イベントループ.
*/
void eventLoop()
{
int quit = 0;
SDL_Event event;
/* unicode 変換を有効にする. */
SDL_EnableUNICODE(1);
while (!quit)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
/* SDL_QUIT イベント (ウィンドウが閉じられた) */
case SDL_QUIT:
quit = 1;
break;
default:
break;
}
}
}
}
/**
* SDLImage.
* あくまでサンプル, 構成変でスミマセン.
*/
class SDLImage
{
/**
* 静的コンストラクタ.
*
* SDL_Init を実行し, SDL を初期化しています.
* SDL_Init 実行後, まだ初期化していないサブシステムを
* 初期化する場合は, SDL_InitSubSytem を使用する必要があります.
*/
static this()
{
int ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
if (ret < 0)
{ // SDL初期化失敗
string errmsg = getErrorMessage();
throw new SDLException("can't init sdl. " ~ errmsg);
}
}
/**
* 静的デストラクタ.
* static this() が正常に完了している場合にのみ,
* プログラム終了時に呼び出されます.
* 本デストラクタにて, SDL終了処理を実行しています.
*/
static ~this()
{
SDL_Quit();
}
/**
* コンストラクタ.
* ビデオ表示初期化等を実施します.
*/
public
this()
{
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
if (screen is null)
{ // Video Mode 設定失敗
string errmsg = getErrorMessage();
throw new SDLException("can't set video mode. " ~ errmsg);
}
}
/**
* イメージ表示.
*/
public
void showImages()
{
SDL_Rect pos;
pos.x = 0;
pos.y = 0;
pos.h = 50;
pos.w = 200;
showImage("sample/resource/sample.bmp", pos);
pos.y += 50;
showImage("sample/resource/sample.png", pos);
pos.y += 50;
showImage("sample/resource/sample.jpg", pos);
pos.y += 50;
showImage("sample/resource/sample.gif", pos);
pos.y += 50;
showImage("sample/resource/sample.tif", pos);
}
/**
* 現在発生している SDL エラーメッセージを取得します.
*
* Returns:
* エラーメッセージ
*/
public static
string getErrorMessage()
{
const char* errmsg = SDL_GetError();
return to!(string)(errmsg);
}
/**
* イメージ表示.
* Params:
* screen = スクリーン
* file = イメージファイル
* pos = 表示位置
*/
private
void showImage(string file, SDL_Rect pos)
{
// イメージのロード.
// SDL_LoadBMP : BMPをロード.
// IMG_Load : いろんな形式をロード. SDL_image が必要.
SDL_Surface* image = IMG_Load(
cast(char*) std.string.toStringz(file));
if (image is null)
{ // イメージロードエラー.
string errmsg = getErrorMessage();
throw new SDLException("can't load image. " ~ errmsg);
}
// 画像がパレット表現なら, そのパレットを使う.
if ((image.format.palette !is null) && (this.screen.format.palette))
{
SDL_SetColors(this.screen,
image.format.palette.colors,
0,
image.format.palette.ncolors);
}
// 高速 Blit 転送
// 参照: http://www.tacoworks.jp/software/SDLdoc-jp/html/sdlblitsurface.html
int ret = SDL_BlitSurface(image, null, this.screen, &pos);
if (ret < 0)
{ // 転送失敗
string errmsg = getErrorMessage();
throw new SDLException("can't blit. " ~ errmsg);
}
// 指定領域の更新
SDL_UpdateRect(this.screen, pos.x, pos.y, image.w, image.h);
// サーフェス開放
SDL_FreeSurface(image);
}
private
{
SDL_Surface* screen;
}
}
/**
* SDL Exception.
* エラー発生時に throw する.
*/
class SDLException : Exception
{
/**
* 指定されたエラーメッセージを持つ, SDLException を構築します.
*
* Params:
* msg = エラーメッセージ
* next = Exception
*/
// this(string msg, Throwable next = null)
this(string msg, Exception next = null)
{
// super(msg, next);
super(msg);
}
}