やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SDL2でイベントループを書く

 イベント処理するために。

成果物

demo

コード

#include <SDL2/SDL.h>
#include <stdio.h>

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480

int main(int argc, char* args[]) {
    SDL_Window* window = NULL;
    SDL_Surface* surface = NULL;
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "could not initialize sdl2: %s\n", SDL_GetError());
        return 1;
    }
    window = SDL_CreateWindow(
                            "Hello SDL2",
                            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                            SCREEN_WIDTH, SCREEN_HEIGHT,
                            SDL_WINDOW_SHOWN
                            );
    if (window == NULL) {
        fprintf(stderr, "could not create window: %s\n", SDL_GetError());
        return 1;
    }
    surface = SDL_GetWindowSurface(window);
    SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF));

    SDL_Event ev;
    while( SDL_WaitEvent(&ev) ) {
        switch(ev.type){
        case SDL_QUIT:
            printf("QUIT\n");
            SDL_DestroyWindow(window);
            SDL_Quit();
            break;
        case SDL_KEYDOWN:
            printf("KeyDonw\n");
            break;
        case SDL_MOUSEBUTTONDOWN:
            printf("MouseDown\n");
            break;
        case SDL_TEXTINPUT:
            printf("SDL_TEXTINPUT: %s\n", ev.text.text);
            break;
        case SDL_TEXTEDITING:
            printf("SDL_TEXTINPUT: %s\n", ev.text.text);
            break;
        default:
            break;
        }
        SDL_UpdateWindowSurface(window);
    }
    return 0;
}

ビルド

g++ main.cpp -o main -lSDL2

実行

./main

構造の解析

イベントループ

    SDL_Event ev;
    while( SDL_WaitEvent(&ev) ) {
        switch(ev.type){
        case SDL_QUIT:
            printf("QUIT\n");
            SDL_DestroyWindow(window);
            SDL_Quit();
            break;
        ...
        }
        SDL_UpdateWindowSurface(window);
    }

 終了するまで無限ループする。SDL_QUITなど規定のイベントに応じて処理を実装する。

 20世紀時代の古めかしい記法。クラスでなく関数なのでごった煮になってしまう。まさか今どきこんな低レベルコードを書くことになろうとは……。もっとこうw = Window(); w.Show();みたいなオブジェクト指向的に書きたいのだが……。

 生成。

SDL_Window* window = NULL;
window = SDL_CreateWindow(...);

 破棄。

SDL_DestroyWindow(window);
SDL_Quit();

描画

SDL_Window* window = NULL;
SDL_Surface* surface = NULL;
window = SDL_CreateWindow(...);
surface = SDL_GetWindowSurface(window);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF));
  1. 窓をつくる
  2. 窓からサーフェイスを取得する
  3. サーフェイスに矩形など何かを描画する

所感

 こんなコード書いてたら人生終わる。でもラズパイでUnity使えないし。

 UIまわりが圧倒的に足りない。Qtでも使うか? どちらも内部でOpenGLを使っていると思われる。

対象環境

$ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux