SDL for D version 1.2.14.3
3つ同時に試したのでごちゃごちゃしてますが、
一応基本的なとこは動くのを確認しましたってことで。
1 | import core.runtime; |
---|---|
2 | import std.c.windows.windows; |
3 | import org.libsdl.sdl; |
4 | import org.libsdl.image; |
5 | import org.libsdl.ttf; |
6 | import org.libsdl.net; |
7 | |
8 | extern (Windows) |
9 | int 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(null, cast(char*)(o.toString() ~ '\0').ptr, "Error\0".ptr, MB_OK | MB_ICONEXCLAMATION); |
27 | result = 1; |
28 | } |
29 | |
30 | return result; |
31 | } |
32 | |
33 | // 画面サイズ |
34 | immutable int SCREEN_WIDTH = 640; |
35 | immutable int SCREEN_HEIGHT = 680; |
36 | |
37 | void 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個も並びました。
なんかドキドキします。
gfxはopengl使うので個人的にはこれで一通りです。ありがとうございます。
で、見たところTTF_RenderUnicode_*とかの引数に出てくるUint16は
そのままじゃなくてwcharにしていいのではないかと思うのですが、どうでしょうか。
そうすれば文字列リテラルそのまま渡せて便利かなと。
TTF_RenderUTF8_*は内部で変換してUnicode版を呼び出しているので最初からこっち呼び出したほうが速いです。
ただSDL_ttfはキャラクタをFreetypeにそのまま渡しているので、サポートしているのはUCS2内っぽい(?)感じです。
なので厳密にはwchar=utf-16として扱うのは間違いかもしれません(この辺の理解がちょっと微妙)が、まあ現実的には問題ないと思われます。ご一考ください。
あと今までのコードだとenumの中身がaliasでグローバルにも宣言されていたのが
imageとmixerではそうなっていません。
まあ修飾付きで使った方が行儀はいい気もしますが、作業漏れかなと思いましたので報告させていただきます。
以上、お手数ですがお時間ありましたらご確認お願いします。
enumの方は付け忘れですので追加します。
UCS-2=UTF-16にして困るのはサロゲートペアが絡むあたりくらいでしょうか。
実害は無いのではないかと思います。
エンディアンもちょっと気になったのですが、
Windowsで試したところwcharで問題無いようです。
意味的にも利便性にもwcharがベターかと思いますので修正します。