/* vim: ts=4 sw=4 sts=4 : * ============================================================================= * SDL sample for C * ============================================================================= */ #include <stdio.h> #include <SDL.h> #include <SDL_image.h> /* エラーメッセージ出力. */ #define ERROR(x) printError(x, __FILE__, __LINE__) #define SDL_ERROR(x) printSDLError(x, __FILE__, __LINE__) /* プロトタイプ宣言 */ int init(void); void quit(void); SDL_Surface* setVideoMode(void); void mainLoop(void); /* プロトタイプ宣言 [画像表示]. */ void showImages(SDL_Surface* screen); void showImage(SDL_Surface* screen, const char* file, SDL_Rect* pos); /* プロトタイプ宣言 [エラー表示用]. */ void printError(const char* msg, const char* file, int line); void printSDLError(const char* msg, const char* file, int line); /** * MAIN. * * @param argc 起動引数の数 * @param argv[] 起動引数 (未使用) */ int main(int argc, char* argv[]) { int ret; SDL_Surface* screen; /* SDL初期化. */ ret = init(); if (ret < 0) { return -1; } /* SDL終了処理を終了時に自動実行するよう登録. */ atexit(quit); /* ビデオモード設定. */ screen = setVideoMode(); if (screen == NULL) { return -1; } /* 画像表示 */ showImages(screen); /* メインループ */ mainLoop(); return 0; } /** * SDL初期化. */ int init(void) { /* 初期化 */ int ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); if (ret < 0) { /* 初期化エラー */ SDL_ERROR("can't init sdl."); return -1; } /* * SDL_Init 後にまだ初期化していないサブシステムを * 初期化する場合は, 下記関数を使用する. * int SDL_InitSubSystem(Uint32 flags); */ return 0; } /** * SDL終了処理. */ void quit(void) { SDL_Quit(); } /** * ビデオ表示初期化. * @return SDL_Screen */ SDL_Surface* setVideoMode(void) { SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); if (screen == NULL) { /* ビデオモード設定エラー */ SDL_ERROR("can't set video mode."); return NULL; } return screen; } /** * 画像表示. * * @param screen スクリーン * @param file ファイル */ void showImages(SDL_Surface* screen) { SDL_Rect pos; pos.x = 0; pos.y = 0; pos.h = 50; pos.w = 200; showImage(screen, "sample/resource/sample.bmp", &pos); pos.y += 50; showImage(screen, "sample/resource/sample.png", &pos); pos.y += 50; showImage(screen, "sample/resource/sample.jpg", &pos); pos.y += 50; showImage(screen, "sample/resource/sample.gif", &pos); pos.y += 50; showImage(screen, "sample/resource/sample.tif", &pos); } /** * ★SDL_image 使用. * 指定されたイメージファイルをロード・表示します. * @param screen スクリーン * @param file イメージファイル * @param pos 表示位置 */ void showImage(SDL_Surface* screen, const char* file, SDL_Rect* pos) { int ret; /* イメージのロード. * SDL_LoadBMP : BMPをロード. * IMG_Load : いろんな形式をロード. SDL_image が必要. */ SDL_Surface* image = IMG_Load(file); if (image == NULL) { /* イメージロードエラー. */ SDL_ERROR("can't load image."); return; } /* 画像がパレット表現なら, そのパレットを使う. */ if (image->format->palette && screen->format->palette) { SDL_SetColors(screen, image->format->palette->colors, 0, image->format->palette->ncolors); } /* 高速Blit転送 * 参照: http://www.tacoworks.jp/software/SDLdoc-jp/html/sdlblitsurface.html */ ret = SDL_BlitSurface(image, NULL, screen, pos); if (ret < 0) { /* 転送失敗 */ SDL_ERROR("can't blit."); return; } /* 指定領域の更新 */ SDL_UpdateRect(screen, pos->x, pos->y, image->w, image->h); /* サーフェス開放 */ SDL_FreeSurface(image); } /** * イベントループ. */ void mainLoop(void) { 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; } } } } /* ============================================================================= * 以下, エラーメッセージ表示や, ユーティリティなど. * 本質ではないので・・・あんま見なくて良いかと. * ============================================================================= */ /** * エラーメッセージ表示. * * @param msg メッセージ * @param file ファイル名 * @param line 行番号 */ void printError(const char* msg, const char* file, int line) { fprintf(stderr, "%s:%d %s\n", file, line, msg); } /** * SDLエラーメッセージを含む, エラーメッセージ表示. * * @param msg メッセージ * @param file ファイル名 * @param line 行番号 */ void printSDLError(const char* msg, const char* file, int line) { char* sdlerr = SDL_GetError(); fprintf(stderr, "%s:%d %s [%s]\n", file, line, msg, sdlerr); }