• R/O
  • SSH
  • HTTPS

dxruby: Commit


Commit MetaInfo

Revisión190 (tree)
Tiempo2010-06-02 22:07:07
Autormirichi

Log Message

1.0.9 tags

Cambiar Resumen

Diferencia incremental

--- tags/1.0.9/dxruby.c (nonexistent)
+++ tags/1.0.9/dxruby.c (revision 190)
@@ -0,0 +1,7313 @@
1+/*
2+###################################
3+#
4+# dxruby.c Ver. 1.0.9
5+#
6+###################################
7+*/
8+#define DXRUBY_VERSION "1.0.9"
9+
10+#undef DIRECTINPUT_VERSION
11+#define DIRECTINPUT_VERSION (0x0800) /* DirectInputバージョン定義 */
12+#define WINVER 0x0500 // バージョン定義 Windows2000以上
13+#define _WIN32_WINNT WINVER
14+
15+#include "ruby.h"
16+#include <stdlib.h>
17+#include <mmsystem.h>
18+#include <tchar.h>
19+#include <d3dx9.h>
20+#include <dmusici.h>
21+#include <dinput.h>
22+#include <memory.h>
23+#include <math.h>
24+#include <WINNLS32.H>
25+//#include <DShow.h>
26+
27+#ifndef RSTRING_PTR
28+# define RSTRING_PTR(s) (RSTRING(s)->ptr)
29+#endif
30+#ifndef RSTRING_LEN
31+# define RSTRING_LEN(s) (RSTRING(s)->len)
32+#endif
33+
34+#ifndef RARRAY_PTR
35+# define RARRAY_PTR(s) (RARRAY(s)->ptr)
36+#endif
37+#ifndef RARRAY_LEN
38+# define RARRAY_LEN(s) (RARRAY(s)->len)
39+#endif
40+
41+#define RELEASE( x ) if( x ) { x->lpVtbl->Release( x ); x = NULL; }
42+
43+#define PADMAX 2
44+
45+#define P_LEFT 0
46+#define P_RIGHT 1
47+#define P_UP 2
48+#define P_DOWN 3
49+#define P_BUTTON0 4
50+#define P_BUTTON1 5
51+#define P_BUTTON2 6
52+#define P_BUTTON3 7
53+#define P_BUTTON4 8
54+#define P_BUTTON5 9
55+#define P_BUTTON6 10
56+#define P_BUTTON7 11
57+#define P_BUTTON8 12
58+#define P_BUTTON9 13
59+#define P_BUTTON10 14
60+#define P_BUTTON11 15
61+#define P_BUTTON12 16
62+#define P_BUTTON13 17
63+#define P_BUTTON14 18
64+#define P_BUTTON15 19
65+#define M_LBUTTON 0
66+#define M_RBUTTON 1
67+#define M_MBUTTON 2
68+#define FORMAT_JPEG D3DXIFF_JPG
69+#define FORMAT_JPG D3DXIFF_JPG
70+#define FORMAT_PNG D3DXIFF_PNG
71+#define FORMAT_BMP D3DXIFF_BMP
72+#define FORMAT_DDS D3DXIFF_DDS
73+#define WAVE_RECT 0
74+#define WAVE_SIN 1
75+#define WAVE_SAW 2
76+#define WAVE_TRI 3
77+
78+//#define WM_GRAPH_NOTIFY (WM_APP + 1) /* IMediaEventExのメッセージ */
79+
80+static VALUE mDXRuby; /* DXRubyモジュール */
81+static VALUE mWindow; /* ウィンドウモジュール */
82+static VALUE mInput; /* インプットモジュール */
83+static VALUE cImage; /* イメージクラス */
84+static VALUE cSound; /* サウンドクラス */
85+static VALUE cFont; /* フォントクラス */
86+static VALUE cSoundEffect; /* 生成効果音クラス */
87+static VALUE eDXRubyError; /* 例外 */
88+static VALUE cDXRubyInternalMark; /* 内部処理用 */
89+static VALUE oDXRubyInternalMark; /* 内部処理用 */
90+
91+/* グローバル変数たち */
92+static HINSTANCE g_hInstance = NULL; /* アプリケーションインスタンス */
93+static HANDLE g_hWnd = NULL; /* ウィンドウハンドル */
94+static LPDIRECT3D9 g_pD3D = NULL; /* Direct3Dインターフェイス */
95+static LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; /* Direct3DDeviceインターフェイス */
96+static D3DPRESENT_PARAMETERS g_D3DPP; /* D3DDeviceの設定 */
97+static LPD3DXSPRITE g_pD3DXSprite = NULL; /* スプライト */
98+
99+static LPDIRECTINPUT8 g_pDInput = NULL; /* DirectInput */
100+static LPDIRECTINPUTDEVICE8 g_pDIDKeyBoard = NULL; /* DirectInputのキーボードデバイス */
101+static LPDIRECTINPUTDEVICE8 g_pDIDJoyPad[PADMAX]; /* DirectInputのパッドデバイス */
102+static BYTE g_diKeyState[256]; /* DirectInputでのキーボード入力用バッファ */
103+static BYTE g_diKeyStateOld[256]; /* DirectInputでのキーボード入力用バッファ1フレーム前 */
104+static BYTE g_diKeyCount[256]; /* DirectInputでのキーボード入力用カウンタ */
105+static BYTE g_diKeyConfig[256]; /* DirectInputでのキーボード・パッド割り当て */
106+static BYTE g_diKeyWait[256]; /* オートリピートウェイト時間 */
107+static BYTE g_diKeyInterval[256]; /* オートリピート間隔 */
108+static int g_JoystickCount = 0;
109+static BYTE g_byMouseState_L, g_byMouseStateOld_L;
110+static BYTE g_byMouseState_M, g_byMouseStateOld_M;
111+static BYTE g_byMouseState_R, g_byMouseStateOld_R;
112+
113+
114+static IDirectMusicPerformance8 *g_pDMPerformance = NULL; /* DirectMusicPerformance8インターフェイス */
115+static IDirectMusicLoader8 *g_pDMLoader = NULL; /* ローダー */
116+static LPDIRECTSOUND8 g_pDSound = NULL; /* DirectSoundインターフェイス */
117+static int g_iRefDM = 0; /* DirectMusicパフォーマンスの参照カウント */
118+static int g_iRefDS = 0; /* DirectSoundの参照カウント */
119+static int g_iRefAll = 1; /* インターフェースの参照カウント */
120+
121+//static IGraphBuilder *g_pGraphBuilder = NULL; /* IGraphBuilderインターフェイス */
122+//static IMediaControl *g_pMediaControl = NULL; /* IMediaControlインターフェイス */
123+//static IVideoWindow *g_pVideoWindow = NULL; /* IVideoWindowインターフェイス */
124+//static IMediaEventEx *g_pMediaEventEx = NULL; /* IMediaEventExインターフェイス */
125+//static int g_PlayingMovie = 0; /* 動画再生中フラグ */
126+
127+
128+/* フレーム調整用 */
129+static __int64 g_OneSecondCount = 0; /* 一秒間にカウンタが数える数 */
130+static int g_isPerformanceCounter = 0; /* パフォーマンスカウンタがあったら1 */
131+static __int64 g_OldTime = 0; /* 前回のフレームが終わった時間 */
132+static __int64 g_OneFrameCount = 0; /* 1フレームの処理にかかった時間 */
133+static __int64 g_DrawTime = 0; /* 描画にかかった時間 */
134+
135+/* ウィンドウ情報構造体 */
136+static struct DXRubyWindowInfo {
137+ int x; /* x座標 */
138+ int y; /* y座標 */
139+ int width; /* 幅 */
140+ int height; /* 高さ */
141+ int windowed; /* ウィンドウモード時にQtrue */
142+ int created; /* ウィンドウを作成したらQtrue */
143+ float scale; /* ウィンドウのサイズ倍率 */
144+ int RefreshRate; /* リフレッシュレート */
145+ int enablemouse; /* マウスを表示するかどうか */
146+ int mousewheelpos; /* マウスホイールの位置 */
147+ int fps; /* fps */
148+ int fpscheck; /* 現在のfps */
149+ int frameskip; /* コマ落ち制御フラグ */
150+ int r; /* 背景クリア色 赤成分 */
151+ int g; /* 背景クリア色 緑成分 */
152+ int b; /* 背景クリア色 青成分 */
153+ int minfilter; /* 縮小フィルタ */
154+ int magfilter; /* 拡大フィルタ */
155+ HANDLE hIcon; /* ウィンドウアイコンハンドル */
156+ int loop; /* 自前ループされてたら1、Window.loopされたら2*/
157+ int requestclose; /* ウィンドウが閉じられたら1 */
158+ int active; /* ゲーム調整用 */
159+} g_WindowInfo;
160+
161+/* テクスチャデータ */
162+struct DXRubyTexture {
163+ LPDIRECT3DTEXTURE9 pD3DTexture; /* スプライトに使うテクスチャ */
164+ int width;
165+ int height;
166+ int refcount;
167+};
168+
169+/* フォントデータ */
170+struct DXRubyFont {
171+ LPD3DXFONT pD3DXFont; /* フォントオブジェクト */
172+ HFONT hFont; /* Image描画に使うフォント */
173+ int size; /* フォントサイズ */
174+};
175+
176+/* フォントデータ */
177+struct DXRubyFontSprite {
178+ struct DXRubyFont *font; /* スプライトに使うフォント */
179+ int color; /* フォントの色 */
180+ char str[0]; /* 文字列オブジェクト */
181+};
182+
183+/* スプライトデータ */
184+struct DXRubySprite {
185+ void *image; /* 描画するイメージオブジェクトもしくはフォント */
186+ int x; /* 描画位置 x */
187+ int y; /* 描画位置 y */
188+ float angle; /* 回転角度 */
189+ float scalex; /* 横拡大率 */
190+ float scaley; /* 縦拡大率 */
191+ float centerx; /* 回転時の中心 x */
192+ float centery; /* 回転時の中心 y */
193+ unsigned char alpha; /* アルファ(透明)値 */
194+ unsigned char blendflag :3; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
195+ unsigned char fontflag :1; /* フォントなら1 */
196+ unsigned char vpflag :1; /* ビューポートなら1 */
197+ unsigned char reserve1 :3; /* 予約2 */
198+ char reserve2; /* 予約3 */
199+ char reserve3; /* 予約4 */
200+ VALUE value;
201+};
202+
203+/* Viewport */
204+struct DXRubyViewport {
205+ D3DVIEWPORT9 viewport;
206+};
207+
208+/* Imageオブジェクトの中身 */
209+struct DXRubyImage {
210+ struct DXRubyTexture *texture;
211+ float x; /* x始点位置 */
212+ float y; /* y始点位置 */
213+ float width; /* イメージの幅 */
214+ float height;/* イメージの高さ */
215+};
216+
217+/* Soundオブジェクト */
218+struct DXRubySound {
219+ IDirectMusicAudioPath8 *pDMDefAudioPath; /* デフォルトオーディオパス */
220+ IDirectMusicSegment8 *pDMSegment; /* セグメント */
221+ int start;
222+ int loopstart;
223+ int loopend;
224+ int loopcount;
225+ int midwavflag; /* midは0、wavは1 */
226+};
227+
228+/* SoundEffectオブジェクト */
229+struct DXRubySoundEffect {
230+ LPDIRECTSOUNDBUFFER pDSBuffer; /* バッファ */
231+};
232+
233+/* Pad情報 */
234+static struct DXRubyPadInfo {
235+ int right;
236+ int left;
237+ int up;
238+ int down;
239+ LPDIRECTINPUTDEVICE8 pDIDJoyPad; /* DirectInputのパッドデバイス */
240+} g_PadInfo[PADMAX];
241+
242+/* Pad状態 */
243+static struct DXRubyPadState {
244+ char button[20];
245+ int PadConfig[20];
246+ int count[20];
247+ int wait[20];
248+ int interval[20];
249+} g_PadState[PADMAX], g_PadStateOld[PADMAX];
250+
251+/* スプライト配列 */
252+static struct DXRubySpriteList {
253+ float z; /* スプライトのZ座標 */
254+ struct DXRubySprite *sprite; /* スプライト構造体へのポインタ */
255+} *g_SpriteList;
256+static int g_SpriteCount; /* スプライトの登録数 */
257+static int g_SpriteAllocateCount; /* スプライト配列のメモリ確保数 */
258+static struct DXRubySprite *g_SpriteStruct;
259+
260+/* 色 */
261+struct DXRubyColor {
262+ unsigned char blue;
263+ unsigned char green;
264+ unsigned char red;
265+ unsigned char alpha;
266+};
267+
268+/* シンボル */
269+static VALUE symbol_blend = Qundef;
270+static VALUE symbol_angle = Qundef;
271+static VALUE symbol_alpha = Qundef;
272+static VALUE symbol_scalex = Qundef;
273+static VALUE symbol_scaley = Qundef;
274+static VALUE symbol_centerx = Qundef;
275+static VALUE symbol_centery = Qundef;
276+static VALUE symbol_z = Qundef;
277+static VALUE symbol_color = Qundef;
278+static VALUE symbol_add = Qundef;
279+static VALUE symbol_add2 = Qundef;
280+static VALUE symbol_sub = Qundef;
281+static VALUE symbol_sub2 = Qundef;
282+static VALUE symbol_italic = Qundef;
283+static VALUE symbol_weight = Qundef;
284+
285+/* キーのオートリピート用 */
286+//static int g_iInputWait;
287+//static int g_iInterval;
288+
289+/* プロトタイプ宣言 */
290+static void InitWindow( void );
291+static void InitDXGraphics( void );
292+static void InitDirectInput( void );
293+LRESULT CALLBACK MainWndProc( HWND hWnd,UINT msg,UINT wParam,LONG lParam );
294+static void InitSync( void );
295+static __int64 GetSystemCounter( void );
296+static void Window_DirectXRelease( void );
297+static struct DXRubyTexture *Image_textureload( char *filename, D3DXIMAGE_INFO *psrcinfo );
298+static void Input_SetConfig( int number, int pad, int key );
299+static void ChangeSize( void );
300+static void inputupdate( void);
301+static VALUE Input_update( VALUE );
302+static VALUE Window_update( VALUE );
303+static VALUE Window_sync( VALUE );
304+static VALUE Window_create( VALUE );
305+static void AllocSpriteList( void );
306+static void SortSpriteList( void );
307+
308+static void release_Image( struct DXRubyImage* image );
309+static void release_Font( struct DXRubyFont* font );
310+
311+static VALUE hash_lookup(VALUE hash, VALUE key);
312+
313+/*********************************************************************
314+ * Windowモジュール
315+ * ウィンドウの管理・描画を行う。
316+ *********************************************************************/
317+
318+/*--------------------------------------------------------------------
319+ ウィンドウの生成と初期化
320+ ---------------------------------------------------------------------*/
321+static VALUE Window_create( VALUE obj )
322+{
323+ HRESULT hr;
324+ RECT rect;
325+
326+ if( g_WindowInfo.created == Qtrue )
327+ {
328+ rb_raise( eDXRubyError, "ウィンドウ作成後に実行することはできません - Window_create" );
329+ }
330+
331+ /* ウィンドウのサイズ設定 */
332+ rect.top = 0;
333+ rect.left = 0;
334+ rect.right = g_WindowInfo.width * g_WindowInfo.scale;
335+ rect.bottom = g_WindowInfo.height * g_WindowInfo.scale;
336+
337+ /* ウィンドウのサイズ修正 */
338+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
339+ { /* フルスクリーン */
340+ SetWindowLong( g_hWnd, GWL_STYLE, WS_POPUP );
341+ SetWindowPos( g_hWnd, HWND_TOP, 0, 0, g_WindowInfo.width, g_WindowInfo.height, SWP_NOZORDER);
342+ }
343+ else
344+ { /* ウィンドウモード */
345+ SetWindowLong( g_hWnd, GWL_STYLE, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
346+ AdjustWindowRect( &rect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE );
347+
348+ /* 幅と高さ計算 */
349+ rect.right = rect.right - rect.left;
350+ rect.bottom = rect.bottom - rect.top;
351+
352+ /* ウィンドウ移動/サイズ設定 */
353+ if( g_WindowInfo.x == CW_USEDEFAULT )
354+ { /* 位置がデフォルトの場合 */
355+ SetWindowPos( g_hWnd, HWND_TOP, 0, 0, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
356+ }
357+ else
358+ { /* 位置指定の場合 */
359+ SetWindowPos( g_hWnd, HWND_TOP, g_WindowInfo.x, g_WindowInfo.y, rect.right, rect.bottom, SWP_NOZORDER );
360+ }
361+ }
362+
363+ /* DirectXのスクリーンサイズ変更 */
364+ ChangeSize();
365+
366+ /* ウィンドウ表示 */
367+ ShowWindow( g_hWnd, SW_SHOWNORMAL );
368+ InvalidateRect( NULL, NULL, TRUE );
369+ UpdateWindow( g_hWnd );
370+
371+ /* シーンのクリア */
372+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
373+ D3DCOLOR_XRGB( g_WindowInfo.r, g_WindowInfo.g, g_WindowInfo.b ), 0, 0 );
374+ g_pD3DDevice->lpVtbl->Present( g_pD3DDevice, NULL, NULL, NULL, NULL );
375+
376+ /* フレーム調整処理初期化 */
377+ InitSync();
378+
379+ g_WindowInfo.created = Qtrue;
380+
381+ return obj;
382+}
383+
384+
385+/*--------------------------------------------------------------------
386+ (内部関数)スクリーンサイズ変更
387+ ---------------------------------------------------------------------*/
388+static void ChangeSize( void )
389+{
390+ D3DVIEWPORT9 vp;
391+ HRESULT hr;
392+
393+
394+ g_D3DPP.BackBufferWidth = g_WindowInfo.width;
395+ g_D3DPP.BackBufferHeight = g_WindowInfo.height;
396+
397+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
398+ {
399+ /* フルスクリーン時(32bitColor/60Hz固定) */
400+ g_D3DPP.BackBufferFormat = D3DFMT_X8R8G8B8;
401+ g_D3DPP.Windowed = FALSE;
402+ g_D3DPP.FullScreen_RefreshRateInHz = 60;
403+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
404+ g_WindowInfo.RefreshRate = 60;
405+ }
406+ else
407+ {
408+ /* ウィンドウモード時 */
409+ g_D3DPP.BackBufferFormat = D3DFMT_UNKNOWN;
410+ g_D3DPP.Windowed = TRUE;
411+ g_D3DPP.FullScreen_RefreshRateInHz = 0;
412+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
413+ g_WindowInfo.RefreshRate = 0;
414+ }
415+
416+ /* スプライトをロストさせる */
417+ if( g_pD3DXSprite )
418+ {
419+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
420+ }
421+
422+ /* 設定変更 */
423+ hr = g_pD3DDevice->lpVtbl->Reset( g_pD3DDevice, &g_D3DPP );
424+ if( FAILED( hr ) )
425+ {
426+ rb_raise( eDXRubyError, "設定に失敗しました - Reset" );
427+ }
428+
429+ /* スプライト復帰 */
430+ if( g_pD3DXSprite )
431+ {
432+ g_pD3DXSprite->lpVtbl->OnResetDevice( g_pD3DXSprite );
433+ }
434+
435+ /* ビューポートの設定 */
436+ vp.X = 0;
437+ vp.Y = 0;
438+ vp.Width = g_D3DPP.BackBufferWidth;
439+ vp.Height = g_D3DPP.BackBufferHeight;
440+ vp.MinZ = 0.0f;
441+ vp.MaxZ = 1.0f;
442+
443+ hr = g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
444+
445+ if( FAILED( hr ) )
446+ {
447+ rb_raise( eDXRubyError, "設定に失敗しました - SetViewport" );
448+ }
449+}
450+
451+
452+/*--------------------------------------------------------------------
453+ Windowsのメッセージループ
454+ ---------------------------------------------------------------------*/
455+static VALUE Window_loop( VALUE obj )
456+{
457+ MSG msg;
458+ msg.message = WM_NULL;
459+
460+ if( g_WindowInfo.created == Qtrue )
461+ {
462+ rb_raise( eDXRubyError, "ウィンドウ作成後に実行することはできません - Window_loop" );
463+ }
464+
465+ g_WindowInfo.loop = 2;
466+ Window_create( obj );
467+
468+ /* メッセージループ */
469+ /* WM_QUITが届くまでメッセージ処理をし続ける */
470+ /* メッセージが無い時はブロックをyieldする */
471+ while( msg.message != WM_QUIT )
472+ {
473+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
474+ {
475+ /* メッセージがある時 */
476+ TranslateMessage( &msg );
477+ DispatchMessage( &msg );
478+ }
479+ else
480+ {
481+ /* メッセージが無い時 */
482+ /* 入力状態更新 */
483+ inputupdate();
484+ /* ブロック実行 */
485+ rb_yield( obj );
486+ /* fps調整 */
487+ Window_sync( obj );
488+ /* 描画 */
489+ Window_update( obj );
490+ }
491+ }
492+
493+ return Qtrue;
494+}
495+
496+
497+/*--------------------------------------------------------------------
498+ (内部関数)ウィンドウプロシージャ
499+ ---------------------------------------------------------------------*/
500+LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
501+{
502+ RECT rect;
503+
504+ switch( msg )
505+ {
506+ /* ウィンドウアクティブ/非アクティブ化 */
507+ case WM_ACTIVATE:
508+ g_WindowInfo.active = (LOWORD(wParam) != 0);
509+ break;
510+ case WM_CLOSE:
511+ /* 自前ループの場合は無条件でキャセルする */
512+ if( g_WindowInfo.loop == 1 )
513+ {
514+ g_WindowInfo.requestclose = 1;
515+ return 0;
516+ }
517+ break;
518+ /* ウィンドウ破棄 */
519+ case WM_DESTROY:
520+ /* ウインドウを閉じる */
521+ PostQuitMessage( 0 );
522+ g_hWnd = NULL;
523+ return 0;
524+
525+// case WM_GRAPH_NOTIFY:
526+// {
527+// long evCode;
528+// LONG param1, param2;
529+// while( SUCCEEDED( g_pMediaEventEx->lpVtbl->GetEvent( g_pMediaEventEx, &evCode, &param1, &param2, 0 )))
530+// {
531+// g_pMediaEventEx->lpVtbl->FreeEventParams( g_pMediaEventEx, evCode, param1, param2 );
532+//
533+// switch (evCode) {
534+// case EC_COMPLETE:
535+// // 再生終了
536+// g_PlayingMovie = 0;
537+// break;
538+// }
539+// }
540+// break;
541+// }
542+
543+ case WM_MOUSEWHEEL:
544+ g_WindowInfo.mousewheelpos += (short)HIWORD(wParam);
545+ break;
546+/*
547+ case WM_SETCURSOR:
548+ if( g_pD3DDevice )
549+ {
550+ if( LOWORD( lParam ) == HTCLIENT ) // クライアント領域のみ
551+ {
552+ if( g_WindowInfo.enablemouse == Qfalse )
553+ {
554+ SetCursor( NULL ); // ウインドウの標準カーソルを消す
555+ return TRUE; // 設定を終えたことを通知
556+ }
557+ }
558+ }
559+ break;
560+*/
561+ }
562+
563+ /* デフォルト処理 */
564+ return DefWindowProc( hWnd, msg, wParam, lParam );
565+}
566+
567+
568+/*--------------------------------------------------------------------
569+ 画面クリア色指定
570+ ---------------------------------------------------------------------*/
571+static VALUE Window_getbgcolor( VALUE obj )
572+{
573+ return rb_ary_new3( 3, INT2FIX( g_WindowInfo.r ), INT2FIX( g_WindowInfo.g ), INT2FIX( g_WindowInfo.b ) );
574+}
575+
576+
577+/*--------------------------------------------------------------------
578+ 画面クリア色指定
579+ ---------------------------------------------------------------------*/
580+static VALUE Window_setbgcolor( VALUE obj, VALUE array )
581+{
582+ Check_Type(array, T_ARRAY);
583+
584+ if( RARRAY_LEN(array) == 4 )
585+ {
586+ g_WindowInfo.r = NUM2INT( rb_ary_entry(array, 1) );
587+ g_WindowInfo.g = NUM2INT( rb_ary_entry(array, 2) );
588+ g_WindowInfo.b = NUM2INT( rb_ary_entry(array, 3) );
589+ }
590+ else
591+ {
592+ g_WindowInfo.r = NUM2INT( rb_ary_entry(array, 0) );
593+ g_WindowInfo.g = NUM2INT( rb_ary_entry(array, 1) );
594+ g_WindowInfo.b = NUM2INT( rb_ary_entry(array, 2) );
595+ }
596+
597+ return obj;
598+}
599+
600+
601+/*--------------------------------------------------------------------
602+ 描画設定(通常描画)
603+ ---------------------------------------------------------------------*/
604+static VALUE Window_draw( int argc, VALUE *argv, VALUE obj )
605+{
606+ struct DXRubyImage *image;
607+
608+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
609+
610+ AllocSpriteList();
611+
612+ /* 引数のイメージオブジェクトから中身を取り出す */
613+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
614+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
615+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
616+ {
617+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
618+ }
619+
620+ /* DXRubySpriteオブジェクト設定 */
621+ g_SpriteStruct[g_SpriteCount].image = image;
622+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
623+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
624+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
625+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
626+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
627+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
628+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
629+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
630+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
631+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
632+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
633+ g_SpriteStruct[g_SpriteCount].value = argv[2];
634+
635+ /* リストデータに追加 */
636+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
637+ g_SpriteList[g_SpriteCount].z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2DBL( argv[3] );
638+ g_SpriteCount++;
639+
640+ return obj;
641+}
642+
643+
644+/*--------------------------------------------------------------------
645+ 描画設定(拡大縮小描画)
646+ ---------------------------------------------------------------------*/
647+static VALUE Window_drawScale( int argc, VALUE *argv, VALUE obj )
648+{
649+ struct DXRubyImage *image;
650+
651+ if( argc < 5 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 5);
652+
653+ AllocSpriteList();
654+
655+ /* 引数のイメージオブジェクトから中身を取り出す */
656+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
657+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
658+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
659+ {
660+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
661+ }
662+
663+ /* DXRubySpriteオブジェクト設定 */
664+ g_SpriteStruct[g_SpriteCount].image = image;
665+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
666+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
667+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
668+ g_SpriteStruct[g_SpriteCount].scalex = NUM2DBL( argv[3] );
669+ g_SpriteStruct[g_SpriteCount].scaley = NUM2DBL( argv[4] );
670+ g_SpriteStruct[g_SpriteCount].centerx = argc < 6 || argv[5] == Qnil ? image->width / 2 : NUM2DBL( argv[5] );
671+ g_SpriteStruct[g_SpriteCount].centery = argc < 7 || argv[6] == Qnil ? image->height / 2 : NUM2DBL( argv[6] );
672+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
673+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
674+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
675+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
676+ g_SpriteStruct[g_SpriteCount].value = argv[2];
677+
678+ /* リストデータに追加 */
679+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
680+ g_SpriteList[g_SpriteCount].z = argc < 8 || argv[7] == Qnil ? 0.0f : NUM2DBL( argv[7] );
681+ g_SpriteCount++;
682+
683+ return obj;
684+}
685+
686+
687+/*--------------------------------------------------------------------
688+ 描画設定(回転描画)
689+ ---------------------------------------------------------------------*/
690+static VALUE Window_drawRot( int argc, VALUE *argv, VALUE obj )
691+{
692+ struct DXRubyImage *image;
693+
694+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
695+
696+ AllocSpriteList();
697+
698+ /* 引数のイメージオブジェクトから中身を取り出す */
699+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
700+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
701+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
702+ {
703+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
704+ }
705+
706+ /* DXRubySpriteオブジェクト設定 */
707+ g_SpriteStruct[g_SpriteCount].image = image;
708+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
709+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
710+ g_SpriteStruct[g_SpriteCount].angle = NUM2DBL( argv[3] );
711+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
712+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
713+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
714+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
715+ g_SpriteStruct[g_SpriteCount].centerx = argc < 5 || argv[4] == Qnil ? image->width / 2 : NUM2DBL( argv[4] );
716+ g_SpriteStruct[g_SpriteCount].centery = argc < 6 || argv[5] == Qnil ? image->height / 2 : NUM2DBL( argv[5] );
717+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
718+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
719+ g_SpriteStruct[g_SpriteCount].value = argv[2];
720+
721+ /* リストデータに追加 */
722+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
723+ g_SpriteList[g_SpriteCount].z = argc < 7 || argv[6] == Qnil ? 0.0f : NUM2DBL( argv[6] );
724+ g_SpriteCount++;
725+
726+ return obj;
727+}
728+
729+
730+/*--------------------------------------------------------------------
731+ 描画設定(半透明描画)
732+ ---------------------------------------------------------------------*/
733+static VALUE Window_drawAlpha( int argc, VALUE *argv, VALUE obj )
734+{
735+ struct DXRubyImage *image;
736+
737+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
738+
739+ AllocSpriteList();
740+
741+ /* 引数のイメージオブジェクトから中身を取り出す */
742+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
743+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
744+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
745+ {
746+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
747+ }
748+
749+ /* DXRubySpriteオブジェクト設定 */
750+ g_SpriteStruct[g_SpriteCount].image = image;
751+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
752+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
753+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
754+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
755+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
756+ g_SpriteStruct[g_SpriteCount].alpha = NUM2INT( argv[3] );
757+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
758+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
759+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
760+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
761+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
762+ g_SpriteStruct[g_SpriteCount].value = argv[2];
763+
764+ /* リストデータに追加 */
765+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
766+ g_SpriteList[g_SpriteCount].z = argc < 5 || argv[4] == Qnil ? 0.0f : NUM2DBL( argv[4] );
767+ g_SpriteCount++;
768+
769+ return obj;
770+}
771+
772+
773+/*--------------------------------------------------------------------
774+ 描画設定(加算合成描画)
775+ ---------------------------------------------------------------------*/
776+static VALUE Window_drawAdd( int argc, VALUE *argv, VALUE obj )
777+{
778+ struct DXRubyImage *image;
779+
780+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
781+
782+ AllocSpriteList();
783+
784+ /* 引数のイメージオブジェクトから中身を取り出す */
785+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
786+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
787+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
788+ {
789+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
790+ }
791+
792+ /* DXRubySpriteオブジェクト設定 */
793+ g_SpriteStruct[g_SpriteCount].image = image;
794+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
795+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
796+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
797+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
798+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
799+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
800+ g_SpriteStruct[g_SpriteCount].blendflag = 4;
801+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
802+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
803+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
804+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
805+ g_SpriteStruct[g_SpriteCount].value = argv[2];
806+
807+ /* リストデータに追加 */
808+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
809+ g_SpriteList[g_SpriteCount].z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2DBL( argv[3] );
810+ g_SpriteCount++;
811+
812+ return obj;
813+}
814+
815+
816+/*--------------------------------------------------------------------
817+ 描画設定(減算合成描画)
818+ ---------------------------------------------------------------------*/
819+static VALUE Window_drawSub( int argc, VALUE *argv, VALUE obj )
820+{
821+ struct DXRubyImage *image;
822+
823+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
824+
825+ AllocSpriteList();
826+
827+ /* 引数のイメージオブジェクトから中身を取り出す */
828+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
829+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
830+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
831+ {
832+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
833+ }
834+
835+ /* DXRubySpriteオブジェクト設定 */
836+ g_SpriteStruct[g_SpriteCount].image = image;
837+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
838+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
839+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
840+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
841+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
842+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
843+ g_SpriteStruct[g_SpriteCount].blendflag = 6;
844+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
845+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
846+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
847+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
848+ g_SpriteStruct[g_SpriteCount].value = argv[2];
849+
850+ /* リストデータに追加 */
851+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
852+ g_SpriteList[g_SpriteCount].z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2DBL( argv[3] );
853+ g_SpriteCount++;
854+
855+ return obj;
856+}
857+
858+
859+/*--------------------------------------------------------------------
860+ 描画設定(フルオプション)
861+ ---------------------------------------------------------------------*/
862+static VALUE Window_drawEx( int argc, VALUE *argv, VALUE obj )
863+{
864+ struct DXRubyImage *image;
865+ VALUE x, y, z, data, angle, scalex, scaley, alpha, centerx, centery, blend, add;
866+ VALUE option;
867+
868+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
869+
870+ if( argc < 4 || argv[3] == Qnil )
871+ {
872+ option = rb_hash_new();
873+ }
874+ else
875+ {
876+ Check_Type( argv[3], T_HASH );
877+ option = argv[3];
878+ }
879+
880+ AllocSpriteList();
881+
882+ blend = hash_lookup( option, symbol_blend );
883+ angle = hash_lookup( option, symbol_angle );
884+ alpha = hash_lookup( option, symbol_alpha );
885+ scalex = hash_lookup( option, symbol_scalex );
886+ scaley = hash_lookup( option, symbol_scaley );
887+ centerx = hash_lookup( option, symbol_centerx );
888+ centery = hash_lookup( option, symbol_centery );
889+ z = hash_lookup( option, symbol_z );
890+
891+ /* 引数のイメージオブジェクトから中身を取り出す */
892+ if( TYPE( argv[2] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
893+ image = (struct DXRubyImage *)DATA_PTR( argv[2] );
894+ if (RDATA(argv[2])->dfree != (RUBY_DATA_FUNC)release_Image)
895+ {
896+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( argv[2] ));
897+ }
898+
899+ /* DXRubySpriteオブジェクト設定 */
900+ g_SpriteStruct[g_SpriteCount].image = image;
901+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
902+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
903+ g_SpriteStruct[g_SpriteCount].angle = (angle == Qnil ? 0.0f : NUM2DBL( angle ));
904+ g_SpriteStruct[g_SpriteCount].scalex = (scalex == Qnil ? 1.0f : NUM2DBL( scalex ));
905+ g_SpriteStruct[g_SpriteCount].scaley = (scaley == Qnil ? 1.0f : NUM2DBL( scaley ));
906+ g_SpriteStruct[g_SpriteCount].centerx = (centerx == Qnil ? image->width / 2 : NUM2DBL( centerx ));
907+ g_SpriteStruct[g_SpriteCount].centery = (centery == Qnil ? image->height / 2 : NUM2DBL( centery ));
908+ g_SpriteStruct[g_SpriteCount].alpha = (alpha == Qnil ? 0xff : NUM2INT( alpha ));
909+ g_SpriteStruct[g_SpriteCount].blendflag = (blend == symbol_add ? 4 :
910+ (blend == symbol_add2 ? 5 :
911+ (blend == symbol_sub ? 6 :
912+ (blend == symbol_sub2 ? 7 : 0))));
913+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
914+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
915+ g_SpriteStruct[g_SpriteCount].value = argv[2];
916+
917+ /* リストデータに追加 */
918+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
919+ g_SpriteList[g_SpriteCount].z = z == Qnil ? 0.0f : NUM2DBL( z );
920+ g_SpriteCount++;
921+
922+ return obj;
923+}
924+
925+
926+/*--------------------------------------------------------------------
927+ フォント描画
928+ ---------------------------------------------------------------------*/
929+static VALUE Window_drawFont( int argc, VALUE *argv, VALUE obj )
930+{
931+ struct DXRubySprite *spr;
932+ struct DXRubyFont *font;
933+ VALUE color;
934+ int cr, cg, cb;
935+ VALUE z, angle, scalex, scaley, alpha, centerx, centery, blend, add;
936+ VALUE option;
937+ struct DXRubyFontSprite *fontsprite;
938+
939+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
940+
941+ Check_Type(argv[2], T_STRING);
942+
943+ if( argc < 5 || argv[4] == Qnil )
944+ {
945+ option = rb_hash_new();
946+ }
947+ else
948+ {
949+ Check_Type( argv[4], T_HASH );
950+ option = argv[4];
951+ }
952+
953+ blend = hash_lookup( option, symbol_blend );
954+ angle = hash_lookup( option, symbol_angle );
955+ alpha = hash_lookup( option, symbol_alpha );
956+ scalex = hash_lookup( option, symbol_scalex );
957+ scaley = hash_lookup( option, symbol_scaley );
958+ centerx = hash_lookup( option, symbol_centerx );
959+ centery = hash_lookup( option, symbol_centery );
960+ z = hash_lookup( option, symbol_z );
961+ color = hash_lookup( option, symbol_color );
962+
963+ AllocSpriteList();
964+
965+ /* 引数のフォントオブジェクトから中身を取り出す */
966+ Data_Get_Struct( argv[3], struct DXRubyFont, font );
967+ if (RDATA(argv[3])->dfree != (RUBY_DATA_FUNC)release_Font)
968+ {
969+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Font)", rb_obj_classname( argv[3] ));
970+ }
971+
972+ fontsprite = malloc( sizeof(struct DXRubyFontSprite) + RSTRING_LEN(argv[2]) + 2 );
973+ if( fontsprite == NULL )
974+ {
975+ rb_raise( eDXRubyError, "フォント用メモリの確保に失敗しました" );
976+ }
977+ /* DXRubySpriteオブジェクト設定 */
978+ g_SpriteStruct[g_SpriteCount].image = fontsprite;
979+ g_SpriteStruct[g_SpriteCount].x = NUM2INT( argv[0] );
980+ g_SpriteStruct[g_SpriteCount].y = NUM2INT( argv[1] );
981+ g_SpriteStruct[g_SpriteCount].angle = (angle == Qnil ? 0.0f : NUM2DBL( angle ));
982+ g_SpriteStruct[g_SpriteCount].scalex = (scalex == Qnil ? 1.0f : NUM2DBL( scalex ));
983+ g_SpriteStruct[g_SpriteCount].scaley = (scaley == Qnil ? 1.0f : NUM2DBL( scaley ));
984+ g_SpriteStruct[g_SpriteCount].centerx = (centerx == Qnil ? 0.0f : NUM2DBL( centerx ));;
985+ g_SpriteStruct[g_SpriteCount].centery = (centery == Qnil ? 0.0f : NUM2DBL( centery ));;
986+ g_SpriteStruct[g_SpriteCount].alpha = (alpha == Qnil ? 0xff : NUM2INT( alpha ));
987+ g_SpriteStruct[g_SpriteCount].blendflag = (blend == symbol_add ? 4 :
988+ (blend == symbol_add2 ? 5 :
989+ (blend == symbol_sub ? 6 :
990+ (blend == symbol_sub2 ? 7 : 0))));
991+ g_SpriteStruct[g_SpriteCount].fontflag = 1;
992+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
993+ g_SpriteStruct[g_SpriteCount].value = argv[3];
994+
995+ lstrcpy(fontsprite->str, RSTRING_PTR(argv[2])); /* 文字列の保存 */
996+ fontsprite->str[RSTRING_LEN(argv[2])] = ' '; /* イタリック対策にスペース追加 */
997+ fontsprite->str[RSTRING_LEN(argv[2])+1] = 0;
998+
999+ if( color != Qnil )
1000+ {
1001+ Check_Type(color, T_ARRAY);
1002+ if( RARRAY_LEN(color) == 4 )
1003+ {
1004+ g_SpriteStruct[g_SpriteCount].alpha = NUM2INT(rb_ary_entry(color, 0));
1005+ cr = NUM2INT(rb_ary_entry(color, 1));
1006+ cg = NUM2INT(rb_ary_entry(color, 2));
1007+ cb = NUM2INT(rb_ary_entry(color, 3));
1008+ }
1009+ else
1010+ {
1011+ cr = NUM2INT(rb_ary_entry(color, 0));
1012+ cg = NUM2INT(rb_ary_entry(color, 1));
1013+ cb = NUM2INT(rb_ary_entry(color, 2));
1014+ }
1015+ }
1016+ else
1017+ {
1018+ cr = 255;
1019+ cg = 255;
1020+ cb = 255;
1021+ }
1022+ fontsprite->color = D3DCOLOR_XRGB(cr, cg, cb);
1023+ fontsprite->font = font;
1024+
1025+ /* リストデータに追加 */
1026+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
1027+ g_SpriteList[g_SpriteCount].z = z == Qnil ? 0.0f : NUM2DBL( z );
1028+ g_SpriteCount++;
1029+
1030+ return obj;
1031+}
1032+
1033+
1034+/*--------------------------------------------------------------------
1035+ ビューポート設定
1036+ ---------------------------------------------------------------------*/
1037+static VALUE Window_setViewport( int argc, VALUE *argv, VALUE obj )
1038+{
1039+ struct DXRubyViewport *vp;
1040+
1041+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
1042+
1043+ AllocSpriteList();
1044+
1045+ if( NUM2INT(argv[0]) < 0 || NUM2INT(argv[1]) < 0 || NUM2INT(argv[2]) < 0 || NUM2INT(argv[3]) < 0 ||
1046+ NUM2INT(argv[0]) + NUM2INT(argv[2]) > g_WindowInfo.width || NUM2INT(argv[1]) + NUM2INT(argv[3]) > g_WindowInfo.height)
1047+ {
1048+ rb_raise(rb_eArgError, "範囲の指定が異常です - setViewport");
1049+ }
1050+
1051+ vp = malloc( sizeof(struct DXRubyViewport) );
1052+
1053+ vp->viewport.X = NUM2INT( argv[0] );
1054+ vp->viewport.Y = NUM2INT( argv[1] );
1055+ vp->viewport.Width = NUM2INT( argv[2] );
1056+ vp->viewport.Height = NUM2INT( argv[3] );
1057+ vp->viewport.MinZ = 0.0f;
1058+ vp->viewport.MaxZ = 1.0f;
1059+
1060+ /* DXRubySpriteオブジェクト設定 */
1061+ g_SpriteStruct[g_SpriteCount].image = vp;
1062+ g_SpriteStruct[g_SpriteCount].x = 0;
1063+ g_SpriteStruct[g_SpriteCount].y = 0;
1064+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
1065+ g_SpriteStruct[g_SpriteCount].scalex = 0.0f;
1066+ g_SpriteStruct[g_SpriteCount].scaley = 0.0f;
1067+ g_SpriteStruct[g_SpriteCount].alpha = 0;
1068+ g_SpriteStruct[g_SpriteCount].centerx = 0;
1069+ g_SpriteStruct[g_SpriteCount].centery = 0;
1070+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
1071+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
1072+ g_SpriteStruct[g_SpriteCount].vpflag = 1;
1073+
1074+ /* リストデータに追加 */
1075+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
1076+ g_SpriteList[g_SpriteCount].z = argc < 5 || argv[4] == Qnil ? 0.0f : NUM2DBL( argv[4] );
1077+ g_SpriteCount++;
1078+
1079+ return obj;
1080+}
1081+
1082+
1083+/*--------------------------------------------------------------------
1084+ マップ描画
1085+ ---------------------------------------------------------------------*/
1086+static VALUE Window_drawTile( int argc, VALUE *argv, VALUE klass )
1087+{
1088+ VALUE vstartx, vstarty, vz;
1089+ VALUE *arr1;
1090+ VALUE *arr2;
1091+ VALUE *mapdata;
1092+ VALUE vdata1, vdata2;
1093+ VALUE vbasex, vbasey, vmap, vmapdata, vsizex, vsizey;
1094+ int basex, basey, sizex, sizey;
1095+ int startx, starty;
1096+ float z;
1097+ int i, j, x, y;
1098+ int width, height;
1099+ struct DXRubyImage *image;
1100+
1101+ rb_scan_args( argc, argv, "81", &vbasex, &vbasey, &vmap, &vmapdata, &vstartx, &vstarty, &vsizex, &vsizey, &vz );
1102+
1103+ basex = NUM2INT( vbasex );
1104+ basey = NUM2INT( vbasey );
1105+ sizex = NUM2INT( vsizex );
1106+ sizey = NUM2INT( vsizey );
1107+
1108+ Check_Type(vmap, T_ARRAY);
1109+ Check_Type(vmapdata, T_ARRAY);
1110+
1111+ if( RARRAY_LEN( vmap ) == 0 )
1112+ {
1113+ return Qnil;
1114+ }
1115+
1116+ arr1 = RARRAY_PTR( vmap );
1117+ mapdata = RARRAY_PTR( vmapdata );
1118+
1119+ startx = NUM2INT( vstartx );
1120+ starty = NUM2INT( vstarty );
1121+ z = vz == Qnil ? 0.0f : NUM2DBL( vz );
1122+
1123+ /* イメージ配列が全部イメージかどうかをチェックしとく */
1124+ for( i = 0; i < RARRAY_LEN(vmapdata); i++ )
1125+ {
1126+ if( TYPE( mapdata[i] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( mapdata[i] ));
1127+ image = (struct DXRubyImage *)DATA_PTR( mapdata[i] );
1128+ if( RDATA( mapdata[i] )->dfree != (RUBY_DATA_FUNC)release_Image )
1129+ {
1130+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( mapdata[i] ));
1131+ }
1132+ }
1133+
1134+ /* 幅と高さ取得 */
1135+ width = NUM2INT( rb_funcall(RARRAY_PTR(vmapdata)[0], rb_intern("width"), 0) );
1136+ height = NUM2INT( rb_funcall(RARRAY_PTR(vmapdata)[0], rb_intern("height"), 0) );
1137+
1138+ y = basey - ((starty % height) < 0 ? height + (starty % height) : (starty % height));
1139+ /* 描画 */
1140+ for( i = starty % height < 0 ? -1 : 0; i < sizey + (starty % height <= 0 ? 0 : 1); i++ )
1141+ {
1142+ int my;
1143+
1144+ if( i + starty / height < 0 )
1145+ {
1146+ my = (((i + starty / height) % RARRAY_LEN( vmap )) + RARRAY_LEN( vmap )) % RARRAY_LEN( vmap );
1147+ }
1148+ else
1149+ {
1150+ my = (i + starty / height) % RARRAY_LEN( vmap );
1151+ }
1152+
1153+ Check_Type(arr1[my], T_ARRAY);
1154+
1155+ if( RARRAY_LEN( arr1[my] ) == 0 )
1156+ {
1157+ continue;
1158+ }
1159+
1160+ arr2 = RARRAY_PTR( arr1[my] );
1161+
1162+ x = basex - ((startx % width) < 0 ? width + (startx % width) : (startx % width));
1163+
1164+ for( j = startx % width < 0 ? -1 : 0; j < sizex + (startx % width <= 0 ? 0 : 1); j++ )
1165+ {
1166+ int mx;
1167+ int index;
1168+
1169+ if( j + startx / width < 0 )
1170+ {
1171+ mx = (((j + startx / width) % RARRAY_LEN( arr1[my] )) + RARRAY_LEN( arr1[my] )) % RARRAY_LEN( arr1[my] );
1172+ }
1173+ else
1174+ {
1175+ mx = (j + startx / width) % RARRAY_LEN( arr1[my] );
1176+ }
1177+
1178+ if( arr2[mx] != Qnil )
1179+ {
1180+ index = NUM2INT( arr2[mx] );
1181+
1182+ if( index >= RARRAY_LEN( vmapdata ) ) rb_raise(eDXRubyError, "マップチップ番号がイメージ配列の範囲を超えています - Window_drawTile");
1183+
1184+ /* イメージオブジェクトから中身を取り出す */
1185+ image = (struct DXRubyImage *)DATA_PTR( mapdata[index] );
1186+
1187+ AllocSpriteList();
1188+
1189+ /* DXRubySpriteオブジェクト設定 */
1190+ g_SpriteStruct[g_SpriteCount].image = image;
1191+ g_SpriteStruct[g_SpriteCount].x = x;
1192+ g_SpriteStruct[g_SpriteCount].y = y;
1193+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
1194+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
1195+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
1196+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
1197+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
1198+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
1199+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
1200+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
1201+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
1202+ g_SpriteStruct[g_SpriteCount].value = mapdata[index];
1203+
1204+ /* リストデータに追加 */
1205+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
1206+ g_SpriteList[g_SpriteCount].z = z;
1207+ g_SpriteCount++;
1208+ }
1209+
1210+ x = x + width;
1211+ }
1212+ y = y + height;
1213+ }
1214+
1215+ return Qnil;
1216+}
1217+
1218+
1219+typedef struct tag_dx_TLVERTEX {
1220+ float x, y, z, rhw;
1221+ D3DCOLOR color;
1222+ float tu, tv;
1223+}TLVERTX, *LPTLVERTEX;
1224+
1225+/*--------------------------------------------------------------------
1226+ (内部関数)画面更新
1227+ ---------------------------------------------------------------------*/
1228+static VALUE Window_update( VALUE obj )
1229+{
1230+ HRESULT hr;
1231+ static int max;
1232+ __int64 drawStartCounter;
1233+
1234+ while( 1 )
1235+ {
1236+ hr = g_pD3DDevice->lpVtbl->TestCooperativeLevel( g_pD3DDevice );
1237+ if( FAILED( hr ) )
1238+ {
1239+ if( hr == D3DERR_DEVICELOST ) /* デバイスはロスト状態である */
1240+ {
1241+ MSG msg;
1242+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
1243+ {
1244+ /* メッセージがある時 */
1245+ TranslateMessage( &msg );
1246+ DispatchMessage( &msg );
1247+ }
1248+ Sleep( 100 );
1249+ continue;
1250+ }
1251+ else if( hr == D3DERR_DEVICENOTRESET ) /* デバイスはロスト状態であるがリセット可能である */
1252+ {
1253+ /* ここへ来た時はデバイスがリセット可能状態である */
1254+ /* スプライトをロストさせる */
1255+ if( g_pD3DXSprite )
1256+ {
1257+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
1258+ }
1259+
1260+ hr = g_pD3DDevice->lpVtbl->Reset( g_pD3DDevice, &g_D3DPP ); /* 復元を試みる */
1261+ if( FAILED( hr ) )
1262+ {
1263+ if( hr == D3DERR_DEVICELOST )
1264+ {
1265+ return obj; /* またロストした */
1266+ }
1267+ rb_raise( eDXRubyError, "DirectX APIの呼び出しに失敗しました - Reset" );
1268+ }
1269+
1270+ if( g_pD3DXSprite ) /* スプライト復帰 */
1271+ {
1272+ g_pD3DXSprite->lpVtbl->OnResetDevice( g_pD3DXSprite );
1273+ }
1274+ break;
1275+ }
1276+ else /* DirectXの内部エラー */
1277+ {
1278+ rb_raise( eDXRubyError, "DirectX APIの内部エラーが発生しました - TestCooperativeLevel" );
1279+ }
1280+ }
1281+ else
1282+ {
1283+ break;
1284+ }
1285+ }
1286+
1287+ drawStartCounter = GetSystemCounter();
1288+
1289+// /* 動画再生中 */
1290+// if( g_PlayingMovie == 1 )
1291+// {
1292+// return obj;
1293+// }
1294+ /* 描画対象が1つも無ければ描画処理そのものを行わない */
1295+ if( g_SpriteCount == 0 )
1296+ {
1297+ /* シーンの表示 */
1298+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
1299+ {
1300+ g_DrawTime = 0;
1301+ g_OldTime += g_OneSecondCount / g_WindowInfo.RefreshRate;
1302+ }
1303+ else
1304+ {
1305+ g_pD3DDevice->lpVtbl->Present( g_pD3DDevice, NULL, NULL, NULL, NULL );
1306+ }
1307+ return obj;
1308+ }
1309+
1310+ /* シーンのクリア */
1311+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
1312+ D3DCOLOR_XRGB( g_WindowInfo.r, g_WindowInfo.g, g_WindowInfo.b ), 0, 0 );
1313+
1314+ /* シーンの描画開始 */
1315+ if( SUCCEEDED( g_pD3DDevice->lpVtbl->BeginScene( g_pD3DDevice ) ) )
1316+ {
1317+ int i;
1318+ int oldflag = 0;
1319+
1320+ /* スプライトの描画開始 */
1321+ g_pD3DXSprite->lpVtbl->Begin( g_pD3DXSprite, D3DXSPRITE_ALPHABLEND );
1322+
1323+ /* 拡大縮小フィルタ設定 */
1324+ g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MINFILTER,
1325+ g_WindowInfo.minfilter);
1326+ g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MAGFILTER,
1327+ g_WindowInfo.magfilter);
1328+
1329+ /* スプライトのz順ソート */
1330+ SortSpriteList();
1331+
1332+ /* スプライトリストに登録されたもののうちスプライトを順に描画 */
1333+ for( i = 0; i < g_SpriteCount; i++ )
1334+ {
1335+ float angle;
1336+ struct DXRubySprite *temp;
1337+
1338+ temp = g_SpriteList[i].sprite;
1339+
1340+ if( temp->vpflag == 1 )
1341+ {
1342+ D3DMATRIX matrix, matrix_t;
1343+ D3DVIEWPORT9 vp = ((struct DXRubyViewport *)temp->image)->viewport;
1344+
1345+ g_pD3DXSprite->lpVtbl->End( g_pD3DXSprite );
1346+ g_pD3DDevice->lpVtbl->EndScene( g_pD3DDevice );
1347+
1348+ matrix._11 = 1;matrix._12 = 0;matrix._13 = 0;matrix._14 = 0;
1349+ matrix._21 = 0;matrix._22 = -1;matrix._23 = 0;matrix._24 = 0;
1350+ matrix._31 = 0;matrix._32 = 0;matrix._33 = 1;matrix._34 = 0;
1351+ matrix._41 = 0;matrix._42 = 0;matrix._43 = 0;matrix._44 = 1;
1352+ g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_WORLDMATRIX(0), &matrix);
1353+ D3DXMatrixTranslation( &matrix_t, (float)-(vp.X + vp.Width)/2, (float)(vp.Y + vp.Height)/2, 0 );
1354+ D3DXMatrixScaling ( &matrix, (float)g_WindowInfo.width/vp.Width, (float)g_WindowInfo.height/vp.Height, 1 );
1355+ D3DXMatrixMultiply ( &matrix , &matrix_t, &matrix );
1356+ g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_VIEW, &matrix);
1357+ matrix._11 = 2.0f/g_WindowInfo.width;
1358+ matrix._12 = matrix._13 = matrix._14 = 0;
1359+ matrix._22 = 2.0f/g_WindowInfo.height;
1360+ matrix._21 = matrix._23 = matrix._24 = 0;
1361+ matrix._31 = matrix._32 = 0;matrix._33 = 0; matrix._34 = 0;
1362+ matrix._41 = matrix._42 = 0;matrix._43 = 1;matrix._44 = 1;
1363+ g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_PROJECTION, &matrix);
1364+ g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &((struct DXRubyViewport *)temp->image)->viewport );
1365+ free( temp->image );
1366+
1367+ g_pD3DDevice->lpVtbl->BeginScene( g_pD3DDevice );
1368+ g_pD3DXSprite->lpVtbl->Begin( g_pD3DXSprite, D3DXSPRITE_ALPHABLEND );
1369+
1370+ continue;
1371+ }
1372+
1373+ if( temp->blendflag != oldflag )
1374+ {
1375+ switch( temp->blendflag )
1376+ {
1377+ case 0: /* 半透明合成 */
1378+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1379+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1380+ break;
1381+ case 4: /* 加算合成1の設定 */
1382+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1383+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ONE);
1384+ break;
1385+ case 5: /* 加算合成2の設定 */
1386+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE);
1387+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1388+ break;
1389+ case 6: /* 減算合成1の設定 */
1390+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ZERO);
1391+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1392+ break;
1393+ case 7: /* 減算合成2の設定 */
1394+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ZERO);
1395+ g_pD3DDevice->lpVtbl->SetRenderState(g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
1396+ break;
1397+ }
1398+ }
1399+
1400+ oldflag = temp->blendflag;
1401+
1402+ angle = 3.141592653589793115997963468544185161590576171875f / 180.0f * temp->angle;
1403+
1404+ if( temp->fontflag == 0)
1405+ {
1406+ TLVERTX VertexDataTbl[6];
1407+ struct DXRubyImage *image = temp->image;
1408+ float sina = sin(angle);
1409+ float cosa = cos(angle);
1410+ float data1x = temp->scalex * cosa;
1411+ float data2x = temp->scalex * sina;
1412+ float data1y = temp->scaley * sina;
1413+ float data2y = temp->scaley * cosa;
1414+ float tu1 = (image->x) / image->texture->width;
1415+ float tu2 = (image->x + image->width) / image->texture->width;
1416+ float tv1 = (image->y) / image->texture->height;
1417+ float tv2 = (image->y + image->height) / image->texture->height;
1418+ float centerx = -temp->centerx;
1419+ float centery = -temp->centery;
1420+ float width = image->width;
1421+ float height = image->height;
1422+ float basex = temp->x - centerx;
1423+ float basey = temp->y - centery;
1424+
1425+ /* 頂点1 */
1426+ VertexDataTbl[0].x = centerx * data1x - centery * data1y + basex - 0.5f;
1427+ VertexDataTbl[0].y = centerx * data2x + centery * data2y + basey - 0.5f;
1428+ /* 頂点2 */
1429+ VertexDataTbl[1].x = VertexDataTbl[3].x = (centerx+width) * data1x - centery * data1y + basex - 0.5f;
1430+ VertexDataTbl[1].y = VertexDataTbl[3].y = (centerx+width) * data2x + centery * data2y + basey - 0.5f;
1431+ /* 頂点3 */
1432+ VertexDataTbl[4].x = (centerx+width) * data1x - (centery+height) * data1y + basex - 0.5f;
1433+ VertexDataTbl[4].y = (centerx+width) * data2x + (centery+height) * data2y + basey - 0.5f;
1434+ /* 頂点4 */
1435+ VertexDataTbl[2].x = VertexDataTbl[5].x = centerx * data1x - (centery+height) * data1y + basex - 0.5f;
1436+ VertexDataTbl[2].y = VertexDataTbl[5].y = centerx * data2x + (centery+height) * data2y + basey - 0.5f;
1437+ /* 頂点色 */
1438+ VertexDataTbl[0].color =
1439+ VertexDataTbl[1].color =
1440+ VertexDataTbl[2].color =
1441+ VertexDataTbl[3].color =
1442+ VertexDataTbl[4].color =
1443+ VertexDataTbl[5].color = D3DCOLOR_ARGB(temp->alpha,255,255,255);
1444+ /* Z座標 */
1445+ VertexDataTbl[0].z =
1446+ VertexDataTbl[1].z =
1447+ VertexDataTbl[2].z =
1448+ VertexDataTbl[3].z =
1449+ VertexDataTbl[4].z =
1450+ VertexDataTbl[5].z = 0.0f;
1451+ /* rhw */
1452+ VertexDataTbl[0].rhw =
1453+ VertexDataTbl[1].rhw =
1454+ VertexDataTbl[2].rhw =
1455+ VertexDataTbl[3].rhw =
1456+ VertexDataTbl[4].rhw =
1457+ VertexDataTbl[5].rhw = 1.0f;
1458+ /* テクスチャ座標 */
1459+ VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = tu1;
1460+ VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = tv1;
1461+ VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = tu2;
1462+ VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = tv2;
1463+
1464+ /* テクスチャをセット */
1465+ g_pD3DDevice->lpVtbl->SetTexture(g_pD3DDevice, 0, (IDirect3DBaseTexture9*)image->texture->pD3DTexture);
1466+
1467+ /* デバイスに使用する頂点フォーマットをセット */
1468+ g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1469+
1470+ /* 描画 */
1471+ g_pD3DDevice->lpVtbl->DrawPrimitiveUP(g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX));
1472+ }
1473+ else
1474+ {
1475+ D3DVECTOR vector;
1476+ D3DXMATRIX matrix;
1477+ D3DXMATRIX matrix_t;
1478+ RECT rect;
1479+
1480+ /* 回転及び拡大縮小 */
1481+ D3DXMatrixScaling ( &matrix_t, temp->scalex, temp->scaley, 1 );
1482+ D3DXMatrixRotationZ ( &matrix , angle );
1483+ D3DXMatrixMultiply ( &matrix , &matrix_t, &matrix );
1484+
1485+ /* 平行移動 */
1486+ D3DXMatrixTranslation( &matrix_t, (float)temp->x + temp->centerx, (float)temp->y + temp->centery, 0 );
1487+ D3DXMatrixMultiply ( &matrix , &matrix, &matrix_t );
1488+
1489+ g_pD3DXSprite->lpVtbl->SetTransform( g_pD3DXSprite, &matrix );
1490+
1491+ rect.left = -temp->centerx;
1492+ rect.top = -temp->centery;
1493+ rect.right = temp->centerx;
1494+ rect.bottom = temp->centery;
1495+ ((struct DXRubyFontSprite *)temp->image)->font->pD3DXFont->lpVtbl->DrawText(((struct DXRubyFontSprite *)temp->image)->font->pD3DXFont, g_pD3DXSprite,
1496+ ((struct DXRubyFontSprite *)temp->image)->str,
1497+ -1,
1498+ &rect,
1499+ DT_LEFT | DT_NOCLIP,
1500+ ((int)temp->alpha << 24) | ((struct DXRubyFontSprite *)temp->image)->color & 0x00ffffff);
1501+ g_pD3DXSprite->lpVtbl->Flush( g_pD3DXSprite );
1502+ free( temp->image );
1503+ }
1504+ }
1505+
1506+ /* スプライトの描画終了 */
1507+ g_pD3DXSprite->lpVtbl->End( g_pD3DXSprite );
1508+
1509+ /* シーンの描画終了 */
1510+ g_pD3DDevice->lpVtbl->EndScene( g_pD3DDevice );
1511+ }
1512+
1513+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
1514+ {
1515+ g_DrawTime = GetSystemCounter() - drawStartCounter;
1516+ }
1517+
1518+ /* シーンの表示 */
1519+ hr = g_pD3DDevice->lpVtbl->Present( g_pD3DDevice, NULL, NULL, NULL, NULL );
1520+
1521+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
1522+ {
1523+ g_OldTime = GetSystemCounter();
1524+ }
1525+
1526+ g_SpriteCount = 0;
1527+ return obj;
1528+}
1529+
1530+
1531+/*--------------------------------------------------------------------
1532+ (内部関数)フレーム調整
1533+ ---------------------------------------------------------------------*/
1534+static VALUE Window_sync( VALUE obj )
1535+{
1536+ __int64 NowTime;
1537+ __int64 WaitTime;
1538+ static __int64 BeforeSecond = 0;
1539+ static int fps = 0;
1540+ static int skip = 0;
1541+
1542+ NowTime = GetSystemCounter();
1543+
1544+ /* ウィンドウモード時 */
1545+ if( g_WindowInfo.windowed != Qnil && g_WindowInfo.windowed != Qfalse )
1546+ {
1547+ g_OneFrameCount = NowTime - g_OldTime;
1548+ if ( g_WindowInfo.fps > 0 ) /* fps指定がnil or 0の時はWait処理しない */
1549+ {
1550+ __int64 SleepTime;
1551+
1552+ WaitTime = g_OneSecondCount / g_WindowInfo.fps;
1553+
1554+ /* もう既に前回から1フレーム分の時間が経っていたら */
1555+ if( g_OldTime + WaitTime < NowTime && skip == 0 )
1556+ {
1557+ /* コマ落ち制御しない場合 */
1558+ if( g_WindowInfo.frameskip == Qfalse )
1559+ {
1560+ fps++;
1561+ g_OldTime = NowTime;
1562+ }
1563+ else /* する場合 */
1564+ {
1565+ /* 今回はウェイトも描画もしない */
1566+ skip++;
1567+ g_SpriteCount = 0;
1568+ g_OldTime = g_OldTime + WaitTime;
1569+ }
1570+ }
1571+ else
1572+ {
1573+ /* 前回描画を飛ばしたのに今回も間に合ってない場合 */
1574+ if( g_OldTime + WaitTime < NowTime && skip == 1 )
1575+ {
1576+ /* 諦めて処理落ち */
1577+ g_OldTime = NowTime;
1578+ }
1579+ else
1580+ {
1581+ __int64 TempTime;
1582+ /* おおまかな時間をSleepで待つ */
1583+ TempTime = GetSystemCounter();
1584+ SleepTime = (WaitTime - (TempTime - g_OldTime)) * 1000 / g_OneSecondCount;
1585+ if( SleepTime > 2 )
1586+ {
1587+ Sleep( (unsigned long)(SleepTime - 2) );
1588+ }
1589+
1590+ TempTime = GetSystemCounter();
1591+
1592+ /* ループで厳密に処理をする */
1593+ for ( ; ; )
1594+ {
1595+ TempTime = GetSystemCounter();
1596+ if( g_OldTime + WaitTime < TempTime )
1597+ {
1598+ break;
1599+ }
1600+ }
1601+ g_OldTime = g_OldTime + WaitTime;
1602+ }
1603+ skip = 0;
1604+ fps++;
1605+ }
1606+ }
1607+ else
1608+ {
1609+ g_OldTime = NowTime;
1610+ fps++;
1611+ }
1612+
1613+ /* FPS値設定 */
1614+ if( (NowTime - BeforeSecond) >= g_OneSecondCount )
1615+ {
1616+ BeforeSecond = NowTime;
1617+ g_WindowInfo.fpscheck = fps;
1618+ fps = 0;
1619+ }
1620+ }
1621+ else
1622+ {
1623+ g_OneFrameCount = NowTime - g_OldTime + g_DrawTime;
1624+ WaitTime = g_OneSecondCount / g_WindowInfo.RefreshRate;
1625+
1626+ /* もう既に前回から1フレーム分の時間が経っていたら */
1627+ if( g_OldTime + WaitTime - g_DrawTime < NowTime && skip == 0 )
1628+ {
1629+ /* 今回はウェイトも描画もしない */
1630+ skip++;
1631+ g_SpriteCount = 0;
1632+// g_OldTime = NowTime;
1633+ return obj;
1634+ }
1635+
1636+ skip = 0;
1637+
1638+// g_OldTime = g_OldTime + WaitTime;
1639+ fps++;
1640+
1641+ /* FPS値設定 */
1642+ if( (NowTime - BeforeSecond) >= g_OneSecondCount )
1643+ {
1644+ BeforeSecond = NowTime;
1645+ g_WindowInfo.fpscheck = fps;
1646+ fps = 0;
1647+ }
1648+ }
1649+
1650+ return obj;
1651+}
1652+/*--------------------------------------------------------------------
1653+ (内部関数)フレーム調整用カウンタ値取得
1654+ ---------------------------------------------------------------------*/
1655+static __int64 GetSystemCounter( void )
1656+{
1657+ __int64 time;
1658+
1659+ if( g_isPerformanceCounter == 1 )
1660+ {
1661+ QueryPerformanceCounter( (LARGE_INTEGER *)&time );
1662+ return time;
1663+ }
1664+ else
1665+ {
1666+ return timeGetTime();
1667+ }
1668+}
1669+
1670+
1671+/*--------------------------------------------------------------------
1672+ ウィンドウのサイズを変更する。
1673+ ---------------------------------------------------------------------*/
1674+static VALUE Window_resize( VALUE klass, VALUE vwidth, VALUE vheight )
1675+{
1676+ g_WindowInfo.width = NUM2INT( vwidth );
1677+ g_WindowInfo.height = NUM2INT( vheight );
1678+ if( g_WindowInfo.created == Qtrue )
1679+ {
1680+ g_WindowInfo.created = Qfalse;
1681+ Window_create( klass );
1682+ }
1683+ return Qnil;
1684+}
1685+
1686+
1687+/*--------------------------------------------------------------------
1688+ ウィンドウのモード(ウィンドウ/全画面)を設定する。
1689+ ---------------------------------------------------------------------*/
1690+static VALUE Window_setwindowed( VALUE obj, VALUE windowed )
1691+{
1692+ g_WindowInfo.windowed = windowed;
1693+
1694+ if( g_WindowInfo.created == Qtrue )
1695+ {
1696+ g_WindowInfo.created = Qfalse;
1697+ Window_create( obj );
1698+ }
1699+
1700+ return g_WindowInfo.windowed;
1701+}
1702+
1703+
1704+/*--------------------------------------------------------------------
1705+ ウィンドウのモード(ウィンドウ/全画面)を取得する。
1706+ ---------------------------------------------------------------------*/
1707+static VALUE Window_getwindowed( VALUE obj )
1708+{
1709+ return g_WindowInfo.windowed;
1710+}
1711+
1712+
1713+/*--------------------------------------------------------------------
1714+ ウィンドウの位置(x座標)を設定する。
1715+ ---------------------------------------------------------------------*/
1716+static VALUE Window_setx( VALUE obj, VALUE x )
1717+{
1718+ if( g_WindowInfo.created == Qtrue )
1719+ {
1720+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setx" );
1721+ }
1722+
1723+ g_WindowInfo.x = NUM2INT( x );
1724+ return x;
1725+}
1726+
1727+
1728+/*--------------------------------------------------------------------
1729+ ウィンドウの位置(y座標)を設定する。
1730+ ---------------------------------------------------------------------*/
1731+static VALUE Window_sety( VALUE obj , VALUE y )
1732+{
1733+ if( g_WindowInfo.created == Qtrue )
1734+ {
1735+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_sety" );
1736+ }
1737+
1738+ g_WindowInfo.y = NUM2INT( y );
1739+ return y;
1740+}
1741+
1742+
1743+/*--------------------------------------------------------------------
1744+ ウィンドウのサイズ(幅)を設定する。
1745+ ---------------------------------------------------------------------*/
1746+static VALUE Window_setwidth( VALUE obj, VALUE vwidth )
1747+{
1748+ int width;
1749+
1750+ if( g_WindowInfo.created == Qtrue )
1751+ {
1752+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setwidth" );
1753+ }
1754+
1755+ width = NUM2INT( vwidth );
1756+ if( width < 0 )
1757+ {
1758+ width = 0;
1759+ }
1760+
1761+ g_WindowInfo.width = width;
1762+ return vwidth;
1763+}
1764+
1765+
1766+/*--------------------------------------------------------------------
1767+ ウィンドウのサイズ(高さ)を設定する。
1768+ ---------------------------------------------------------------------*/
1769+static VALUE Window_setheight( VALUE obj , VALUE vheight)
1770+{
1771+ int height;
1772+
1773+ if( g_WindowInfo.created == Qtrue )
1774+ {
1775+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setheight" );
1776+ }
1777+
1778+ height = NUM2INT( vheight );
1779+ if( height < 0 )
1780+ {
1781+ height = 0;
1782+ }
1783+
1784+ g_WindowInfo.height = height;
1785+ return vheight;
1786+}
1787+
1788+
1789+/*--------------------------------------------------------------------
1790+ ウィンドウの位置(x座標)を返す。
1791+ ---------------------------------------------------------------------*/
1792+static VALUE Window_x( VALUE obj )
1793+{
1794+ return INT2FIX( g_WindowInfo.x );
1795+}
1796+
1797+
1798+/*--------------------------------------------------------------------
1799+ ウィンドウの位置(y座標)を返す。
1800+ ---------------------------------------------------------------------*/
1801+static VALUE Window_y( VALUE obj )
1802+{
1803+ return INT2FIX( g_WindowInfo.y );
1804+}
1805+
1806+
1807+/*--------------------------------------------------------------------
1808+ ウィンドウのサイズ(幅)を返す。
1809+ ---------------------------------------------------------------------*/
1810+static VALUE Window_width( VALUE obj )
1811+{
1812+ return INT2FIX( g_WindowInfo.width );
1813+}
1814+
1815+
1816+/*--------------------------------------------------------------------
1817+ ウィンドウのサイズ(高さ)を返す。
1818+ ---------------------------------------------------------------------*/
1819+static VALUE Window_height( VALUE obj )
1820+{
1821+ return INT2FIX( g_WindowInfo.height );
1822+}
1823+
1824+
1825+/*--------------------------------------------------------------------
1826+ ウィンドウタイトル取得
1827+ ---------------------------------------------------------------------*/
1828+static VALUE Window_getCaption( VALUE obj )
1829+{
1830+ char buf[256];
1831+
1832+ GetWindowText( g_hWnd, buf, 256 );
1833+
1834+ return rb_str_new2( buf );
1835+}
1836+
1837+
1838+/*--------------------------------------------------------------------
1839+ ウィンドウタイトル設定
1840+ ---------------------------------------------------------------------*/
1841+static VALUE Window_setCaption( VALUE obj, VALUE caption )
1842+{
1843+ Check_Type(caption, T_STRING);
1844+
1845+ SetWindowText( g_hWnd, RSTRING_PTR( caption ) );
1846+
1847+ return caption;
1848+}
1849+
1850+
1851+/*--------------------------------------------------------------------
1852+ ウィンドウのサイズ倍率を取得する
1853+ ---------------------------------------------------------------------*/
1854+static VALUE Window_getScale( VALUE obj )
1855+{
1856+ return rb_float_new( g_WindowInfo.scale );
1857+}
1858+
1859+
1860+/*--------------------------------------------------------------------
1861+ ウィンドウのサイズ倍率を設定する
1862+ ---------------------------------------------------------------------*/
1863+static VALUE Window_setScale( VALUE obj, VALUE scale )
1864+{
1865+ g_WindowInfo.scale = NUM2DBL(scale);
1866+
1867+ return scale;
1868+}
1869+
1870+
1871+/*--------------------------------------------------------------------
1872+ fps値を設定する
1873+ ---------------------------------------------------------------------*/
1874+static VALUE Window_getrealfps( VALUE obj )
1875+{
1876+ return INT2FIX( g_WindowInfo.fpscheck );
1877+}
1878+
1879+
1880+/*--------------------------------------------------------------------
1881+ fps値を取得する
1882+ ---------------------------------------------------------------------*/
1883+static VALUE Window_getfps( VALUE obj )
1884+{
1885+ return INT2FIX( g_WindowInfo.fpscheck );
1886+}
1887+
1888+
1889+/*--------------------------------------------------------------------
1890+ fps値を設定する
1891+ ---------------------------------------------------------------------*/
1892+static VALUE Window_setfps( VALUE obj, VALUE fps )
1893+{
1894+ g_WindowInfo.fps = fps == Qnil ? 0 : NUM2INT(fps);
1895+
1896+ return fps;
1897+}
1898+
1899+
1900+/*--------------------------------------------------------------------
1901+ 縮小フィルタ取得
1902+ ---------------------------------------------------------------------*/
1903+static VALUE Window_getMinFilter( VALUE obj )
1904+{
1905+ return INT2FIX( g_WindowInfo.minfilter );
1906+}
1907+
1908+
1909+/*--------------------------------------------------------------------
1910+ 縮小フィルタ設定
1911+ ---------------------------------------------------------------------*/
1912+static VALUE Window_setMinFilter( VALUE obj, VALUE minfilter )
1913+{
1914+ g_WindowInfo.minfilter = FIX2INT( minfilter );
1915+ return minfilter;
1916+}
1917+
1918+
1919+/*--------------------------------------------------------------------
1920+ 拡大フィルタ取得
1921+ ---------------------------------------------------------------------*/
1922+static VALUE Window_getMagFilter( VALUE obj )
1923+{
1924+ return INT2FIX( g_WindowInfo.minfilter );
1925+}
1926+
1927+
1928+/*--------------------------------------------------------------------
1929+ 拡大フィルタ設定
1930+ ---------------------------------------------------------------------*/
1931+static VALUE Window_setMagFilter( VALUE obj, VALUE magfilter )
1932+{
1933+ g_WindowInfo.magfilter = FIX2INT( magfilter );
1934+ return magfilter;
1935+}
1936+
1937+
1938+/*--------------------------------------------------------------------
1939+ 1フレームの処理負荷を%で取得する
1940+ ---------------------------------------------------------------------*/
1941+static VALUE Window_getload( VALUE obj )
1942+{
1943+ if( g_WindowInfo.fps == 0 )
1944+ {
1945+ return INT2FIX( 0 );
1946+ }
1947+ return rb_float_new( (double) ( (double)g_OneFrameCount * 100.0 / ((double)g_OneSecondCount / (double)g_WindowInfo.fps )) );
1948+}
1949+
1950+
1951+/*--------------------------------------------------------------------
1952+ ウィンドウハンドルを取得する
1953+ ---------------------------------------------------------------------*/
1954+static VALUE Window_gethWnd( VALUE obj )
1955+{
1956+ return INT2NUM( (int)g_hWnd );
1957+}
1958+
1959+
1960+/*--------------------------------------------------------------------
1961+ フレームスキップon/offを取得する
1962+ ---------------------------------------------------------------------*/
1963+static VALUE Window_getframeskip( VALUE obj )
1964+{
1965+ return g_WindowInfo.frameskip;
1966+}
1967+
1968+
1969+/*--------------------------------------------------------------------
1970+ フレームスキップon/offを設定する
1971+ ---------------------------------------------------------------------*/
1972+static VALUE Window_setframeskip( VALUE obj, VALUE skip )
1973+{
1974+ g_WindowInfo.frameskip = (skip == Qnil || skip == Qfalse) ? Qfalse : Qtrue;
1975+
1976+ return skip;
1977+}
1978+
1979+
1980+/*--------------------------------------------------------------------
1981+ ウィンドウのアクティブ状態を取得
1982+ ---------------------------------------------------------------------*/
1983+static VALUE Window_get_active( VALUE obj )
1984+{
1985+ return ( g_WindowInfo.active != 0 ? Qtrue : Qfalse );
1986+}
1987+
1988+
1989+/*--------------------------------------------------------------------
1990+ ウィンドウアイコンを設定する
1991+ ---------------------------------------------------------------------*/
1992+static VALUE Window_loadIcon( VALUE obj, VALUE filename )
1993+{
1994+ Check_Type( filename, T_STRING );
1995+ g_WindowInfo.hIcon = LoadImage( 0, RSTRING_PTR(filename), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_LOADFROMFILE );
1996+ if( g_WindowInfo.hIcon == NULL )
1997+ {
1998+ rb_raise( eDXRubyError, "アイコン画像ファイルのロードに失敗しました - Window_loadIcon" );
1999+ }
2000+
2001+ SendMessage(g_hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)g_WindowInfo.hIcon);
2002+
2003+ return Qnil;
2004+}
2005+
2006+
2007+/*--------------------------------------------------------------------
2008+ ファイルオープンダイアログを表示する
2009+ ---------------------------------------------------------------------*/
2010+static VALUE Window_openDialog(VALUE obj, VALUE vfilter, VALUE vtitle)
2011+{
2012+ OPENFILENAME OFN;
2013+ char buf[MAX_PATH*2];
2014+ VALUE filter;
2015+ buf[0] = 0;
2016+
2017+ Check_Type(vfilter, T_ARRAY);
2018+ Check_Type(vtitle, T_STRING);
2019+
2020+ ZeroMemory(&OFN,sizeof(OPENFILENAME));
2021+ OFN.lStructSize = sizeof(OPENFILENAME);
2022+ OFN.hwndOwner = g_hWnd;
2023+
2024+ OFN.lpstrFilter = "すべてのファイル (*.*)\0*.*\0\0";
2025+ filter = rb_ary_join( vfilter, rb_str_new( "\0", 1 ) );
2026+ filter = rb_str_cat( filter, "\0", 1 );
2027+ OFN.lpstrFilter = RSTRING_PTR(filter);
2028+ OFN.lpstrFile = buf;
2029+ OFN.nMaxFile = MAX_PATH*2;
2030+ OFN.Flags = OFN_FILEMUSTEXIST;
2031+ OFN.lpstrTitle = RSTRING_PTR(vtitle);
2032+ OFN.lpstrDefExt = 0;
2033+ if( !GetOpenFileName(&OFN) )
2034+ {
2035+ return Qnil;
2036+ }
2037+
2038+ return rb_str_new2( buf );
2039+}
2040+
2041+
2042+/*--------------------------------------------------------------------
2043+ ファイルセーブダイアログを表示する
2044+ ---------------------------------------------------------------------*/
2045+static VALUE Window_saveDialog(VALUE obj, VALUE vfilter, VALUE vtitle)
2046+{
2047+ OPENFILENAME OFN;
2048+ char buf[MAX_PATH*2];
2049+ VALUE filter;
2050+ buf[0] = 0;
2051+
2052+ Check_Type(vfilter, T_ARRAY);
2053+ Check_Type(vtitle, T_STRING);
2054+
2055+ ZeroMemory(&OFN,sizeof(OPENFILENAME));
2056+ OFN.lStructSize = sizeof(OPENFILENAME);
2057+ OFN.hwndOwner = g_hWnd;
2058+
2059+ OFN.lpstrFilter = "すべてのファイル (*.*)\0*.*\0\0";
2060+ filter = rb_ary_join( vfilter, rb_str_new( "\0", 1 ) );
2061+ filter = rb_str_cat( filter, "\0", 1 );
2062+ OFN.lpstrFilter = RSTRING_PTR(filter);
2063+ OFN.lpstrFile = buf;
2064+ OFN.nMaxFile = MAX_PATH*2;
2065+ OFN.Flags = OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
2066+ OFN.lpstrTitle = RSTRING_PTR(vtitle);
2067+ OFN.lpstrDefExt = 0;
2068+ if( !GetSaveFileName(&OFN) )
2069+ {
2070+ return Qnil;
2071+ }
2072+
2073+ return rb_str_new2( buf );
2074+}
2075+
2076+
2077+/*--------------------------------------------------------------------
2078+ 終了時に実行する
2079+ ---------------------------------------------------------------------*/
2080+static VALUE Window_shutdown( VALUE obj )
2081+{
2082+ /* アイコンリソース解放 */
2083+ if( g_WindowInfo.hIcon != 0 )
2084+ {
2085+ DestroyIcon(g_WindowInfo.hIcon);
2086+ }
2087+
2088+ /* マウス状態復元 */
2089+ if( g_WindowInfo.enablemouse == Qfalse )
2090+ {
2091+ int c;
2092+ c = ShowCursor( TRUE );
2093+ while( c < 0 ) c = ShowCursor( TRUE );
2094+ }
2095+
2096+ /* リスト解放 */
2097+ g_SpriteCount = 0;
2098+
2099+// /* 動画再生用インターフェイスの解放 */
2100+// if( g_pGraphBuilder != NULL )
2101+// {
2102+// g_pMediaControl->lpVtbl->Stop( g_pMediaControl );
2103+// RELEASE( g_pMediaEventEx );
2104+// RELEASE( g_pVideoWindow );
2105+// RELEASE( g_pMediaControl );
2106+// RELEASE( g_pGraphBuilder );
2107+// }
2108+
2109+ /* DirectX解放 */
2110+ Window_DirectXRelease();
2111+
2112+ /* ウインドウ・クラスの登録解除 */
2113+ UnregisterClass( "DXRuby", g_hInstance );
2114+
2115+ /* フレーム調整の後始末 */
2116+ timeEndPeriod( 1 );
2117+
2118+ g_iRefAll--;
2119+ if( g_iRefAll == 0 )
2120+ {
2121+ CoUninitialize();
2122+ }
2123+
2124+ return obj;
2125+}
2126+
2127+
2128+/*--------------------------------------------------------------------
2129+ DirectXオブジェクトを解放する
2130+ ---------------------------------------------------------------------*/
2131+void Window_DirectXRelease()
2132+{
2133+ int i;
2134+ HRESULT hr;
2135+
2136+ /* スプライトオブジェクトの使用終了 */
2137+ if( g_pD3DXSprite )
2138+ {
2139+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
2140+ }
2141+
2142+ /* スプライトオブジェクト破棄 */
2143+ RELEASE( g_pD3DXSprite );
2144+
2145+ for( i = 0 ; i < g_JoystickCount; i++ )
2146+ {
2147+ /* DirectInputDevice(JoyPad)オブジェクトの使用終了 */
2148+ if( g_pDIDJoyPad[i] )
2149+ {
2150+ g_pDIDJoyPad[i]->lpVtbl->Unacquire( g_pDIDJoyPad[i] );
2151+ }
2152+
2153+ /* DirectInputDevide(JoyPad)オブジェクトの破棄 */
2154+ RELEASE( g_pDIDJoyPad[i] );
2155+ }
2156+
2157+ /* DirectInputDevice(Keyboard)オブジェクトの使用終了 */
2158+ if( g_pDIDKeyBoard )
2159+ {
2160+ g_pDIDKeyBoard->lpVtbl->Unacquire( g_pDIDKeyBoard );
2161+ }
2162+
2163+ /* DirectInputDevide(Keyboard)オブジェクトの破棄 */
2164+ RELEASE( g_pDIDKeyBoard );
2165+
2166+ /* DirectInputオブジェクトの破棄 */
2167+ RELEASE( g_pDInput );
2168+
2169+ /* Direct3D Deviceオブジェクトの破棄 */
2170+ RELEASE( g_pD3DDevice );
2171+
2172+ /* Direct3Dオブジェクトの破棄 */
2173+ RELEASE( g_pD3D );
2174+}
2175+
2176+
2177+/*--------------------------------------------------------------------
2178+ スクリーンショットを撮る
2179+ ---------------------------------------------------------------------*/
2180+static VALUE Window_getScreenShot( int argc, VALUE *argv, VALUE obj )
2181+{
2182+ HRESULT hr;
2183+ D3DDISPLAYMODE dmode;
2184+ LPDIRECT3DSURFACE9 pSurface;
2185+ RECT rect;
2186+ VALUE filename, format;
2187+
2188+ rb_scan_args( argc, argv, "11", &filename, &format );
2189+
2190+ Check_Type( filename, T_STRING );
2191+
2192+ /* 現在のディスプレイのフォーマットなどを取得 */
2193+ hr = g_pD3D->lpVtbl->GetAdapterDisplayMode(g_pD3D, D3DADAPTER_DEFAULT, &dmode);
2194+ if( FAILED( hr ) )
2195+ {
2196+ rb_raise( eDXRubyError, "キャプチャに失敗しました - GetAdapterDisplayMode" );
2197+ }
2198+
2199+ /* キャプチャ用サーフェス作成 */
2200+ hr = g_pD3DDevice->lpVtbl->CreateOffscreenPlainSurface(g_pD3DDevice,
2201+ dmode.Width,
2202+ dmode.Height,
2203+ D3DFMT_A8R8G8B8,
2204+ D3DPOOL_SCRATCH, &pSurface, NULL);
2205+ if( FAILED( hr ) )
2206+ {
2207+ rb_raise( eDXRubyError, "キャプチャに失敗しました - CreateOffscreenPlainSurface" );
2208+ }
2209+ /* キャプチャ */
2210+ hr = g_pD3DDevice->lpVtbl->GetFrontBufferData(g_pD3DDevice, 0, pSurface);
2211+ if( FAILED( hr ) )
2212+ {
2213+ RELEASE(pSurface);
2214+ rb_raise( eDXRubyError, "キャプチャに失敗しました - GetFrontBufferData" );
2215+ }
2216+
2217+ /* サーフェスの保存 */
2218+ if( g_D3DPP.Windowed )
2219+ {
2220+ POINT p = { 0, 0 };
2221+ ClientToScreen(g_hWnd , &p);
2222+ rect.left = p.x; rect.top = p.y;
2223+ p.x = g_D3DPP.BackBufferWidth * g_WindowInfo.scale;
2224+ p.y = g_D3DPP.BackBufferHeight * g_WindowInfo.scale;
2225+ ClientToScreen(g_hWnd, &p);
2226+ rect.right = p.x; rect.bottom = p.y;
2227+ }
2228+ hr = D3DXSaveSurfaceToFile(
2229+ RSTRING_PTR( filename ), /* 保存ファイル名 */
2230+ format == Qnil ? D3DXIFF_JPG : FIX2INT( format ), /* ファイルフォーマット */
2231+ pSurface, /* 保存するサーフェス */
2232+ NULL, /* パレット */
2233+ g_D3DPP.Windowed ? &rect : NULL); /* 保存領域 */
2234+ RELEASE(pSurface);
2235+ if( FAILED( hr ) )
2236+ {
2237+ rb_raise( eDXRubyError, "キャプチャに失敗しました - D3DXSaveSurfaceToFile" );
2238+ }
2239+
2240+ return obj;
2241+}
2242+
2243+
2244+/*--------------------------------------------------------------------
2245+ 使用可能なスクリーンサイズを取得する
2246+ ---------------------------------------------------------------------*/
2247+static VALUE Window_getScreenModes( VALUE obj )
2248+{
2249+ D3DDISPLAYMODE d3ddm;
2250+ int count , max, oldHeight, oldWidth;
2251+ VALUE ary, temp;
2252+
2253+ ary = rb_ary_new();
2254+ max = g_pD3D->lpVtbl->GetAdapterModeCount( g_pD3D, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
2255+
2256+ for( count = 0 ; count < max ; count++ )
2257+ {
2258+ temp = rb_ary_new();
2259+ g_pD3D->lpVtbl->EnumAdapterModes( g_pD3D, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 , count , &d3ddm);
2260+ rb_ary_push( temp, INT2NUM(d3ddm.Width) );
2261+ rb_ary_push( temp, INT2NUM(d3ddm.Height) );
2262+// rb_ary_push( temp, INT2NUM(d3ddm.RefreshRate) );
2263+ rb_ary_push( ary, temp );
2264+ }
2265+
2266+ rb_funcall( ary, rb_intern("uniq!"), 0 );
2267+
2268+ return ary;
2269+}
2270+
2271+
2272+///*--------------------------------------------------------------------
2273+// 動画を再生する
2274+// ---------------------------------------------------------------------*/
2275+//static VALUE Window_playMovie( VALUE obj, VALUE vfilename )
2276+//{
2277+// HRESULT hr;
2278+// WCHAR filename [ MAX_PATH ] ;
2279+//
2280+// Check_Type( vfilename, T_STRING );
2281+// MultiByteToWideChar ( CP_ACP, 0, RSTRING_PTR(vfilename), -1, filename, MAX_PATH );
2282+//
2283+// // IGraphBuilderインターフェイスの取得
2284+// hr = CoCreateInstance( &CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void **)(&g_pGraphBuilder) );
2285+//
2286+// if( FAILED( hr ) )
2287+// {
2288+// rb_raise( eDXRubyError, "IGraphBuilderインターフェイスの取得に失敗しました - Window_playMovie" );
2289+// }
2290+//
2291+// // IMediaControlインターフェイスの取得
2292+// hr = g_pGraphBuilder->lpVtbl->QueryInterface( g_pGraphBuilder, &IID_IMediaControl, (void**)(&g_pMediaControl) );
2293+// if( FAILED( hr ) )
2294+// {
2295+// rb_raise( eDXRubyError, "IMediaControlインターフェイスの取得に失敗しました - Window_playMovie" );
2296+// }
2297+//
2298+// hr = g_pGraphBuilder->lpVtbl->QueryInterface( g_pGraphBuilder, &IID_IVideoWindow, (LPVOID *)&g_pVideoWindow );
2299+// if( FAILED( hr ) )
2300+// {
2301+// rb_raise( eDXRubyError, "IVideoWindowインターフェイスの取得に失敗しました - Window_playMovie" );
2302+// }
2303+//
2304+// hr = g_pGraphBuilder->lpVtbl->RenderFile( g_pGraphBuilder, filename, NULL );
2305+// if( FAILED( hr ) )
2306+// {
2307+// rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - Window_playMovie" );
2308+// }
2309+//
2310+// g_pVideoWindow->lpVtbl->put_Owner( g_pVideoWindow, (OAHWND)g_hWnd );
2311+// g_pVideoWindow->lpVtbl->put_WindowStyle( g_pVideoWindow, WS_CHILD|WS_CLIPSIBLINGS );
2312+// g_pVideoWindow->lpVtbl->SetWindowPosition( g_pVideoWindow,0, 0, g_WindowInfo.width, g_WindowInfo.height );
2313+//
2314+// // メディア再生
2315+// hr = g_pMediaControl->lpVtbl->Run( g_pMediaControl );
2316+// if( FAILED( hr ) )
2317+// {
2318+// rb_raise( eDXRubyError, "再生に失敗しました - Window_playMovie" );
2319+// }
2320+//
2321+// g_PlayingMovie = 1;
2322+//// g_pMediaControl->lpVtbl->Stop( g_pMediaControl );
2323+// return obj;
2324+//}
2325+
2326+
2327+
2328+/*********************************************************************
2329+ * Imageクラス
2330+ *
2331+ * 描画用の画像を保持するクラス。
2332+ * ファイル名を渡してloadすると読み込まれ、Window::drawに渡して描画する。
2333+ *********************************************************************/
2334+
2335+/*--------------------------------------------------------------------
2336+ 参照されなくなったときにGCから呼ばれる関数
2337+ ---------------------------------------------------------------------*/
2338+static void release_Image( struct DXRubyImage* image )
2339+{
2340+ /* テクスチャオブジェクトの開放 */
2341+ if( image )
2342+ {
2343+ if( image->texture )
2344+ {
2345+ image->texture->refcount--;
2346+ if( image->texture->refcount == 0 )
2347+ {
2348+ RELEASE( image->texture->pD3DTexture );
2349+ free( image->texture );
2350+ }
2351+ }
2352+ free( image );
2353+ image = NULL;
2354+
2355+ g_iRefAll--;
2356+ if( g_iRefAll == 0 )
2357+ {
2358+ CoUninitialize();
2359+ }
2360+ }
2361+}
2362+
2363+
2364+/*--------------------------------------------------------------------
2365+ Imgaeクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
2366+ ---------------------------------------------------------------------*/
2367+static VALUE Image_allocate( VALUE klass )
2368+{
2369+ VALUE obj;
2370+ struct DXRubyImage *image;
2371+
2372+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
2373+ image = malloc(sizeof(struct DXRubyImage));
2374+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_allocate" );
2375+ obj = Data_Wrap_Struct(klass, 0, release_Image, image);
2376+
2377+ /* とりあえずテクスチャオブジェクトはNULLにしておく */
2378+ image->texture = NULL;
2379+
2380+ return obj;
2381+}
2382+
2383+
2384+/*--------------------------------------------------------------------
2385+ イメージのデータ設定(内部処理用box描画)
2386+ ---------------------------------------------------------------------*/
2387+static void fill( int x1, int y1, int x2, int y2, int col, struct DXRubyImage *image )
2388+{
2389+ D3DLOCKED_RECT texrect;
2390+ int x, y;
2391+ RECT rect;
2392+ int *p;
2393+
2394+ rect.left = x1 + image->x;
2395+ rect.top = y1 + image->y;
2396+ rect.right = x2 + image->x + 1;
2397+ rect.bottom = y2 + image->y + 1;
2398+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
2399+ for( y = 0; y <= y2 - y1; y++ )
2400+ {
2401+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
2402+ for( x = 0; x <= x2 - x1; x++ )
2403+ {
2404+ *(p++) = col;
2405+ }
2406+ }
2407+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
2408+ return;
2409+}
2410+
2411+
2412+/*--------------------------------------------------------------------
2413+ 配列から色取得
2414+ ---------------------------------------------------------------------*/
2415+static int array2color( VALUE color )
2416+{
2417+ int col;
2418+
2419+ Check_Type(color, T_ARRAY);
2420+ if( RARRAY_LEN( color ) < 3 ) rb_raise( eDXRubyError, "配列から色の取得に失敗しました - getcolor" );
2421+
2422+ if( RARRAY_LEN( color ) == 3 )
2423+ {
2424+ col = D3DCOLOR_ARGB(255, NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)), NUM2INT(rb_ary_entry(color, 2)));
2425+ }
2426+ else
2427+ {
2428+ col = D3DCOLOR_ARGB(NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)),
2429+ NUM2INT(rb_ary_entry(color, 2)), NUM2INT(rb_ary_entry(color, 3)));
2430+ }
2431+ return col;
2432+}
2433+
2434+
2435+/*--------------------------------------------------------------------
2436+ ImgaeクラスのInitialize
2437+ ---------------------------------------------------------------------*/
2438+static VALUE Image_initialize( int argc, VALUE *argv, VALUE obj )
2439+{
2440+ struct DXRubyImage *image;
2441+ struct DXRubyTexture *texture;
2442+ HRESULT hr;
2443+ D3DSURFACE_DESC desc;
2444+ VALUE vwidth, vheight, vary;
2445+ int col = 0, width, height;
2446+
2447+ g_iRefAll++;
2448+
2449+ rb_scan_args( argc, argv, "21", &vwidth, &vheight, &vary );
2450+
2451+ width = NUM2INT( vwidth );
2452+ height = NUM2INT( vheight );
2453+
2454+ if( width <= 0 || height <= 0 )
2455+ {
2456+ rb_raise( eDXRubyError, "Imageオブジェクトの作成に失敗しました - Image_initialize" );
2457+ }
2458+
2459+ if( vary != Qnil )
2460+ {
2461+ Check_Type( vary, T_ARRAY );
2462+ col = array2color( vary );
2463+ }
2464+
2465+ /* テクスチャメモリ取得 */
2466+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2467+
2468+ if( texture == NULL )
2469+ {
2470+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_initialize" );
2471+ }
2472+
2473+ /* テクスチャオブジェクトを作成する */
2474+ hr = D3DXCreateTexture( g_pD3DDevice, width, height,
2475+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2476+ &texture->pD3DTexture);
2477+
2478+ if( FAILED( hr ) )
2479+ {
2480+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_initialize" );
2481+ }
2482+
2483+ texture->refcount = 1;
2484+
2485+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2486+ texture->width = desc.Width;
2487+ texture->height = desc.Height;
2488+
2489+ /* Imageオブジェクト設定 */
2490+ Data_Get_Struct( obj, struct DXRubyImage, image );
2491+
2492+ image->texture = texture;
2493+ image->x = 0;
2494+ image->y = 0;
2495+ image->width = width;
2496+ image->height = height;
2497+
2498+ fill( 0, 0, width - 1, height - 1, col, image );
2499+
2500+ return obj;
2501+}
2502+
2503+
2504+/*--------------------------------------------------------------------
2505+ Imgaeクラスのload
2506+ ---------------------------------------------------------------------*/
2507+static VALUE Image_load( int argc, VALUE *argv, VALUE klass )
2508+{
2509+ struct DXRubyImage *image;
2510+ struct DXRubyTexture *texture;
2511+ D3DXIMAGE_INFO srcinfo;
2512+ D3DSURFACE_DESC desc;
2513+ HRESULT hr;
2514+ VALUE filename, vx, vy, vwidth, vheight, obj;
2515+ int x, y, width, height;
2516+
2517+ /* デバイスオブジェクトの初期化チェック */
2518+ if( g_pD3DDevice == NULL )
2519+ {
2520+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
2521+ }
2522+
2523+ rb_scan_args( argc, argv, "14", &filename, &vx, &vy, &vwidth, &vheight );
2524+
2525+ Check_Type(filename, T_STRING);
2526+
2527+ /* ファイル情報取得 */
2528+ hr = D3DXGetImageInfoFromFile( RSTRING_PTR( filename ), &srcinfo );
2529+
2530+ if( FAILED( hr ) )
2531+ {
2532+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", RSTRING_PTR( filename ) );
2533+ }
2534+
2535+ if( vx == Qnil )
2536+ {
2537+ x = 0;
2538+ y = 0;
2539+ width = srcinfo.Width;
2540+ height = srcinfo.Height;
2541+ }
2542+ else
2543+ {
2544+ x = NUM2INT( vx );
2545+ y = vy == Qnil ? 0 : NUM2INT( vy );
2546+ if( x < 0 || x >= srcinfo.Width || y < 0 || y >= srcinfo.Height )
2547+ {
2548+ rb_raise( eDXRubyError, "画像の原点位置が異常値です(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_load", x, y, srcinfo.Width, srcinfo.Height );
2549+ }
2550+ width = vwidth == Qnil ? srcinfo.Width - x : NUM2INT( vwidth );
2551+ height = vheight == Qnil ? srcinfo.Height - y : NUM2INT( vheight );
2552+ if( srcinfo.Width - x < width || x + width > srcinfo.Width || srcinfo.Height - y < height || y + height > srcinfo.Height ||
2553+ width < 0 || height < 0 )
2554+ {
2555+ rb_raise( eDXRubyError, "画像のサイズが異常値です - Image_load" );
2556+ }
2557+ }
2558+
2559+ /* テクスチャロード */
2560+ texture = Image_textureload( RSTRING_PTR( filename ), &srcinfo );
2561+ texture->refcount = 1;
2562+
2563+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2564+ texture->width = desc.Width;
2565+ texture->height = desc.Height;
2566+
2567+ /* Imageオブジェクト設定 */
2568+ image = malloc(sizeof(struct DXRubyImage));
2569+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_load" );
2570+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2571+
2572+ image->texture = texture;
2573+ image->x = x;
2574+ image->y = y;
2575+ image->width = width;
2576+ image->height = height;
2577+
2578+ g_iRefAll++;
2579+
2580+ return obj;
2581+}
2582+
2583+
2584+/*--------------------------------------------------------------------
2585+ ImgaeクラスのloadFromFileInMemory
2586+ ---------------------------------------------------------------------*/
2587+static VALUE Image_loadFromFileInMemory( VALUE klass, VALUE vstring )
2588+{
2589+ struct DXRubyImage *image;
2590+ struct DXRubyTexture *texture;
2591+ D3DXIMAGE_INFO srcinfo;
2592+ D3DSURFACE_DESC desc;
2593+ HRESULT hr;
2594+ VALUE obj;
2595+ int size, x, y, width, height;
2596+
2597+ /* デバイスオブジェクトの初期化チェック */
2598+ if( g_pD3DDevice == NULL )
2599+ {
2600+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
2601+ }
2602+
2603+ Check_Type(vstring, T_STRING);
2604+ size = RSTRING_LEN( vstring );
2605+
2606+ /* ファイル情報取得 */
2607+ hr = D3DXGetImageInfoFromFileInMemory( RSTRING_PTR( vstring ), size, &srcinfo );
2608+
2609+ if( FAILED( hr ) )
2610+ {
2611+ rb_raise( eDXRubyError, "イメージデータの読み込みに失敗しました - Image_loadFromFileInMemory" );
2612+ }
2613+
2614+ /* テクスチャメモリ取得 */
2615+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2616+
2617+ if( texture == NULL )
2618+ {
2619+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_loadFromFileInMemory" );
2620+ }
2621+
2622+ /* ファイルを読み込んでテクスチャオブジェクトを作成する */
2623+ hr = D3DXCreateTextureFromFileInMemoryEx( g_pD3DDevice, RSTRING_PTR( vstring ), size, srcinfo.Width, srcinfo.Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2624+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
2625+ 0, 0, &texture->pD3DTexture);
2626+
2627+ if( FAILED( hr ) )
2628+ {
2629+ rb_raise( eDXRubyError, "イメージデータの読み込みに失敗しました - Image_loadFromFileInMemory" );
2630+ }
2631+
2632+ texture->refcount = 1;
2633+
2634+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2635+ texture->width = desc.Width;
2636+ texture->height = desc.Height;
2637+
2638+ /* Imageオブジェクト設定 */
2639+ image = malloc(sizeof(struct DXRubyImage));
2640+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_loadFromFileInMemory" );
2641+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2642+
2643+ image->texture = texture;
2644+ image->x = 0;
2645+ image->y = 0;
2646+ image->width = srcinfo.Width;
2647+ image->height = srcinfo.Height;
2648+
2649+ g_iRefAll++;
2650+
2651+ return obj;
2652+}
2653+
2654+
2655+/*--------------------------------------------------------------------
2656+ Imgaeオブジェクトの分割作成
2657+ ---------------------------------------------------------------------*/
2658+static VALUE Image_loadToArray( VALUE klass, VALUE filename, VALUE vx, VALUE vy )
2659+{
2660+ struct DXRubyImage *image;
2661+ struct DXRubyTexture *texture;
2662+ int i, j, x, y;
2663+ VALUE obj;
2664+ VALUE array;
2665+ D3DXIMAGE_INFO srcinfo;
2666+ D3DSURFACE_DESC desc;
2667+ HRESULT hr;
2668+
2669+ Check_Type(filename, T_STRING);
2670+ x = NUM2INT( vx );
2671+ y = NUM2INT( vy );
2672+
2673+ if( x <= 0 || y <= 0 ) rb_raise( eDXRubyError, "画像の数指定が異常値です(x=%d,y=%d) - Image_loadToArray", x, y );
2674+
2675+ /* ファイル情報取得 */
2676+ hr = D3DXGetImageInfoFromFile( RSTRING_PTR( filename ), &srcinfo );
2677+
2678+ if( FAILED( hr ) )
2679+ {
2680+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", RSTRING_PTR( filename ) );
2681+ }
2682+
2683+ /* テクスチャロード */
2684+ texture = Image_textureload( RSTRING_PTR( filename ), &srcinfo );
2685+ texture->refcount = x * y;
2686+
2687+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
2688+ texture->width = desc.Width;
2689+ texture->height = desc.Height;
2690+
2691+ /* Ruby配列作成 */
2692+ array = rb_ary_new();
2693+
2694+ for( i = 0; i < y; i++ )
2695+ {
2696+ for( j = 0; j < x; j++ )
2697+ {
2698+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
2699+ image = malloc(sizeof(struct DXRubyImage));
2700+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_loadToArray" );
2701+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2702+
2703+ image->texture = texture;
2704+ image->x = j * srcinfo.Width / x;
2705+ image->y = i * srcinfo.Height / y;
2706+ image->width = srcinfo.Width / x;
2707+ image->height = srcinfo.Height / y;
2708+
2709+ rb_ary_push(array, obj);
2710+ g_iRefAll++;
2711+ }
2712+ }
2713+
2714+ return array;
2715+}
2716+
2717+
2718+/*--------------------------------------------------------------------
2719+ Textureロード
2720+ ---------------------------------------------------------------------*/
2721+static struct DXRubyTexture *Image_textureload( char *filename, D3DXIMAGE_INFO *psrcinfo)
2722+{
2723+ HRESULT hr;
2724+ struct DXRubyTexture *texture;
2725+
2726+ /* テクスチャメモリ取得 */
2727+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2728+
2729+ if( texture == NULL )
2730+ {
2731+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_textureload" );
2732+ }
2733+
2734+ /* ファイルを読み込んでテクスチャオブジェクトを作成する */
2735+ hr = D3DXCreateTextureFromFileEx( g_pD3DDevice, filename,psrcinfo->Width, psrcinfo->Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2736+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
2737+ 0, 0, &texture->pD3DTexture);
2738+
2739+ if( FAILED( hr ) )
2740+ {
2741+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", filename );
2742+ }
2743+
2744+ return texture;
2745+}
2746+
2747+
2748+/*--------------------------------------------------------------------
2749+ 配列からイメージを作る
2750+ ---------------------------------------------------------------------*/
2751+static VALUE Image_createFromArray( VALUE klass, VALUE vwidth, VALUE vheight, VALUE array )
2752+{
2753+ struct DXRubyImage *image;
2754+ struct DXRubyTexture *texture;
2755+ HRESULT hr;
2756+ int i, j, x, y;
2757+ D3DLOCKED_RECT LockedRect;
2758+ VALUE obj;
2759+ int width, height;
2760+ D3DSURFACE_DESC desc;
2761+
2762+ /* デバイスオブジェクトの初期化チェック */
2763+ if( g_pD3DDevice == NULL )
2764+ {
2765+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
2766+ }
2767+
2768+ width = NUM2INT( vwidth );
2769+ height = NUM2INT( vheight );
2770+ Check_Type(array, T_ARRAY);
2771+
2772+ if( width <= 0 || height <= 0 ) rb_raise( eDXRubyError, "画像のサイズ指定が異常値です(width=%d,height=%d) - Image_loadToArray", width, height );
2773+
2774+ /* テクスチャメモリ取得 */
2775+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2776+ if( texture == NULL )
2777+ {
2778+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_textureload" );
2779+ }
2780+
2781+ /* テクスチャサイズ割り出し */
2782+ for( x = 1; x < width; x = x * 2 );
2783+ for( y = 1; y < height; y = y * 2 );
2784+
2785+ /* テクスチャオブジェクトを作成する */
2786+ hr = D3DXCreateTexture( g_pD3DDevice, x, y,
2787+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2788+ &texture->pD3DTexture);
2789+ if( FAILED( hr ) )
2790+ {
2791+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_initialize" );
2792+ }
2793+
2794+ /* テクスチャロック */
2795+ hr = texture->pD3DTexture->lpVtbl->LockRect( texture->pD3DTexture, 0, &LockedRect, NULL, 0 );
2796+ if( FAILED( hr ) )
2797+ {
2798+ rb_raise( eDXRubyError, "サーフェイスのロックに失敗しました - LockRect" );
2799+ }
2800+
2801+ /* 書き込み */
2802+ for( i = 0; i < height; i++ )
2803+ {
2804+ for( j = 0; j < width * 4; j += 4 )
2805+ {
2806+ int a1 = NUM2INT(rb_ary_entry(array, j + i * width * 4));
2807+ int a2 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 1));
2808+ int a3 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 2));
2809+ int a4 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 3));
2810+ *((int*)((char *)LockedRect.pBits + j + i * LockedRect.Pitch)) = D3DCOLOR_ARGB(a1, a2, a3, a4);
2811+ }
2812+ }
2813+
2814+ /* テクスチャアンロック */
2815+ texture->pD3DTexture->lpVtbl->UnlockRect( texture->pD3DTexture, 0 );
2816+
2817+ texture->refcount = 1;
2818+ texture->pD3DTexture->lpVtbl->GetLevelDesc( texture->pD3DTexture, 0, &desc );
2819+ texture->width = desc.Width;
2820+ texture->height = desc.Height;
2821+
2822+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
2823+ image = malloc(sizeof(struct DXRubyImage));
2824+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_createFromArray" );
2825+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2826+
2827+ image->texture = texture;
2828+ image->x = 0;
2829+ image->y = 0;
2830+ image->width = width;
2831+ image->height = height;
2832+
2833+ g_iRefAll++;
2834+
2835+ return obj;
2836+}
2837+
2838+
2839+/*--------------------------------------------------------------------
2840+ Imgaeオブジェクトのslice
2841+ ---------------------------------------------------------------------*/
2842+static VALUE Image_slice_instance( int argc, VALUE *argv, VALUE vsrcimage )
2843+{
2844+ struct DXRubyImage *srcimage;
2845+ struct DXRubyImage *image;
2846+ struct DXRubyTexture *texture;
2847+ D3DXIMAGE_INFO srcinfo;
2848+ HRESULT hr;
2849+ VALUE vx, vy, vwidth, vheight, obj;
2850+ int x, y, width, height;
2851+
2852+ rb_scan_args( argc, argv, "04", &vx, &vy, &vwidth, &vheight );
2853+
2854+ Data_Get_Struct( vsrcimage, struct DXRubyImage, srcimage );
2855+
2856+ if( vx == Qnil )
2857+ {
2858+ x = 0;
2859+ y = 0;
2860+ width = srcimage->width;
2861+ height = srcimage->height;
2862+ }
2863+ else
2864+ {
2865+ x = NUM2INT( vx );
2866+ y = vy == Qnil ? 0 : NUM2INT( vy );
2867+ if( x < 0 || x >= srcimage->width || y < 0 || y >= srcimage->height )
2868+ {
2869+ rb_raise( eDXRubyError, "画像の原点位置が異常値です(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_slice", x, y, srcimage->width, srcimage->height );
2870+ }
2871+ width = vwidth == Qnil ? srcimage->width - x : NUM2INT( vwidth );
2872+ height = vheight == Qnil ? srcimage->height - y : NUM2INT( vheight );
2873+ if( srcimage->width - x < width || x + width > srcimage->width || srcimage->height - y < height || y + height > srcimage->height ||
2874+ width < 0 || height < 0 )
2875+ {
2876+ rb_raise( eDXRubyError, "画像のサイズが異常値です - Image_slice" );
2877+ }
2878+ }
2879+
2880+ texture = srcimage->texture;
2881+ texture->refcount += 1;
2882+
2883+ /* Imageオブジェクト設定 */
2884+ image = malloc(sizeof(struct DXRubyImage));
2885+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_slice" );
2886+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2887+
2888+ image->texture = texture;
2889+ image->x = x + srcimage->x;
2890+ image->y = y + srcimage->y;
2891+ image->width = width;
2892+ image->height = height;
2893+
2894+ g_iRefAll++;
2895+
2896+ return obj;
2897+}
2898+
2899+
2900+/*--------------------------------------------------------------------
2901+ ImgaeオブジェクトのsliceToArray
2902+ ---------------------------------------------------------------------*/
2903+static VALUE Image_sliceToArray( VALUE self, VALUE vx, VALUE vy )
2904+{
2905+ struct DXRubyImage *srcimage;
2906+ struct DXRubyTexture *texture;
2907+ HRESULT hr;
2908+ int x, y, i, j;
2909+ VALUE array, obj;
2910+
2911+ x = NUM2INT( vx );
2912+ y = NUM2INT( vy );
2913+
2914+ if( x <= 0 || y <= 0 ) rb_raise( eDXRubyError, "画像の数指定が異常値です(x=%d,y=%d) - Image_sliceToArray", x, y );
2915+
2916+ Data_Get_Struct( self, struct DXRubyImage, srcimage );
2917+
2918+ texture = srcimage->texture;
2919+ texture->refcount += x * y;
2920+
2921+ /* Ruby配列作成 */
2922+ array = rb_ary_new();
2923+
2924+ for( i = 0; i < y; i++ )
2925+ {
2926+ for( j = 0; j < x; j++ )
2927+ {
2928+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
2929+ struct DXRubyImage *image = malloc(sizeof(struct DXRubyImage));
2930+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_sliceToArray" );
2931+ obj = Data_Wrap_Struct(cImage, 0, release_Image, image);
2932+
2933+ image->texture = texture;
2934+ image->x = srcimage->x + j * srcimage->width / x;
2935+ image->y = srcimage->y + i * srcimage->height / y;
2936+ image->width = srcimage->width / x;
2937+ image->height = srcimage->height / y;
2938+
2939+ rb_ary_push( array, obj );
2940+ g_iRefAll++;
2941+ }
2942+ }
2943+
2944+ return array;
2945+}
2946+
2947+
2948+/*--------------------------------------------------------------------
2949+ イメージのデータ取得
2950+ ---------------------------------------------------------------------*/
2951+static VALUE Image_getPixel( VALUE obj, VALUE vx, VALUE vy )
2952+{
2953+ struct DXRubyImage *image;
2954+ VALUE ary[4];
2955+ struct DXRubyColor a;
2956+ D3DLOCKED_RECT texrect;
2957+ int x, y;
2958+ RECT rect;
2959+
2960+ x = NUM2INT( vx );
2961+ y = NUM2INT( vy );
2962+
2963+ Data_Get_Struct( obj, struct DXRubyImage, image );
2964+
2965+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
2966+ {
2967+ ary[0] = ary[1] = ary[2] = ary[3] = INT2FIX( 0 );
2968+ return rb_ary_new4( 4, ary );
2969+ }
2970+
2971+ rect.left = x + image->x;
2972+ rect.top = y + image->y;
2973+ rect.right = x + image->x + 1;
2974+ rect.bottom = y + image->y + 1;
2975+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
2976+
2977+ a = *(struct DXRubyColor *)texrect.pBits;
2978+
2979+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
2980+
2981+ ary[0] = INT2FIX( a.alpha );
2982+ ary[1] = INT2FIX( a.red );
2983+ ary[2] = INT2FIX( a.green );
2984+ ary[3] = INT2FIX( a.blue );
2985+
2986+ return rb_ary_new4( 4, ary );
2987+}
2988+
2989+
2990+/*--------------------------------------------------------------------
2991+ イメージのデータ設定
2992+ ---------------------------------------------------------------------*/
2993+static VALUE Image_setPixel( VALUE obj, VALUE vx, VALUE vy, VALUE color )
2994+{
2995+ struct DXRubyImage *image;
2996+ int a1, a2, a3, a4;
2997+ D3DLOCKED_RECT texrect;
2998+ int x, y;
2999+ RECT rect;
3000+
3001+ x = NUM2INT( vx );
3002+ y = NUM2INT( vy );
3003+ Check_Type(color, T_ARRAY);
3004+
3005+ Data_Get_Struct( obj, struct DXRubyImage, image );
3006+
3007+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
3008+ {
3009+ return obj;
3010+ }
3011+
3012+ rect.left = x + image->x;
3013+ rect.top = y + image->y;
3014+ rect.right = x + image->x + 1;
3015+ rect.bottom = y + image->y + 1;
3016+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3017+
3018+ *((int*)((char *)texrect.pBits)) = array2color( color );
3019+
3020+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3021+
3022+ return obj;
3023+}
3024+
3025+
3026+/*--------------------------------------------------------------------
3027+ イメージの色比較
3028+ ---------------------------------------------------------------------*/
3029+static VALUE Image_compare( VALUE obj, VALUE vx, VALUE vy, VALUE color )
3030+{
3031+ struct DXRubyImage *image;
3032+ DWORD a;
3033+ D3DLOCKED_RECT texrect;
3034+ int x, y, col;
3035+ int a1, a2, a3, a4;
3036+ RECT rect;
3037+
3038+ x = NUM2INT( vx );
3039+ y = NUM2INT( vy );
3040+ Check_Type(color, T_ARRAY);
3041+
3042+ Data_Get_Struct( obj, struct DXRubyImage, image );
3043+
3044+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
3045+ {
3046+ return INT2FIX( 0 );
3047+ }
3048+
3049+ col = array2color( color );
3050+
3051+ rect.left = x + image->x;
3052+ rect.top = y + image->y;
3053+ rect.right = x + image->x + 1;
3054+ rect.bottom = y + image->y + 1;
3055+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
3056+
3057+ a = *(LPDWORD)texrect.pBits;
3058+
3059+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3060+
3061+ if( RARRAY_LEN( color ) == 3 )
3062+ {
3063+
3064+ if( (a & 0x00ffffff) == ((DWORD)col & 0x00ffffff) )
3065+ {
3066+ return Qtrue;
3067+ }
3068+ else
3069+ {
3070+ return Qfalse;
3071+ }
3072+ }
3073+ else
3074+ {
3075+ if( a == (DWORD)col )
3076+ {
3077+ return Qtrue;
3078+ }
3079+ else
3080+ {
3081+ return Qfalse;
3082+ }
3083+ }
3084+}
3085+
3086+
3087+/*--------------------------------------------------------------------
3088+ イメージのデータ設定(box描画塗りつぶさない)
3089+ ---------------------------------------------------------------------*/
3090+static VALUE Image_box( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
3091+{
3092+ struct DXRubyImage *image;
3093+ D3DLOCKED_RECT texrect;
3094+ int x, y, x1, y1, x2, y2;
3095+ int col;
3096+ RECT rect;
3097+
3098+ Data_Get_Struct( obj, struct DXRubyImage, image );
3099+
3100+ x1 = NUM2INT( vx1 );
3101+ y1 = NUM2INT( vy1 );
3102+ x2 = NUM2INT( vx2 );
3103+ y2 = NUM2INT( vy2 );
3104+
3105+ /* 左上から右下の指定に修正 */
3106+ if( x1 > x2 )
3107+ {
3108+ x = x2;
3109+ x2 = x1;
3110+ x1 = x;
3111+ }
3112+ if( y1 > y2 )
3113+ {
3114+ y = y2;
3115+ y2 = y1;
3116+ y1 = y;
3117+ }
3118+
3119+ /* 範囲外の指定は無視 */
3120+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
3121+ {
3122+ return obj;
3123+ }
3124+
3125+ /* クリップ */
3126+ if( x1 < 0 )
3127+ {
3128+ x1 = 0;
3129+ }
3130+ if( x2 > image->width - 1 )
3131+ {
3132+ x2 = image->width - 1;
3133+ }
3134+ if( y1 < 0 )
3135+ {
3136+ y1 = 0;
3137+ }
3138+ if( y2 > image->height - 1 )
3139+ {
3140+ y2 = image->height - 1;
3141+ }
3142+
3143+ Check_Type(color, T_ARRAY);
3144+ col = array2color( color );
3145+
3146+ rect.left = x1 + image->x;
3147+ rect.top = y1 + image->y;
3148+ rect.right = x2 + image->x + 1;
3149+ rect.bottom = y2 + image->y + 1;
3150+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3151+ for( y = 0; y <= y2 - y1; y++ )
3152+ {
3153+ *((int*)((char *)texrect.pBits + y * texrect.Pitch)) = col;
3154+ *((int*)((char *)texrect.pBits + (x2 - x1)* 4 + y * texrect.Pitch)) = col;
3155+ }
3156+ for( x = 0; x <= x2 - x1; x++ )
3157+ {
3158+ *((int*)((char *)texrect.pBits + x * 4)) = col;
3159+ *((int*)((char *)texrect.pBits + x * 4 + (y2 - y1) * texrect.Pitch)) = col;
3160+ }
3161+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3162+
3163+ return obj;
3164+}
3165+
3166+
3167+/*--------------------------------------------------------------------
3168+ イメージのデータ設定(box描画塗りつぶす)
3169+ ---------------------------------------------------------------------*/
3170+static VALUE Image_boxFill( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
3171+{
3172+ struct DXRubyImage *image;
3173+ int x, y, x1, y1, x2, y2;
3174+ int col;
3175+
3176+ Data_Get_Struct( obj, struct DXRubyImage, image );
3177+
3178+ x1 = NUM2INT( vx1 );
3179+ y1 = NUM2INT( vy1 );
3180+ x2 = NUM2INT( vx2 );
3181+ y2 = NUM2INT( vy2 );
3182+
3183+ /* 左上から右下の指定に修正 */
3184+ if( x1 > x2 )
3185+ {
3186+ x = x2;
3187+ x2 = x1;
3188+ x1 = x;
3189+ }
3190+ if( y1 > y2 )
3191+ {
3192+ y = y2;
3193+ y2 = y1;
3194+ y1 = y;
3195+ }
3196+
3197+ /* 範囲外の指定は無視 */
3198+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
3199+ {
3200+ return obj;
3201+ }
3202+
3203+ /* クリップ */
3204+ if( x1 < 0 )
3205+ {
3206+ x1 = 0;
3207+ }
3208+ if( x2 > image->width - 1 )
3209+ {
3210+ x2 = image->width - 1;
3211+ }
3212+ if( y1 < 0 )
3213+ {
3214+ y1 = 0;
3215+ }
3216+ if( y2 > image->height - 1 )
3217+ {
3218+ y2 = image->height - 1;
3219+ }
3220+
3221+ Check_Type(color, T_ARRAY);
3222+ col = array2color( color );
3223+
3224+ fill( x1, y1, x2, y2, col, image );
3225+
3226+ return obj;
3227+}
3228+
3229+
3230+/*--------------------------------------------------------------------
3231+ イメージのデータ設定(全部塗りつぶす)
3232+ ---------------------------------------------------------------------*/
3233+static VALUE Image_fill( VALUE obj, VALUE color )
3234+{
3235+ struct DXRubyImage *image;
3236+ int col;
3237+
3238+ Data_Get_Struct( obj, struct DXRubyImage, image );
3239+
3240+ Check_Type(color, T_ARRAY);
3241+ col = array2color( color );
3242+
3243+ fill( 0, 0, image->width-1, image->height-1, col, image );
3244+
3245+ return obj;
3246+}
3247+
3248+
3249+/*--------------------------------------------------------------------
3250+ イメージのカラーキー設定。実体は指定色を透明に。
3251+ ---------------------------------------------------------------------*/
3252+static VALUE Image_setColorKey( VALUE obj, VALUE color )
3253+{
3254+ struct DXRubyImage *image;
3255+ int col;
3256+ D3DLOCKED_RECT texrect;
3257+ int x, y;
3258+ RECT rect;
3259+ int *p;
3260+
3261+ Data_Get_Struct( obj, struct DXRubyImage, image );
3262+
3263+ Check_Type(color, T_ARRAY);
3264+ col = array2color( color ) & 0x00ffffff;
3265+
3266+ rect.left = image->x;
3267+ rect.top = image->y;
3268+ rect.right = image->x + image->width;
3269+ rect.bottom = image->y + image->height;
3270+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3271+ for( y = 0; y < image->height; y++ )
3272+ {
3273+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
3274+ for( x = 0; x < image->width; x++ )
3275+ {
3276+ if( (*p & 0x00ffffff) == col )
3277+ {
3278+// *((int*)((char *)texrect.pBits + x * 4 + y * texrect.Pitch)) = col;
3279+ *p = col;
3280+ }
3281+ p++;
3282+ }
3283+ }
3284+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3285+
3286+ return obj;
3287+}
3288+
3289+
3290+/*--------------------------------------------------------------------
3291+ イメージのデータ設定(circle用のline描画)
3292+ ---------------------------------------------------------------------*/
3293+static void Image_circle_line( int x1, int x2, int y, RECT *rect, int col, D3DLOCKED_RECT *texrect )
3294+{
3295+ int x;
3296+ int *p;
3297+
3298+ if( y < 0 || y >= rect->bottom - rect->top )
3299+ {
3300+ return;
3301+ }
3302+
3303+ /* クリップ */
3304+ if( x1 < 0 )
3305+ {
3306+ x1 = 0;
3307+ }
3308+ if( x2 > rect->right - rect->left - 1 )
3309+ {
3310+ x2 = rect->right - rect->left - 1;
3311+ }
3312+ if( x1 > x2 )
3313+ {
3314+ return;
3315+ }
3316+
3317+ p = (int*)((char *)texrect->pBits + y * texrect->Pitch + x1 * 4);
3318+ for( x = 0; x <= x2 - x1; x++ )
3319+ {
3320+ *(p++) = col;
3321+ }
3322+}
3323+
3324+
3325+/*--------------------------------------------------------------------
3326+ イメージのデータ設定(circle描画塗りつぶす)
3327+ ---------------------------------------------------------------------*/
3328+static VALUE Image_circleFill( VALUE obj, VALUE vx0, VALUE vy0, VALUE vr, VALUE color )
3329+{
3330+ struct DXRubyImage *image;
3331+ int x0, y0, r, F, x, y;
3332+ int col;
3333+ D3DLOCKED_RECT texrect;
3334+ RECT rect;
3335+ HRESULT hr;
3336+ int tempx, tempy;
3337+
3338+ Data_Get_Struct( obj, struct DXRubyImage, image );
3339+
3340+ x0 = NUM2INT( vx0 );
3341+ y0 = NUM2INT( vy0 );
3342+ r = NUM2INT( vr );
3343+
3344+ Check_Type(color, T_ARRAY);
3345+ col = array2color( color );
3346+
3347+ rect.left = x0 < r ? image->x : x0 + image->x - r;
3348+ rect.top = y0 < r ? image->y : y0 + image->y - r;
3349+ rect.right = x0 + r >= image->width ? image->x + image->width : x0 + image->x + r + 1;
3350+ rect.bottom = y0 + r >= image->height ? image->y + image->height : y0 + image->y + r + 1;
3351+ if( rect.left >= rect.right || rect.top >= rect.bottom )
3352+ {
3353+ return obj;
3354+ }
3355+
3356+ hr = image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3357+
3358+ x = r;
3359+ y = 0;
3360+ F = -2 * r + 3;
3361+
3362+ tempx = x0 - rect.left + (int)image->x;
3363+ tempy = y0 - rect.top + (int)image->y;
3364+ while ( x >= y )
3365+ {
3366+ Image_circle_line( tempx - x, tempx + x, tempy + y, &rect, col, &texrect );
3367+ Image_circle_line( tempx - x, tempx + x, tempy - y, &rect, col, &texrect );
3368+ Image_circle_line( tempx - y, tempx + y, tempy + x, &rect, col, &texrect );
3369+ Image_circle_line( tempx - y, tempx + y, tempy - x, &rect, col, &texrect );
3370+ if ( F >= 0 )
3371+ {
3372+ x--;
3373+ F -= 4 * x;
3374+ }
3375+ y++;
3376+ F += 4 * y + 2;
3377+ }
3378+
3379+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3380+
3381+ return obj;
3382+}
3383+
3384+
3385+/*--------------------------------------------------------------------
3386+ イメージのデータ設定(内部処理用pixel描画)
3387+ ---------------------------------------------------------------------*/
3388+static void Image_circle_pixel( int x, int y, RECT *rect, int col, D3DLOCKED_RECT *texrect )
3389+{
3390+ if( x < 0 || x >= rect->right - rect->left || y < 0 || y >= rect->bottom - rect->top )
3391+ {
3392+ return;
3393+ }
3394+
3395+ *((int*)((char *)texrect->pBits + x * 4 + y * texrect->Pitch)) = col;
3396+
3397+ return;
3398+}
3399+
3400+
3401+/*--------------------------------------------------------------------
3402+ イメージのデータ設定(circle描画塗りつぶさない)
3403+ ---------------------------------------------------------------------*/
3404+static VALUE Image_circle( VALUE obj, VALUE vx0, VALUE vy0, VALUE vr, VALUE color )
3405+{
3406+ struct DXRubyImage *image;
3407+ D3DLOCKED_RECT texrect;
3408+ int x0, y0, r, F, x, y;
3409+ int col;
3410+ RECT rect;
3411+
3412+ Data_Get_Struct( obj, struct DXRubyImage, image );
3413+
3414+ x0 = NUM2INT( vx0 );
3415+ y0 = NUM2INT( vy0 );
3416+ r = NUM2INT( vr );
3417+
3418+ Check_Type(color, T_ARRAY);
3419+ col = array2color( color );
3420+
3421+ rect.left = x0 < r ? image->x : x0 + image->x - r;
3422+ rect.top = y0 < r ? image->y : y0 + image->y - r;
3423+ rect.right = x0 + r >= image->width ? image->x + image->width : x0 + image->x + r + 1;
3424+ rect.bottom = y0 + r >= image->height ? image->y + image->height : y0 + image->y + r + 1;
3425+ if( rect.left >= rect.right || rect.top >= rect.bottom )
3426+ {
3427+ return obj;
3428+ }
3429+
3430+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3431+
3432+ x = r;
3433+ y = 0;
3434+ F = -2 * r + 3;
3435+
3436+ while ( x >= y )
3437+ {
3438+ int tempx = x0 - rect.left + (int)image->x;
3439+ int tempy = y0 - rect.top + (int)image->y;
3440+ Image_circle_pixel( tempx + x, tempy + y, &rect, col, &texrect );
3441+ Image_circle_pixel( tempx - x, tempy + y, &rect, col, &texrect );
3442+ Image_circle_pixel( tempx + x, tempy - y, &rect, col, &texrect );
3443+ Image_circle_pixel( tempx - x, tempy - y, &rect, col, &texrect );
3444+ Image_circle_pixel( tempx + y, tempy + x, &rect, col, &texrect );
3445+ Image_circle_pixel( tempx - y, tempy + x, &rect, col, &texrect );
3446+ Image_circle_pixel( tempx + y, tempy - x, &rect, col, &texrect );
3447+ Image_circle_pixel( tempx - y, tempy - x, &rect, col, &texrect );
3448+ if ( F >= 0 )
3449+ {
3450+ x--;
3451+ F -= 4 * x;
3452+ }
3453+ y++;
3454+ F += 4 * y + 2;
3455+ }
3456+
3457+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3458+
3459+ return obj;
3460+}
3461+
3462+
3463+/*--------------------------------------------------------------------
3464+ イメージのデータ設定(line描画)
3465+ ---------------------------------------------------------------------*/
3466+static VALUE Image_line( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
3467+{
3468+ struct DXRubyImage *image;
3469+ D3DLOCKED_RECT texrect;
3470+ int x1, y1, x2, y2, xp, yp;
3471+ int col;
3472+ int c, d, dx, dy, i;
3473+ RECT rect;
3474+
3475+ Data_Get_Struct( obj, struct DXRubyImage, image );
3476+
3477+ x1 = NUM2INT( vx1 );
3478+ y1 = NUM2INT( vy1 );
3479+ x2 = NUM2INT( vx2 );
3480+ y2 = NUM2INT( vy2 );
3481+
3482+ Check_Type(color, T_ARRAY);
3483+ col = array2color( color );
3484+
3485+ rect.left = (x1 < x2 ? x1 : x2) < image->x ? image->x : (x1 < x2 ? x1 : x2);
3486+ rect.top = (y1 < y2 ? y1 : y2) < image->y ? image->y : (y1 < y2 ? y1 : y2);
3487+ rect.right = (x1 > x2 ? x1 : x2) >= image->width ? image->x + image->width : image->x + (x1 > x2 ? x1 : x2) + 1;
3488+ rect.bottom = (y1 > y2 ? y1 : y2) >= image->height ? image->y + image->height : image->y + (y1 > y2 ? y1 : y2) + 1;
3489+ if( rect.left >= rect.right || rect.top >= rect.bottom )
3490+ {
3491+ return obj;
3492+ }
3493+
3494+ x1 = x1 - rect.left + image->x;
3495+ x2 = x2 - rect.left + image->x;
3496+ y1 = y1 - rect.top + image->y;
3497+ y2 = y2 - rect.top + image->y;
3498+
3499+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
3500+
3501+ dx = x2 > x1 ? x2 - x1 : x1 - x2;
3502+ dy = y2 > y1 ? y2 - y1 : y1 - y2;
3503+
3504+ /* ブレゼンハムアルゴリズムによる線分描画 */
3505+ if( dx < dy )
3506+ {
3507+ xp = x1 < x2 ? 1 : -1;
3508+ d = y1 < y2 ? 1 : -1;
3509+ c = dy / 2;
3510+ for( i = 0; i <= dy; i++ )
3511+ {
3512+ if( x1 >= 0 && x1 < (int)rect.right - rect.left && y1 >= 0 && y1 < (int)rect.bottom - rect.top )
3513+ {
3514+ *((int*)((char *)texrect.pBits + x1 * 4 + y1 * texrect.Pitch)) = col;
3515+ }
3516+ y1 = y1 + d;
3517+ c = c + dx;
3518+ if( c >= dy )
3519+ {
3520+ c = c - dy;
3521+ x1 = x1 + xp;
3522+ }
3523+ }
3524+ }
3525+ else
3526+ {
3527+ yp = y1 < y2 ? 1 : -1;
3528+ d = x1 < x2 ? 1 : -1;
3529+ c = dx / 2;
3530+ for( i = 0; i <= dx; i++ )
3531+ {
3532+ if( x1 >= 0 && x1 < (int)rect.right - rect.left && y1 >= 0 && y1 < (int)rect.bottom - rect.top )
3533+ {
3534+ *((int*)((char *)texrect.pBits + x1 * 4 + y1 * texrect.Pitch)) = col;
3535+ }
3536+ x1 = x1 + d;
3537+ c = c + dy;
3538+ if( c >= dx )
3539+ {
3540+ c = c - dx;
3541+ y1 = y1 + yp;
3542+ }
3543+ }
3544+ }
3545+
3546+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
3547+
3548+ return obj;
3549+}
3550+
3551+
3552+/*--------------------------------------------------------------------
3553+ イメージオブジェクト間データ転送
3554+ ---------------------------------------------------------------------*/
3555+static VALUE Image_copyRect( int argc, VALUE *argv, VALUE obj )
3556+{
3557+ struct DXRubyImage *srcimage;
3558+ struct DXRubyImage *dstimage;
3559+ D3DLOCKED_RECT srctrect;
3560+ D3DLOCKED_RECT dsttrect;
3561+ VALUE vx, vy, data, vx1, vy1, vwidth, vheight;
3562+ int x, y, x1, y1, width, height;
3563+ int i, j;
3564+ RECT srcrect;
3565+ RECT dstrect;
3566+ int *psrc;
3567+ int *pdst;
3568+
3569+ rb_scan_args( argc, argv, "34", &vx, &vy, &data, &vx1, &vy1, &vwidth, &vheight );
3570+
3571+ Data_Get_Struct( obj, struct DXRubyImage, dstimage );
3572+ Data_Get_Struct( data, struct DXRubyImage, srcimage );
3573+
3574+ if( dstimage == srcimage ) rb_raise( eDXRubyError, "描画元と先に同じImageオブジェクトが指定されています - Image_copyRect" );
3575+
3576+ x = NUM2INT( vx );
3577+ y = NUM2INT( vy );
3578+ x1 = vx1 == Qnil ? 0 : NUM2INT( vx1 );
3579+ y1 = vy1 == Qnil ? 0 : NUM2INT( vy1 );
3580+ width = vwidth == Qnil ? srcimage->width - x1 : NUM2INT( vwidth );
3581+ height = vheight == Qnil ? srcimage->height - y1 : NUM2INT( vheight );
3582+
3583+ /* 画像のクリッピング */
3584+ if( x < 0 )
3585+ {
3586+ x1 -= x;
3587+ width -= x;
3588+ x = 0;
3589+ }
3590+ if( y < 0 )
3591+ {
3592+ y1 -= y;
3593+ height -= y;
3594+ y = 0;
3595+ }
3596+ if( x1 < 0 )
3597+ {
3598+ x -=x1;
3599+ width -= x1;
3600+ x1 = 0;
3601+ }
3602+ if( y1 < 0 )
3603+ {
3604+ y -=y1;
3605+ height -= y1;
3606+ y1 = 0;
3607+ }
3608+ if( x + width > dstimage->width )
3609+ {
3610+ width -= x + width - dstimage->width;
3611+ }
3612+ if( y + height > dstimage->height )
3613+ {
3614+ height -= y + height - dstimage->height;
3615+ }
3616+ if( x1 + width > srcimage->width )
3617+ {
3618+ width -= x1 + width - srcimage->width;
3619+ }
3620+ if( y1 + height > srcimage->height )
3621+ {
3622+ height -= y1 + height - srcimage->height;
3623+ }
3624+
3625+ /* 範囲外 */
3626+ if( x >= dstimage->width || y >= dstimage->height || x1 >= srcimage->width || y1 >= srcimage->height ||
3627+ width < 0 || height < 0 )
3628+ {
3629+ return obj;
3630+ }
3631+
3632+ dstrect.left = x + dstimage->x;
3633+ dstrect.top = y + dstimage->y;
3634+ dstrect.right = x + dstimage->x + width;
3635+ dstrect.bottom = y + dstimage->y + height;
3636+ srcrect.left = x1 + srcimage->x;
3637+ srcrect.top = y1 + srcimage->y;
3638+ srcrect.right = x1 + srcimage->x + width;
3639+ srcrect.bottom = y1 + srcimage->y + height;
3640+
3641+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
3642+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
3643+
3644+ for( i = 0; i < height; i++)
3645+ {
3646+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
3647+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
3648+ for( j = 0; j < width; j++)
3649+ {
3650+ *(pdst++) = *(psrc++);
3651+ }
3652+ }
3653+
3654+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
3655+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
3656+
3657+ return obj;
3658+}
3659+
3660+
3661+/*--------------------------------------------------------------------
3662+ イメージオブジェクトのdup/clone
3663+ ---------------------------------------------------------------------*/
3664+static VALUE Image_initialize_copy( VALUE self, VALUE obj )
3665+{
3666+ struct DXRubyImage *srcimage;
3667+ struct DXRubyImage *dstimage;
3668+ struct DXRubyTexture *texture;
3669+ D3DLOCKED_RECT srctrect;
3670+ D3DLOCKED_RECT dsttrect;
3671+ int i, j;
3672+ RECT srcrect;
3673+ RECT dstrect;
3674+ HRESULT hr;
3675+ D3DSURFACE_DESC desc;
3676+ int *psrc;
3677+ int *pdst;
3678+
3679+ if( TYPE(obj) != T_DATA || RDATA(obj)->dfree != release_Image )
3680+ {
3681+ rb_raise( eDXRubyError, "wrong argument type" );
3682+ }
3683+
3684+ Data_Get_Struct( self, struct DXRubyImage, dstimage );
3685+ Data_Get_Struct( obj, struct DXRubyImage, srcimage );
3686+
3687+ g_iRefAll++;
3688+
3689+ /* テクスチャメモリ取得 */
3690+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
3691+ if( texture == NULL )
3692+ {
3693+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_dup" );
3694+ }
3695+
3696+ /* テクスチャオブジェクトを作成する */
3697+ hr = D3DXCreateTexture( g_pD3DDevice, srcimage->width, srcimage->height,
3698+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
3699+ &texture->pD3DTexture);
3700+ if( FAILED( hr ) )
3701+ {
3702+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_dup" );
3703+ }
3704+
3705+ texture->refcount = 1;
3706+
3707+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
3708+ texture->width = desc.Width;
3709+ texture->height = desc.Height;
3710+
3711+ dstimage->texture = texture;
3712+ dstimage->x = 0;
3713+ dstimage->y = 0;
3714+ dstimage->width = srcimage->width;
3715+ dstimage->height =srcimage-> height;
3716+
3717+ /* イメージコピー */
3718+ dstrect.left = 0;
3719+ dstrect.top = 0;
3720+ dstrect.right = srcimage->width;
3721+ dstrect.bottom = srcimage->height;
3722+ srcrect.left = srcimage->x;
3723+ srcrect.top = srcimage->y;
3724+ srcrect.right = srcimage->x + srcimage->width;
3725+ srcrect.bottom = srcimage->y + srcimage->height;
3726+
3727+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
3728+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
3729+
3730+ for( i = 0; i < srcimage->height; i++)
3731+ {
3732+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
3733+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
3734+ for( j = 0; j < srcimage->width; j++)
3735+ {
3736+ *(pdst++) = *(psrc++);
3737+ }
3738+ }
3739+
3740+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
3741+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
3742+
3743+ return obj;
3744+}
3745+
3746+
3747+/*--------------------------------------------------------------------
3748+ イメージオブジェクト間αつきデータ転送
3749+ ---------------------------------------------------------------------*/
3750+static VALUE Image_draw( int argc, VALUE *argv, VALUE obj )
3751+{
3752+ struct DXRubyImage *srcimage;
3753+ struct DXRubyImage *dstimage;
3754+ D3DLOCKED_RECT srctrect;
3755+ D3DLOCKED_RECT dsttrect;
3756+ VALUE vx, vy, data, vx1, vy1, vwidth, vheight;
3757+ int x, y, x1, y1, width, height;
3758+ int i, j;
3759+ RECT srcrect;
3760+ RECT dstrect;
3761+ int *psrc;
3762+ int *pdst;
3763+
3764+ rb_scan_args( argc, argv, "34", &vx, &vy, &data, &vx1, &vy1, &vwidth, &vheight );
3765+
3766+ Data_Get_Struct( obj, struct DXRubyImage, dstimage );
3767+ Data_Get_Struct( data, struct DXRubyImage, srcimage );
3768+
3769+ if( dstimage == srcimage ) rb_raise( eDXRubyError, "描画元と先に同じImageオブジェクトが指定されています - Image_draw" );
3770+
3771+ x = NUM2INT( vx );
3772+ y = NUM2INT( vy );
3773+ x1 = vx1 == Qnil ? 0 : NUM2INT( vx1 );
3774+ y1 = vy1 == Qnil ? 0 : NUM2INT( vy1 );
3775+ width = vwidth == Qnil ? srcimage->width - x1 : NUM2INT( vwidth );
3776+ height = vheight == Qnil ? srcimage->height - y1 : NUM2INT( vheight );
3777+
3778+ /* 画像のクリッピング */
3779+ if( x < 0 )
3780+ {
3781+ x1 -= x;
3782+ width -= x;
3783+ x = 0;
3784+ }
3785+ if( y < 0 )
3786+ {
3787+ y1 -= y;
3788+ height -= y;
3789+ y = 0;
3790+ }
3791+ if( x1 < 0 )
3792+ {
3793+ x -=x1;
3794+ width -= x1;
3795+ x1 = 0;
3796+ }
3797+ if( y1 < 0 )
3798+ {
3799+ y -=y1;
3800+ height -= y1;
3801+ y1 = 0;
3802+ }
3803+ if( x + width > dstimage->width )
3804+ {
3805+ width -= x + width - dstimage->width;
3806+ }
3807+ if( y + height > dstimage->height )
3808+ {
3809+ height -= y + height - dstimage->height;
3810+ }
3811+ if( x1 + width > srcimage->width )
3812+ {
3813+ width -= x1 + width - srcimage->width;
3814+ }
3815+ if( y1 + height > srcimage->height )
3816+ {
3817+ height -= y1 + height - srcimage->height;
3818+ }
3819+
3820+ /* 範囲外 */
3821+ if( x >= dstimage->width || y >= dstimage->height || x1 >= srcimage->width || y1 >= srcimage->height ||
3822+ width < 0 || height < 0 )
3823+ {
3824+ return obj;
3825+ }
3826+
3827+ dstrect.left = x + dstimage->x;
3828+ dstrect.top = y + dstimage->y;
3829+ dstrect.right = x + dstimage->x + width;
3830+ dstrect.bottom = y + dstimage->y + height;
3831+ srcrect.left = x1 + srcimage->x;
3832+ srcrect.top = y1 + srcimage->y;
3833+ srcrect.right = x1 + srcimage->x + width;
3834+ srcrect.bottom = y1 + srcimage->y + height;
3835+
3836+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
3837+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
3838+
3839+ for( i = 0; i < height; i++)
3840+ {
3841+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
3842+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
3843+ for( j = 0; j < width; j++)
3844+ {
3845+ struct DXRubyColor s = *((struct DXRubyColor*)(psrc));
3846+
3847+ if( s.alpha == 255 )
3848+ {
3849+ *((struct DXRubyColor*)(pdst)) = s;
3850+ }
3851+ else if( s.alpha != 0 )
3852+ {
3853+ struct DXRubyColor d = *((struct DXRubyColor*)(pdst));
3854+
3855+ s.red = ((int)s.red * (int)s.alpha * 255 + (int)d.red * (int)d.alpha * (255 - (int)s.alpha) ) / 255 / 255;
3856+ s.green = ((int)s.green * (int)s.alpha * 255 + (int)d.green * (int)d.alpha * (255 - (int)s.alpha) ) / 255 / 255;
3857+ s.blue = ((int)s.blue * (int)s.alpha * 255 + (int)d.blue * (int)d.alpha * (255 - (int)s.alpha) ) / 255 / 255;
3858+
3859+ if( d.alpha > s.alpha)
3860+ {
3861+ s.alpha = d.alpha;
3862+ }
3863+
3864+ *((struct DXRubyColor*)(pdst)) = s;
3865+ }
3866+ psrc++;
3867+ pdst++;
3868+ }
3869+ }
3870+
3871+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
3872+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
3873+
3874+ return obj;
3875+}
3876+
3877+
3878+/*--------------------------------------------------------------------
3879+ イメージにフォント描画
3880+ ---------------------------------------------------------------------*/
3881+static VALUE Image_drawFont( int argc, VALUE *argv, VALUE obj )
3882+{
3883+ struct DXRubyFont *font;
3884+ struct DXRubyImage *image;
3885+ VALUE vx, vy, vcolor, str, data;
3886+ int cr, cg, cb, x, y;
3887+ LPDIRECT3DSURFACE9 pD3DSurface;
3888+ HDC hDC;
3889+ RECT rc;
3890+ HRESULT hr;
3891+ D3DLOCKED_RECT srctrect;
3892+ D3DLOCKED_RECT dsttrect;
3893+ int i, j;
3894+ int h;
3895+ RECT srcrect;
3896+ RECT dstrect;
3897+ int *psrc;
3898+ int *pdst;
3899+
3900+ /* 引数取得 */
3901+ rb_scan_args( argc, argv, "41", &vx, &vy, &str, &data, &vcolor);
3902+
3903+ Check_Type(str, T_STRING);
3904+
3905+ /* 引数のフォントオブジェクトから中身を取り出す */
3906+ Data_Get_Struct( obj, struct DXRubyImage, image );
3907+ Data_Get_Struct( data, struct DXRubyFont, font );
3908+ if (RDATA(data)->dfree != (RUBY_DATA_FUNC)release_Font)
3909+ {
3910+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Font)", rb_obj_classname( data ));
3911+ }
3912+
3913+ x = NUM2INT( vx );
3914+ y = NUM2INT( vy );
3915+ if( vcolor != Qnil )
3916+ {
3917+ Check_Type(vcolor, T_ARRAY);
3918+ if( RARRAY_LEN(vcolor) == 4 )
3919+ {
3920+ cr = NUM2INT(rb_ary_entry(vcolor, 1));
3921+ cg = NUM2INT(rb_ary_entry(vcolor, 2));
3922+ cb = NUM2INT(rb_ary_entry(vcolor, 3));
3923+ }
3924+ else
3925+ {
3926+ cr = NUM2INT(rb_ary_entry(vcolor, 0));
3927+ cg = NUM2INT(rb_ary_entry(vcolor, 1));
3928+ cb = NUM2INT(rb_ary_entry(vcolor, 2));
3929+ }
3930+ }
3931+ else
3932+ {
3933+ cr = 255;
3934+ cg = 255;
3935+ cb = 255;
3936+ }
3937+
3938+ if( x >= image->width || y >= image->height )
3939+ {
3940+ return obj;
3941+ }
3942+
3943+ /* オフスクリーンサーフェイスに文字描画 */
3944+ hr = g_pD3DDevice->lpVtbl->CreateOffscreenPlainSurface ( g_pD3DDevice, image->width, image->height
3945+ , D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &pD3DSurface, NULL );
3946+ if( FAILED( hr ) )
3947+ {
3948+ rb_raise( eDXRubyError, "サーフェイスの生成に失敗しました - CreateOffscreenPlainSurface" );
3949+ }
3950+ hr = pD3DSurface->lpVtbl->GetDC( pD3DSurface, &hDC );
3951+ if( FAILED( hr ) )
3952+ {
3953+ rb_raise( eDXRubyError, "DCの取得に失敗しました - GetDC" );
3954+ }
3955+ SelectObject( hDC, font->hFont );
3956+ SetRect( &rc, x, y, x + 1, y + 1 );
3957+ SetTextColor( hDC, RGB( 255, 255, 255 ) );
3958+ SetBkColor( hDC, RGB( 0, 0, 0 ) );
3959+ h = DrawText( hDC, RSTRING_PTR(str), -1, &rc, DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_NOFULLWIDTHCHARBREAK);
3960+ pD3DSurface->lpVtbl->ReleaseDC( pD3DSurface, hDC );
3961+
3962+ if( y + h < 0 )
3963+ {
3964+ RELEASE( pD3DSurface );
3965+ return obj;
3966+ }
3967+
3968+ /* Imageオブジェクトに転送 */
3969+ if( x < 0 )
3970+ {
3971+ x = 0;
3972+ }
3973+ if( y < 0 )
3974+ {
3975+ h += y;
3976+ y = 0;
3977+ }
3978+
3979+ srcrect.left = x;
3980+ srcrect.top = y;
3981+ srcrect.right = image->width;
3982+ srcrect.bottom = image->height < y + h ? image->height : y + h;
3983+ dstrect.left = x + image->x;
3984+ dstrect.top = y + image->y;
3985+ dstrect.right = image->x + image->width;
3986+ dstrect.bottom = image->y + (image->height < y + h ? image->height : y + h);
3987+
3988+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
3989+ pD3DSurface->lpVtbl->LockRect( pD3DSurface, &srctrect, &srcrect, D3DLOCK_READONLY );
3990+
3991+ for( i = 0; i < srcrect.bottom - srcrect.top; i++)
3992+ {
3993+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
3994+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
3995+ for( j = 0; j < srcrect.right - srcrect.left; j++)
3996+ {
3997+ struct DXRubyColor s = *((struct DXRubyColor*)(psrc));
3998+
3999+ if( s.red == 255 )
4000+ {
4001+ *((int *)(pdst)) = D3DCOLOR_ARGB(0xff, cr, cg, cb);
4002+ }
4003+ else if( s.red != 0 )
4004+ {
4005+ struct DXRubyColor d = *((struct DXRubyColor*)(pdst));
4006+ struct DXRubyColor data;
4007+
4008+ data.alpha = s.red > d.alpha ? s.red : d.alpha;
4009+ data.red = ((int)s.red * cr * 255 + (int)d.red * (int)d.alpha * (255 - (int)s.red) ) / 255 / 255;
4010+ data.green = ((int)s.red * cg * 255 + (int)d.green * (int)d.alpha * (255 - (int)s.red) ) / 255 / 255;
4011+ data.blue = ((int)s.red * cb * 255 + (int)d.blue * (int)d.alpha * (255 - (int)s.red) ) / 255 / 255;
4012+
4013+ *((struct DXRubyColor*)(pdst)) = data;
4014+ }
4015+ psrc++;
4016+ pdst++;
4017+ }
4018+ }
4019+
4020+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
4021+ pD3DSurface->lpVtbl->UnlockRect( pD3DSurface );
4022+
4023+ RELEASE( pD3DSurface );
4024+ return obj;
4025+}
4026+
4027+
4028+/*--------------------------------------------------------------------
4029+ イメージをファイルに保存する。
4030+ ---------------------------------------------------------------------*/
4031+static VALUE Image_save( int argc, VALUE *argv, VALUE obj )
4032+{
4033+ HRESULT hr;
4034+ struct DXRubyImage *image;
4035+ VALUE filename, format;
4036+
4037+ rb_scan_args( argc, argv, "11", &filename, &format );
4038+
4039+ Data_Get_Struct( obj, struct DXRubyImage, image );
4040+
4041+ hr = D3DXSaveTextureToFile(
4042+ RSTRING_PTR( filename ), /* 保存ファイル名 */
4043+ format == Qnil ? D3DXIFF_JPG : FIX2INT( format ), /* ファイルフォーマット */
4044+ (IDirect3DBaseTexture9*)image->texture->pD3DTexture,/* 保存するサーフェス */
4045+ NULL); /* パレット */
4046+ if( FAILED( hr ) )
4047+ {
4048+ rb_raise( eDXRubyError, "ファイルの保存に失敗しました - Image_save" );
4049+ }
4050+
4051+ return obj;
4052+}
4053+
4054+
4055+/*--------------------------------------------------------------------
4056+ イメージの開始位置xを返す。
4057+ ---------------------------------------------------------------------*/
4058+static VALUE Image_getX( VALUE obj )
4059+{
4060+ struct DXRubyImage *image;
4061+
4062+ Data_Get_Struct( obj, struct DXRubyImage, image );
4063+
4064+ return INT2FIX( image->x );
4065+}
4066+
4067+
4068+/*--------------------------------------------------------------------
4069+ イメージの開始位置yを返す。
4070+ ---------------------------------------------------------------------*/
4071+static VALUE Image_getY( VALUE obj )
4072+{
4073+ struct DXRubyImage *image;
4074+
4075+ Data_Get_Struct( obj, struct DXRubyImage, image );
4076+
4077+ return INT2FIX( image->y );
4078+}
4079+
4080+
4081+/*--------------------------------------------------------------------
4082+ イメージのサイズ(幅)を返す。
4083+ ---------------------------------------------------------------------*/
4084+static VALUE Image_getWidth( VALUE obj )
4085+{
4086+ struct DXRubyImage *image;
4087+
4088+ Data_Get_Struct( obj, struct DXRubyImage, image );
4089+
4090+ return INT2FIX( image->width );
4091+}
4092+
4093+
4094+/*--------------------------------------------------------------------
4095+ イメージのサイズ(高さ)を返す。
4096+ ---------------------------------------------------------------------*/
4097+static VALUE Image_getHeight( VALUE obj )
4098+{
4099+ struct DXRubyImage *image;
4100+
4101+ Data_Get_Struct( obj, struct DXRubyImage, image );
4102+
4103+ return INT2FIX( image->height );
4104+}
4105+
4106+
4107+/*--------------------------------------------------------------------
4108+ イメージの開始位置xを設定する。
4109+ ---------------------------------------------------------------------*/
4110+static VALUE Image_setX( VALUE obj, VALUE x )
4111+{
4112+ struct DXRubyImage *image;
4113+
4114+ Data_Get_Struct( obj, struct DXRubyImage, image );
4115+ image->x = NUM2INT( x );
4116+
4117+ return x;
4118+}
4119+
4120+
4121+/*--------------------------------------------------------------------
4122+ イメージの開始位置yを設定する。
4123+ ---------------------------------------------------------------------*/
4124+static VALUE Image_setY( VALUE obj, VALUE y )
4125+{
4126+ struct DXRubyImage *image;
4127+
4128+ Data_Get_Struct( obj, struct DXRubyImage, image );
4129+ image->y = NUM2INT( y );
4130+
4131+ return y;
4132+}
4133+
4134+
4135+/*--------------------------------------------------------------------
4136+ イメージのサイズ(幅)を設定する。
4137+ ---------------------------------------------------------------------*/
4138+static VALUE Image_setWidth( VALUE obj, VALUE width )
4139+{
4140+ struct DXRubyImage *image;
4141+
4142+ Data_Get_Struct( obj, struct DXRubyImage, image );
4143+ image->width = NUM2INT( width );
4144+
4145+ return width;
4146+}
4147+
4148+
4149+/*--------------------------------------------------------------------
4150+ イメージのサイズ(高さ)を設定する。
4151+ ---------------------------------------------------------------------*/
4152+static VALUE Image_setHeight( VALUE obj, VALUE height )
4153+{
4154+ struct DXRubyImage *image;
4155+
4156+ Data_Get_Struct( obj, struct DXRubyImage, image );
4157+ image->height = NUM2INT( height );
4158+
4159+ return height;
4160+}
4161+
4162+
4163+
4164+/*********************************************************************
4165+ * Soundクラス
4166+ *
4167+ * DirectMusicを使用して音を鳴らす。
4168+ * とりあえず音を出そうと頑張っている。
4169+ *********************************************************************/
4170+
4171+/*--------------------------------------------------------------------
4172+ 参照されなくなったときにGCから呼ばれる関数
4173+ ---------------------------------------------------------------------*/
4174+static void release_Sound( struct DXRubySound* sound )
4175+{
4176+ HRESULT hr;
4177+
4178+ /* サウンドオブジェクトの開放 */
4179+ if( sound )
4180+ {
4181+ /* バンド解放 */
4182+ if ( sound->pDMSegment != NULL )
4183+ {
4184+ hr = sound->pDMSegment->lpVtbl->Unload( sound->pDMSegment, (IUnknown* )sound->pDMDefAudioPath );
4185+ if( FAILED( hr ) )
4186+ {
4187+ rb_raise( eDXRubyError, "バンドの解放に失敗しました - Unload" );
4188+ }
4189+ /* セグメントを開放 */
4190+ RELEASE( sound->pDMSegment );
4191+ }
4192+
4193+ /* デフォルトオーディオパスを開放 */
4194+ RELEASE( sound->pDMDefAudioPath );
4195+
4196+ g_iRefDM--;
4197+
4198+ if( g_iRefDM <= 0 )
4199+ {
4200+ /* 演奏停止 */
4201+ if ( g_pDMPerformance )
4202+ {
4203+ hr = g_pDMPerformance->lpVtbl->Stop( g_pDMPerformance, NULL, NULL, 0, 0 );
4204+ if ( FAILED( hr ) )
4205+ {
4206+ rb_raise( eDXRubyError, "パフォーマンスの終了に失敗しました - Stop" );
4207+ }
4208+ }
4209+ g_pDMPerformance->lpVtbl->CloseDown( g_pDMPerformance );
4210+ RELEASE(g_pDMPerformance);
4211+
4212+ /* ローダを開放 */
4213+ RELEASE(g_pDMLoader);
4214+ }
4215+
4216+ free( sound );
4217+ sound = NULL;
4218+
4219+ g_iRefAll--;
4220+ if( g_iRefAll == 0 )
4221+ {
4222+ CoUninitialize();
4223+ }
4224+ }
4225+}
4226+
4227+
4228+/*--------------------------------------------------------------------
4229+ Soundクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
4230+ ---------------------------------------------------------------------*/
4231+static VALUE Sound_allocate( VALUE klass )
4232+{
4233+ VALUE obj;
4234+ struct DXRubySound *sound;
4235+
4236+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
4237+ sound = malloc(sizeof(struct DXRubySound));
4238+ if( sound == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Sound_allocate" );
4239+ obj = Data_Wrap_Struct(klass, 0, release_Sound, sound);
4240+
4241+ /* とりあえずサウンドオブジェクトはNULLにしておく */
4242+ sound->pDMSegment = NULL;
4243+
4244+ return obj;
4245+}
4246+
4247+
4248+/*--------------------------------------------------------------------
4249+ Soundクラスのinitialize。ファイルをロードする。
4250+ ---------------------------------------------------------------------*/
4251+static VALUE Sound_initialize( VALUE obj, VALUE filename )
4252+{
4253+ HRESULT hr;
4254+ WCHAR wstrFileName[MAX_PATH];
4255+ struct DXRubySound *sound;
4256+ CHAR strPath[MAX_PATH];
4257+ DWORD i;
4258+ WCHAR wstrSearchPath[MAX_PATH];
4259+
4260+ g_iRefAll++;
4261+
4262+ Check_Type(filename, T_STRING);
4263+
4264+ if( g_iRefDM == 0 )
4265+ {
4266+ /* パフォーマンスの作成 */
4267+ hr = CoCreateInstance( &CLSID_DirectMusicPerformance, NULL,
4268+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicPerformance8,
4269+ (void**)&g_pDMPerformance );
4270+ if( FAILED( hr ) )
4271+ {
4272+ rb_raise( eDXRubyError, "DirectMusicの初期化に失敗しました - CoCreateInstance" );
4273+ }
4274+
4275+ /* パフォーマンスの初期化 */
4276+ hr = g_pDMPerformance->lpVtbl->InitAudio( g_pDMPerformance,
4277+ NULL, /* IDirectMusicインターフェイスは不要 */
4278+ NULL, /* IDirectSoundインターフェイスは不要 */
4279+ g_hWnd, /* ウィンドウのハンドル */
4280+ DMUS_APATH_SHARED_STEREOPLUSREVERB, /* デフォルトのオーディオパス・タイプ */
4281+ 64, /* パフォーマンス・チャンネルの数 */
4282+ DMUS_AUDIOF_ALL, /* シンセサイザの機能 */
4283+ NULL ); /* オーディオ・パラメータにはデフォルトを使用 */
4284+ if( FAILED( hr ) )
4285+ {
4286+ rb_raise( eDXRubyError, "DirectMusicの初期化に失敗しました - InitAudio" );
4287+ }
4288+
4289+ /* ローダーの作成 */
4290+ hr = CoCreateInstance( &CLSID_DirectMusicLoader, NULL,
4291+ CLSCTX_INPROC_SERVER, &IID_IDirectMusicLoader8,
4292+ (void**)&g_pDMLoader );
4293+ if( FAILED( hr ) )
4294+ {
4295+ rb_raise( eDXRubyError, "DirectMusicの初期化に失敗しました - CoCreateInstance" );
4296+ }
4297+
4298+ /* ローダーの初期化(検索パスをカレント・ディレクトリに設定) */
4299+ i = GetCurrentDirectory( MAX_PATH, strPath );
4300+ if ( i == 0 || MAX_PATH < i )
4301+ {
4302+ rb_raise( eDXRubyError, "カレント・ディレクトリの取得に失敗 - GetCurrentDirectory" );
4303+ }
4304+
4305+ /* マルチ・バイト文字をUNICODEに変換 */
4306+ MultiByteToWideChar( CP_ACP, 0, strPath, -1, wstrSearchPath, MAX_PATH );
4307+
4308+ /* ローダーに検索パスを設定 */
4309+ hr = g_pDMLoader->lpVtbl->SetSearchDirectory( g_pDMLoader, &GUID_DirectMusicAllTypes,
4310+ wstrSearchPath, FALSE );
4311+ if( FAILED( hr ) )
4312+ {
4313+ rb_raise( eDXRubyError, "検索パスの設定に失敗 - SetSearchDirectory" );
4314+ }
4315+ }
4316+ g_iRefDM++;
4317+
4318+ /* サウンドオブジェクト取得 */
4319+ Data_Get_Struct( obj, struct DXRubySound, sound );
4320+
4321+ /* オーディオ・パス作成 */
4322+ hr = g_pDMPerformance->lpVtbl->CreateStandardAudioPath( g_pDMPerformance,
4323+ DMUS_APATH_DYNAMIC_STEREO, /* パスの種類。 */
4324+ 64, /* パフォーマンス チャンネルの数。 */
4325+ TRUE, /* ここでアクティブになる。 */
4326+ &sound->pDMDefAudioPath ); /* オーディオパスを受け取るポインタ。 */
4327+
4328+ if ( FAILED( hr ) )
4329+ {
4330+ rb_raise( eDXRubyError, "オーディオパスの作成に失敗しました - CreateStandardAudioPath" );
4331+ }
4332+
4333+ /* ファイルロード */
4334+ MultiByteToWideChar( CP_ACP, 0, RSTRING_PTR( filename ), -1, wstrFileName, MAX_PATH );
4335+ hr = g_pDMLoader->lpVtbl->LoadObjectFromFile( g_pDMLoader, &CLSID_DirectMusicSegment,
4336+ &IID_IDirectMusicSegment8,
4337+ wstrFileName,
4338+ (LPVOID*)&sound->pDMSegment );
4339+ if( FAILED( hr ) )
4340+ {
4341+ sound->pDMSegment = NULL;
4342+ rb_raise( eDXRubyError, "ファイルのロードに失敗しました - LoadObjectFromFile" );
4343+ }
4344+
4345+ sound->start = 0;
4346+ sound->loopstart = 0;
4347+ sound->loopend = 0;
4348+
4349+ /* MIDIの場合 */
4350+ if( strstr( RSTRING_PTR( filename ), ".mid" ) != NULL )
4351+ {
4352+ hr = sound->pDMSegment->lpVtbl->SetParam( sound->pDMSegment, &GUID_StandardMIDIFile,
4353+ 0xFFFFFFFF, 0, 0, NULL);
4354+ if( FAILED( hr ) )
4355+ {
4356+ rb_raise( eDXRubyError, "ファイルのロードに失敗しました - SetParam" );
4357+ }
4358+ sound->loopcount = DMUS_SEG_REPEAT_INFINITE;
4359+ sound->midwavflag = 0;
4360+ /* ループ回数設定 */
4361+ hr = sound->pDMSegment->lpVtbl->SetRepeats( sound->pDMSegment, sound->loopcount );
4362+
4363+ if( FAILED( hr ) )
4364+ {
4365+ rb_raise( eDXRubyError, "ループ回数の設定に失敗しました - SetRepeats" );
4366+ }
4367+ }
4368+ else
4369+ {
4370+ sound->loopcount = 1;
4371+ sound->midwavflag = 1;
4372+ }
4373+
4374+ /* バンドダウンロード */
4375+ hr = sound->pDMSegment->lpVtbl->Download( sound->pDMSegment, (IUnknown* )sound->pDMDefAudioPath );
4376+
4377+ if( FAILED( hr ) )
4378+ {
4379+ rb_raise( eDXRubyError, "バンドのロードに失敗しました - Download" );
4380+ }
4381+
4382+
4383+ /* 音量設定 */
4384+ hr = sound->pDMDefAudioPath->lpVtbl->SetVolume( sound->pDMDefAudioPath, 230 * 9600 / 255 - 9600 , 0 );
4385+
4386+ if( FAILED( hr ) )
4387+ {
4388+ rb_raise( eDXRubyError, "音量の設定に失敗しました - SetVolume" );
4389+ }
4390+
4391+ return obj;
4392+}
4393+
4394+
4395+/*--------------------------------------------------------------------
4396+ 開始位置を設定する
4397+ ---------------------------------------------------------------------*/
4398+static VALUE Sound_setStart( VALUE obj, VALUE vstart )
4399+{
4400+ HRESULT hr;
4401+ struct DXRubySound *sound;
4402+
4403+ Data_Get_Struct( obj, struct DXRubySound, sound );
4404+ sound->start = NUM2INT( vstart );
4405+
4406+ if( sound->midwavflag == 1 && sound->start > 0 ) /* wavの場合 */
4407+ {
4408+ hr = sound->pDMSegment->lpVtbl->SetLength( sound->pDMSegment, sound->start * DMUS_PPQ / 768 + 1 );
4409+ if( FAILED( hr ) )
4410+ {
4411+ rb_raise( eDXRubyError, "セグメント開始位置の設定に失敗しました - SetLength" );
4412+ }
4413+ }
4414+
4415+ /* セグメント再生スタート位置設定 */
4416+ hr = sound->pDMSegment->lpVtbl->SetStartPoint( sound->pDMSegment, sound->start * DMUS_PPQ / 768 );
4417+
4418+ if( FAILED( hr ) )
4419+ {
4420+ rb_raise( eDXRubyError, "セグメント開始位置の設定に失敗しました - SetStartPoint" );
4421+ }
4422+
4423+ return obj;
4424+}
4425+
4426+
4427+/*--------------------------------------------------------------------
4428+ ループ開始位置を設定する
4429+ ---------------------------------------------------------------------*/
4430+static VALUE Sound_setLoopStart( VALUE obj, VALUE vloopstart )
4431+{
4432+ HRESULT hr;
4433+ struct DXRubySound *sound;
4434+
4435+ Data_Get_Struct( obj, struct DXRubySound, sound );
4436+ sound->loopstart = NUM2INT( vloopstart );
4437+
4438+ if( sound->midwavflag == 1 )
4439+ {
4440+ rb_raise( eDXRubyError, "WAVデータにループ開始位置は設定できません - Sound_loopStart=" );
4441+ }
4442+
4443+ if( sound->loopstart <= sound->loopend )
4444+ {
4445+ /* ループ範囲設定 */
4446+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, sound->loopstart * DMUS_PPQ / 768
4447+ , sound->loopend * DMUS_PPQ / 768 );
4448+ if( FAILED( hr ) )
4449+ {
4450+ rb_raise( eDXRubyError, "ループ範囲の設定に失敗しました - SetLoopPoints" );
4451+ }
4452+ }
4453+ else
4454+ {
4455+ /* ループ範囲設定 */
4456+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, 0, 0 );
4457+
4458+ if( FAILED( hr ) )
4459+ {
4460+ rb_raise( eDXRubyError, "ループ範囲の設定に失敗しました - SetLoopPoints" );
4461+ }
4462+ }
4463+
4464+ return obj;
4465+}
4466+
4467+
4468+/*--------------------------------------------------------------------
4469+ ループ終了位置を設定する
4470+ ---------------------------------------------------------------------*/
4471+static VALUE Sound_setLoopEnd( VALUE obj, VALUE vloopend )
4472+{
4473+ HRESULT hr;
4474+ struct DXRubySound *sound;
4475+
4476+ Data_Get_Struct( obj, struct DXRubySound, sound );
4477+ sound->loopend = NUM2INT( vloopend );
4478+
4479+ if( sound->midwavflag == 1 )
4480+ {
4481+ rb_raise( eDXRubyError, "WAVデータにループ終了位置は設定できません - Sound_loopEnd=" );
4482+ }
4483+
4484+ if( sound->loopstart <= sound->loopend )
4485+ {
4486+ /* ループ範囲設定 */
4487+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, sound->loopstart * DMUS_PPQ / 768
4488+ , sound->loopend * DMUS_PPQ / 768 );
4489+ if( FAILED( hr ) )
4490+ {
4491+ rb_raise( eDXRubyError, "ループ範囲の設定に失敗しました - SetLoopPoints" );
4492+ }
4493+ }
4494+ else
4495+ {
4496+ /* ループ範囲設定 */
4497+ hr = sound->pDMSegment->lpVtbl->SetLoopPoints( sound->pDMSegment, 0, 0 );
4498+
4499+ if( FAILED( hr ) )
4500+ {
4501+ rb_raise( eDXRubyError, "ループ範囲の設定に失敗しました - SetLoopPoints" );
4502+ }
4503+ }
4504+
4505+
4506+ return obj;
4507+}
4508+
4509+
4510+/*--------------------------------------------------------------------
4511+ ループ回数を設定する
4512+ ---------------------------------------------------------------------*/
4513+static VALUE Sound_setLoopCount( VALUE obj, VALUE vloopcount )
4514+{
4515+ HRESULT hr;
4516+ struct DXRubySound *sound;
4517+
4518+ Data_Get_Struct( obj, struct DXRubySound, sound );
4519+ sound->loopcount = NUM2INT( vloopcount );
4520+
4521+ /* ループ回数設定 */
4522+ hr = sound->pDMSegment->lpVtbl->SetRepeats( sound->pDMSegment, sound->loopcount );
4523+
4524+ if( FAILED( hr ) )
4525+ {
4526+ rb_raise( eDXRubyError, "ループ回数の設定に失敗しました - SetRepeats" );
4527+ }
4528+
4529+ return obj;
4530+}
4531+
4532+
4533+/*--------------------------------------------------------------------
4534+ 音量を設定する
4535+ ---------------------------------------------------------------------*/
4536+static VALUE Sound_setVolume( int argc, VALUE *argv, VALUE obj )
4537+{
4538+ HRESULT hr;
4539+ struct DXRubySound *sound;
4540+ VALUE vvolume, vtime;
4541+ int volume, time;
4542+
4543+ rb_scan_args( argc, argv, "11", &vvolume, &vtime );
4544+
4545+ time = vtime == Qnil ? 0 : NUM2INT( vtime );
4546+ volume = NUM2INT( vvolume ) > 255 ? 255 : NUM2INT( vvolume );
4547+ Data_Get_Struct( obj, struct DXRubySound, sound );
4548+
4549+ /* 音量設定 */
4550+ hr = sound->pDMDefAudioPath->lpVtbl->SetVolume( sound->pDMDefAudioPath, volume * 9600 / 255 - 9600, time );
4551+
4552+ if( FAILED( hr ) )
4553+ {
4554+ rb_raise( eDXRubyError, "音量の設定に失敗しました - SetVolume" );
4555+ }
4556+
4557+ return obj;
4558+}
4559+
4560+
4561+/*--------------------------------------------------------------------
4562+ 音を鳴らす
4563+ ---------------------------------------------------------------------*/
4564+static VALUE Sound_play( VALUE obj )
4565+{
4566+ HRESULT hr;
4567+ struct DXRubySound *sound;
4568+
4569+ Data_Get_Struct( obj, struct DXRubySound, sound );
4570+
4571+ /* 再生 */
4572+ if( sound->midwavflag == 0 )
4573+ {
4574+ hr = g_pDMPerformance->lpVtbl->PlaySegmentEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, NULL, NULL,
4575+ DMUS_SEGF_CONTROL, 0, NULL, NULL, (IUnknown* )sound->pDMDefAudioPath );
4576+ }
4577+ else
4578+ {
4579+ hr = g_pDMPerformance->lpVtbl->PlaySegmentEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, NULL, NULL,
4580+ DMUS_SEGF_SECONDARY, 0, NULL, NULL, (IUnknown* )sound->pDMDefAudioPath );
4581+ }
4582+ if( FAILED( hr ) )
4583+ {
4584+ rb_raise( eDXRubyError, "音の再生に失敗しました - PlaySegmentEx" );
4585+ }
4586+
4587+ return obj;
4588+}
4589+
4590+
4591+/*--------------------------------------------------------------------
4592+ 音を止める
4593+ ---------------------------------------------------------------------*/
4594+static VALUE Sound_stop( VALUE obj )
4595+{
4596+ HRESULT hr;
4597+ struct DXRubySound *sound;
4598+
4599+ Data_Get_Struct( obj, struct DXRubySound, sound );
4600+
4601+ /* 再生 */
4602+ hr = g_pDMPerformance->lpVtbl->StopEx( g_pDMPerformance, (IUnknown* )sound->pDMSegment, 0, 0 );
4603+
4604+ if( FAILED( hr ) )
4605+ {
4606+ rb_raise( eDXRubyError, "音の停止に失敗しました - StopEx" );
4607+ }
4608+
4609+ return obj;
4610+
4611+}
4612+
4613+
4614+/*********************************************************************
4615+ * SoundEffectクラス
4616+ *
4617+ * DirectSoundを使用して音を鳴らす。
4618+ * とりあえず音を出そうと頑張っている。
4619+ *********************************************************************/
4620+
4621+/*--------------------------------------------------------------------
4622+ 参照されなくなったときにGCから呼ばれる関数
4623+ ---------------------------------------------------------------------*/
4624+static void release_SoundEffect( struct DXRubySoundEffect* soundeffect )
4625+{
4626+ /* サウンドオブジェクトの開放 */
4627+ if( soundeffect )
4628+ {
4629+ /* サウンドバッファを開放 */
4630+ RELEASE( soundeffect->pDSBuffer );
4631+
4632+ g_iRefDS--;
4633+
4634+ if( g_iRefDS == 0 )
4635+ {
4636+ RELEASE( g_pDSound );
4637+ }
4638+
4639+ free( soundeffect );
4640+ soundeffect = NULL;
4641+
4642+ g_iRefAll--;
4643+ if( g_iRefAll == 0 )
4644+ {
4645+ CoUninitialize();
4646+ }
4647+ }
4648+}
4649+
4650+
4651+/*--------------------------------------------------------------------
4652+ SoundEffectクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
4653+ ---------------------------------------------------------------------*/
4654+static VALUE SoundEffect_allocate( VALUE klass )
4655+{
4656+ VALUE obj;
4657+ struct DXRubySoundEffect *soundeffect;
4658+
4659+ /* DXRubySoundEffectのメモリ取得&SoundEffectオブジェクト生成 */
4660+ soundeffect = malloc(sizeof(struct DXRubySoundEffect));
4661+ if( soundeffect == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - SoundEffect_allocate" );
4662+ obj = Data_Wrap_Struct(klass, 0, release_SoundEffect, soundeffect);
4663+
4664+ /* とりあえずサウンドオブジェクトはNULLにしておく */
4665+ soundeffect->pDSBuffer = NULL;
4666+
4667+ return obj;
4668+}
4669+
4670+
4671+static short calcwave(int type, double vol, double count, double p)
4672+{
4673+ switch( type )
4674+ {
4675+ case 1: /* サイン波 */
4676+ return (sin( (3.141592653589793115997963468544185161590576171875f * 2) * (double)count / (double)p )) * (double)vol * 128;
4677+ break;
4678+ case 2: /* ノコギリ波 */
4679+ return ((double)count / (double)p - 0.5) * (double)vol * 256;
4680+ break;
4681+ case 3: /* 三角波 */
4682+ if( count < p / 4 ) /* 1/4 */
4683+ {
4684+ return (double)count / ((double)p / 4) * (double)vol * 128;
4685+ }
4686+ else if( count < p / 2 ) /* 2/4 */
4687+ {
4688+ return ((double)p / 2 - (double)count) / ((double)p / 4) * (double)vol * 128;
4689+ }
4690+ else if( count < p * 3 / 4 ) /* 3/4 */
4691+ {
4692+ return -((double)count - (double)p / 2)/ ((double)p / 4) * (double)vol * 128;
4693+ }
4694+ else /* 最後 */
4695+ {
4696+ return -((double)p - (double)count) / ((double)p / 4) * (double)vol * 128;
4697+ }
4698+ break;
4699+ case 0: /* 矩形波 */
4700+ default: /* デフォルト */
4701+ if( count < p / 2 ) /* 前半 */
4702+ {
4703+ return vol * 128;
4704+ }
4705+ else /* 後半 */
4706+ {
4707+ return -vol * 128;
4708+ }
4709+ break;
4710+ }
4711+}
4712+/*--------------------------------------------------------------------
4713+ SoundEffectクラスのinitialize。波形を生成する。
4714+ ---------------------------------------------------------------------*/
4715+static VALUE SoundEffect_initialize( int argc, VALUE *argv, VALUE obj )
4716+{
4717+ HRESULT hr;
4718+ struct DXRubySoundEffect *soundeffect;
4719+ DSBUFFERDESC desc;
4720+ WAVEFORMATEX pcmwf;
4721+ int i;
4722+ short *pointer, *pointer2;
4723+ DWORD size, size2;
4724+ VALUE vf;
4725+ double count;
4726+ int vol;
4727+ double f;
4728+ VALUE vsize, vtype, vresolution;
4729+ int type, resolution;
4730+
4731+ g_iRefAll++;
4732+
4733+ rb_scan_args( argc, argv, "12", &vsize, &vtype, &vresolution );
4734+
4735+ type = vtype == Qnil ? 0 : NUM2INT( vtype );
4736+ resolution = vresolution == Qnil ? 1000 : (NUM2INT( vresolution ) > 44100 ? 44100 : NUM2INT( vresolution ));
4737+
4738+ /* DirectSoundオブジェクトの作成 */
4739+ if( g_iRefDS == 0 )
4740+ {
4741+ hr = DirectSoundCreate8( &DSDEVID_DefaultPlayback, &g_pDSound, NULL );
4742+ if( FAILED( hr ) )
4743+ {
4744+ rb_raise( eDXRubyError, "DirectSoundの初期化に失敗しました - DirectSoundCreate8" );
4745+ }
4746+
4747+ hr = g_pDSound->lpVtbl->SetCooperativeLevel( g_pDSound, g_hWnd, DSSCL_PRIORITY );
4748+ if( FAILED( hr ) )
4749+ {
4750+ rb_raise( eDXRubyError, "DirectSoundの初期化に失敗しました - SetCooperativeLevel" );
4751+ }
4752+ }
4753+ g_iRefDS++;
4754+
4755+ /* サウンドオブジェクト作成 */
4756+ Data_Get_Struct( obj, struct DXRubySoundEffect, soundeffect );
4757+
4758+ /* サウンドバッファ作成 */
4759+ pcmwf.wFormatTag = WAVE_FORMAT_PCM;
4760+ pcmwf.nChannels = 1;
4761+ pcmwf.nSamplesPerSec = 44100 * 2;
4762+ pcmwf.wBitsPerSample = 16;
4763+ pcmwf.nBlockAlign = pcmwf.nChannels * pcmwf.wBitsPerSample / 8;
4764+ pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
4765+ pcmwf.cbSize = 0;
4766+
4767+ desc.dwSize = sizeof(desc);
4768+ desc.dwFlags = DSBCAPS_GLOBALFOCUS;
4769+ desc.dwBufferBytes = pcmwf.nAvgBytesPerSec / 100 * NUM2INT(vsize) / 10;
4770+ desc.dwReserved = 0;
4771+ desc.lpwfxFormat = &pcmwf;
4772+ desc.guid3DAlgorithm = DS3DALG_DEFAULT;
4773+
4774+ hr = g_pDSound->lpVtbl->CreateSoundBuffer( g_pDSound, &desc, &soundeffect->pDSBuffer, NULL );
4775+
4776+ if( FAILED( hr ) )
4777+ {
4778+ rb_raise( eDXRubyError, "サウンドバッファの作成に失敗しました - CreateSoundBuffer" );
4779+ }
4780+
4781+ /* ロック */
4782+ hr = soundeffect->pDSBuffer->lpVtbl->Lock( soundeffect->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
4783+ if( FAILED( hr ) || size2 != 0 )
4784+ {
4785+ rb_raise( eDXRubyError, "サウンドバッファのロックに失敗しました - Lock" );
4786+ }
4787+
4788+ /* 音バッファ初期化 */
4789+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
4790+ {
4791+ pointer[i] = 0;
4792+ }
4793+
4794+ count = 0;
4795+
4796+ /* 波形生成 */
4797+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
4798+ {
4799+ /* 指定時間単位でブロックを呼び出す */
4800+ if ( i % (pcmwf.nSamplesPerSec / resolution) == 0 )
4801+ {
4802+ vf = rb_yield( obj );
4803+ if( TYPE( vf ) != T_ARRAY )
4804+ {
4805+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4806+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4807+ break;
4808+ }
4809+ switch (TYPE( rb_ary_entry(vf, 0) )) {
4810+ case T_FIXNUM:
4811+ case T_FLOAT:
4812+ f = NUM2DBL( rb_ary_entry(vf, 0) );
4813+ break;
4814+ default:
4815+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4816+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4817+ break;
4818+ }
4819+ switch (TYPE( rb_ary_entry(vf, 1) )) {
4820+ case T_FIXNUM:
4821+ case T_FLOAT:
4822+ vol = NUM2DBL(rb_ary_entry(vf, 1));
4823+ break;
4824+ default:
4825+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4826+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4827+ break;
4828+ }
4829+ /* 最大/最低周波数と最大ボリュームの制限 */
4830+ f = f > pcmwf.nSamplesPerSec / 2.0f ? pcmwf.nSamplesPerSec / 2.0f : f;
4831+ f = f < 20 ? 20 : f;
4832+ vol = vol > 255 ? 255 : vol;
4833+ vol = vol < 0 ? 0 : vol;
4834+ }
4835+ count = count + f;
4836+ if( count >= pcmwf.nSamplesPerSec )
4837+ {
4838+ count = count - pcmwf.nSamplesPerSec;
4839+ }
4840+ pointer[i] = calcwave(type, vol, count, pcmwf.nSamplesPerSec);
4841+ }
4842+
4843+ /* アンロック */
4844+ hr = soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4845+ if( FAILED( hr ) )
4846+ {
4847+ rb_raise( eDXRubyError, "サウンドバッファのロックに失敗しました - Lock" );
4848+ }
4849+
4850+ return obj;
4851+
4852+}
4853+
4854+
4855+/*--------------------------------------------------------------------
4856+ 波形を合成する。
4857+ ---------------------------------------------------------------------*/
4858+static VALUE SoundEffect_add( int argc, VALUE *argv, VALUE obj )
4859+{
4860+ HRESULT hr;
4861+ struct DXRubySoundEffect *soundeffect;
4862+ DSBUFFERDESC desc;
4863+ WAVEFORMATEX pcmwf;
4864+ int i;
4865+ short *pointer, *pointer2;
4866+ DWORD size, size2;
4867+ VALUE vf, vtype, vresolution;
4868+ double count;
4869+ int vol;
4870+ double f;
4871+ int type, resolution;
4872+ int data;
4873+
4874+ rb_scan_args( argc, argv, "02", &vtype, &vresolution );
4875+
4876+ type = vtype == Qnil ? 0 : NUM2INT( vtype );
4877+ resolution = vresolution == Qnil ? 1000 : (NUM2INT( vresolution ) > 44100 ? 44100 : NUM2INT( vresolution ));
4878+
4879+ /* サウンドオブジェクト取得 */
4880+ Data_Get_Struct( obj, struct DXRubySoundEffect, soundeffect );
4881+
4882+ /* ロック */
4883+ hr = soundeffect->pDSBuffer->lpVtbl->Lock( soundeffect->pDSBuffer, 0, 0, &pointer, &size, &pointer2, &size2, DSBLOCK_ENTIREBUFFER );
4884+ if( FAILED( hr ) || size2 != 0 )
4885+ {
4886+ rb_raise( eDXRubyError, "サウンドバッファのロックに失敗しました - Lock" );
4887+ }
4888+
4889+ pcmwf.nChannels = 1;
4890+ pcmwf.nSamplesPerSec = 44100 * 2;
4891+ pcmwf.wBitsPerSample = 16;
4892+ pcmwf.nBlockAlign = pcmwf.nChannels * pcmwf.wBitsPerSample / 8;
4893+ pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
4894+ desc.dwBufferBytes = size;
4895+
4896+ count = 0;
4897+
4898+ /* 波形生成 */
4899+ for( i = 0; i < desc.dwBufferBytes / (pcmwf.wBitsPerSample / 8); i++ )
4900+ {
4901+ /* 指定時間単位でブロックを呼び出す */
4902+ if ( i % (pcmwf.nSamplesPerSec / resolution) == 0 )
4903+ {
4904+ vf = rb_yield( obj );
4905+ if( TYPE( vf ) != T_ARRAY )
4906+ {
4907+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4908+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4909+ break;
4910+ }
4911+ switch (TYPE( rb_ary_entry(vf, 0) )) {
4912+ case T_FIXNUM:
4913+ case T_FLOAT:
4914+ f = NUM2DBL( rb_ary_entry(vf, 0) );
4915+ break;
4916+ default:
4917+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4918+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4919+ break;
4920+ }
4921+ switch (TYPE( rb_ary_entry(vf, 1) )) {
4922+ case T_FIXNUM:
4923+ case T_FLOAT:
4924+ vol = NUM2DBL(rb_ary_entry(vf, 1));
4925+ break;
4926+ default:
4927+ soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4928+ rb_raise(rb_eTypeError, "not valid value - SoundEffect_initialize");
4929+ break;
4930+ }
4931+ /* 最大/最低周波数と最大ボリュームの制限 */
4932+ f = f > pcmwf.nSamplesPerSec / 2.0f ? pcmwf.nSamplesPerSec / 2.0f : f;
4933+ f = f < 20 ? 20 : f;
4934+ vol = vol > 255 ? 255 : vol;
4935+ vol = vol < 0 ? 0 : vol;
4936+ }
4937+ count = count + f;
4938+ if( count >= pcmwf.nSamplesPerSec )
4939+ {
4940+ count = count - pcmwf.nSamplesPerSec;
4941+ }
4942+
4943+ data = calcwave(type, vol, count, pcmwf.nSamplesPerSec);
4944+
4945+ if( data + (int)pointer[i] > 32767 )
4946+ {
4947+ pointer[i] = 32767;
4948+ }
4949+ else if( data + (int)pointer[i] < -32768 )
4950+ {
4951+ pointer[i] = -32768;
4952+ }
4953+ else
4954+ {
4955+ pointer[i] += data;
4956+ }
4957+ }
4958+
4959+ /* アンロック */
4960+ hr = soundeffect->pDSBuffer->lpVtbl->Unlock( soundeffect->pDSBuffer, pointer, size, pointer2, size2 );
4961+ if( FAILED( hr ) )
4962+ {
4963+ rb_raise( eDXRubyError, "サウンドバッファのロックに失敗しました - Lock" );
4964+ }
4965+
4966+ return obj;
4967+
4968+}
4969+
4970+
4971+/*--------------------------------------------------------------------
4972+ 音を鳴らす
4973+ ---------------------------------------------------------------------*/
4974+static VALUE SoundEffect_play( VALUE obj )
4975+{
4976+ HRESULT hr;
4977+ struct DXRubySoundEffect *soundeffect;
4978+
4979+ Data_Get_Struct( obj, struct DXRubySoundEffect, soundeffect );
4980+
4981+ /* とめる */
4982+ hr = soundeffect->pDSBuffer->lpVtbl->Stop( soundeffect->pDSBuffer );
4983+ if( FAILED( hr ) )
4984+ {
4985+ rb_raise( eDXRubyError, "音の再生に失敗しました - SoundEffect_play" );
4986+ }
4987+
4988+ hr = soundeffect->pDSBuffer->lpVtbl->SetCurrentPosition( soundeffect->pDSBuffer, 0 );
4989+ if( FAILED( hr ) )
4990+ {
4991+ rb_raise( eDXRubyError, "音の再生に失敗しました - SoundEffect_play" );
4992+ }
4993+
4994+ /* 再生 */
4995+ hr = soundeffect->pDSBuffer->lpVtbl->Play( soundeffect->pDSBuffer, 0, 0, 0 );
4996+ if( FAILED( hr ) )
4997+ {
4998+ rb_raise( eDXRubyError, "音の再生に失敗しました - SoundEffect_play" );
4999+ }
5000+ return obj;
5001+}
5002+
5003+
5004+/*--------------------------------------------------------------------
5005+ 音を止める
5006+ ---------------------------------------------------------------------*/
5007+static VALUE SoundEffect_stop( VALUE obj )
5008+{
5009+ HRESULT hr;
5010+ struct DXRubySoundEffect *soundeffect;
5011+
5012+ Data_Get_Struct( obj, struct DXRubySoundEffect, soundeffect );
5013+
5014+ /* とめる */
5015+ hr = soundeffect->pDSBuffer->lpVtbl->Stop( soundeffect->pDSBuffer );
5016+ if( FAILED( hr ) )
5017+ {
5018+ rb_raise( eDXRubyError, "音の停止に失敗しました - Stop" );
5019+ }
5020+
5021+ return obj;
5022+}
5023+
5024+
5025+
5026+/*********************************************************************
5027+ * Inputモジュール
5028+ *
5029+ * DirectInputを使用してキーボード・パッドの入力を行う。
5030+ *********************************************************************/
5031+
5032+/*--------------------------------------------------------------------
5033+ Windowsメッセージ処理込みの入力更新
5034+ ---------------------------------------------------------------------*/
5035+static VALUE Input_update( VALUE obj )
5036+{
5037+ MSG msg;
5038+ msg.message = WM_NULL;
5039+
5040+ if( g_WindowInfo.loop == 2 )
5041+ {
5042+ rb_raise( eDXRubyError, "Window.loop実行中にInput.updateは実行できません。" );
5043+ }
5044+
5045+ g_WindowInfo.loop = 1;
5046+
5047+ /* メッセージループ */
5048+ /* メッセージがなくなるまで処理をし続ける */
5049+ /* メッセージが無い時はブロックをyieldする */
5050+ while (1)
5051+ {
5052+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
5053+ {
5054+ /* メッセージがある時 */
5055+ TranslateMessage( &msg );
5056+ DispatchMessage( &msg );
5057+ }
5058+ else
5059+ {
5060+ break;
5061+ }
5062+ }
5063+
5064+ if( g_WindowInfo.requestclose == 1 )
5065+ {
5066+ g_WindowInfo.requestclose = 0;
5067+ return Qtrue;
5068+ }
5069+
5070+ /* メッセージが無い時 */
5071+ /* 入力状態更新 */
5072+ inputupdate();
5073+
5074+ return Qfalse;
5075+}
5076+
5077+
5078+/*--------------------------------------------------------------------
5079+ Inputモジュールの入力処理
5080+ ---------------------------------------------------------------------*/
5081+static void inputupdate( void )
5082+{
5083+ int i, j;
5084+ DIJOYSTATE paddata;
5085+
5086+ /* フォーカスがはずれた場合、キーとパッド、マウスボタンの入力を受け付けなくする */
5087+ if( g_WindowInfo.active == 0 )
5088+ {
5089+ /* キーボードのデータをクリアする */
5090+ ZeroMemory( &g_diKeyState, sizeof(g_diKeyState) );
5091+ ZeroMemory( &g_diKeyStateOld, sizeof(g_diKeyStateOld) );
5092+
5093+ /* パッドデータをクリアする */
5094+ for( i = 0; i < g_JoystickCount; i++ )
5095+ {
5096+ for( j = 0; j < 20; j++ )
5097+ {
5098+ g_PadStateOld[i].button[j] = g_PadState[i].button[j];
5099+ g_PadState[i].button[j] = 0;
5100+ }
5101+ }
5102+
5103+ /* マウスボタンのデータをクリアする */
5104+ g_byMouseStateOld_L = g_byMouseState_L;
5105+ g_byMouseStateOld_M = g_byMouseState_M;
5106+ g_byMouseStateOld_R = g_byMouseState_R;
5107+ g_byMouseState_L = 0;
5108+ g_byMouseState_M = 0;
5109+ g_byMouseState_R = 0;
5110+
5111+ return;
5112+ }
5113+
5114+ /* デバイスアクセス権を再取得する */
5115+ g_pDIDKeyBoard->lpVtbl->Acquire( g_pDIDKeyBoard );
5116+
5117+ for( i = 0; i < g_JoystickCount; i++ )
5118+ {
5119+ g_pDIDJoyPad[i]->lpVtbl->Poll( g_pDIDJoyPad[i] );
5120+ g_pDIDJoyPad[i]->lpVtbl->Acquire( g_pDIDJoyPad[i] );
5121+ }
5122+
5123+ /* キーボードの直接データを取得する */
5124+ memcpy( g_diKeyStateOld, g_diKeyState, sizeof(g_diKeyState) );
5125+ g_pDIDKeyBoard->lpVtbl->GetDeviceState( g_pDIDKeyBoard, 256, g_diKeyState );
5126+
5127+ /* ゲームパッドのデータを取得する */
5128+ for( i = 0; i < g_JoystickCount; i++ )
5129+ {
5130+ int j;
5131+
5132+ g_pDIDJoyPad[i]->lpVtbl->GetDeviceState( g_pDIDJoyPad[i], sizeof(DIJOYSTATE), &paddata );
5133+
5134+ for( j = 0; j < 20; j++ )
5135+ {
5136+ g_PadStateOld[i].button[j] = g_PadState[i].button[j];
5137+ g_PadState[i].button[j] = 0;
5138+ }
5139+
5140+ /* 左 */
5141+ if( paddata.lX < g_PadInfo[i].left )
5142+ {
5143+ g_PadState[i].button[P_LEFT] = 1;
5144+ }
5145+ /* 右 */
5146+ else if( paddata.lX > g_PadInfo[i].right )
5147+ {
5148+ g_PadState[i].button[P_RIGHT] = 1;
5149+ }
5150+
5151+ /* 上 */
5152+ if( paddata.lY < g_PadInfo[i].up )
5153+ {
5154+ g_PadState[i].button[P_UP] = 1;
5155+ }
5156+ /* 下 */
5157+ else if( paddata.lY > g_PadInfo[i].down )
5158+ {
5159+ g_PadState[i].button[P_DOWN] = 1;
5160+ }
5161+
5162+ /* ボタン状態 */
5163+ for( j = 0; j < 16; j++)
5164+ {
5165+ g_PadState[i].button[j + 4] = paddata.rgbButtons[j] >> 7;
5166+ }
5167+ }
5168+
5169+ /* マウスボタンの状態 */
5170+ g_byMouseStateOld_L = g_byMouseState_L;
5171+ g_byMouseStateOld_M = g_byMouseState_M;
5172+ g_byMouseStateOld_R = g_byMouseState_R;
5173+ g_byMouseState_L = GetKeyState( VK_LBUTTON );
5174+ g_byMouseState_M = GetKeyState( VK_MBUTTON );
5175+ g_byMouseState_R = GetKeyState( VK_RBUTTON );
5176+
5177+ return;
5178+}
5179+
5180+
5181+/*--------------------------------------------------------------------
5182+ Inputモジュールのデータ取得
5183+
5184+ 横方向の入力をxの増分で返す
5185+ ---------------------------------------------------------------------*/
5186+static VALUE Input_x( int argc, VALUE *argv, VALUE obj )
5187+{
5188+ int x = 0;
5189+ VALUE vnumber;
5190+ int number;
5191+
5192+ rb_scan_args( argc, argv, "01", &vnumber);
5193+
5194+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5195+
5196+ if( number < 0 || number >= PADMAX )
5197+ {
5198+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_x" );
5199+ }
5200+
5201+ /* ひだり */
5202+ if( g_diKeyState[g_PadState[number].PadConfig[P_LEFT]] & 0x80 || g_PadState[number].button[P_LEFT] == 1 )
5203+ {
5204+ x = x - 1;
5205+ }
5206+
5207+ /* みぎ */
5208+ if( g_diKeyState[g_PadState[number].PadConfig[P_RIGHT]] & 0x80 || g_PadState[number].button[P_RIGHT] == 1 )
5209+ {
5210+ x = x + 1;
5211+ }
5212+
5213+ return INT2FIX( x );
5214+}
5215+
5216+
5217+/*--------------------------------------------------------------------
5218+ Inputモジュールのデータ取得
5219+
5220+ 縦方向の入力をyの増分で返す
5221+ ---------------------------------------------------------------------*/
5222+static VALUE Input_y( int argc, VALUE *argv, VALUE obj )
5223+{
5224+ int y = 0;
5225+ VALUE vnumber;
5226+ int number;
5227+
5228+ rb_scan_args( argc, argv, "01", &vnumber);
5229+
5230+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5231+
5232+ if( number < 0 || number >= PADMAX )
5233+ {
5234+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_y" );
5235+ }
5236+
5237+
5238+ /* うえ */
5239+ if( g_diKeyState[g_PadState[number].PadConfig[P_UP]] & 0x80 || g_PadState[number].button[P_UP] == 1 )
5240+ {
5241+ y = y - 1;
5242+ }
5243+
5244+ /* した */
5245+ if( g_diKeyState[g_PadState[number].PadConfig[P_DOWN]] & 0x80 || g_PadState[number].button[P_DOWN] == 1 )
5246+ {
5247+ y = y + 1;
5248+ }
5249+
5250+ return INT2FIX( y );
5251+}
5252+
5253+
5254+/*--------------------------------------------------------------------
5255+ Inputモジュールのデータ取得
5256+
5257+ 押されていたらtrueになる。引数はキーコード。
5258+ ---------------------------------------------------------------------*/
5259+static VALUE Input_keyDown( VALUE obj , VALUE vkey )
5260+{
5261+ int key, padbutton = 0;
5262+
5263+ key = NUM2INT( vkey );
5264+ if( key < 0 || key >= 256 )
5265+ {
5266+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_keyDown" );
5267+ }
5268+
5269+ if( g_diKeyConfig[key] != -1 && g_PadState[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
5270+ {
5271+ padbutton = 1;
5272+ }
5273+
5274+ if( g_diKeyState[key] & 0x80 || padbutton == 1)
5275+ {
5276+ return Qtrue;
5277+ }
5278+
5279+ return Qfalse;
5280+}
5281+
5282+
5283+/*--------------------------------------------------------------------
5284+ Inputモジュールのデータ取得
5285+
5286+ 押した瞬間だけtrueになる。引数はキーコード。
5287+ ---------------------------------------------------------------------*/
5288+static VALUE Input_keyPush( VALUE obj , VALUE vkey )
5289+{
5290+ int key, padbutton = 0, padbuttonold = 0;
5291+
5292+ key = NUM2INT( vkey );
5293+ if( key < 0 || key >= 256 )
5294+ {
5295+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_keyPush" );
5296+ }
5297+
5298+ if( g_diKeyConfig[key] != -1 )
5299+ {
5300+ if( g_PadState[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
5301+ {
5302+ padbutton = 1;
5303+ }
5304+ if( g_PadStateOld[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
5305+ {
5306+ padbuttonold = 1;
5307+ }
5308+ }
5309+
5310+ if( (g_diKeyState[key] & 0x80) || padbutton == 1 ) /* 入力されている */
5311+ {
5312+ if( !(g_diKeyStateOld[key] & 0x80) && padbuttonold == 0 ) /* 前回OFFである */
5313+ {
5314+ g_diKeyCount[key] = 0; /* カウント初期化 */
5315+ return Qtrue; /* なにはともあれTrue */
5316+ }
5317+ else /* 前回ONだった */
5318+ {
5319+ g_diKeyCount[key]++; /* カウント */
5320+ if( g_diKeyWait[key] <= g_diKeyCount[key] ) /* ウェイトタイムを超えたか */
5321+ {
5322+ if( g_diKeyInterval[key] != 0 &&
5323+ (g_diKeyCount[key] - g_diKeyWait[key]) % g_diKeyInterval[key] == 0 ) /* インターバルタイムごとに */
5324+ {
5325+ return Qtrue; /* True */
5326+ }
5327+ }
5328+ }
5329+ }
5330+
5331+ return Qfalse;
5332+}
5333+
5334+
5335+/*--------------------------------------------------------------------
5336+ Inputモジュールのデータ取得
5337+
5338+ 押されていたらtrueになる。引数はボタン番号。
5339+ ---------------------------------------------------------------------*/
5340+static VALUE Input_padDown( int argc, VALUE *argv, VALUE obj )
5341+{
5342+ VALUE vnumber, vbutton;
5343+ int number, button, key = 0;
5344+
5345+ rb_scan_args( argc, argv, "11", &vbutton, &vnumber);
5346+
5347+ button = NUM2INT( vbutton );
5348+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5349+
5350+ if( number < 0 || button < 0 || number >= PADMAX || button >= 20 )
5351+ {
5352+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_padDown" );
5353+ }
5354+
5355+ if( g_PadState[number].PadConfig[button] != -1 && g_diKeyState[g_PadState[number].PadConfig[button]] & 0x80 )
5356+ {
5357+ key = 1;
5358+ }
5359+
5360+ if( key == 1 || g_PadState[number].button[button] == 1 )
5361+ {
5362+ return Qtrue;
5363+ }
5364+
5365+ return Qfalse;
5366+}
5367+
5368+
5369+/*--------------------------------------------------------------------
5370+ Inputモジュールのデータ取得
5371+
5372+ 押した瞬間だけtrueになる。引数はボタン番号。
5373+ ---------------------------------------------------------------------*/
5374+static VALUE Input_padPush( int argc, VALUE *argv, VALUE obj )
5375+{
5376+ VALUE vnumber, vbutton;
5377+ int number, button, key = 0, keyold = 0;
5378+
5379+ rb_scan_args( argc, argv, "11", &vbutton, &vnumber);
5380+
5381+ button = NUM2INT( vbutton );
5382+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5383+
5384+ if( number < 0 || button < 0 || number >= PADMAX || button >= 20 )
5385+ {
5386+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_padPush" );
5387+ }
5388+
5389+ if( g_PadState[number].PadConfig[button] != -1 )
5390+ {
5391+ if( g_diKeyState[g_PadState[number].PadConfig[button]] & 0x80 )
5392+ {
5393+ key = 1;
5394+ }
5395+ if( g_diKeyStateOld[g_PadState[number].PadConfig[button]] & 0x80 )
5396+ {
5397+ keyold = 1;
5398+ }
5399+ }
5400+
5401+ if( key == 1 || g_PadState[number].button[button] == 1 ) /* 入力されている */
5402+ {
5403+ if( keyold == 0 && g_PadStateOld[number].button[button] == 0 ) /* 前回OFFである */
5404+ {
5405+ g_PadState[number].count[button] = 0; /* カウント初期化 */
5406+ return Qtrue; /* なにはともあれTrue */
5407+ }
5408+ else /* 前回ONだった */
5409+ {
5410+ g_PadState[number].count[button]++; /* カウント */
5411+ if( g_PadState[number].wait[button] <= g_PadState[number].count[button] ) /* ウェイトタイムを超えたか */
5412+ {
5413+ if( g_PadState[number].interval[button] != 0 &&
5414+ (g_PadState[number].count[button] - g_PadState[number].wait[button])
5415+ % g_PadState[number].interval[button] == 0 ) /* インターバルタイムごとに */
5416+ {
5417+ return Qtrue; /* True */
5418+ }
5419+ }
5420+ }
5421+ }
5422+
5423+ return Qfalse;
5424+}
5425+
5426+
5427+/*--------------------------------------------------------------------
5428+ パッドとキーの対応を設定する
5429+ ---------------------------------------------------------------------*/
5430+static void Input_SetConfig( int number, int pad, int key )
5431+{
5432+ int i, j;
5433+
5434+ if( pad == -1 ) /* キーに対するパッド割り当て解除処理 */
5435+ {
5436+ g_diKeyConfig[key] = -1;
5437+ for( i = 0; i < PADMAX; i++)
5438+ {
5439+ for( j = 0; j < 20; j++)
5440+ {
5441+ if( g_PadState[i].PadConfig[j] == key )
5442+ {
5443+ g_PadState[i].PadConfig[j] = -1;
5444+ }
5445+ }
5446+ }
5447+ }
5448+ else if( key == -1 || key == 0 ) /* パッドに対するキー割り当て解除処理 */
5449+ {
5450+ g_PadState[number].PadConfig[pad] = -1;
5451+ for( i = 0; i < 256; i++)
5452+ {
5453+ if( g_diKeyConfig[i] == pad )
5454+ {
5455+ g_diKeyConfig[i] = -1;
5456+ }
5457+ }
5458+ }
5459+ else /* 割り当て処理 */
5460+ {
5461+ g_PadState[number].PadConfig[pad] = key;
5462+ g_diKeyConfig[key] = number * 20 + pad;
5463+ }
5464+}
5465+
5466+static VALUE Input_setconfig( int argc, VALUE *argv, VALUE obj )
5467+{
5468+ VALUE vnumber, vpad, vkey;
5469+ int number, pad, key;
5470+
5471+ rb_scan_args( argc, argv, "21", &vpad, &vkey, &vnumber);
5472+
5473+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5474+ pad = (vpad == Qnil ? -1 : NUM2INT( vpad ));
5475+ key = (vkey == Qnil ? -1 : NUM2INT( vkey ));
5476+
5477+ if( number < 0 || pad < -1 || key < -1 || number >= PADMAX || pad >= 20 || key >= 256 )
5478+ {
5479+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setconfig" );
5480+ }
5481+
5482+ if( pad != -1 || key != -1 )
5483+ {
5484+ Input_SetConfig( number, pad, key );
5485+ }
5486+
5487+ return obj;
5488+}
5489+
5490+
5491+/*--------------------------------------------------------------------
5492+ マウスホイールの状態を返す
5493+ ---------------------------------------------------------------------*/
5494+static VALUE Input_getmousewheelpos( VALUE obj )
5495+{
5496+ return INT2FIX(g_WindowInfo.mousewheelpos);
5497+}
5498+
5499+
5500+/*--------------------------------------------------------------------
5501+ マウスホイールの状態を設定する
5502+ ---------------------------------------------------------------------*/
5503+static VALUE Input_setmousewheelpos( VALUE obj, VALUE wheelpos )
5504+{
5505+ g_WindowInfo.mousewheelpos = NUM2INT( wheelpos );
5506+
5507+ return obj;
5508+}
5509+
5510+
5511+/*--------------------------------------------------------------------
5512+ マウスのボタン状態を返す
5513+ ---------------------------------------------------------------------*/
5514+static VALUE Input_mouseDown( VALUE obj, VALUE button )
5515+{
5516+
5517+ switch( NUM2INT( button ) )
5518+ {
5519+ case M_LBUTTON:
5520+ if( g_byMouseState_L & 0x80 )
5521+ {
5522+ return Qtrue;
5523+ }
5524+ else
5525+ {
5526+ return Qfalse;
5527+ }
5528+
5529+ case M_RBUTTON:
5530+ if( g_byMouseState_R & 0x80 )
5531+ {
5532+ return Qtrue;
5533+ }
5534+ else
5535+ {
5536+ return Qfalse;
5537+ }
5538+
5539+ case M_MBUTTON:
5540+ if( g_byMouseState_M & 0x80 )
5541+ {
5542+ return Qtrue;
5543+ }
5544+ else
5545+ {
5546+ return Qfalse;
5547+ }
5548+ }
5549+
5550+ return Qnil;
5551+}
5552+
5553+
5554+/*--------------------------------------------------------------------
5555+ マウスのボタン状態を返す
5556+ ---------------------------------------------------------------------*/
5557+static VALUE Input_mousePush( VALUE obj, VALUE button )
5558+{
5559+
5560+ switch( NUM2INT( button ) )
5561+ {
5562+ case M_LBUTTON:
5563+ if( (g_byMouseState_L & 0x80) && !(g_byMouseStateOld_L & 0x80) )
5564+ {
5565+ return Qtrue;
5566+ }
5567+ else
5568+ {
5569+ return Qfalse;
5570+ }
5571+
5572+ case M_RBUTTON:
5573+ if( g_byMouseState_R & 0x80 && !(g_byMouseStateOld_R & 0x80) )
5574+ {
5575+ return Qtrue;
5576+ }
5577+ else
5578+ {
5579+ return Qfalse;
5580+ }
5581+
5582+ case M_MBUTTON:
5583+ if( g_byMouseState_M & 0x80 && !(g_byMouseStateOld_M & 0x80) )
5584+ {
5585+ return Qtrue;
5586+ }
5587+ else
5588+ {
5589+ return Qfalse;
5590+ }
5591+ }
5592+
5593+ return Qnil;
5594+}
5595+
5596+
5597+/*--------------------------------------------------------------------
5598+ マウスカーソルの位置を返す
5599+ ---------------------------------------------------------------------*/
5600+static VALUE Input_getmouseposx( VALUE obj )
5601+{
5602+ POINT cursor;
5603+
5604+ GetCursorPos( &cursor );
5605+ ScreenToClient( g_hWnd, &cursor );
5606+ return INT2FIX( cursor.x );
5607+}
5608+
5609+
5610+/*--------------------------------------------------------------------
5611+ マウスカーソルの位置を返す
5612+ ---------------------------------------------------------------------*/
5613+static VALUE Input_getmouseposy( VALUE obj )
5614+{
5615+ POINT cursor;
5616+
5617+ GetCursorPos( &cursor );
5618+ ScreenToClient( g_hWnd, &cursor );
5619+
5620+ return INT2FIX( cursor.y );
5621+}
5622+
5623+
5624+/*--------------------------------------------------------------------
5625+ マウスカーソルの位置を設定する
5626+ ---------------------------------------------------------------------*/
5627+static VALUE Input_setmousepos( VALUE klass, VALUE vx, VALUE vy )
5628+{
5629+ POINT cursor;
5630+
5631+ cursor.x = NUM2INT( vx );
5632+ cursor.y = NUM2INT( vy );
5633+ ClientToScreen( g_hWnd, &cursor );
5634+ SetCursorPos( cursor.x, cursor.y );
5635+
5636+ return Qnil;
5637+}
5638+
5639+
5640+/*--------------------------------------------------------------------
5641+ マウス描画するかどうかの設定
5642+ ---------------------------------------------------------------------*/
5643+static VALUE Input_enablemouse( VALUE obj, VALUE draw )
5644+{
5645+ VALUE flag = Qfalse;
5646+ int c;
5647+
5648+ if( draw != Qnil && draw != Qfalse )
5649+ {
5650+ flag = Qtrue;
5651+ }
5652+
5653+ if( flag == Qtrue )
5654+ {
5655+ c = ShowCursor( TRUE );
5656+ while( c < 0 ) c = ShowCursor( TRUE );
5657+ }
5658+ else
5659+ {
5660+ c = ShowCursor( FALSE );
5661+ while( c >= 0 ) c = ShowCursor( FALSE );
5662+ }
5663+
5664+ g_WindowInfo.enablemouse = flag;
5665+
5666+ return draw;
5667+}
5668+
5669+
5670+/*--------------------------------------------------------------------
5671+ Inputモジュールの全キーオートリピート状態設定
5672+ ---------------------------------------------------------------------*/
5673+static VALUE Input_setrepeat( VALUE obj , VALUE vwait, VALUE vinterval )
5674+{
5675+ int wait, interval, i, j;
5676+
5677+ wait = NUM2INT( vwait );
5678+ interval = NUM2INT( vinterval );
5679+
5680+ for( i = 0; i < 256; i++)
5681+ {
5682+ g_diKeyWait[i] = wait;
5683+ g_diKeyInterval[i] = interval;
5684+ }
5685+
5686+ for( i = 0; i < PADMAX; i++)
5687+ {
5688+ for( j = 0; j < 20; j++)
5689+ {
5690+ g_PadState[i].wait[j] = wait;
5691+ g_PadState[i].interval[j] = interval;
5692+ }
5693+ }
5694+
5695+ return obj;
5696+}
5697+
5698+
5699+/*--------------------------------------------------------------------
5700+ Inputモジュールのキーオートリピート状態設定
5701+ ---------------------------------------------------------------------*/
5702+static VALUE Input_setkeyrepeat( VALUE obj , VALUE vkey, VALUE vwait, VALUE vinterval )
5703+{
5704+ int key, wait, interval;
5705+
5706+ key = NUM2INT( vkey );
5707+ wait = NUM2INT( vwait );
5708+ interval = NUM2INT( vinterval );
5709+
5710+ if( key < 0 || key >= 256 || wait < 0 || interval < 0 )
5711+ {
5712+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setKeyRepeat" );
5713+ }
5714+
5715+ g_diKeyWait[key] = wait;
5716+ g_diKeyInterval[key] = interval;
5717+
5718+ return obj;
5719+}
5720+
5721+
5722+/*--------------------------------------------------------------------
5723+ Inputモジュールのパッドオートリピート状態設定
5724+ ---------------------------------------------------------------------*/
5725+static VALUE Input_setpadrepeat( int argc, VALUE *argv, VALUE obj )
5726+{
5727+ VALUE vpad, vwait, vinterval, vnumber;
5728+ int pad, wait, interval, number;
5729+
5730+ rb_scan_args( argc, argv, "31", &vpad, &vwait, &vinterval, &vnumber );
5731+
5732+ pad = NUM2INT( vpad );
5733+ wait = NUM2INT( vwait );
5734+ interval = NUM2INT( vinterval );
5735+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
5736+
5737+ if( number < 0 || pad < 0 || number >= PADMAX || pad >= 20 ||
5738+ wait < 0 || interval < 0 )
5739+ {
5740+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setPadRepeat" );
5741+ }
5742+
5743+ g_PadState[number].wait[pad] = wait;
5744+ g_PadState[number].interval[pad] = interval;
5745+
5746+ return obj;
5747+}
5748+
5749+
5750+/*--------------------------------------------------------------------
5751+ Inputモジュールのデータ取得
5752+
5753+ 押されているキーの配列を返す。
5754+ ---------------------------------------------------------------------*/
5755+static VALUE Input_getKeys( VALUE obj )
5756+{
5757+ int i, j;
5758+ VALUE buf[256];
5759+
5760+ for( i = 0, j = 0; i < 256; i++ )
5761+ {
5762+ if( g_diKeyState[i] & 0x80 ) /* 入力されている */
5763+ {
5764+ buf[j++] = INT2FIX( i );
5765+ }
5766+ }
5767+
5768+ return rb_ary_new4( j, buf );
5769+}
5770+
5771+
5772+/*--------------------------------------------------------------------
5773+ Inputモジュールのデータ取得
5774+
5775+ 押されているパッドの配列を返す。
5776+ ---------------------------------------------------------------------*/
5777+static VALUE Input_getPads( int argc, VALUE *argv, VALUE obj )
5778+{
5779+ int i, j, number;
5780+ VALUE buf[20];
5781+ VALUE vnumber;
5782+
5783+ rb_scan_args( argc, argv, "01", &vnumber);
5784+
5785+ number = vnumber == Qnil ? 0 : NUM2INT( vnumber );
5786+
5787+ for( i = 0, j = 0; i < 20; i++ )
5788+ {
5789+ if( g_PadState[number].button[i] == 1 )
5790+ {
5791+ buf[j++] = INT2FIX( i );
5792+ }
5793+ }
5794+
5795+ return rb_ary_new4( j, buf );
5796+}
5797+
5798+
5799+
5800+/*********************************************************************
5801+ * Fontクラス
5802+ *
5803+ * D3DXFontインターフェースを使用してフォントを描画する。
5804+ * スプライト描画に混ぜ込むことでとりあえず実装。
5805+ *********************************************************************/
5806+/*--------------------------------------------------------------------
5807+ 参照されなくなったときにGCから呼ばれる関数
5808+ ---------------------------------------------------------------------*/
5809+static void release_Font( struct DXRubyFont* font )
5810+{
5811+ /* フォントオブジェクトの開放 */
5812+ if( font )
5813+ {
5814+ RELEASE( font->pD3DXFont );
5815+ if( font->hFont != NULL )
5816+ {
5817+ DeleteObject( font->hFont );
5818+ }
5819+ free( font );
5820+ font = NULL;
5821+
5822+ g_iRefAll--;
5823+ if( g_iRefAll == 0 )
5824+ {
5825+ CoUninitialize();
5826+ }
5827+ }
5828+}
5829+
5830+
5831+/*--------------------------------------------------------------------
5832+ Fontクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
5833+ ---------------------------------------------------------------------*/
5834+static VALUE Font_allocate( VALUE klass )
5835+{
5836+ VALUE obj;
5837+ struct DXRubyFont *font;
5838+
5839+ /* DXRubyFontのメモリ取得&Fontオブジェクト生成 */
5840+ font = malloc( sizeof(struct DXRubyFont) );
5841+ if( font == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Font_allocate" );
5842+ font->pD3DXFont = NULL;
5843+ font->hFont = NULL;
5844+ return Data_Wrap_Struct(klass, 0, release_Font, font);
5845+}
5846+
5847+
5848+/*--------------------------------------------------------------------
5849+ FontクラスのInitialize
5850+ ---------------------------------------------------------------------*/
5851+static VALUE Font_initialize( int argc, VALUE *argv, VALUE obj )
5852+{
5853+ struct DXRubyFont *font;
5854+ HRESULT hr;
5855+ D3DXFONT_DESC desc;
5856+ VALUE size, fontname, option, hash, vweight, vitalic;
5857+ LOGFONT logfont;
5858+ int weight, italic;
5859+
5860+ g_iRefAll++;
5861+
5862+ /* デバイスオブジェクトの初期化チェック */
5863+ if( g_pD3DDevice == NULL )
5864+ {
5865+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
5866+ }
5867+
5868+ rb_scan_args( argc, argv, "12", &size, &fontname, &hash );
5869+
5870+ if( hash == Qnil )
5871+ {
5872+ option = rb_hash_new();
5873+ }
5874+ else
5875+ {
5876+ Check_Type( hash, T_HASH );
5877+ option = hash;
5878+ }
5879+
5880+ vweight = hash_lookup( option, symbol_weight );
5881+ vitalic = hash_lookup( option, symbol_italic );
5882+
5883+ if( vweight == Qnil || vweight == Qfalse )
5884+ {
5885+ weight = 400;
5886+ }
5887+ else if( vweight == Qtrue )
5888+ {
5889+ weight = 1000;
5890+ }
5891+ else
5892+ {
5893+ weight = NUM2INT( vweight );
5894+ }
5895+
5896+ if( vitalic == Qnil || vitalic == Qfalse )
5897+ {
5898+ italic = FALSE;
5899+ }
5900+ else
5901+ {
5902+ italic = TRUE;
5903+ }
5904+
5905+ desc.Height = NUM2INT( size );
5906+ desc.Width = 0;
5907+ desc.Weight = weight;
5908+ desc.MipLevels = 0;
5909+ desc.Italic = italic;
5910+ desc.CharSet = DEFAULT_CHARSET;
5911+ desc.OutputPrecision = 0;
5912+ desc.Quality = DEFAULT_QUALITY;
5913+ desc.PitchAndFamily = DEFAULT_PITCH || FF_DONTCARE;
5914+
5915+ ZeroMemory( &logfont, sizeof(logfont) );
5916+ logfont.lfHeight = NUM2INT( size );
5917+ logfont.lfWidth = 0;
5918+ logfont.lfWeight = weight;
5919+ logfont.lfItalic = italic;
5920+ logfont.lfCharSet = DEFAULT_CHARSET;
5921+ logfont.lfQuality = ANTIALIASED_QUALITY;
5922+ if( fontname == Qnil )
5923+ {
5924+ lstrcpy(desc.FaceName, "");
5925+ lstrcpy(logfont.lfFaceName, "");
5926+ }
5927+ else
5928+ {
5929+ Check_Type(fontname, T_STRING);
5930+ lstrcpy(desc.FaceName, RSTRING_PTR( fontname ));
5931+ lstrcpy(logfont.lfFaceName, RSTRING_PTR( fontname ));
5932+ }
5933+
5934+ /* フォントオブジェクト取り出し */
5935+ Data_Get_Struct( obj, struct DXRubyFont, font );
5936+
5937+ hr = D3DXCreateFontIndirect( g_pD3DDevice, &desc, &font->pD3DXFont );
5938+
5939+ if( FAILED( hr ) )
5940+ {
5941+ rb_raise( eDXRubyError, "フォントの作成に失敗しました - D3DXCreateFontIndirect" );
5942+ }
5943+
5944+ font->hFont = CreateFontIndirect( &logfont );
5945+
5946+ if( font->hFont == NULL )
5947+ {
5948+ rb_raise( eDXRubyError, "フォントの作成に失敗しました - CreateFontIndirect" );
5949+ }
5950+
5951+ font->size = NUM2INT( size );
5952+
5953+ return obj;
5954+}
5955+
5956+
5957+/*--------------------------------------------------------------------
5958+ Fontクラスのinstall
5959+ ---------------------------------------------------------------------*/
5960+static VALUE Font_install( VALUE klass, VALUE vstr )
5961+{
5962+ int result;
5963+ Check_Type( vstr, T_STRING );
5964+
5965+ result = AddFontResourceEx( RSTRING_PTR( vstr ), 0x10, 0 );
5966+ if( result == 0 )
5967+ {
5968+ rb_raise( eDXRubyError, "フォントのインストールに失敗しました - Font_install" );
5969+ }
5970+
5971+ return INT2FIX( result );
5972+}
5973+
5974+
5975+/*--------------------------------------------------------------------
5976+ フォントの幅を取得する
5977+ ---------------------------------------------------------------------*/
5978+static VALUE Font_getWidth( VALUE obj, VALUE str )
5979+{
5980+ HDC hDC;
5981+ struct DXRubyFont *font;
5982+ RECT rc;
5983+
5984+ Check_Type( str, T_STRING );
5985+
5986+ /* フォントオブジェクト取り出し */
5987+ Data_Get_Struct( obj, struct DXRubyFont, font );
5988+
5989+ hDC = GetDC( g_hWnd );
5990+ if( hDC == NULL )
5991+ {
5992+ rb_raise( eDXRubyError, "DCの取得に失敗しました - GetDC" );
5993+ }
5994+
5995+ SelectObject( hDC, font->hFont );
5996+ SetRect( &rc, 0, 0, 1, 1 );
5997+ DrawText( hDC, RSTRING_PTR( str ), -1, &rc, DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_CALCRECT | DT_SINGLELINE);
5998+ ReleaseDC( g_hWnd, hDC );
5999+
6000+ return INT2FIX( rc.right );
6001+}
6002+
6003+
6004+/*--------------------------------------------------------------------
6005+ フォントのサイズを取得する
6006+ ---------------------------------------------------------------------*/
6007+static VALUE Font_getSize( VALUE obj )
6008+{
6009+ HDC hDC;
6010+ struct DXRubyFont *font;
6011+ RECT rc;
6012+
6013+ /* フォントオブジェクト取り出し */
6014+ Data_Get_Struct( obj, struct DXRubyFont, font );
6015+
6016+ return INT2FIX( font->size );
6017+}
6018+
6019+
6020+/*********************************************************************
6021+ * DXRubyInternalMarkクラス
6022+ *
6023+ * Window.draw系でImageオブジェクトを束縛しないとGCに回収されるのでその対策
6024+ *********************************************************************/
6025+/*--------------------------------------------------------------------
6026+ DXRubyInternalMarkのmark関数
6027+ ---------------------------------------------------------------------*/
6028+static void DXRubyInternalMark_mark( VALUE klass )
6029+{
6030+ int i;
6031+
6032+ for( i = 0; i < g_SpriteCount; i++ )
6033+ {
6034+ rb_gc_mark( g_SpriteList[i].sprite->value );
6035+ }
6036+}
6037+
6038+
6039+/*
6040+***************************************************************
6041+*
6042+* Global functions
6043+*
6044+***************************************************************/
6045+
6046+void Init_dxruby()
6047+{
6048+ HRESULT hr;
6049+ int i, j;
6050+
6051+ hr = CoInitialize(NULL);
6052+
6053+ if( FAILED( hr ) )
6054+ {
6055+ rb_raise( eDXRubyError, "COMの初期化に失敗しました - CoInitialize" );
6056+ }
6057+
6058+ /* インスタンスハンドル取得 */
6059+ g_hInstance = (HINSTANCE)GetModuleHandle( NULL );
6060+
6061+ /* DXRubyモジュール登録 */
6062+ mDXRuby = rb_define_module( "DXRuby" );
6063+
6064+ /* Windowモジュール登録 */
6065+ mWindow = rb_define_module_under( mDXRuby, "Window" );
6066+
6067+ /* Windowモジュールにメソッド登録 */
6068+ rb_define_singleton_method( mWindow, "loop" , Window_loop , 0 );
6069+ rb_define_singleton_method( mWindow, "draw" , Window_draw , -1 );
6070+ rb_define_singleton_method( mWindow, "draw_scale", Window_drawScale , -1 );
6071+ rb_define_singleton_method( mWindow, "drawScale", Window_drawScale , -1 );
6072+ rb_define_singleton_method( mWindow, "draw_rot" , Window_drawRot , -1 );
6073+ rb_define_singleton_method( mWindow, "drawRot" , Window_drawRot , -1 );
6074+ rb_define_singleton_method( mWindow, "draw_alpha", Window_drawAlpha , -1 );
6075+ rb_define_singleton_method( mWindow, "drawAlpha", Window_drawAlpha , -1 );
6076+ rb_define_singleton_method( mWindow, "draw_add" , Window_drawAdd , -1 );
6077+ rb_define_singleton_method( mWindow, "drawAdd" , Window_drawAdd , -1 );
6078+ rb_define_singleton_method( mWindow, "draw_sub" , Window_drawSub , -1 );
6079+ rb_define_singleton_method( mWindow, "drawSub" , Window_drawSub , -1 );
6080+ rb_define_singleton_method( mWindow, "draw_ex" , Window_drawEx , -1 );
6081+ rb_define_singleton_method( mWindow, "drawEx" , Window_drawEx , -1 );
6082+ rb_define_singleton_method( mWindow, "draw_font", Window_drawFont , -1 );
6083+ rb_define_singleton_method( mWindow, "drawFont" , Window_drawFont , -1 );
6084+ rb_define_singleton_method( mWindow, "draw_tile", Window_drawTile , -1 );
6085+ rb_define_singleton_method( mWindow, "drawTile" , Window_drawTile , -1 );
6086+ rb_define_singleton_method( mWindow, "set_viewport" , Window_setViewport , -1 );
6087+ rb_define_singleton_method( mWindow, "setViewport" , Window_setViewport , -1 );
6088+ rb_define_singleton_method( mWindow, "x" , Window_x , 0 );
6089+ rb_define_singleton_method( mWindow, "x=" , Window_setx , 1 );
6090+ rb_define_singleton_method( mWindow, "y" , Window_y , 0 );
6091+ rb_define_singleton_method( mWindow, "y=" , Window_sety , 1 );
6092+ rb_define_singleton_method( mWindow, "width" , Window_width , 0 );
6093+ rb_define_singleton_method( mWindow, "width=" , Window_setwidth , 1 );
6094+ rb_define_singleton_method( mWindow, "height" , Window_height , 0 );
6095+ rb_define_singleton_method( mWindow, "height=" , Window_setheight , 1 );
6096+ rb_define_singleton_method( mWindow, "caption" , Window_getCaption , 0 );
6097+ rb_define_singleton_method( mWindow, "caption=" , Window_setCaption , 1 );
6098+ rb_define_singleton_method( mWindow, "scale" , Window_getScale , 0 );
6099+ rb_define_singleton_method( mWindow, "scale=" , Window_setScale , 1 );
6100+ rb_define_singleton_method( mWindow, "windowed?", Window_getwindowed, 0 );
6101+ rb_define_singleton_method( mWindow, "windowed=", Window_setwindowed, 1 );
6102+ rb_define_singleton_method( mWindow, "real_fps" , Window_getrealfps , 0 );
6103+ rb_define_singleton_method( mWindow, "fps" , Window_getfps , 0 );
6104+ rb_define_singleton_method( mWindow, "fps=" , Window_setfps , 1 );
6105+ rb_define_singleton_method( mWindow, "frameskip?" , Window_getframeskip, 0 );
6106+ rb_define_singleton_method( mWindow, "frameskip=" , Window_setframeskip, 1 );
6107+ rb_define_singleton_method( mWindow, "bgcolor" , Window_getbgcolor , 0 );
6108+ rb_define_singleton_method( mWindow, "bgcolor=" , Window_setbgcolor , 1 );
6109+ rb_define_singleton_method( mWindow, "min_filter" , Window_getMinFilter , 0 );
6110+ rb_define_singleton_method( mWindow, "minFilter" , Window_getMinFilter , 0 );
6111+ rb_define_singleton_method( mWindow, "min_filter=" , Window_setMinFilter , 1 );
6112+ rb_define_singleton_method( mWindow, "minFilter=" , Window_setMinFilter , 1 );
6113+ rb_define_singleton_method( mWindow, "mag_filter" , Window_getMagFilter , 0 );
6114+ rb_define_singleton_method( mWindow, "magFilter" , Window_getMagFilter , 0 );
6115+ rb_define_singleton_method( mWindow, "mag_filter=" , Window_setMagFilter , 1 );
6116+ rb_define_singleton_method( mWindow, "magFilter=" , Window_setMagFilter , 1 );
6117+ rb_define_singleton_method( mWindow, "get_load" , Window_getload, 0 );
6118+ rb_define_singleton_method( mWindow, "getLoad" , Window_getload, 0 );
6119+ rb_define_singleton_method( mWindow, "open_filename", Window_openDialog, 2 );
6120+ rb_define_singleton_method( mWindow, "openFilename" , Window_openDialog, 2 );
6121+ rb_define_singleton_method( mWindow, "save_filename", Window_saveDialog, 2 );
6122+ rb_define_singleton_method( mWindow, "saveFilename" , Window_saveDialog, 2 );
6123+ rb_define_singleton_method( mWindow, "get_screen_shot", Window_getScreenShot, -1 );
6124+ rb_define_singleton_method( mWindow, "getScreenShot", Window_getScreenShot, -1 );
6125+ rb_define_singleton_method( mWindow, "create" , Window_create , 0 );
6126+ rb_define_singleton_method( mWindow, "update" , Window_update , 0 );
6127+ rb_define_singleton_method( mWindow, "sync" , Window_sync , 0 );
6128+ rb_define_singleton_method( mWindow, "hWnd" , Window_gethWnd, 0 );
6129+ rb_define_singleton_method( mWindow, "load_icon" , Window_loadIcon, 1 );
6130+ rb_define_singleton_method( mWindow, "loadIcon" , Window_loadIcon, 1 );
6131+// rb_define_singleton_method( mWindow, "playMovie" , Window_playMovie, 1 );
6132+ rb_define_singleton_method( mWindow, "active?" , Window_get_active, 0 );
6133+ rb_define_singleton_method( mWindow, "resize" , Window_resize , 2 );
6134+ rb_define_singleton_method( mWindow, "getScreenModes", Window_getScreenModes, 0 );
6135+ rb_define_singleton_method( mWindow, "get_screen_modes", Window_getScreenModes, 0 );
6136+
6137+
6138+ /* Imageクラス定義 */
6139+ cImage = rb_define_class_under( mDXRuby, "Image", rb_cObject );
6140+
6141+ /* Imageクラスにクラスメソッド登録*/
6142+ rb_define_singleton_method(cImage, "load", Image_load, -1);
6143+ rb_define_singleton_method(cImage, "load_to_array", Image_loadToArray, 3);
6144+ rb_define_singleton_method(cImage, "loadToArray", Image_loadToArray, 3);
6145+ rb_define_singleton_method(cImage, "create_from_array", Image_createFromArray, 3);
6146+ rb_define_singleton_method(cImage, "createFromArray", Image_createFromArray, 3);
6147+ rb_define_singleton_method(cImage, "load_from_file_in_memory", Image_loadFromFileInMemory, 1);
6148+ rb_define_singleton_method(cImage, "loadFromFileInMemory", Image_loadFromFileInMemory, 1);
6149+
6150+
6151+ /* Imageクラスにメソッド登録*/
6152+ rb_define_private_method( cImage, "initialize", Image_initialize, -1 );
6153+ rb_define_method( cImage, "width" , Image_getWidth , 0 );
6154+ rb_define_method( cImage, "height" , Image_getHeight , 0 );
6155+ rb_define_method( cImage, "width=" , Image_setWidth , 1 );
6156+ rb_define_method( cImage, "height=" , Image_setHeight , 1 );
6157+ rb_define_method( cImage, "x" , Image_getX , 0 );
6158+ rb_define_method( cImage, "y" , Image_getY , 0 );
6159+ rb_define_method( cImage, "x=" , Image_setX , 1 );
6160+ rb_define_method( cImage, "y=" , Image_setY , 1 );
6161+ rb_define_method( cImage, "texture_x" , Image_getX , 0 );
6162+ rb_define_method( cImage, "texture_y" , Image_getY , 0 );
6163+ rb_define_method( cImage, "texture_x=", Image_setX , 1 );
6164+ rb_define_method( cImage, "texture_y=", Image_setY , 1 );
6165+ rb_define_method( cImage, "[]=" , Image_setPixel , 3 );
6166+ rb_define_method( cImage, "[]" , Image_getPixel , 2 );
6167+ rb_define_method( cImage, "box" , Image_box , 5 );
6168+ rb_define_method( cImage, "box_fill" , Image_boxFill , 5 );
6169+ rb_define_method( cImage, "boxFill" , Image_boxFill , 5 );
6170+ rb_define_method( cImage, "fill" , Image_fill , 1 );
6171+ rb_define_method( cImage, "line" , Image_line , 5 );
6172+ rb_define_method( cImage, "circle" , Image_circle , 4 );
6173+ rb_define_method( cImage, "circle_fill", Image_circleFill, 4 );
6174+ rb_define_method( cImage, "circleFill", Image_circleFill, 4 );
6175+ rb_define_method( cImage, "compare" , Image_compare , 3 );
6176+ rb_define_method( cImage, "copy_rect" , Image_copyRect , -1 );
6177+ rb_define_method( cImage, "copyRect" , Image_copyRect , -1 );
6178+ rb_define_method( cImage, "draw" , Image_draw , -1 );
6179+ rb_define_method( cImage, "draw_text" , Image_drawFont , -1 );
6180+ rb_define_method( cImage, "draw_font" , Image_drawFont , -1 );
6181+ rb_define_method( cImage, "drawFont" , Image_drawFont , -1 );
6182+ rb_define_method( cImage, "save" , Image_save , -1 );
6183+ rb_define_method( cImage, "slice" , Image_slice_instance, -1);
6184+ rb_define_method( cImage, "set_color_key", Image_setColorKey , 1 );
6185+ rb_define_method( cImage, "setColorKey", Image_setColorKey , 1 );
6186+ rb_define_method( cImage, "slice_to_array", Image_sliceToArray , 2 );
6187+ rb_define_method( cImage, "sliceToArray", Image_sliceToArray , 2 );
6188+ rb_define_method( cImage, "initialize_copy", Image_initialize_copy , 1 );
6189+
6190+ /* Imageオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
6191+ rb_define_alloc_func( cImage, Image_allocate );
6192+
6193+
6194+ /* Inputモジュール登録 */
6195+ mInput = rb_define_module_under( mDXRuby, "Input" );
6196+
6197+ /* Inputモジュールにメソッド登録 */
6198+ rb_define_singleton_method( mInput, "x" , Input_x , -1 );
6199+ rb_define_singleton_method( mInput, "y" , Input_y , -1 );
6200+ rb_define_singleton_method( mInput, "set_mouse_pos" , Input_setmousepos , 2 );
6201+ rb_define_singleton_method( mInput, "setMousePos" , Input_setmousepos , 2 );
6202+ rb_define_singleton_method( mInput, "mouse_pos_x" , Input_getmouseposx , 0 );
6203+ rb_define_singleton_method( mInput, "mousePosX" , Input_getmouseposx , 0 );
6204+ rb_define_singleton_method( mInput, "mouse_pos_y" , Input_getmouseposy , 0 );
6205+ rb_define_singleton_method( mInput, "mousePosY" , Input_getmouseposy , 0 );
6206+ rb_define_singleton_method( mInput, "key_down?" , Input_keyDown , 1 );
6207+ rb_define_singleton_method( mInput, "keyDown?" , Input_keyDown , 1 );
6208+ rb_define_singleton_method( mInput, "key_push?" , Input_keyPush , 1 );
6209+ rb_define_singleton_method( mInput, "keyPush?" , Input_keyPush , 1 );
6210+ rb_define_singleton_method( mInput, "pad_down?" , Input_padDown , -1 );
6211+ rb_define_singleton_method( mInput, "padDown?" , Input_padDown , -1 );
6212+ rb_define_singleton_method( mInput, "pad_push?" , Input_padPush , -1 );
6213+ rb_define_singleton_method( mInput, "padPush?" , Input_padPush , -1 );
6214+ rb_define_singleton_method( mInput, "mouse_down?" , Input_mouseDown , 1 );
6215+ rb_define_singleton_method( mInput, "mouseDown?" , Input_mouseDown , 1 );
6216+ rb_define_singleton_method( mInput, "mouse_push?" , Input_mousePush , 1 );
6217+ rb_define_singleton_method( mInput, "mousePush?" , Input_mousePush , 1 );
6218+ rb_define_singleton_method( mInput, "mouse_enable=" , Input_enablemouse , 1 );
6219+ rb_define_singleton_method( mInput, "mouseEnable=" , Input_enablemouse , 1 );
6220+ rb_define_singleton_method( mInput, "mouse_wheel_pos", Input_getmousewheelpos, 0 );
6221+ rb_define_singleton_method( mInput, "mouseWheelPos" , Input_getmousewheelpos, 0 );
6222+ rb_define_singleton_method( mInput, "mouse_wheel_pos=", Input_setmousewheelpos, 1 );
6223+ rb_define_singleton_method( mInput, "mouseWheelPos=" , Input_setmousewheelpos, 1 );
6224+ rb_define_singleton_method( mInput, "set_config" , Input_setconfig , -1 );
6225+ rb_define_singleton_method( mInput, "setConfig" , Input_setconfig , -1 );
6226+ rb_define_singleton_method( mInput, "set_repeat" , Input_setrepeat , 2 );
6227+ rb_define_singleton_method( mInput, "setRepeat" , Input_setrepeat , 2 );
6228+ rb_define_singleton_method( mInput, "update" , Input_update , 0 );
6229+ rb_define_singleton_method( mInput, "set_key_repeat" , Input_setkeyrepeat , 3 );
6230+ rb_define_singleton_method( mInput, "setKeyRepeat" , Input_setkeyrepeat , 3 );
6231+ rb_define_singleton_method( mInput, "set_pad_repeat" , Input_setpadrepeat , -1 );
6232+ rb_define_singleton_method( mInput, "setPadRepeat" , Input_setpadrepeat , -1 );
6233+ rb_define_singleton_method( mInput, "keys" , Input_getKeys , 0 );
6234+ rb_define_singleton_method( mInput, "pads" , Input_getPads , -1 );
6235+
6236+
6237+ /* Fontクラス登録 */
6238+ cFont = rb_define_class_under( mDXRuby, "Font", rb_cObject );
6239+
6240+ /* Fontクラスにクラスメソッド登録*/
6241+ rb_define_singleton_method(cFont, "install", Font_install, 1);
6242+
6243+ /* Fontクラスにメソッド登録*/
6244+ rb_define_private_method( cFont, "initialize", Font_initialize, -1 );
6245+ rb_define_method( cFont, "get_width" , Font_getWidth , 1 );
6246+ rb_define_method( cFont, "getWidth" , Font_getWidth , 1 );
6247+ rb_define_method( cFont, "size" , Font_getSize , 0 );
6248+
6249+ /* Fontオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
6250+ rb_define_alloc_func( cFont, Font_allocate );
6251+
6252+
6253+ /* Soundクラス定義 */
6254+ cSound = rb_define_class_under( mDXRuby, "Sound", rb_cObject );
6255+
6256+ /* Soundクラスにメソッド登録*/
6257+ rb_define_private_method( cSound, "initialize" , Sound_initialize , 1 );
6258+ rb_define_method( cSound, "play" , Sound_play , 0 );
6259+ rb_define_method( cSound, "stop" , Sound_stop , 0 );
6260+ rb_define_method( cSound, "set_volume" , Sound_setVolume , -1 );
6261+ rb_define_method( cSound, "setVolume" , Sound_setVolume , -1 );
6262+ rb_define_method( cSound, "start=" , Sound_setStart , 1 );
6263+ rb_define_method( cSound, "loop_start=" , Sound_setLoopStart , 1 );
6264+ rb_define_method( cSound, "loopStart=" , Sound_setLoopStart , 1 );
6265+ rb_define_method( cSound, "loop_end=" , Sound_setLoopEnd , 1 );
6266+ rb_define_method( cSound, "loopEnd=" , Sound_setLoopEnd , 1 );
6267+ rb_define_method( cSound, "loop_count=" , Sound_setLoopCount , 1 );
6268+ rb_define_method( cSound, "loopCount=" , Sound_setLoopCount , 1 );
6269+
6270+ /* Soundオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
6271+ rb_define_alloc_func( cSound, Sound_allocate );
6272+
6273+
6274+ /* SoundEffectクラス定義 */
6275+ cSoundEffect = rb_define_class_under( mDXRuby, "SoundEffect", rb_cObject );
6276+
6277+ /* SoundEffectクラスにメソッド登録*/
6278+ rb_define_private_method( cSoundEffect, "initialize", SoundEffect_initialize, -1 );
6279+ rb_define_method( cSoundEffect, "play" , SoundEffect_play , 0 );
6280+ rb_define_method( cSoundEffect, "stop" , SoundEffect_stop , 0 );
6281+ rb_define_method( cSoundEffect, "add" , SoundEffect_add , -1 );
6282+
6283+ /* SoundEffectオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
6284+ rb_define_alloc_func( cSoundEffect, SoundEffect_allocate );
6285+
6286+
6287+ /* DXRubyInternalMarkクラス定義 */
6288+ cDXRubyInternalMark = rb_define_class_under( mDXRuby, "DXRubyInternalMark", rb_cObject );
6289+ oDXRubyInternalMark = Data_Wrap_Struct(cDXRubyInternalMark, DXRubyInternalMark_mark, 0, 0);
6290+ rb_global_variable( &oDXRubyInternalMark );
6291+
6292+
6293+ /* キーボードのスキャンコード定数設定 */
6294+ rb_define_const( mDXRuby, "K_ESCAPE" , INT2FIX(DIK_ESCAPE) );
6295+ rb_define_const( mDXRuby, "K_1" , INT2FIX(DIK_1) );
6296+ rb_define_const( mDXRuby, "K_2" , INT2FIX(DIK_2) );
6297+ rb_define_const( mDXRuby, "K_3" , INT2FIX(DIK_3) );
6298+ rb_define_const( mDXRuby, "K_4" , INT2FIX(DIK_4) );
6299+ rb_define_const( mDXRuby, "K_5" , INT2FIX(DIK_5) );
6300+ rb_define_const( mDXRuby, "K_6" , INT2FIX(DIK_6) );
6301+ rb_define_const( mDXRuby, "K_7" , INT2FIX(DIK_7) );
6302+ rb_define_const( mDXRuby, "K_8" , INT2FIX(DIK_8) );
6303+ rb_define_const( mDXRuby, "K_9" , INT2FIX(DIK_9) );
6304+ rb_define_const( mDXRuby, "K_0" , INT2FIX(DIK_0) );
6305+ rb_define_const( mDXRuby, "K_MINUS" , INT2FIX(DIK_MINUS) );
6306+ rb_define_const( mDXRuby, "K_EQUALS" , INT2FIX(DIK_EQUALS) );
6307+ rb_define_const( mDXRuby, "K_BACK" , INT2FIX(DIK_BACK) );
6308+ rb_define_const( mDXRuby, "K_TAB" , INT2FIX(DIK_TAB) );
6309+ rb_define_const( mDXRuby, "K_Q" , INT2FIX(DIK_Q) );
6310+ rb_define_const( mDXRuby, "K_W" , INT2FIX(DIK_W) );
6311+ rb_define_const( mDXRuby, "K_E" , INT2FIX(DIK_E) );
6312+ rb_define_const( mDXRuby, "K_R" , INT2FIX(DIK_R) );
6313+ rb_define_const( mDXRuby, "K_T" , INT2FIX(DIK_T) );
6314+ rb_define_const( mDXRuby, "K_Y" , INT2FIX(DIK_Y) );
6315+ rb_define_const( mDXRuby, "K_U" , INT2FIX(DIK_U) );
6316+ rb_define_const( mDXRuby, "K_I" , INT2FIX(DIK_I) );
6317+ rb_define_const( mDXRuby, "K_O" , INT2FIX(DIK_O) );
6318+ rb_define_const( mDXRuby, "K_P" , INT2FIX(DIK_P) );
6319+ rb_define_const( mDXRuby, "K_LBRACKET" , INT2FIX(DIK_LBRACKET) );
6320+ rb_define_const( mDXRuby, "K_RBRACKET" , INT2FIX(DIK_RBRACKET) );
6321+ rb_define_const( mDXRuby, "K_RETURN" , INT2FIX(DIK_RETURN) );
6322+ rb_define_const( mDXRuby, "K_LCONTROL" , INT2FIX(DIK_LCONTROL) );
6323+ rb_define_const( mDXRuby, "K_A" , INT2FIX(DIK_A) );
6324+ rb_define_const( mDXRuby, "K_S" , INT2FIX(DIK_S) );
6325+ rb_define_const( mDXRuby, "K_D" , INT2FIX(DIK_D) );
6326+ rb_define_const( mDXRuby, "K_F" , INT2FIX(DIK_F) );
6327+ rb_define_const( mDXRuby, "K_G" , INT2FIX(DIK_G) );
6328+ rb_define_const( mDXRuby, "K_H" , INT2FIX(DIK_H) );
6329+ rb_define_const( mDXRuby, "K_J" , INT2FIX(DIK_J) );
6330+ rb_define_const( mDXRuby, "K_K" , INT2FIX(DIK_K) );
6331+ rb_define_const( mDXRuby, "K_L" , INT2FIX(DIK_L) );
6332+ rb_define_const( mDXRuby, "K_SEMICOLON" , INT2FIX(DIK_SEMICOLON) );
6333+ rb_define_const( mDXRuby, "K_APOSTROPHE" , INT2FIX(DIK_APOSTROPHE) );
6334+ rb_define_const( mDXRuby, "K_GRAVE" , INT2FIX(DIK_GRAVE) );
6335+ rb_define_const( mDXRuby, "K_LSHIFT" , INT2FIX(DIK_LSHIFT) );
6336+ rb_define_const( mDXRuby, "K_BACKSLASH" , INT2FIX(DIK_BACKSLASH) );
6337+ rb_define_const( mDXRuby, "K_Z" , INT2FIX(DIK_Z) );
6338+ rb_define_const( mDXRuby, "K_X" , INT2FIX(DIK_X) );
6339+ rb_define_const( mDXRuby, "K_C" , INT2FIX(DIK_C) );
6340+ rb_define_const( mDXRuby, "K_V" , INT2FIX(DIK_V) );
6341+ rb_define_const( mDXRuby, "K_B" , INT2FIX(DIK_B) );
6342+ rb_define_const( mDXRuby, "K_N" , INT2FIX(DIK_N) );
6343+ rb_define_const( mDXRuby, "K_M" , INT2FIX(DIK_M) );
6344+ rb_define_const( mDXRuby, "K_COMMA" , INT2FIX(DIK_COMMA) );
6345+ rb_define_const( mDXRuby, "K_PERIOD" , INT2FIX(DIK_PERIOD) );
6346+ rb_define_const( mDXRuby, "K_SLASH" , INT2FIX(DIK_SLASH) );
6347+ rb_define_const( mDXRuby, "K_RSHIFT" , INT2FIX(DIK_RSHIFT) );
6348+ rb_define_const( mDXRuby, "K_MULTIPLY" , INT2FIX(DIK_MULTIPLY) );
6349+ rb_define_const( mDXRuby, "K_LMENU" , INT2FIX(DIK_LMENU) );
6350+ rb_define_const( mDXRuby, "K_SPACE" , INT2FIX(DIK_SPACE) );
6351+ rb_define_const( mDXRuby, "K_CAPITAL" , INT2FIX(DIK_CAPITAL) );
6352+ rb_define_const( mDXRuby, "K_F1" , INT2FIX(DIK_F1) );
6353+ rb_define_const( mDXRuby, "K_F2" , INT2FIX(DIK_F2) );
6354+ rb_define_const( mDXRuby, "K_F3" , INT2FIX(DIK_F3) );
6355+ rb_define_const( mDXRuby, "K_F4" , INT2FIX(DIK_F4) );
6356+ rb_define_const( mDXRuby, "K_F5" , INT2FIX(DIK_F5) );
6357+ rb_define_const( mDXRuby, "K_F6" , INT2FIX(DIK_F6) );
6358+ rb_define_const( mDXRuby, "K_F7" , INT2FIX(DIK_F7) );
6359+ rb_define_const( mDXRuby, "K_F8" , INT2FIX(DIK_F8) );
6360+ rb_define_const( mDXRuby, "K_F9" , INT2FIX(DIK_F9) );
6361+ rb_define_const( mDXRuby, "K_F10" , INT2FIX(DIK_F10) );
6362+ rb_define_const( mDXRuby, "K_NUMLOCK" , INT2FIX(DIK_NUMLOCK) );
6363+ rb_define_const( mDXRuby, "K_SCROLL" , INT2FIX(DIK_SCROLL) );
6364+ rb_define_const( mDXRuby, "K_NUMPAD7" , INT2FIX(DIK_NUMPAD7) );
6365+ rb_define_const( mDXRuby, "K_NUMPAD8" , INT2FIX(DIK_NUMPAD8) );
6366+ rb_define_const( mDXRuby, "K_NUMPAD9" , INT2FIX(DIK_NUMPAD9) );
6367+ rb_define_const( mDXRuby, "K_SUBTRACT" , INT2FIX(DIK_SUBTRACT) );
6368+ rb_define_const( mDXRuby, "K_NUMPAD4" , INT2FIX(DIK_NUMPAD4) );
6369+ rb_define_const( mDXRuby, "K_NUMPAD5" , INT2FIX(DIK_NUMPAD5) );
6370+ rb_define_const( mDXRuby, "K_NUMPAD6" , INT2FIX(DIK_NUMPAD6) );
6371+ rb_define_const( mDXRuby, "K_ADD" , INT2FIX(DIK_ADD) );
6372+ rb_define_const( mDXRuby, "K_NUMPAD1" , INT2FIX(DIK_NUMPAD1) );
6373+ rb_define_const( mDXRuby, "K_NUMPAD2" , INT2FIX(DIK_NUMPAD2) );
6374+ rb_define_const( mDXRuby, "K_NUMPAD3" , INT2FIX(DIK_NUMPAD3) );
6375+ rb_define_const( mDXRuby, "K_NUMPAD0" , INT2FIX(DIK_NUMPAD0) );
6376+ rb_define_const( mDXRuby, "K_DECIMAL" , INT2FIX(DIK_DECIMAL) );
6377+ rb_define_const( mDXRuby, "K_OEM_102" , INT2FIX(DIK_OEM_102) );
6378+ rb_define_const( mDXRuby, "K_F11" , INT2FIX(DIK_F11) );
6379+ rb_define_const( mDXRuby, "K_F12" , INT2FIX(DIK_F12) );
6380+ rb_define_const( mDXRuby, "K_F13" , INT2FIX(DIK_F13) );
6381+ rb_define_const( mDXRuby, "K_F14" , INT2FIX(DIK_F14) );
6382+ rb_define_const( mDXRuby, "K_F15" , INT2FIX(DIK_F15) );
6383+ rb_define_const( mDXRuby, "K_KANA" , INT2FIX(DIK_KANA) );
6384+ rb_define_const( mDXRuby, "K_ABNT_C1" , INT2FIX(DIK_ABNT_C1) );
6385+ rb_define_const( mDXRuby, "K_CONVERT" , INT2FIX(DIK_CONVERT) );
6386+ rb_define_const( mDXRuby, "K_NOCONVERT" , INT2FIX(DIK_NOCONVERT) );
6387+ rb_define_const( mDXRuby, "K_YEN" , INT2FIX(DIK_YEN) );
6388+ rb_define_const( mDXRuby, "K_ABNT_C2" , INT2FIX(DIK_ABNT_C2) );
6389+ rb_define_const( mDXRuby, "K_NUMPADEQUALS", INT2FIX(DIK_NUMPADEQUALS) );
6390+ rb_define_const( mDXRuby, "K_PREVTRACK" , INT2FIX(DIK_PREVTRACK) );
6391+ rb_define_const( mDXRuby, "K_AT" , INT2FIX(DIK_AT) );
6392+ rb_define_const( mDXRuby, "K_COLON" , INT2FIX(DIK_COLON) );
6393+ rb_define_const( mDXRuby, "K_UNDERLINE" , INT2FIX(DIK_UNDERLINE) );
6394+ rb_define_const( mDXRuby, "K_KANJI" , INT2FIX(DIK_KANJI) );
6395+ rb_define_const( mDXRuby, "K_STOP" , INT2FIX(DIK_STOP) );
6396+ rb_define_const( mDXRuby, "K_AX" , INT2FIX(DIK_AX) );
6397+ rb_define_const( mDXRuby, "K_UNLABELED" , INT2FIX(DIK_UNLABELED) );
6398+ rb_define_const( mDXRuby, "K_NEXTTRACK" , INT2FIX(DIK_NEXTTRACK) );
6399+ rb_define_const( mDXRuby, "K_NUMPADENTER", INT2FIX(DIK_NUMPADENTER) );
6400+ rb_define_const( mDXRuby, "K_RCONTROL" , INT2FIX(DIK_RCONTROL) );
6401+ rb_define_const( mDXRuby, "K_MUTE" , INT2FIX(DIK_MUTE) );
6402+ rb_define_const( mDXRuby, "K_CALCULATOR" , INT2FIX(DIK_CALCULATOR) );
6403+ rb_define_const( mDXRuby, "K_PLAYPAUSE" , INT2FIX(DIK_PLAYPAUSE) );
6404+ rb_define_const( mDXRuby, "K_MEDIASTOP" , INT2FIX(DIK_MEDIASTOP) );
6405+ rb_define_const( mDXRuby, "K_VOLUMEDOWN" , INT2FIX(DIK_VOLUMEDOWN) );
6406+ rb_define_const( mDXRuby, "K_VOLUMEUP" , INT2FIX(DIK_VOLUMEUP) );
6407+ rb_define_const( mDXRuby, "K_WEBHOME" , INT2FIX(DIK_WEBHOME) );
6408+ rb_define_const( mDXRuby, "K_NUMPADCOMMA", INT2FIX(DIK_NUMPADCOMMA) );
6409+ rb_define_const( mDXRuby, "K_DIVIDE" , INT2FIX(DIK_DIVIDE) );
6410+ rb_define_const( mDXRuby, "K_SYSRQ" , INT2FIX(DIK_SYSRQ) );
6411+ rb_define_const( mDXRuby, "K_RMENU" , INT2FIX(DIK_RMENU) );
6412+ rb_define_const( mDXRuby, "K_PAUSE" , INT2FIX(DIK_PAUSE) );
6413+ rb_define_const( mDXRuby, "K_HOME" , INT2FIX(DIK_HOME) );
6414+ rb_define_const( mDXRuby, "K_UP" , INT2FIX(DIK_UP) );
6415+ rb_define_const( mDXRuby, "K_PRIOR" , INT2FIX(DIK_PRIOR) );
6416+ rb_define_const( mDXRuby, "K_LEFT" , INT2FIX(DIK_LEFT) );
6417+ rb_define_const( mDXRuby, "K_RIGHT" , INT2FIX(DIK_RIGHT) );
6418+ rb_define_const( mDXRuby, "K_END" , INT2FIX(DIK_END) );
6419+ rb_define_const( mDXRuby, "K_DOWN" , INT2FIX(DIK_DOWN) );
6420+ rb_define_const( mDXRuby, "K_NEXT" , INT2FIX(DIK_NEXT) );
6421+ rb_define_const( mDXRuby, "K_INSERT" , INT2FIX(DIK_INSERT) );
6422+ rb_define_const( mDXRuby, "K_DELETE" , INT2FIX(DIK_DELETE) );
6423+ rb_define_const( mDXRuby, "K_LWIN" , INT2FIX(DIK_LWIN) );
6424+ rb_define_const( mDXRuby, "K_RWIN" , INT2FIX(DIK_RWIN) );
6425+ rb_define_const( mDXRuby, "K_APPS" , INT2FIX(DIK_APPS) );
6426+ rb_define_const( mDXRuby, "K_POWER" , INT2FIX(DIK_POWER) );
6427+ rb_define_const( mDXRuby, "K_SLEEP" , INT2FIX(DIK_SLEEP) );
6428+ rb_define_const( mDXRuby, "K_WAKE" , INT2FIX(DIK_WAKE) );
6429+ rb_define_const( mDXRuby, "K_WEBSEARCH" , INT2FIX(DIK_WEBSEARCH) );
6430+ rb_define_const( mDXRuby, "K_WEBFAVORITES", INT2FIX(DIK_WEBFAVORITES) );
6431+ rb_define_const( mDXRuby, "K_WEBREFRESH" , INT2FIX(DIK_WEBREFRESH) );
6432+ rb_define_const( mDXRuby, "K_WEBSTOP" , INT2FIX(DIK_WEBSTOP) );
6433+ rb_define_const( mDXRuby, "K_WEBFORWARD" , INT2FIX(DIK_WEBFORWARD) );
6434+ rb_define_const( mDXRuby, "K_WEBBACK" , INT2FIX(DIK_WEBBACK) );
6435+ rb_define_const( mDXRuby, "K_MYCOMPUTER" , INT2FIX(DIK_MYCOMPUTER) );
6436+ rb_define_const( mDXRuby, "K_MAIL" , INT2FIX(DIK_MAIL) );
6437+ rb_define_const( mDXRuby, "K_MEDIASELECT", INT2FIX(DIK_MEDIASELECT) );
6438+ rb_define_const( mDXRuby, "K_BACKSPACE" , INT2FIX(DIK_BACK) );
6439+ rb_define_const( mDXRuby, "K_NUMPADSTAR" , INT2FIX(DIK_MULTIPLY) );
6440+ rb_define_const( mDXRuby, "K_LALT" , INT2FIX(DIK_LMENU) );
6441+ rb_define_const( mDXRuby, "K_CAPSLOCK" , INT2FIX(DIK_CAPITAL) );
6442+ rb_define_const( mDXRuby, "K_NUMPADMINUS", INT2FIX(DIK_SUBTRACT) );
6443+ rb_define_const( mDXRuby, "K_NUMPADPLUS" , INT2FIX(DIK_ADD) );
6444+ rb_define_const( mDXRuby, "K_NUMPADPERIOD", INT2FIX(DIK_DECIMAL) );
6445+ rb_define_const( mDXRuby, "K_NUMPADSLASH", INT2FIX(DIK_DIVIDE) );
6446+ rb_define_const( mDXRuby, "K_RALT" , INT2FIX(DIK_RMENU) );
6447+ rb_define_const( mDXRuby, "K_UPARROW" , INT2FIX(DIK_UP) );
6448+ rb_define_const( mDXRuby, "K_PGUP" , INT2FIX(DIK_PRIOR) );
6449+ rb_define_const( mDXRuby, "K_LEFTARROW" , INT2FIX(DIK_LEFT) );
6450+ rb_define_const( mDXRuby, "K_RIGHTARROW" , INT2FIX(DIK_RIGHT) );
6451+ rb_define_const( mDXRuby, "K_DOWNARROW" , INT2FIX(DIK_DOWN) );
6452+ rb_define_const( mDXRuby, "K_PGDN" , INT2FIX(DIK_NEXT) );
6453+
6454+ rb_define_const( mDXRuby, "P_UP" , INT2FIX(P_UP) );
6455+ rb_define_const( mDXRuby, "P_LEFT" , INT2FIX(P_LEFT) );
6456+ rb_define_const( mDXRuby, "P_RIGHT" , INT2FIX(P_RIGHT) );
6457+ rb_define_const( mDXRuby, "P_DOWN" , INT2FIX(P_DOWN) );
6458+ rb_define_const( mDXRuby, "P_BUTTON0" , INT2FIX(P_BUTTON0) );
6459+ rb_define_const( mDXRuby, "P_BUTTON1" , INT2FIX(P_BUTTON1) );
6460+ rb_define_const( mDXRuby, "P_BUTTON2" , INT2FIX(P_BUTTON2) );
6461+ rb_define_const( mDXRuby, "P_BUTTON3" , INT2FIX(P_BUTTON3) );
6462+ rb_define_const( mDXRuby, "P_BUTTON4" , INT2FIX(P_BUTTON4) );
6463+ rb_define_const( mDXRuby, "P_BUTTON5" , INT2FIX(P_BUTTON5) );
6464+ rb_define_const( mDXRuby, "P_BUTTON6" , INT2FIX(P_BUTTON6) );
6465+ rb_define_const( mDXRuby, "P_BUTTON7" , INT2FIX(P_BUTTON7) );
6466+ rb_define_const( mDXRuby, "P_BUTTON8" , INT2FIX(P_BUTTON8) );
6467+ rb_define_const( mDXRuby, "P_BUTTON9" , INT2FIX(P_BUTTON9) );
6468+ rb_define_const( mDXRuby, "P_BUTTON10" , INT2FIX(P_BUTTON10) );
6469+ rb_define_const( mDXRuby, "P_BUTTON11" , INT2FIX(P_BUTTON11) );
6470+ rb_define_const( mDXRuby, "P_BUTTON12" , INT2FIX(P_BUTTON12) );
6471+ rb_define_const( mDXRuby, "P_BUTTON13" , INT2FIX(P_BUTTON13) );
6472+ rb_define_const( mDXRuby, "P_BUTTON14" , INT2FIX(P_BUTTON14) );
6473+ rb_define_const( mDXRuby, "P_BUTTON15" , INT2FIX(P_BUTTON15) );
6474+
6475+ rb_define_const( mDXRuby, "M_LBUTTON" , INT2FIX(M_LBUTTON) );
6476+ rb_define_const( mDXRuby, "M_RBUTTON" , INT2FIX(M_RBUTTON) );
6477+ rb_define_const( mDXRuby, "M_MBUTTON" , INT2FIX(M_MBUTTON) );
6478+
6479+ rb_define_const( mDXRuby, "FORMAT_JPEG" , INT2FIX(FORMAT_JPEG));
6480+ rb_define_const( mDXRuby, "FORMAT_JPG" , INT2FIX(FORMAT_JPG) );
6481+// rb_define_const( mDXRuby, "FORMAT_PNG" , INT2FIX(FORMAT_PNG) );
6482+ rb_define_const( mDXRuby, "FORMAT_BMP" , INT2FIX(FORMAT_BMP) );
6483+ rb_define_const( mDXRuby, "FORMAT_DDS" , INT2FIX(FORMAT_DDS) );
6484+
6485+ rb_define_const( mDXRuby, "WAVE_SIN" , INT2FIX(WAVE_SIN) );
6486+ rb_define_const( mDXRuby, "WAVE_SAW" , INT2FIX(WAVE_SAW) );
6487+ rb_define_const( mDXRuby, "WAVE_TRI" , INT2FIX(WAVE_TRI) );
6488+ rb_define_const( mDXRuby, "WAVE_RECT" , INT2FIX(WAVE_RECT) );
6489+
6490+ rb_define_const( mDXRuby, "TEXF_POINT" , INT2FIX(D3DTEXF_POINT) );
6491+ rb_define_const( mDXRuby, "TEXF_LINEAR" , INT2FIX(D3DTEXF_LINEAR) );
6492+ rb_define_const( mDXRuby, "TEXF_GAUSSIANQUAD", INT2FIX(D3DTEXF_GAUSSIANQUAD) );
6493+
6494+ /* 例外定義 */
6495+ eDXRubyError = rb_define_class_under( mDXRuby, "DXRubyError", rb_eRuntimeError );
6496+
6497+ /* 定数登録 */
6498+ rb_define_const( mDXRuby, "VERSION", rb_str_new2( DXRUBY_VERSION ) );
6499+
6500+ {
6501+ VALUE temp;
6502+ temp = rb_eval_string( "$dxruby_no_include" );
6503+ if( temp == Qfalse || temp == Qnil )
6504+ {
6505+ rb_include_module( rb_cObject, mDXRuby );
6506+ }
6507+ }
6508+
6509+ /* シンボル定義 */
6510+ symbol_blend = ID2SYM(rb_intern("blend"));
6511+ symbol_angle = ID2SYM(rb_intern("angle"));
6512+ symbol_alpha = ID2SYM(rb_intern("alpha"));
6513+ symbol_scalex = ID2SYM(rb_intern("scalex"));
6514+ symbol_scaley = ID2SYM(rb_intern("scaley"));
6515+ symbol_centerx = ID2SYM(rb_intern("centerx"));
6516+ symbol_centery = ID2SYM(rb_intern("centery"));
6517+ symbol_z = ID2SYM(rb_intern("z"));
6518+ symbol_color = ID2SYM(rb_intern("color"));
6519+ symbol_add = ID2SYM(rb_intern("add"));
6520+ symbol_add2 = ID2SYM(rb_intern("add2"));
6521+ symbol_sub = ID2SYM(rb_intern("sub"));
6522+ symbol_italic = ID2SYM(rb_intern("italic"));
6523+ symbol_weight = ID2SYM(rb_intern("weight"));
6524+
6525+ /* 終了時に実行する関数 */
6526+ rb_set_end_proc( Window_shutdown, Qnil );
6527+
6528+ /* スプライト構造体の初期値設定 */
6529+ g_SpriteCount = 0;
6530+ g_SpriteAllocateCount = 128;
6531+ g_SpriteList = malloc( g_SpriteAllocateCount * sizeof(struct DXRubySpriteList) );
6532+ g_SpriteStruct = malloc( g_SpriteAllocateCount * sizeof(struct DXRubySprite) );
6533+
6534+ g_WindowInfo.width = 640;
6535+ g_WindowInfo.height = 480;
6536+ g_WindowInfo.windowed = Qtrue;
6537+ g_WindowInfo.created = Qfalse;
6538+ g_WindowInfo.scale = 1;
6539+ g_WindowInfo.enablemouse = Qtrue;
6540+ g_WindowInfo.mousewheelpos = 0;
6541+ g_WindowInfo.fps = 60;
6542+ g_WindowInfo.frameskip = Qfalse;
6543+ g_WindowInfo.r = 0;
6544+ g_WindowInfo.g = 0;
6545+ g_WindowInfo.b = 0;
6546+ g_WindowInfo.minfilter = D3DTEXF_LINEAR;
6547+ g_WindowInfo.magfilter = D3DTEXF_LINEAR;
6548+ g_WindowInfo.hIcon = 0;
6549+ g_WindowInfo.loop = 0;
6550+ g_WindowInfo.requestclose = 0;
6551+ g_WindowInfo.active = 0;
6552+
6553+ /* 割り当て初期化 */
6554+ for( i = 0; i < 256; i++)
6555+ {
6556+ g_diKeyConfig[i] = -1;
6557+ }
6558+ for( i = 0; i < PADMAX; i++)
6559+ {
6560+ for( j = 0; j < 20; j++)
6561+ {
6562+ g_PadState[i].PadConfig[j] = -1;
6563+ }
6564+ }
6565+
6566+ /* デフォルトの割り当て */
6567+ Input_SetConfig( 0, P_LEFT , DIK_LEFT );
6568+ Input_SetConfig( 0, P_RIGHT , DIK_RIGHT );
6569+ Input_SetConfig( 0, P_UP , DIK_UP );
6570+ Input_SetConfig( 0, P_DOWN , DIK_DOWN );
6571+ Input_SetConfig( 0, P_BUTTON0, DIK_Z );
6572+ Input_SetConfig( 0, P_BUTTON1, DIK_X );
6573+ Input_SetConfig( 0, P_BUTTON2, DIK_C );
6574+
6575+ /* ウィンドウ作成(この時点では非表示) */
6576+ InitWindow();
6577+
6578+ /* DirectX Graphicsの初期化 */
6579+ InitDXGraphics();
6580+
6581+ /* DirectInput初期化 */
6582+ InitDirectInput();
6583+}
6584+
6585+
6586+/*--------------------------------------------------------------------
6587+ (内部関数)ウィンドウの生成
6588+ ---------------------------------------------------------------------*/
6589+static void InitWindow( void )
6590+{
6591+ WNDCLASSEX wcex;
6592+ RECT rect;
6593+
6594+ /* ウインドウ・クラスの登録 */
6595+ wcex.cbSize = sizeof( WNDCLASSEX );
6596+ wcex.style = CS_HREDRAW | CS_VREDRAW;
6597+ wcex.lpfnWndProc = (WNDPROC)MainWndProc;
6598+ wcex.cbClsExtra = 0;
6599+ wcex.cbWndExtra = 0;
6600+ wcex.hInstance = g_hInstance;
6601+ wcex.hIcon = NULL;
6602+ wcex.hIconSm = NULL;
6603+ wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
6604+ wcex.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
6605+ wcex.lpszMenuName = NULL;
6606+ wcex.lpszClassName = "DXRuby";
6607+
6608+ if( !RegisterClassEx( &wcex ) )
6609+ {
6610+ rb_raise( eDXRubyError, "ウィンドウの初期化に失敗しました - RegusterClassEx" );
6611+ }
6612+
6613+ /* メイン・ウインドウ作成(ウインドウ・モード用) */
6614+ rect.top = 0;
6615+ rect.left = 0;
6616+ rect.right = g_WindowInfo.width;
6617+ rect.bottom = g_WindowInfo.height;
6618+
6619+ AdjustWindowRect( &rect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE );
6620+
6621+ rect.right = rect.right - rect.left;
6622+ rect.bottom = rect.bottom - rect.top;
6623+ rect.left = 0;
6624+ rect.top = 0;
6625+
6626+ g_hWnd = CreateWindow( TEXT("DXRuby"), TEXT("DXRuby Application"),
6627+ WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
6628+ CW_USEDEFAULT, CW_USEDEFAULT,
6629+ rect.right - rect.left, rect.bottom - rect.top,
6630+ NULL, NULL, g_hInstance, NULL );
6631+ if( g_hWnd == NULL )
6632+ {
6633+ rb_raise( eDXRubyError, "ウィンドウの初期化に失敗しました - CreateWindow" );
6634+ }
6635+
6636+ GetWindowRect( g_hWnd, &rect );
6637+ g_WindowInfo.x = rect.left;
6638+ g_WindowInfo.y = rect.top;
6639+
6640+ WINNLSEnableIME( g_hWnd, FALSE );
6641+}
6642+
6643+
6644+/*--------------------------------------------------------------------
6645+ (内部関数)DirectX Graphics初期化
6646+ ---------------------------------------------------------------------*/
6647+static void InitDXGraphics( void )
6648+{
6649+ D3DVIEWPORT9 vp;
6650+ HRESULT hr;
6651+
6652+ /* Direct3Dオブジェクトの作成 */
6653+ g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
6654+
6655+ if( g_pD3D == NULL )
6656+ {
6657+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - Direct3DCreate9" );
6658+ }
6659+
6660+ /* D3DDeviceオブジェクトの作成(ウインドウ・モード) */
6661+ ZeroMemory( &g_D3DPP, sizeof( g_D3DPP ) );
6662+
6663+ g_D3DPP.BackBufferWidth = 0;
6664+ g_D3DPP.BackBufferHeight = 0;
6665+ g_D3DPP.BackBufferFormat = D3DFMT_UNKNOWN;
6666+ g_D3DPP.BackBufferCount = 1;
6667+ g_D3DPP.MultiSampleType = D3DMULTISAMPLE_NONE;
6668+ g_D3DPP.MultiSampleQuality = 0;
6669+ g_D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
6670+ g_D3DPP.hDeviceWindow = g_hWnd;
6671+ g_D3DPP.Windowed = TRUE;
6672+ g_D3DPP.EnableAutoDepthStencil = FALSE;
6673+ g_D3DPP.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
6674+ g_D3DPP.Flags = 0;
6675+ g_D3DPP.FullScreen_RefreshRateInHz = 0;
6676+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
6677+
6678+ hr = g_pD3D->lpVtbl->CreateDevice( g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
6679+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice );
6680+
6681+ if( FAILED( hr ) )
6682+ {
6683+ hr = g_pD3D->lpVtbl->CreateDevice( g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
6684+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice );
6685+
6686+ if( FAILED( hr ) )
6687+ {
6688+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - CreateDevice" );
6689+ }
6690+ }
6691+
6692+ /* ビューポートの設定 */
6693+ vp.X = 0;
6694+ vp.Y = 0;
6695+ vp.Width = g_D3DPP.BackBufferWidth;
6696+ vp.Height = g_D3DPP.BackBufferHeight;
6697+ vp.MinZ = 0.0f;
6698+ vp.MaxZ = 1.0f;
6699+
6700+ hr = g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
6701+
6702+ if( FAILED( hr ) )
6703+ {
6704+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - SetViewport" );
6705+ }
6706+
6707+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
6708+ D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
6709+
6710+ /* スプライトオブジェクト作成 */
6711+ hr = D3DXCreateSprite( g_pD3DDevice, &g_pD3DXSprite );
6712+
6713+ if( FAILED( hr ) )
6714+ {
6715+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - CreateSprite" );
6716+ }
6717+}
6718+
6719+
6720+/*--------------------------------------------------------------------
6721+ (内部関数)フレーム調整初期化
6722+ ---------------------------------------------------------------------*/
6723+static void InitSync( void )
6724+{
6725+ timeBeginPeriod( 1 );
6726+
6727+ /* パフォーマンスカウンタの秒間カウント値取得 */
6728+ if( QueryPerformanceFrequency( (LARGE_INTEGER *)&g_OneSecondCount ) )
6729+ {
6730+ /* パフォーマンスカウンタがある場合 */
6731+ g_isPerformanceCounter = 1;
6732+ QueryPerformanceCounter( (LARGE_INTEGER *)&g_OldTime );
6733+ }
6734+ else
6735+ {
6736+ /* パフォーマンスカウンタが無い場合 */
6737+ g_isPerformanceCounter = 0;
6738+ g_OneSecondCount = 1000;
6739+ g_OldTime = timeGetTime();
6740+ }
6741+}
6742+
6743+
6744+/* デバイス列挙関数 */
6745+BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, void* pContext )
6746+{
6747+ HRESULT hr;
6748+
6749+ /* 列挙されたジョイスティックへのインターフェイスを取得する */
6750+ hr = g_pDInput->lpVtbl->CreateDevice( g_pDInput,
6751+ &pdidInstance->guidInstance,
6752+ &g_pDIDJoyPad[g_JoystickCount],
6753+ NULL );
6754+ if( SUCCEEDED( hr ) )
6755+ {
6756+ return (++g_JoystickCount == PADMAX)?(DIENUM_STOP):(DIENUM_CONTINUE);
6757+ }
6758+
6759+ return DIENUM_STOP;
6760+}
6761+
6762+/* オブジェクト(軸)列挙関数 */
6763+BOOL CALLBACK EnumAxisCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, void *pContext )
6764+{
6765+ HRESULT hr;
6766+ DIPROPRANGE diprg = { sizeof(DIPROPRANGE), sizeof(DIPROPHEADER) };
6767+ struct DXRubyPadInfo *pad;
6768+
6769+ pad = (struct DXRubyPadInfo *)pContext;
6770+
6771+ diprg.diph.dwHow = DIPH_BYID;
6772+ diprg.diph.dwObj = pdidoi->dwType;
6773+
6774+ /*========================================================*/
6775+ /* 取得 */
6776+ hr = pad->pDIDJoyPad->lpVtbl->GetProperty( pad->pDIDJoyPad, DIPROP_RANGE, &diprg.diph );
6777+
6778+ if( FAILED( hr ) )
6779+ {
6780+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - GetProperty" );
6781+ }
6782+
6783+ /* x軸 */
6784+ if( memcmp( &pdidoi->guidType, &GUID_XAxis ,sizeof(GUID)) == 0 )
6785+ {
6786+ int xcenter;
6787+ xcenter = (diprg.lMin + diprg.lMax) / 2;
6788+ pad->left = (xcenter - diprg.lMin) / 2;
6789+ pad->right = (diprg.lMax - xcenter) / 2 + xcenter;
6790+ }
6791+
6792+ /* y軸 */
6793+ if( memcmp( &pdidoi->guidType, &GUID_YAxis ,sizeof(GUID)) == 0 )
6794+ {
6795+ int ycenter;
6796+ ycenter = (diprg.lMin + diprg.lMax) / 2;
6797+ pad->up = (ycenter - diprg.lMin) / 2;
6798+ pad->down = (diprg.lMax - ycenter) / 2 + ycenter;
6799+ }
6800+
6801+ return DIENUM_CONTINUE;
6802+}
6803+
6804+/*--------------------------------------------------------------------
6805+ (内部関数)DirectInput初期化
6806+ ---------------------------------------------------------------------*/
6807+static void InitDirectInput( void )
6808+{
6809+ HRESULT hr;
6810+ int i;
6811+
6812+/* DirectInput初期化 */
6813+
6814+ /* DirectInputオブジェクトの作成 */
6815+ hr = DirectInput8Create( g_hInstance, DIRECTINPUT_VERSION,
6816+ &IID_IDirectInput8, (void **)&g_pDInput, NULL );
6817+
6818+ if( FAILED( hr ) )
6819+ {
6820+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - DirectInput8Create" );
6821+ }
6822+
6823+/* キーボード */
6824+
6825+ /* デバイス・オブジェクトを作成(キーボード) */
6826+ hr = g_pDInput->lpVtbl->CreateDevice( g_pDInput, &GUID_SysKeyboard, &g_pDIDKeyBoard, NULL );
6827+
6828+ if( FAILED( hr ) )
6829+ {
6830+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - CreateDevice" );
6831+ }
6832+
6833+ /* データ形式を設定(キーボードですよ) */
6834+ hr = g_pDIDKeyBoard->lpVtbl->SetDataFormat( g_pDIDKeyBoard, &c_dfDIKeyboard );
6835+
6836+ if( FAILED( hr ) )
6837+ {
6838+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetDataFormat" );
6839+ }
6840+
6841+ /* キーボードのモードを設定(フォアグラウンド&非排他モード) */
6842+ hr = g_pDIDKeyBoard->lpVtbl->SetCooperativeLevel( g_pDIDKeyBoard, g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
6843+
6844+ if( FAILED( hr ) )
6845+ {
6846+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetCooperativeLevel" );
6847+ }
6848+
6849+ /* 入力制御開始 */
6850+ g_pDIDKeyBoard->lpVtbl->Acquire( g_pDIDKeyBoard );
6851+
6852+
6853+/* ゲームパッド */
6854+
6855+ for( i = 0; i < PADMAX; i++)
6856+ {
6857+ g_pDIDJoyPad[i] = NULL;
6858+ }
6859+ g_JoystickCount = 0;
6860+
6861+ /* ゲームデバイス列挙 */
6862+ hr = g_pDInput->lpVtbl->EnumDevices( g_pDInput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY );
6863+
6864+ if( FAILED( hr ) )
6865+ {
6866+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - EnumDevices" );
6867+ }
6868+
6869+ /* ゲームデバイス初期化 */
6870+ for ( i = 0; i < g_JoystickCount; i++ )
6871+ {
6872+ /* データ形式を設定 */
6873+ hr = g_pDIDJoyPad[i]->lpVtbl->SetDataFormat( g_pDIDJoyPad[i], &c_dfDIJoystick );
6874+
6875+ if( FAILED( hr ) )
6876+ {
6877+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetDataFormat" );
6878+ }
6879+
6880+ /* キーボードのモードを設定(フォアグラウンド&非排他モード) */
6881+ hr = g_pDIDJoyPad[i]->lpVtbl->SetCooperativeLevel( g_pDIDJoyPad[i], g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
6882+
6883+ if( FAILED( hr ) )
6884+ {
6885+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetCooperativeLevel" );
6886+ }
6887+
6888+ /* オブジェクト列挙 */
6889+ g_PadInfo[i].pDIDJoyPad = g_pDIDJoyPad[i];
6890+ hr = g_pDIDJoyPad[i]->lpVtbl->EnumObjects( g_pDIDJoyPad[i], EnumAxisCallback, &g_PadInfo[i], DIDFT_AXIS );
6891+
6892+ if( FAILED( hr ) )
6893+ {
6894+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - EnumObjects" );
6895+ }
6896+
6897+ /* 入力制御開始 */
6898+ g_pDIDJoyPad[i]->lpVtbl->Acquire( g_pDIDJoyPad[i] );
6899+ }
6900+
6901+}
6902+
6903+
6904+
6905+
6906+static void AllocSpriteList( void )
6907+{
6908+ int i;
6909+
6910+ if( g_SpriteCount >= g_SpriteAllocateCount )
6911+ {
6912+ g_SpriteAllocateCount = g_SpriteAllocateCount * 3 / 2; /* 1.5倍にする */
6913+ g_SpriteList = realloc(g_SpriteList, g_SpriteAllocateCount * sizeof(struct DXRubySpriteList) );
6914+ g_SpriteStruct = realloc(g_SpriteStruct, g_SpriteAllocateCount * sizeof(struct DXRubySprite) );
6915+ for( i = 0; i < g_SpriteCount; i++)
6916+ {
6917+ g_SpriteList[i].sprite = &g_SpriteStruct[i];
6918+ }
6919+ }
6920+}
6921+
6922+
6923+/* マージソート */
6924+void merge( struct DXRubySpriteList *list, struct DXRubySpriteList *temp, int left, int mid, int right )
6925+{
6926+ int left_end, num_elements, tmp_pos;
6927+
6928+ left_end = mid - 1;
6929+ tmp_pos = left;
6930+ num_elements = right - left + 1;
6931+
6932+ while ((left <= left_end) && (mid <= right))
6933+ {
6934+ if (list[left].z <= list[mid].z)
6935+ temp[tmp_pos++] = list[left++];
6936+ else
6937+ temp[tmp_pos++] = list[mid++];
6938+ }
6939+
6940+ while (left <= left_end)
6941+ {
6942+ temp[tmp_pos++] = list[left++];
6943+ }
6944+ while (mid <= right)
6945+ {
6946+ temp[tmp_pos++] = list[mid++];
6947+ }
6948+
6949+ while (num_elements--)
6950+ {
6951+ list[right] = temp[right--];
6952+ }
6953+}
6954+void m_sort( struct DXRubySpriteList *list, struct DXRubySpriteList *temp, int left, int right )
6955+{
6956+ int mid;
6957+
6958+ if( right > left )
6959+ {
6960+ mid = (right + left) / 2;
6961+ m_sort( list, temp, left, mid );
6962+ m_sort( list, temp, mid+1, right );
6963+
6964+ merge( list, temp, left, mid+1, right );
6965+ }
6966+}
6967+void SortSpriteList( void )
6968+{
6969+ struct DXRubySpriteList *temp;
6970+ int i;
6971+
6972+ for( i = 0; i < g_SpriteCount; i++ )
6973+ {
6974+ if( g_SpriteList[i].z != 0.0f )
6975+ {
6976+ temp = malloc( sizeof(struct DXRubySpriteList)* g_SpriteCount );
6977+ m_sort( g_SpriteList, temp, 0, g_SpriteCount - 1 );
6978+ free(temp);
6979+ break;
6980+ }
6981+ }
6982+}
6983+
6984+
6985+static VALUE hash_lookup(VALUE hash, VALUE key)
6986+{
6987+ VALUE val;
6988+
6989+ if (!RHASH_TBL(hash) || !st_lookup(RHASH_TBL(hash), key, &val)) {
6990+ return Qnil;
6991+ }
6992+ return val;
6993+}
6994+
6995+
6996+/***********************
6997+ * 外部インターフェース
6998+ ***********************/
6999+
7000+/*--------------------------------------------------------------------
7001+ 描画設定(通常描画)
7002+ ---------------------------------------------------------------------*/
7003+void DXRuby_draw( int x, int y, VALUE vimage, float z )
7004+{
7005+ struct DXRubyImage *image;
7006+
7007+ AllocSpriteList();
7008+
7009+ /* 引数のイメージオブジェクトから中身を取り出す */
7010+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7011+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7012+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7013+ {
7014+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7015+ }
7016+
7017+ /* DXRubySpriteオブジェクト設定 */
7018+ g_SpriteStruct[g_SpriteCount].image = image;
7019+ g_SpriteStruct[g_SpriteCount].x = x;
7020+ g_SpriteStruct[g_SpriteCount].y = y;
7021+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
7022+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
7023+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
7024+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
7025+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
7026+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
7027+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
7028+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7029+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7030+ g_SpriteStruct[g_SpriteCount].value = vimage;
7031+
7032+ /* リストデータに追加 */
7033+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7034+ g_SpriteList[g_SpriteCount].z = z;
7035+ g_SpriteCount++;
7036+}
7037+
7038+
7039+/*--------------------------------------------------------------------
7040+ 描画設定(拡大縮小描画) フラグは0にするとcenter無視
7041+ ---------------------------------------------------------------------*/
7042+void DXRuby_drawScale( int x, int y, VALUE vimage, float scalex, float scaley, float centerx, float centery, float z, int flag )
7043+{
7044+ struct DXRubyImage *image;
7045+
7046+ AllocSpriteList();
7047+
7048+ /* 引数のイメージオブジェクトから中身を取り出す */
7049+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7050+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7051+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7052+ {
7053+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7054+ }
7055+
7056+ /* DXRubySpriteオブジェクト設定 */
7057+ g_SpriteStruct[g_SpriteCount].image = image;
7058+ g_SpriteStruct[g_SpriteCount].x = x;
7059+ g_SpriteStruct[g_SpriteCount].y = y;
7060+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
7061+ g_SpriteStruct[g_SpriteCount].scalex = scalex;
7062+ g_SpriteStruct[g_SpriteCount].scaley = scaley;
7063+ g_SpriteStruct[g_SpriteCount].centerx = flag ? centerx :image->width / 2;
7064+ g_SpriteStruct[g_SpriteCount].centery = flag ? centery : image->height / 2;
7065+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
7066+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
7067+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7068+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7069+ g_SpriteStruct[g_SpriteCount].value = vimage;
7070+
7071+ /* リストデータに追加 */
7072+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7073+ g_SpriteList[g_SpriteCount].z = z;
7074+ g_SpriteCount++;
7075+}
7076+
7077+
7078+/*--------------------------------------------------------------------
7079+ 描画設定(回転描画) フラグは0にするとcenter無視
7080+ ---------------------------------------------------------------------*/
7081+void DXRuby_drawRot( int x, int y, VALUE vimage, float angle, int centerx, int centery, int z, int flag)
7082+{
7083+ struct DXRubyImage *image;
7084+
7085+ AllocSpriteList();
7086+
7087+ /* 引数のイメージオブジェクトから中身を取り出す */
7088+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7089+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7090+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7091+ {
7092+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7093+ }
7094+
7095+ /* DXRubySpriteオブジェクト設定 */
7096+ g_SpriteStruct[g_SpriteCount].image = image;
7097+ g_SpriteStruct[g_SpriteCount].x = x;
7098+ g_SpriteStruct[g_SpriteCount].y = y;
7099+ g_SpriteStruct[g_SpriteCount].angle = angle;
7100+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
7101+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
7102+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
7103+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
7104+ g_SpriteStruct[g_SpriteCount].centerx = flag ? centerx : image->width / 2;
7105+ g_SpriteStruct[g_SpriteCount].centery = flag ? centery : image->height / 2;
7106+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7107+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7108+ g_SpriteStruct[g_SpriteCount].value = vimage;
7109+
7110+ /* リストデータに追加 */
7111+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7112+ g_SpriteList[g_SpriteCount].z = z;
7113+ g_SpriteCount++;
7114+}
7115+
7116+
7117+/*--------------------------------------------------------------------
7118+ 描画設定(半透明描画)
7119+ ---------------------------------------------------------------------*/
7120+void DXRuby_drawAlpha( int x, int y, VALUE vimage, int alpha, int z )
7121+{
7122+ struct DXRubyImage *image;
7123+
7124+ AllocSpriteList();
7125+
7126+ /* 引数のイメージオブジェクトから中身を取り出す */
7127+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7128+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7129+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7130+ {
7131+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7132+ }
7133+
7134+ /* DXRubySpriteオブジェクト設定 */
7135+ g_SpriteStruct[g_SpriteCount].image = image;
7136+ g_SpriteStruct[g_SpriteCount].x = x;
7137+ g_SpriteStruct[g_SpriteCount].y = y;
7138+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
7139+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
7140+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
7141+ g_SpriteStruct[g_SpriteCount].alpha = alpha;
7142+ g_SpriteStruct[g_SpriteCount].blendflag = 0;
7143+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
7144+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
7145+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7146+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7147+ g_SpriteStruct[g_SpriteCount].value = vimage;
7148+
7149+ /* リストデータに追加 */
7150+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7151+ g_SpriteList[g_SpriteCount].z = z;
7152+ g_SpriteCount++;
7153+}
7154+
7155+
7156+/*--------------------------------------------------------------------
7157+ 描画設定(加算合成描画)
7158+ ---------------------------------------------------------------------*/
7159+void DXRuby_drawAdd( int x, int y, VALUE vimage, int z )
7160+{
7161+ struct DXRubyImage *image;
7162+
7163+ AllocSpriteList();
7164+
7165+ /* 引数のイメージオブジェクトから中身を取り出す */
7166+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7167+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7168+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7169+ {
7170+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7171+ }
7172+
7173+ /* DXRubySpriteオブジェクト設定 */
7174+ g_SpriteStruct[g_SpriteCount].image = image;
7175+ g_SpriteStruct[g_SpriteCount].x = x;
7176+ g_SpriteStruct[g_SpriteCount].y = y;
7177+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
7178+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
7179+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
7180+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
7181+ g_SpriteStruct[g_SpriteCount].blendflag = 4;
7182+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
7183+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
7184+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7185+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7186+ g_SpriteStruct[g_SpriteCount].value = vimage;
7187+
7188+ /* リストデータに追加 */
7189+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7190+ g_SpriteList[g_SpriteCount].z = z;
7191+ g_SpriteCount++;
7192+}
7193+
7194+
7195+/*--------------------------------------------------------------------
7196+ 描画設定(減算合成描画)
7197+ ---------------------------------------------------------------------*/
7198+void DXRuby_drawSub( int x, int y, VALUE vimage, int z )
7199+{
7200+ struct DXRubyImage *image;
7201+
7202+ AllocSpriteList();
7203+
7204+ /* 引数のイメージオブジェクトから中身を取り出す */
7205+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7206+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7207+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7208+ {
7209+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7210+ }
7211+
7212+ /* DXRubySpriteオブジェクト設定 */
7213+ g_SpriteStruct[g_SpriteCount].image = image;
7214+ g_SpriteStruct[g_SpriteCount].x = x;
7215+ g_SpriteStruct[g_SpriteCount].y = y;
7216+ g_SpriteStruct[g_SpriteCount].angle = 0.0f;
7217+ g_SpriteStruct[g_SpriteCount].scalex = 1.0f;
7218+ g_SpriteStruct[g_SpriteCount].scaley = 1.0f;
7219+ g_SpriteStruct[g_SpriteCount].alpha = 0xff;
7220+ g_SpriteStruct[g_SpriteCount].blendflag = 6;
7221+ g_SpriteStruct[g_SpriteCount].centerx = image->width / 2;
7222+ g_SpriteStruct[g_SpriteCount].centery = image->height / 2;
7223+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7224+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7225+ g_SpriteStruct[g_SpriteCount].value = vimage;
7226+
7227+ /* リストデータに追加 */
7228+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7229+ g_SpriteList[g_SpriteCount].z = z;
7230+ g_SpriteCount++;
7231+}
7232+
7233+
7234+/*--------------------------------------------------------------------
7235+ 描画設定(フルオプション)
7236+ ---------------------------------------------------------------------*/
7237+void DXRuby_drawEx( int x, int y, VALUE vimage, float angle, float scalex, float scaley, float centerx, float centery, int alpha, int blend, int z, int flag )
7238+{
7239+ struct DXRubyImage *image;
7240+ AllocSpriteList();
7241+
7242+ /* 引数のイメージオブジェクトから中身を取り出す */
7243+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7244+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7245+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7246+ {
7247+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7248+ }
7249+
7250+ /* DXRubySpriteオブジェクト設定 */
7251+ g_SpriteStruct[g_SpriteCount].image = image;
7252+ g_SpriteStruct[g_SpriteCount].x = x;
7253+ g_SpriteStruct[g_SpriteCount].y = y;
7254+ g_SpriteStruct[g_SpriteCount].angle = angle;
7255+ g_SpriteStruct[g_SpriteCount].scalex = scalex;
7256+ g_SpriteStruct[g_SpriteCount].scaley = scaley;
7257+ g_SpriteStruct[g_SpriteCount].centerx = flag ? centerx : image->width / 2;
7258+ g_SpriteStruct[g_SpriteCount].centery = flag ? centery : image->height / 2;
7259+ g_SpriteStruct[g_SpriteCount].alpha = alpha;
7260+ g_SpriteStruct[g_SpriteCount].blendflag = blend;
7261+ g_SpriteStruct[g_SpriteCount].fontflag = 0;
7262+ g_SpriteStruct[g_SpriteCount].vpflag = 0;
7263+ g_SpriteStruct[g_SpriteCount].value = vimage;
7264+
7265+ /* リストデータに追加 */
7266+ g_SpriteList[g_SpriteCount].sprite = &g_SpriteStruct[g_SpriteCount];
7267+ g_SpriteList[g_SpriteCount].z = z;
7268+ g_SpriteCount++;
7269+}
7270+
7271+
7272+/*--------------------------------------------------------------------
7273+ イメージのロック
7274+ ---------------------------------------------------------------------*/
7275+void *DXRuby_lock( VALUE vimage, char **address, int *pitch, int *width, int *height )
7276+{
7277+ struct DXRubyImage *image;
7278+ D3DLOCKED_RECT texrect;
7279+ RECT rect;
7280+
7281+ /* 引数のイメージオブジェクトから中身を取り出す */
7282+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7283+ image = (struct DXRubyImage *)DATA_PTR( vimage );
7284+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)release_Image )
7285+ {
7286+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
7287+ }
7288+
7289+ rect.left = (long)image->x;
7290+ rect.top = (long)image->y;
7291+ rect.right = (long)(image->x + image->width);
7292+ rect.bottom = (long)(image->y + image->height);
7293+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
7294+
7295+ // *((int*)((char *)texrect.pBits + x * 4 + y * texrect.Pitch)) = col;
7296+
7297+ *address = (char *)texrect.pBits;
7298+ *pitch = texrect.Pitch;
7299+ *width = (int)image->width;
7300+ *height = (int)image->height;
7301+
7302+ return image->texture->pD3DTexture;
7303+}
7304+
7305+
7306+/*--------------------------------------------------------------------
7307+ イメージのアンロック
7308+ ---------------------------------------------------------------------*/
7309+void DXRuby_unlock( void *texture )
7310+{
7311+ ((LPDIRECT3DTEXTURE9)texture)->lpVtbl->UnlockRect( (LPDIRECT3DTEXTURE9)texture, 0 );
7312+}
7313+
--- tags/1.0.9/sample/laser.rb (nonexistent)
+++ tags/1.0.9/sample/laser.rb (revision 190)
@@ -0,0 +1,154 @@
1+#! ruby -Ks
2+require 'dxruby'
3+require 'dxrubyex'
4+
5+image_houdai = Image.new(10,10,[0,255,0])
6+
7+ENEMY_OBJECTS = []
8+ENEMY_COLLISIONS = []
9+
10+class Enemy
11+ attr_reader :delete, :x, :y, :width, :height
12+ @@image = Image.new(50,50).circleFill(25,25,24,[255,0,255])
13+ @@image_damage = Image.new(50,50).circleFill(25,25,24,[255,200,255])
14+ def initialize
15+ @x = rand(590)
16+ @y = -49
17+ @speed = rand(5)
18+ @collision = CollisionCircle.new(self, 25, 25, 24)
19+ @delete = false
20+ @width = 50
21+ @height = 50
22+ @hp = 100
23+ end
24+
25+ def update
26+ @y += 1
27+ if @y >= 480
28+ @collision.delete
29+ @delete = true
30+ else
31+ @collision.set(@x,@y)
32+ ENEMY_COLLISIONS.push(@collision)
33+ end
34+ end
35+
36+ def hit(o) end
37+
38+ def damage(o)
39+ @hp -= 1
40+ if @hp == 0
41+ @delete = true
42+ else
43+ Window.draw(@x, @y, @@image_damage,2)
44+ end
45+ end
46+
47+ def draw
48+ Window.draw(@x, @y, @@image)
49+ end
50+end
51+
52+class Laser
53+ attr_reader :collision, :enemy, :x, :y
54+ @@image_laser = Image.new(1,1,[128,255,255,255])
55+ def initialize(x, y)
56+ @x = x
57+ @y = y
58+ @collision = [CollisionTriangle.new(self, 0,0,0,0,0,0),CollisionTriangle.new(self, 0,0,0,0,0,0)]
59+ @collision[0].set(@x,@y)
60+ @collision[1].set(@x,@y)
61+ @angle = 0
62+ @enemy = []
63+ end
64+
65+ def shot(d)
66+ @enemy.push(d)
67+ end
68+
69+ def get_near_enemy
70+ near_distance = 800
71+ near_enemy = nil
72+ @enemy.each do |e|
73+ distance = Math.sqrt((@x - (e.x + e.width/2))**2 + (@y - (e.y + e.height/2))**2)
74+ if distance < near_distance
75+ near_distance = distance
76+ near_enemy = e
77+ end
78+ end
79+ return near_enemy
80+ end
81+
82+ def rotation(x1,y1,x2,y2,x3,y3,x4,y4,angle)
83+ sina = Math.sin(angle/180.0*Math::PI)
84+ cosa = Math.cos(angle/180.0*Math::PI)
85+ result_x1 = x1 * cosa + y1 * sina
86+ result_y1 = x1 * sina - y1 * cosa
87+ result_x2 = x2 * cosa + y2 * sina
88+ result_y2 = x2 * sina - y2 * cosa
89+ result_x3 = x3 * cosa + y3 * sina
90+ result_y3 = x3 * sina - y3 * cosa
91+ result_x4 = x4 * cosa + y4 * sina
92+ result_y4 = x4 * sina - y4 * cosa
93+ return [result_x1, result_y1, result_x2, result_y2, result_x3, result_y3, result_x4, result_y4]
94+ end
95+
96+ def update
97+ if Input.mouseDown?(M_LBUTTON)
98+ mx,my = Input.mousePosX, Input.mousePosY
99+ @angle = Math.atan2(mx - @x, @y - my) / Math::PI * 180
100+ x1,y1,x2,y2,x3,y3,x4,y4 = rotation(-5,-800,5,-800,5,0,-5,0,@angle+180)
101+ @collision[0].setRange(x1,y1,x2,y2,x3,y3)
102+ @collision[1].setRange(x2,y2,x3,y3,x4,y4)
103+ end
104+ end
105+
106+ def draw(length)
107+ Window.drawEx(@x, @y, @@image_laser, :centerx=>0.5,:centery=>1,:scalex=>10,:scaley=>length,:angle=>@angle,:blend=>:add,:z=>1)
108+ end
109+end
110+
111+laser = [Laser.new(145, 474), Laser.new(505, 474)]
112+font = Font.new(32)
113+
114+count = 0
115+Window.loop do
116+ count += 1
117+ if count % 50 == 0
118+ ENEMY_OBJECTS.push(Enemy.new)
119+ end
120+
121+ if Input.mouseDown?(M_LBUTTON)
122+ laser[0].update
123+ laser[1].update
124+ end
125+
126+ ENEMY_OBJECTS.each do |e| e.update end
127+
128+ laser.each do |l|
129+ Collision.check(l.collision, ENEMY_COLLISIONS) if Input.mouseDown?(M_LBUTTON)
130+ enemy = l.get_near_enemy
131+ enemy.damage(l) if enemy
132+ if Input.mouseDown?(M_LBUTTON)
133+ if enemy
134+ length = Math::sqrt(((enemy.x + enemy.width/2) - (l.x+5))**2 + ((enemy.y + enemy.height/2) - (l.y+5))**2)
135+ else
136+ length = 800
137+ end
138+ l.draw(length)
139+ end
140+ end
141+
142+ ENEMY_OBJECTS.each do |e| e.draw end
143+ ENEMY_COLLISIONS.clear
144+ ENEMY_OBJECTS.delete_if do |e| e.delete end
145+
146+ laser[0].enemy.clear
147+ laser[1].enemy.clear
148+ Window.drawFont(0,0,Window.getLoad.to_i.to_s + " %", font, :z=>3)
149+
150+ Window.draw(140,470,image_houdai)
151+ Window.draw(500,470,image_houdai)
152+end
153+
154+
--- tags/1.0.9/sample/readme_sample.txt (nonexistent)
+++ tags/1.0.9/sample/readme_sample.txt (revision 190)
@@ -0,0 +1,50 @@
1+DXRuby サンプルプログラム
2+
3+まず最初に、ソースが汚くてごめんなさい。
4+テキトーに作ったものたちを参考になればって感じで詰め込んであります。
5+
6+8_puzzle
7+ ・・・8パズルです。画像を読み込んで遊んでみてください。
8+
9+block_destory
10+ ・・・英語でなんていうんですかね。こうですか、わかりません!ブロック崩しです。
11+
12+block_fall
13+ ・・・有名なアレモドキです。
14+
15+dot
16+ ・・・砂が降ってくるデモです。マウスでいじってください。
17+
18+drawtile
19+ ・・・Window.drawTileとWindow.setViewportのデモ。マップの2レイヤ描画をしています。
20+
21+flight
22+ ・・・空を飛んでるっぽい疑似3D表現のサンプルです。カーソルキーで動きます。
23+
24+mapedit
25+ ・・・疑似3Dの簡易マップエディタです。shift押しながらクリックで土地の上げ下げできます。
26+
27+meiro
28+ ・・・3D迷路です。
29+
30+minsanple
31+ ・・・最も簡単なサンプルです。
32+
33+race
34+ ・・・レースモドキです。ImageオブジェクトのcopyRectメソッドを使っています。
35+
36+sample
37+ ・・・Windowモジュールの各種機能のサンプルとなっています。
38+
39+soundeffect
40+ ・・・SoundEffectクラスのサンプルです。ZXCキーで音がでます。
41+
42+dxrubyex_sample1
43+ ・・・同梱のDXRubyExtensionのサンプルその1です。
44+
45+dxrubyex_sample2
46+ ・・・同梱のDXRubyExtensionのサンプルその2です。
47+
48+laser
49+ ・・・DXRubyExtensionを使ってレーザーを実装してみたサンプルです。
50+
--- tags/1.0.9/sample/drawtile.rb (nonexistent)
+++ tags/1.0.9/sample/drawtile.rb (revision 190)
@@ -0,0 +1,164 @@
1+# マップデータから背景描画サンプル
2+require 'dxruby'
3+
4+# マップデータ
5+map1 = [
6+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
7+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1],
8+ [1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 2, 1, 1, 1, 1, 1],
9+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 2, 1],
10+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1],
11+ [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1],
12+ [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1],
13+ [1, 1, 1, 1, 1, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1],
14+ [1, 1, 1, 2, 0, 0, 0, 3, 3, 3, 3, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1],
15+ [1, 1, 1, 2, 0, 0, 0, 0, 3, 3, 3, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1],
16+ [1, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1],
17+ [1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1],
18+ [1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 1],
19+ [1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1],
20+ [1, 1, 1, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1],
21+ [1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1],
22+ [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1],
23+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1],
24+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1],
25+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 3, 0, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1],
26+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1],
27+ [1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 0, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1],
28+ [1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 3, 3, 3, 0, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 1],
29+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2],
30+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
31+ [1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
32+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1],
33+ [1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1],
34+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1],
35+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
36+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
37+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
38+]
39+
40+# 手前に描画する用のマップデータ(4は木のあたま。nilにすると描画しない)
41+map2 = [
42+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil],
43+ [nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil],
44+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil],
45+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
46+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
47+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
48+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil],
49+ [nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
50+ [nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
51+ [nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
52+ [nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
53+ [nil, nil, 4, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
54+ [nil, nil, nil, nil, 4, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
55+ [nil, nil, nil, nil, nil, 4, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
56+ [nil, nil, 4, nil, nil, nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
57+ [nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
58+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
59+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
60+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
61+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
62+ [nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
63+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil],
64+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4],
65+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, 4, 4],
66+ [nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, 4, 4, 4],
67+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, 4, 4, nil],
68+ [nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, 4, 4, nil, nil],
69+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil],
70+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
71+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
72+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil],
73+ [nil, nil, nil, nil, nil, nil, nil, nil, nil, 4, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
74+]
75+
76+
77+# 絵のデータを作る
78+mapimage = []
79+mapimage.push(Image.new(32, 32, [100, 100, 200])) # 海
80+mapimage.push(Image.new(32, 32, [50, 200, 50])) # 平地
81+mapimage.push(Image.new(32, 32, [50, 200, 50])) # 木の根元
82+mapimage[2].boxFill(13, 0, 18, 28, [200, 50, 50])
83+mapimage.push(Image.new(32, 32, [50, 200, 50])) # 山
84+for i in 1..30 do
85+ mapimage[3].line(15 - i/2, i, 16 + i/2, i, [200, 100, 100])
86+end
87+mapimage.push(Image.new(32, 32)) # 木のあたま。背景は透明色にしておく。
88+mapimage[4].boxFill(13, 16, 18, 31, [200, 50, 50])
89+mapimage[4].circleFill(16, 10, 8, [0, 255, 0])
90+
91+image = Image.new(32, 48). # 主人公
92+ circle(15, 5, 5, [255, 255, 255]).
93+ line(5, 18, 26, 18, [255, 255, 255]).
94+ line(15, 10, 15, 31, [255, 255, 255]).
95+ line(15, 31, 5, 47, [255, 255, 255]).
96+ line(15, 31, 25, 47, [255, 255, 255])
97+
98+# 座標初期位置
99+x = 0
100+y = 0
101+dx = 0
102+dy = 0
103+font = Font.new(32)
104+
105+# 0:入力待ち中、1:移動中
106+state = 0
107+
108+# 移動カウント
109+count = 0
110+
111+
112+Window.loop do
113+ # ビューポート設定
114+ Window.setViewport(32, 32, 640-64, 480-64, 0)
115+
116+ # 移動中はカウントアップするだけ
117+ if state == 1 then
118+ count = count + 4 # カウントアップ
119+ if count >= 32 then # カウント完了なら入力待ちに遷移
120+ state = 0
121+ count = 0
122+ x = x + dx # x座標移動
123+ y = y + dy # y座標移動
124+ # 座標ループ処理
125+ x = 0 if x > 31
126+ x = 31 if x < 0
127+ y = 0 if y > 31
128+ y = 31 if y < 0
129+ end
130+ end
131+
132+ # 入力待ち中
133+ if state == 0 then
134+ ix = Input.x
135+ iy = Input.y
136+ # 押されたチェック
137+ if ix + iy != 0 and (ix == 0 or iy == 0) then # ナナメは却下
138+ tempx = x + ix
139+ tempy = y + iy
140+ tempx = tempx - 32 if tempx > 31
141+ tempy = tempy - 32 if tempy > 31
142+ if map1[tempy][tempx] == 1 then
143+ state = 1 # スクロール中に遷移
144+ dx = ix
145+ dy = iy
146+ end
147+ end
148+ end
149+
150+ # 優先順位を変えて2回描画することで、キャラより手前にマップチップを描画することもできます。
151+ # ベースマップ描画
152+ Window.drawTile(32, 32, map1, mapimage, (x - 8.5) * 32 + count * dx, (y - 6) * 32 + count * dy, 18, 13, 0) # 優先順位0
153+
154+ # 人より手前に描画するマップ
155+ Window.drawTile(32, 32, map2, mapimage, (x - 8.5) * 32 + count * dx, (y - 6) * 32 + count * dy, 18, 13, 2) # 優先順位2
156+
157+ # 人描画
158+ Window.draw(9.5 * 32, 7 * 32 - 16, image, 1) # 人は優先順位をマップの間にしておく
159+
160+ # エスケープキーで終了
161+ break if Input.keyPush?(K_ESCAPE)
162+ Window.drawFont(32,32,Window.fps.to_s + " fps", font, :z=>3)
163+ Window.drawFont(32,64,Window.getLoad.to_i.to_s + " %", font, :z=>3)
164+end
--- tags/1.0.9/sample/8_puzzle.rb (nonexistent)
+++ tags/1.0.9/sample/8_puzzle.rb (revision 190)
@@ -0,0 +1,55 @@
1+#!ruby -Ks
2+# DXRuby サンプル 8パズル
3+# 左クリックでピースを移動、右クリックでシャッフル
4+# 使用可能な画像はjpg、png、bmpなど通常のフォーマットです。
5+require 'dxruby'
6+
7+filename = Window.openFilename([["スベテノファイル(*.*)", "*.*"]], "パズル用の画像を選択")
8+image = Image.loadToArray(filename, 3, 3)
9+
10+# 窓設定
11+width = image[0].width
12+height = image[0].height
13+if width < 32 then
14+ Window.scale = 48.0 / width
15+end
16+Window.width = image[0].width * 3
17+Window.height = image[0].height * 3
18+Window.caption = "8パズル"
19+
20+# パズルの情報
21+piece = [0,1,2,3,4,5,6,7,8]
22+
23+# クリック時の処理。空いてる位置のとなりだったら入れ替える。
24+def click(x, y, piece)
25+ i = piece.index(8) # 空いてるピース検索
26+ if (((i % 3) - x).abs == 1 and (i / 3) == y) or (((i / 3) - y).abs == 1 and (i % 3) == x) then
27+ piece[x + y * 3], piece[i] = piece[i], piece[x + y * 3] # 入れ替え a,b = b,aでswapできる
28+ end
29+end
30+
31+# メインループ
32+Window.loop do
33+
34+ # 右クリックでシャッフル(ランダムで1000回ほどクリックしてもらってます^^;)
35+ if Input.mousePush?(M_RBUTTON) then
36+ 1000.times do
37+ click(rand(3), rand(3), piece)
38+ end
39+ end
40+
41+ # 左クリック処理
42+ if Input.mousePush?(M_LBUTTON) then
43+ click((Input.mousePosX / Window.scale / image[0].width).to_i, (Input.mousePosY / Window.scale / image[0].height).to_i, piece)
44+ end
45+
46+ # 完了判定と描画
47+ for i in 0..8
48+ if piece[i] != 8 or piece == [0,1,2,3,4,5,6,7,8] then
49+ Window.draw(i % 3 * image[0].width , i / 3 * image[0].height, image[piece[i]])
50+ end
51+ end
52+
53+ # エスケープキーで終了
54+ break if Input.keyPush?(K_ESCAPE)
55+end
--- tags/1.0.9/sample/flight.rb (nonexistent)
+++ tags/1.0.9/sample/flight.rb (revision 190)
@@ -0,0 +1,75 @@
1+#ruby -Ks
2+# DXRuby サンプル 飛んでるようなもの
3+require 'dxruby'
4+
5+image = Image.new(32,32)
6+image.boxFill(13, 16, 18, 26, [255, 200, 50, 50]) # 木
7+image.line(13, 16, 13, 26, [255, 0, 0, 0])
8+image.line(18, 16, 18, 26, [255, 0, 0, 0])
9+image.circleFill(16, 8, 8, [255, 0, 255, 0])
10+image.circle(16, 8, 8, [255, 0, 0, 0])
11+
12+class Bg
13+ @@ground = Image.new(1000,600, [255, 0, 0, 255])
14+ attr_accessor :y, :angle
15+
16+ def initialize
17+ @y = 290
18+ @angle = 0
19+ end
20+
21+ def update
22+ @angle -= Input.x*1.8
23+ if @angle < -75 then
24+ @angle = -75
25+ end
26+ if @angle > 75 then
27+ @angle = 75
28+ end
29+ @y -= Input.y*5
30+ @y = 400 if @y > 400
31+ @y = 100 if @y < 100
32+ Window.drawRot(-180, @y, @@ground, angle, 500, 240-@y, 0)
33+ end
34+end
35+
36+bg = Bg.new
37+Window.bgcolor = [200,250,255]
38+x = 320
39+y = 240
40+z = []
41+Obj = Struct.new(:x, :y, :z)
42+font = Font.new(32)
43+angle = 0
44+objx = 0
45+
46+Window.loop do
47+
48+ z.push(Obj.new(rand(2000) - 680, 500, 5.0))
49+ z.push(Obj.new(rand(2000) - 680, 500, 5.0))
50+
51+ bg.update
52+
53+ rad = Math::PI/180.0*bg.angle
54+ sina = Math.sin(rad)
55+ cosa = Math.cos(rad)
56+ bgy1 = (530 - bg.y) / 290.0
57+ bgy2 = bg.y - 240
58+ z.delete_if do |obj|
59+ drawx = ((obj.x - 320) / obj.z * cosa - (((obj.y - 240) / obj.z - 50) * bgy1 + bgy2) * sina) + 320
60+ drawy = ((obj.x - 320) / obj.z * sina + (((obj.y - 240) / obj.z - 50) * bgy1 + bgy2) * cosa) + 240
61+
62+ Window.drawEx(drawx - image.width / 2, drawy - image.height / 2, image, :scalex=>5.0 / obj.z, :scaley=>5.0 / obj.z, :z=>5 - obj.z, :angle=>bg.angle)
63+
64+ obj.x += bg.angle / 3.0
65+ obj.z -= 0.15
66+ if obj.z < 0.5 then
67+ true
68+ else
69+ false
70+ end
71+ end
72+
73+ break if Input.keyPush?(K_ESCAPE)
74+ Window.drawFont(0, 448, Window.getLoad.to_i.to_s + " %", font)
75+end
--- tags/1.0.9/sample/meiro.rb (nonexistent)
+++ tags/1.0.9/sample/meiro.rb (revision 190)
@@ -0,0 +1,106 @@
1+#!ruby -Ks
2+# DXRuby サンプル 3D迷路
3+require 'dxruby'
4+
5+# マップ
6+map = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
7+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
8+ [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1],
9+ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1],
10+ [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1],
11+ [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
12+ [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
13+ [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1],
14+ [1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1],
15+ [1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1],
16+ [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
17+ [1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1],
18+ [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1],
19+ [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1],
20+ [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
21+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
22+ ]
23+
24+x = 1
25+y = 1
26+angle = 1
27+
28+# 向きによる増分
29+angledata = [[0, -1], [1, 0], [0, 1], [-1, 0]]
30+
31+block = Image.new(16, 16, [255, 255, 255, 255])
32+image = Array.new(4) {Array.new(3) {Image.new(256, 256)}}
33+jibun = Image.new(16, 16, [255, 255, 0, 0])
34+
35+# 3D画像生成
36+# 計算でかなり強引に作っている
37+# それぞれの距離ごとに綺麗な画像を作って読み込んだほうがよいと思います
38+for i in 0..3
39+ for j in 0..2
40+ if i != 3
41+ x1 = ((32 + 192 * (j - 1)) - 128) / (3 - i) + 128
42+ y1 = (32 - 128) / (3 - i) + 128
43+ x2 = ((224 + 192 * (j - 1)) - 128) / (3 - i) + 128
44+ y2 = (224 - 128) / (3 - i) + 128
45+ image[i][j].boxFill(x1, y1, x2, y2, [255, 255/(3 - i), 255/(3 - i), 255/(3 - i)])
46+ else
47+ x1 = 256
48+ y1 = 0
49+ x2 = 0
50+ y2 = 256
51+ end
52+ if j == 0
53+ x3 = (((224 + 192 * (j - 1)) - 128) / (4 - i) + 128)
54+ y3 = (32 - 128) / (4 - i) + 128
55+ y4 = (224 - 128) / (4 - i) + 128
56+ for k in 0..(x3-x2)
57+ image[i][j].line(k+x2, y1 + (y3 - y1) / (x3-x2) * k, k+x2, y2 + (y4 - y2) / (x3-x2) * k, [255,128/(4 - i),128/(4 - i),255/(4 - i)])
58+ end
59+ elsif j == 2
60+ x3 = (((32 + 192 * (j - 1)) - 128) / (4 - i) + 128)
61+ y3 = (32 - 128) / (4 - i) + 128
62+ y4 = (224 - 128) / (4 - i) + 128
63+ for k in 0..(x1 - x3)
64+ image[i][j].line(x1 - k, y1 + (y3 - y1) / (x1-x3) * k, x1 - k, y2 + (y4 - y2) / (x1-x3) * k, [255,128/(4 - i),128/(4 - i),255/(4 - i)])
65+ end
66+ end
67+ end
68+end
69+
70+Window.loop do
71+ # 左右おした
72+ angle += Input.x if Input.padPush?(P_LEFT) or Input.padPush?(P_RIGHT)
73+ angle = 0 if angle > 3
74+ angle = 3 if angle < 0
75+
76+ # 上おした
77+ if Input.padPush?(P_UP) or Input.padPush?(P_DOWN)
78+ newx = x + angledata[angle - Input.y - 1][0]
79+ newy = y + angledata[angle - Input.y - 1][1]
80+ x, y = newx, newy if map[newy][newx] == 0
81+ end
82+
83+ # 3D画面描画
84+ for i in 0..3
85+ for j in 0..2
86+ jx = x + angledata[angle - 3][0] * (j - 1) + angledata[angle - 2][0] * (i - 3)
87+ iy = y + angledata[angle - 2][1] * (i - 3) + angledata[angle - 3][1] * (j - 1)
88+ next if iy < 0 or iy > 15 or jx < 0 or jx > 15
89+ if map[iy][jx] == 1
90+ Window.draw(0, 0, image[i][j], i - (j - 1).abs)
91+ end
92+ end
93+ end
94+
95+ # 右のマップ
96+ for i in 0..15
97+ for j in 0..15
98+ Window.draw(j * 16 + 288, i * 16, block) if map[i][j] == 1
99+ end
100+ end
101+
102+ # 自分(赤の四角だけど)描画
103+ Window.draw(x * 16 + 288, y * 16, jibun)
104+
105+ break if Input.keyPush?(K_ESCAPE)
106+end
--- tags/1.0.9/sample/sample.rb (nonexistent)
+++ tags/1.0.9/sample/sample.rb (revision 190)
@@ -0,0 +1,110 @@
1+#!ruby -Ks
2+# DXRuby サンプルプログラム
3+
4+# ライブラリの取り込み
5+require 'dxruby'
6+
7+# 窓位置。省略するとOSデフォルト
8+#Window.x = 0
9+#Window.y = 0
10+
11+# スクリーンイメージサイズ。省略するとこのサイズ
12+#Window.width = 640
13+#Window.height = 480
14+
15+# ウィンドウのキャプション。省略すると「DXRuby Application」
16+Window.caption = "サンプル"
17+
18+# スクリーンイメージサイズに対するウィンドウの倍率。2にすると縦横2倍で表示される。
19+# 勝手にアンチエイリアシングされる。
20+# 省略すると1。
21+#Window.scale = 1
22+
23+# ウィンドウモードにするかどうか。trueでウィンドウ。falseでフルスクリーン。
24+# 省略するとtrue。
25+#Window.windowed = true
26+
27+# 秒間更新頻度を設定する。
28+# 省略すると60。
29+#Window.fps = 60
30+
31+# 重くてfpsが守れない場合に描画をスキップする指定。
32+# 省略するとfalse
33+#Window.frameskip = false
34+
35+# 画像ファイルを読み込んでイメージオブジェクトを作成する。
36+# jpgとかbmpとかpngとかが使える。
37+image = Image.load("data.png")
38+
39+# キャラの状態を設定する
40+x = 100
41+y = 100
42+rot = 0
43+scale = 1
44+alpha = 255
45+
46+# ウィンドウが閉じられたら自動的に終了するループ
47+Window.loop do
48+
49+ # キャラを動かしたりする
50+ # xとyメソッドはパッド入力をx座標とy座標の増分(-1、0、1)で返す。
51+ # 引数はパッド番号。0はキーボードと兼用。省略は0。
52+ x = x + Input.x
53+ y = y + Input.y
54+
55+ # Zを押したらクルクル回る
56+ # 第2引数は入力するボタン。
57+ # Zにはパッドのボタン0が標準で割り当てられている。
58+ if Input.keyDown?(K_Z) == true then
59+ rot = rot + 5
60+ if rot > 359 then
61+ rot = rot - 360
62+ end
63+ end
64+
65+ # Xを押したらサイズ変更
66+ # Xにはパッドのボタン1が標準で割り当てられている。
67+ if Input.keyDown?(K_X) == true then
68+ scale = scale + 0.05
69+ if scale > 2 then
70+ scale= 0.2
71+ end
72+ end
73+
74+ # Cを押したら半透明
75+ # Cにはパッドのボタン2が標準で割り当てられている。
76+ if Input.keyDown?(K_C) == true then
77+ alpha = alpha - 2
78+ if alpha < 0 then
79+ alpha= 255
80+ end
81+ end
82+
83+ # 普通に描画する
84+ Window.draw(x + 50, y + 100, image)
85+
86+ # なんかしてキャラを描画する
87+ Window.drawRot(x, y, image, rot) # 回転(0が基準で右回り。360で一周)
88+ Window.drawScale(x + 50, y, image, scale, scale) # 拡大縮小(1が基準で倍率を表す)
89+ Window.drawAlpha(x + 100, y, image, alpha) # 半透明(0が透明で255が通常描画)
90+
91+ # 全部同時に適用するメソッドはこちら
92+ Window.drawEx(x + 50, y + 50, image, :angle => rot, :scalex => scale, :scaley => scale, :alpha => alpha)
93+
94+ # エスケープキーで終了
95+ if Input.keyDown?(K_ESCAPE) == true then
96+ break
97+ end
98+
99+ # スクリーンショット機能
100+ if Input.keyPush?(K_F12) == true then
101+ if ! File.exist?("screenshot") then
102+ Dir.mkdir("screenshot")
103+ end
104+ Window.getScreenShot("screenshot/screenshot" + Time.now.strftime("%Y%m%d_%H%M%S") + ".jpg")
105+ end
106+end
107+
108+
109+
110+
--- tags/1.0.9/sample/block_destroy.rb (nonexistent)
+++ tags/1.0.9/sample/block_destroy.rb (revision 190)
@@ -0,0 +1,161 @@
1+#!ruby -Ks
2+# DXRuby サンプル ブロック崩しモドキ
3+# 左クリックでボールが飛びます。後はマウスで打ち返して。
4+require 'dxruby'
5+
6+Window.caption = "ブロック崩しモドキ"
7+
8+# ブロックの構造体
9+Block = Struct.new(:x, :y, :image)
10+
11+# 音データ作成
12+v = 80 # ボリューム
13+s1 = SoundEffect.new(50) do # 50mSecの効果音。ブロック内は1msの変化
14+ v = v - 4 if v > 0 # ボリュームダウン
15+ [220, v] # ブロックの戻りの配列が周波数とボリューム
16+end
17+v = 80
18+s2 = SoundEffect.new(50) do
19+ v = v - 4 if v > 0
20+ [440, v]
21+end
22+v = 80
23+s3 = SoundEffect.new(50) do
24+ v = v - 4 if v > 0
25+ [880, v]
26+end
27+
28+# 画像データ作成。
29+# パッドの画像
30+padimage = Image.new(100, 20)
31+padimage.boxFill(0, 0, 99, 19, [255, 255, 255])
32+
33+# ブロックの画像。ちょっと綺麗にしようと思ったらずいぶん増えちゃった
34+blockimage = [Image.new(60, 20, [255, 0, 0]),
35+ Image.new(60, 20, [255, 255, 0]),
36+ Image.new(60, 20, [0, 255, 0])]
37+blockimage[0].line(0, 0, 59, 0, [255, 150, 150])
38+blockimage[0].line(0, 0, 0, 19, [255, 150, 150])
39+blockimage[0].line(0, 19, 59, 19, [120, 0, 0])
40+blockimage[0].line(59, 0, 59, 19, [120, 0, 0])
41+blockimage[1].line(0, 0, 59, 0, [255, 255, 150])
42+blockimage[1].line(0, 0, 0, 19, [255, 255, 150])
43+blockimage[1].line(0, 19, 59, 19, [150, 150, 0])
44+blockimage[1].line(59, 0, 59, 19, [150, 150, 0])
45+blockimage[2].line(0, 0, 59, 0, [150, 255, 120])
46+blockimage[2].line(0, 0, 0, 19, [150, 255, 120])
47+blockimage[2].line(0, 19, 59, 19, [0, 150, 0])
48+blockimage[2].line(59, 0, 59, 19, [0, 150, 0])
49+
50+# 弾の画像
51+ballimage = Image.new(24, 24)
52+ballimage.circleFill(12, 12, 11, [255, 255, 255])
53+
54+# 玉の情報
55+tx = 0
56+ty = 416
57+dtx = 0
58+dty = 0
59+
60+# 0は初期化、1は玉が飛んでない。2は飛んでる。
61+state = 0
62+
63+block = []
64+
65+# メインループ
66+Window.loop do
67+ x = Input.mousePosX - 50
68+ x = 0 if x < 0
69+ x = 540 if x > 540
70+ y = Input.mousePosY - 10
71+ y = 220 if y < 220
72+ y = 460 if y > 460
73+
74+ case state
75+ when 0
76+ # ブロック配列初期化
77+ block.clear
78+ # ブロック生成
79+ for i in 0..9
80+ for j in 0..5
81+ block.push(Block.new(i * 64 + 2, j * 24 + 50, blockimage[j / 2]))
82+ end
83+ end
84+ state = 1
85+
86+ when 1
87+ # 飛んでないときはパッドにくっついている
88+ if Input.mousePush?(M_LBUTTON) then # マウスの左クリックで飛ばす
89+ state = 2
90+ dtx = rand(2) * 16 - 8
91+ dty = -8
92+ else # くっついてるとき
93+ tx = x + 38
94+ ty = y - 24
95+ end
96+
97+ when 2
98+ # ゲームメイン処理
99+ # ブロックとの判定
100+ block.delete_if do |b|
101+ flag = false
102+ # 横にブロックがあったら横にはねかえる
103+ if tx + dtx + 24 > b.x and tx + dtx < b.x + 60 and
104+ ty + 24 > b.y and ty < b.y + 20 then
105+ dtx = -dtx
106+ s3.play
107+ # ナナメにあった場合は縦にもはねかえる
108+ if tx + 24 > b.x and tx < b.x + 60 and
109+ ty + dty + 24 > b.y and ty + dty < b.y + 20 then
110+ dty = -dty
111+ end
112+ flag = true
113+
114+ # 縦にブロックがあったら縦にはねかえる
115+ elsif tx + 24 > b.x and tx < b.x + 60 and
116+ ty + dty + 24 > b.y and ty + dty < b.y + 20 then
117+ dty = -dty
118+ s3.play
119+ flag = true
120+ end
121+ flag
122+ end
123+ # 移動
124+ tx = tx + dtx
125+ ty = ty + dty
126+ # パッドとの判定
127+ if tx + 24 > x and tx < x + 100 and ty + 24 > y and ty < y + 20 and dty > 0 then
128+ dty = -8
129+ if tx < x + 38 - dtx * 2 then
130+ dtx = -8
131+ else
132+ dtx = 8
133+ end
134+ s1.play
135+ end
136+ # 画面外の判定
137+ if tx > 607 then
138+ dtx = -8
139+ s2.play
140+ end
141+ if tx < 8 then
142+ dtx = 8
143+ s2.play
144+ end
145+ if ty <= 0 then
146+ dty = 8
147+ s2.play
148+ end
149+ state = 1 if ty > 479 # ボールが落ちた
150+ state = 0 if block.size == 0 # ブロックが全部消えた
151+ end
152+
153+ # 画像描画
154+ Window.draw(x, y, padimage)
155+ Window.draw(tx, ty, ballimage)
156+ block.each do |b|
157+ Window.draw(b.x, b.y, b.image)
158+ end
159+
160+ break if Input.keyDown?(K_ESCAPE)
161+end
--- tags/1.0.9/sample/mapedit.rb (nonexistent)
+++ tags/1.0.9/sample/mapedit.rb (revision 190)
@@ -0,0 +1,270 @@
1+#!ruby -Ks
2+# DXRuby 簡易マップエディタ
3+require 'dxruby'
4+
5+# マップデータ
6+map=[
7+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
8+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
9+ [1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
10+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
11+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1],
12+ [0, 0, 0, 0, 1, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1],
13+ [2, 2, 2, 2, 1, 1, 4, 4, 4, 4, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 3, 1, 1, 1, 1],
14+ [2, 2, 2, 1, 2, 1, 1, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 1, 1, 1, 1, 3, 3, 3, 3, 1, 3, 1, 3, 1, 1],
15+ [2, 2, 2, 1, 1, 1, 1, 1, 4, 4, 4, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 3, 1, 3, 3, 3, 3, 3, 3, 1, 1],
16+ [2, 2, 2, 2, 2, 2, 1, 1, 4, 4, 4, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1],
17+ [1, 2, 2, 2, 2, 2, 2, 1, 4, 4, 4, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1],
18+ [1, 1, 1, 2, 2, 1, 2, 1, 4, 4, 4, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3],
19+ [1, 1, 2, 1, 2, 2, 1, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3],
20+ [1, 1, 1, 2, 2, 1, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3],
21+ [1, 1, 1, 2, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3],
22+ [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3],
23+ [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1],
24+ [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 4, 4, 1, 4, 1, 4, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
25+ [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
26+ [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 4, 4, 4, 4, 4, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
27+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 4, 4, 4, 4, 4, 4, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1],
28+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 4, 4, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
29+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1],
30+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1],
31+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 0],
32+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 0, 0],
33+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 0, 0, 0],
34+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0],
35+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,