Nanashi-softプログラマ専用Windows gcc SDL


◇Windowsでgcc+SDL -四角を描く-

ウィンドウを生成して、そこに四角を描いてみます

○SDLヘッダ定義

一番最初にSDLヘッダを書きます

#include "SDL.h"

これを書いたら、stdio.hや string.hは不要です(書いても問題ありません)
SDL.h内で全て宣言済みなのでしょう

○画面初期化

main関数が必須です

int main(int argc,char *argv[]){

mainの引数などを省略すると、うまくコンパイルできないようです
SDL.hで何か宣言しているのでしょうか?

画面を初期化します

if(SDL_Init(SDL_INIT_VIDEO) < 0){
  return -1;
}

初期化に失敗したら終了するようにしておきます

○実画面用サーフェスを生成

実画面に描画する為のサーフェスを生成します
サーフェスとは SDLにおける画面描画領域の単位です
ここで生成したサーフェスに描画すると、実画面に反映する事ができます

SDL_Surface *screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
if(screen == NULL){
  SDL_Quit();
  return -1;
}

先頭の3つの引数は、横ドット数、縦ドット数、色深度です
色深度は現在表示している色数に合わせる必要がありますが、ここでは割愛します
色が変になるだけで、とりあえずエラーにはなりません

4つ目の引数は、生成したサーフェスの種類を指示します
SDL_SWSURFACEは、システムメモリ上に確保される
他にも沢山ありますが、ここでは割愛します

○四角を描画する

専用関数があるので、それを使ってみます

SDL_Rect box;
box.x = 160;
box.y = 120;
box.w = 320;
box.h = 240;
SDL_FillRect(screen, &box, 0xff2B4B65);
SDL_UpdateRect(screen,0,0,0,0);

先頭の screenは、実画面用サーフェスです
そこに描画しておいて、updateで更新をかけると表示されます

updateしなければ描画されないので、面倒な気がしますが、
逆に考えれば、updateしなければ描画されないので、裏画面が必要無いメリットがあります

○無限ループを作る

SDLは、無限ループを作らなければそのまま終わってしまい、画面を確認する事ができません

SDL_Event event;
int done = 0;
while(!done){
  while(SDL_PollEvent(&event)){
    switch(event.type){
    case SDL_KEYDOWN:
      if(event.key.keysym.sym == SDLK_ESCAPE){
        done = 1;
      }
      break;
    case SDL_QUIT:
      done = 1;
      break;
    }
  }
}

一番外に、フラグが立ったら終了する無限ループを作ります
その内側に、SDLのイベント受け取り待ちループを作ります
イベントが来ると、event.typeの中身を確認して、それぞれの動作を行います

キー入力があると、SDL_KEYDOWNが来ます
event.key.keysym.symにどのキーが押されたが来ているので、押されたキー毎に動作を行います
ここでは、ESCキーが押されたら、一番外の無限ループを終了させるフラグを立てました
SDL_QUITは、プログラムの終了通知が来た事を示すので、これが来ても終了フラグを立てます

○SDLを終了する

最後に、SDLの終了処理を行います

SDL_Quit();

これは、プログラム終了時には必ず書いて下さい

特にエラー終了時には記述するように注意です
これを記述せずに終了していると、メモリリークを起こすみたいです

○ビルドする

コマンドは以下の通りです

gcc -o 「拡張子無しファイル名」「ファイル名」 `sdl-config --cflags --libs`

例) wintest.cファイルをビルドする場合

gcc -o wintest wintest.c `sdl-config --cflags --libs`

エラーが無ければ、実行ファイル wintestが生成されます

./wintest
で起動可能です

○ソース

#include "SDL.h"

int main(int argc,char *argv[]){
  int done;
  SDL_Event event;

  if(SDL_Init(SDL_INIT_VIDEO) < 0){
    return -1;
  }

  SDL_Surface *screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
  if(screen == NULL){
    SDL_Quit();
    return -1;
  }

  SDL_Rect box;
  box.x = 160;
  box.y = 120;
  box.w = 320;
  box.h = 240;
  SDL_FillRect(screen, &box, 0xff2B4B65);
  SDL_UpdateRect(screen,0,0,0,0);

  done = 0;
  while(!done){
    while(SDL_PollEvent(&event)){
      switch(event.type){
      case SDL_KEYDOWN:
        if(event.key.keysym.sym == SDLK_ESCAPE){
          done = 1;
        }
        break;
      case SDL_QUIT:
        done = 1;
        break;
      }
    }
  }

  SDL_Quit();

  return 0;
}



TOPプログラマ専用Windows gcc SDL