• SDL_imageとSDL_ttfとSDL_netを追加

    2011年04月12日 00時25分
    あと使いそうなのがimage、ttf、netあたりでしょうか。とりあえず入れておきました。


    SDL for D version 1.2.14.3


    3つ同時に試したのでごちゃごちゃしてますが、
    一応基本的なとこは動くのを確認しましたってことで。
    1import core.runtime;
    2import std.c.windows.windows;
    3import org.libsdl.sdl;
    4import org.libsdl.image;
    5import org.libsdl.ttf;
    6import org.libsdl.net;
    7
    8extern (Windows)
    9int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    10{
    11    void exceptionHandler(Throwable e)
    12    {
    13        throw e;
    14    }
    15
    16    int result;
    17    try
    18    {
    19        Runtime.initialize(&exceptionHandler);
    20        scope (exit) Runtime.terminate(&exceptionHandler);
    21
    22        dmain();
    23    }
    24    catch (Throwable o)
    25    {
    26        MessageBoxA(nullcast(char*)(o.toString() ~ '\0').ptr, "Error\0".ptr, MB_OK | MB_ICONEXCLAMATION);
    27        result = 1;
    28    }
    29
    30    return result;
    31}
    32
    33// 画面サイズ
    34immutable int SCREEN_WIDTH = 640;
    35immutable int SCREEN_HEIGHT = 680;
    36
    37void dmain()
    38{
    39    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
    40        throw new Error("SDL_Init failed.");
    41    scope(exit) SDL_Quit();
    42
    43    SDL_Surface* screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_HWSURFACE);
    44    if (screen is null)
    45        throw new Error("SDL_SetVideoMode failed.");
    46
    47
    48    // 画像の読み込みと解放
    49    SDL_Surface* image = IMG_Load("hoge.png");
    50    if (image is null)
    51        throw new Error("IMG_Load failed.");
    52    scope(exit) SDL_FreeSurface(image);
    53
    54
    55    // SDL_netの初期化と解放
    56    if(SDLNet_Init() != 0)
    57        throw new Error("SDLNet_Init failed.");
    58    scope(exit) SDLNet_Quit();
    59
    60    // ホスト名からIPアドレスを取得
    61    IPaddress address;
    62    if(SDLNet_ResolveHost(&address, "ku6.jp\0".ptr, 80))
    63        throw new Error("SDLNet_Init failed.");
    64
    65    // TCP接続のオープンとクローズ
    66    TCPsocket socket = SDLNet_TCP_Open(&address);
    67    if (socket is null)
    68        throw new Error("SDLNet_TCP_Open failed.");
    69    scope(exit) SDLNet_TCP_Close(socket);
    70
    71    // HTTPリクエストを送信
    72    string message = "GET /SDL_net.txt HTTP/1.0\r\n\r\n";
    73    SDLNet_TCP_Send(socket, message.ptr, message.length);
    74
    75    // 結果を受信
    76    char[] buffer = new char[64 * 1024];
    77    SDLNet_TCP_Recv(socket, buffer.ptr, buffer.length - 1);
    78
    79    // 各行の先頭ポインタを収集しつつ改行コードを文字終端とする
    80    char*[] lines = [buffer.ptr];
    81    for (uint i; i < buffer.length - 1; ++i)
    82    {
    83        if (buffer[i] == '\r')
    84        {
    85            buffer[i] = 0;
    86            if (buffer[i + 1] == '\n')
    87                lines ~= &buffer[i + 2];
    88            ++i;
    89        }
    90        else if (buffer[i] == '\n')
    91        {
    92            buffer[i] = 0;
    93            lines ~= &buffer[i + 1];
    94        }
    95    }
    96
    97
    98    // TTFの初期化と解放
    99    if(TTF_Init() != 0)
    100        throw new Error("TTF_Init failed.");
    101    scope(exit) TTF_Quit();
    102
    103    // フォントの取得と解放
    104    TTF_Font* font = TTF_OpenFont("ipam.ttf", 16);
    105    if (font is null)
    106        throw new Error("TTF_OpenFont failed.");
    107    scope(exit) TTF_CloseFont(font);
    108
    109    // 各行のテキストサーフェスの作成
    110    SDL_Color color = SDL_Color(128, 255, 128);
    111    SDL_Surface*[] textSurfaces;
    112    foreach (line; lines)
    113        textSurfaces ~= TTF_RenderUTF8_Solid(font, line, color);
    114
    115
    116    for (;;)
    117    {
    118        SDL_Event event;
    119        while (SDL_PollEvent(&event))
    120        {
    121            if (event.type == SDL_QUIT)
    122                return;
    123        }
    124
    125        // 画像の表示
    126        SDL_BlitSurface(image, null, screen, null);
    127
    128        // テキストの表示
    129        SDL_Rect rect;
    130        for (uint i; i < textSurfaces.length; ++i)
    131        {
    132            rect.y = cast(short)(18 * i);
    133            SDL_BlitSurface(textSurfaces[i], null, screen, &rect);
    134        }
    135
    136        // 画面の更新
    137        SDL_UpdateRect(screen, 0, 0, 0, 0);
    138    }
    139}


    SDL_Netがイマイチ使い方よくわからんのですが、一応上のコードで動いてはいます。


    あと、SDL_xxxをいっぱい足していったら、DLLが15個も並びました。
    なんかドキドキします。
  • ttf助かりました。
    k 2011年04月12日 01時49分 [編集]
  • 使わせて頂いてます。
    gfxはopengl使うので個人的にはこれで一通りです。ありがとうございます。

    で、見たところTTF_RenderUnicode_*とかの引数に出てくるUint16は
    そのままじゃなくてwcharにしていいのではないかと思うのですが、どうでしょうか。
    そうすれば文字列リテラルそのまま渡せて便利かなと。
    TTF_RenderUTF8_*は内部で変換してUnicode版を呼び出しているので最初からこっち呼び出したほうが速いです。
    ただSDL_ttfはキャラクタをFreetypeにそのまま渡しているので、サポートしているのはUCS2内っぽい(?)感じです。
    なので厳密にはwchar=utf-16として扱うのは間違いかもしれません(この辺の理解がちょっと微妙)が、まあ現実的には問題ないと思われます。ご一考ください。

    あと今までのコードだとenumの中身がaliasでグローバルにも宣言されていたのが
    imageとmixerではそうなっていません。
    まあ修飾付きで使った方が行儀はいい気もしますが、作業漏れかなと思いましたので報告させていただきます。

    以上、お手数ですがお時間ありましたらご確認お願いします。
    wagi 2011年04月13日 21時47分 [編集]
  • 丁寧にありがとうございます。
    enumの方は付け忘れですので追加します。


    UCS-2=UTF-16にして困るのはサロゲートペアが絡むあたりくらいでしょうか。
    実害は無いのではないかと思います。

    エンディアンもちょっと気になったのですが、
    Windowsで試したところwcharで問題無いようです。

    意味的にも利便性にもwcharがベターかと思いますので修正します。
    クロ 2011年04月13日 23時09分 [編集]

コメントを書く

名前
本文
編集用パスワード
管理者のみ閲覧