/* 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); } }