• R/O
  • SSH
  • HTTPS

dxruby: Commit


Commit MetaInfo

Revisión276 (tree)
Tiempo2012-05-17 21:19:53
Autormirichi

Log Message

tags 1.2.2

Cambiar Resumen

Diferencia incremental

--- tags/1.2.2/input.c (nonexistent)
+++ tags/1.2.2/input.c (revision 276)
@@ -0,0 +1,1306 @@
1+#define WINVER 0x0500 /* バージョン定義 Windows2000以上 */
2+#define _WIN32_WINNT WINVER
3+#undef DIRECTINPUT_VERSION
4+#define DIRECTINPUT_VERSION (0x0800) /* DirectInputバージョン定義 */
5+
6+#include "ruby.h"
7+#ifndef RUBY_ST_H
8+#include "st.h"
9+#endif
10+#include <dinput.h>
11+
12+#define DXRUBY_EXTERN 1
13+#include "dxruby.h"
14+#include "input.h"
15+
16+#define PADMAX 2
17+
18+#define P_LEFT 0
19+#define P_RIGHT 1
20+#define P_UP 2
21+#define P_DOWN 3
22+#define P_BUTTON0 4
23+#define P_BUTTON1 5
24+#define P_BUTTON2 6
25+#define P_BUTTON3 7
26+#define P_BUTTON4 8
27+#define P_BUTTON5 9
28+#define P_BUTTON6 10
29+#define P_BUTTON7 11
30+#define P_BUTTON8 12
31+#define P_BUTTON9 13
32+#define P_BUTTON10 14
33+#define P_BUTTON11 15
34+#define P_BUTTON12 16
35+#define P_BUTTON13 17
36+#define P_BUTTON14 18
37+#define P_BUTTON15 19
38+#define M_LBUTTON 0
39+#define M_RBUTTON 1
40+#define M_MBUTTON 2
41+
42+static VALUE mInput; /* インプットモジュール */
43+static LPDIRECTINPUT8 g_pDInput = NULL; /* DirectInput */
44+static LPDIRECTINPUTDEVICE8 g_pDIDKeyBoard = NULL; /* DirectInputのキーボードデバイス */
45+static LPDIRECTINPUTDEVICE8 g_pDIDJoyPad[PADMAX]; /* DirectInputのパッドデバイス */
46+static BYTE g_diKeyState[256]; /* DirectInputでのキーボード入力用バッファ */
47+static BYTE g_diKeyStateOld[256]; /* DirectInputでのキーボード入力用バッファ1フレーム前 */
48+static BYTE g_diKeyCount[256]; /* DirectInputでのキーボード入力用カウンタ */
49+static BYTE g_diKeyConfig[256]; /* DirectInputでのキーボード・パッド割り当て */
50+static BYTE g_diKeyWait[256]; /* オートリピートウェイト時間 */
51+static BYTE g_diKeyInterval[256]; /* オートリピート間隔 */
52+static int g_JoystickCount = 0;
53+static BYTE g_byMouseState_L, g_byMouseStateOld_L;
54+static BYTE g_byMouseState_M, g_byMouseStateOld_M;
55+static BYTE g_byMouseState_R, g_byMouseStateOld_R;
56+
57+/* Pad情報 */
58+static struct DXRubyPadInfo {
59+ int right;
60+ int left;
61+ int up;
62+ int down;
63+ LPDIRECTINPUTDEVICE8 pDIDJoyPad; /* DirectInputのパッドデバイス */
64+} g_PadInfo[PADMAX];
65+
66+/* Pad状態 */
67+static struct DXRubyPadState {
68+ char button[20];
69+ int PadConfig[20];
70+ int count[20];
71+ int wait[20];
72+ int interval[20];
73+} g_PadState[PADMAX], g_PadStateOld[PADMAX];
74+
75+/*********************************************************************
76+ * Inputモジュール
77+ *
78+ * DirectInputを使用してキーボード・パッドの入力を行う。
79+ *********************************************************************/
80+
81+/*--------------------------------------------------------------------
82+ Windowsメッセージ処理込みの入力更新
83+ ---------------------------------------------------------------------*/
84+VALUE Input_update( VALUE obj )
85+{
86+ MSG msg;
87+ msg.message = WM_NULL;
88+
89+ if( g_WindowInfo.userloop == 2 )
90+ {
91+ rb_raise( eDXRubyError, "Window.loop実行中にInput.updateは実行できません。" );
92+ }
93+
94+ g_WindowInfo.userloop = 1;
95+
96+ /* メッセージループ */
97+ /* メッセージがなくなるまで処理をし続ける */
98+ /* メッセージが無い時はブロックをyieldする */
99+ while (1)
100+ {
101+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
102+ {
103+ /* メッセージがある時 */
104+ TranslateMessage( &msg );
105+ DispatchMessage( &msg );
106+ }
107+ else
108+ {
109+ break;
110+ }
111+ }
112+
113+ if( g_WindowInfo.requestclose == 1 )
114+ {
115+ g_WindowInfo.requestclose = 0;
116+ return Qtrue;
117+ }
118+
119+ /* メッセージが無い時 */
120+ /* 入力状態更新 */
121+ inputupdate_internal();
122+
123+ return Qfalse;
124+}
125+
126+
127+/*--------------------------------------------------------------------
128+ Inputモジュールの入力処理
129+ ---------------------------------------------------------------------*/
130+void inputupdate_internal( void )
131+{
132+ int i, j;
133+ DIJOYSTATE paddata;
134+
135+ /* フォーカスがはずれた場合、キーとパッド、マウスボタンの入力を受け付けなくする */
136+ if( g_WindowInfo.active == 0 )
137+ {
138+ /* キーボードのデータをクリアする */
139+ ZeroMemory( &g_diKeyState, sizeof(g_diKeyState) );
140+ ZeroMemory( &g_diKeyStateOld, sizeof(g_diKeyStateOld) );
141+
142+ /* パッドデータをクリアする */
143+ for( i = 0; i < g_JoystickCount; i++ )
144+ {
145+ for( j = 0; j < 20; j++ )
146+ {
147+ g_PadStateOld[i].button[j] = g_PadState[i].button[j];
148+ g_PadState[i].button[j] = 0;
149+ }
150+ }
151+
152+ /* マウスボタンのデータをクリアする */
153+ g_byMouseStateOld_L = g_byMouseState_L;
154+ g_byMouseStateOld_M = g_byMouseState_M;
155+ g_byMouseStateOld_R = g_byMouseState_R;
156+ g_byMouseState_L = 0;
157+ g_byMouseState_M = 0;
158+ g_byMouseState_R = 0;
159+
160+ return;
161+ }
162+
163+ /* デバイスアクセス権を再取得する */
164+ g_pDIDKeyBoard->lpVtbl->Acquire( g_pDIDKeyBoard );
165+
166+ for( i = 0; i < g_JoystickCount; i++ )
167+ {
168+ g_pDIDJoyPad[i]->lpVtbl->Poll( g_pDIDJoyPad[i] );
169+ g_pDIDJoyPad[i]->lpVtbl->Acquire( g_pDIDJoyPad[i] );
170+ }
171+
172+ /* キーボードの直接データを取得する */
173+ memcpy( g_diKeyStateOld, g_diKeyState, sizeof(g_diKeyState) );
174+ g_pDIDKeyBoard->lpVtbl->GetDeviceState( g_pDIDKeyBoard, 256, g_diKeyState );
175+
176+ /* ゲームパッドのデータを取得する */
177+ for( i = 0; i < g_JoystickCount; i++ )
178+ {
179+ int j;
180+
181+ g_pDIDJoyPad[i]->lpVtbl->GetDeviceState( g_pDIDJoyPad[i], sizeof(DIJOYSTATE), &paddata );
182+
183+ for( j = 0; j < 20; j++ )
184+ {
185+ g_PadStateOld[i].button[j] = g_PadState[i].button[j];
186+ g_PadState[i].button[j] = 0;
187+ }
188+
189+ /* 左 */
190+ if( paddata.lX < g_PadInfo[i].left )
191+ {
192+ g_PadState[i].button[P_LEFT] = 1;
193+ }
194+ /* 右 */
195+ else if( paddata.lX > g_PadInfo[i].right )
196+ {
197+ g_PadState[i].button[P_RIGHT] = 1;
198+ }
199+
200+ /* 上 */
201+ if( paddata.lY < g_PadInfo[i].up )
202+ {
203+ g_PadState[i].button[P_UP] = 1;
204+ }
205+ /* 下 */
206+ else if( paddata.lY > g_PadInfo[i].down )
207+ {
208+ g_PadState[i].button[P_DOWN] = 1;
209+ }
210+
211+ /* ボタン状態 */
212+ for( j = 0; j < 16; j++)
213+ {
214+ g_PadState[i].button[j + 4] = paddata.rgbButtons[j] >> 7;
215+ }
216+ }
217+
218+ /* マウスボタンの状態 */
219+ g_byMouseStateOld_L = g_byMouseState_L;
220+ g_byMouseStateOld_M = g_byMouseState_M;
221+ g_byMouseStateOld_R = g_byMouseState_R;
222+ g_byMouseState_L = GetKeyState( VK_LBUTTON );
223+ g_byMouseState_M = GetKeyState( VK_MBUTTON );
224+ g_byMouseState_R = GetKeyState( VK_RBUTTON );
225+
226+ return;
227+}
228+
229+
230+/*--------------------------------------------------------------------
231+ Inputモジュールのデータ取得
232+
233+ 横方向の入力をxの増分で返す
234+ ---------------------------------------------------------------------*/
235+static VALUE Input_x( int argc, VALUE *argv, VALUE obj )
236+{
237+ int x = 0;
238+ VALUE vnumber;
239+ int number;
240+
241+ rb_scan_args( argc, argv, "01", &vnumber);
242+
243+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
244+
245+ if( number < 0 || number >= PADMAX )
246+ {
247+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_x" );
248+ }
249+
250+ /* ひだり */
251+ if( g_diKeyState[g_PadState[number].PadConfig[P_LEFT]] & 0x80 || g_PadState[number].button[P_LEFT] == 1 )
252+ {
253+ x = x - 1;
254+ }
255+
256+ /* みぎ */
257+ if( g_diKeyState[g_PadState[number].PadConfig[P_RIGHT]] & 0x80 || g_PadState[number].button[P_RIGHT] == 1 )
258+ {
259+ x = x + 1;
260+ }
261+
262+ return INT2FIX( x );
263+}
264+
265+
266+/*--------------------------------------------------------------------
267+ Inputモジュールのデータ取得
268+
269+ 縦方向の入力をyの増分で返す
270+ ---------------------------------------------------------------------*/
271+static VALUE Input_y( int argc, VALUE *argv, VALUE obj )
272+{
273+ int y = 0;
274+ VALUE vnumber;
275+ int number;
276+
277+ rb_scan_args( argc, argv, "01", &vnumber);
278+
279+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
280+
281+ if( number < 0 || number >= PADMAX )
282+ {
283+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_y" );
284+ }
285+
286+
287+ /* うえ */
288+ if( g_diKeyState[g_PadState[number].PadConfig[P_UP]] & 0x80 || g_PadState[number].button[P_UP] == 1 )
289+ {
290+ y = y - 1;
291+ }
292+
293+ /* した */
294+ if( g_diKeyState[g_PadState[number].PadConfig[P_DOWN]] & 0x80 || g_PadState[number].button[P_DOWN] == 1 )
295+ {
296+ y = y + 1;
297+ }
298+
299+ return INT2FIX( y );
300+}
301+
302+
303+/*--------------------------------------------------------------------
304+ Inputモジュールのデータ取得
305+
306+ 押されていたらtrueになる。引数はキーコード。
307+ ---------------------------------------------------------------------*/
308+static VALUE Input_keyDown( VALUE obj , VALUE vkey )
309+{
310+ int key, padbutton = 0;
311+
312+ key = NUM2INT( vkey );
313+ if( key < 0 || key >= 256 )
314+ {
315+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_keyDown" );
316+ }
317+
318+ if( g_diKeyConfig[key] != -1 && g_PadState[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
319+ {
320+ padbutton = 1;
321+ }
322+
323+ if( g_diKeyState[key] & 0x80 || padbutton == 1)
324+ {
325+ return Qtrue;
326+ }
327+
328+ return Qfalse;
329+}
330+
331+
332+/*--------------------------------------------------------------------
333+ Inputモジュールのデータ取得
334+
335+ 押した瞬間だけtrueになる。引数はキーコード。
336+ ---------------------------------------------------------------------*/
337+static VALUE Input_keyPush( VALUE obj , VALUE vkey )
338+{
339+ int key, padbutton = 0, padbuttonold = 0;
340+
341+ key = NUM2INT( vkey );
342+ if( key < 0 || key >= 256 )
343+ {
344+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_keyPush" );
345+ }
346+
347+ if( g_diKeyConfig[key] != -1 )
348+ {
349+ if( g_PadState[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
350+ {
351+ padbutton = 1;
352+ }
353+ if( g_PadStateOld[g_diKeyConfig[key] / 20].button[g_diKeyConfig[key] % 20] == 1 )
354+ {
355+ padbuttonold = 1;
356+ }
357+ }
358+
359+ if( (g_diKeyState[key] & 0x80) || padbutton == 1 ) /* 入力されている */
360+ {
361+ if( !(g_diKeyStateOld[key] & 0x80) && padbuttonold == 0 ) /* 前回OFFである */
362+ {
363+ g_diKeyCount[key] = 0; /* カウント初期化 */
364+ return Qtrue; /* なにはともあれTrue */
365+ }
366+ else /* 前回ONだった */
367+ {
368+ g_diKeyCount[key]++; /* カウント */
369+ if( g_diKeyWait[key] <= g_diKeyCount[key] ) /* ウェイトタイムを超えたか */
370+ {
371+ if( g_diKeyInterval[key] != 0 &&
372+ (g_diKeyCount[key] - g_diKeyWait[key]) % g_diKeyInterval[key] == 0 ) /* インターバルタイムごとに */
373+ {
374+ return Qtrue; /* True */
375+ }
376+ }
377+ }
378+ }
379+
380+ return Qfalse;
381+}
382+
383+
384+/*--------------------------------------------------------------------
385+ Inputモジュールのデータ取得
386+
387+ 押されていたらtrueになる。引数はボタン番号。
388+ ---------------------------------------------------------------------*/
389+static VALUE Input_padDown( int argc, VALUE *argv, VALUE obj )
390+{
391+ VALUE vnumber, vbutton;
392+ int number, button, key = 0;
393+
394+ rb_scan_args( argc, argv, "11", &vbutton, &vnumber);
395+
396+ button = NUM2INT( vbutton );
397+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
398+
399+ if( number < 0 || button < 0 || number >= PADMAX || button >= 20 )
400+ {
401+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_padDown" );
402+ }
403+
404+ if( g_PadState[number].PadConfig[button] != -1 && g_diKeyState[g_PadState[number].PadConfig[button]] & 0x80 )
405+ {
406+ key = 1;
407+ }
408+
409+ if( key == 1 || g_PadState[number].button[button] == 1 )
410+ {
411+ return Qtrue;
412+ }
413+
414+ return Qfalse;
415+}
416+
417+
418+/*--------------------------------------------------------------------
419+ Inputモジュールのデータ取得
420+
421+ 押した瞬間だけtrueになる。引数はボタン番号。
422+ ---------------------------------------------------------------------*/
423+static VALUE Input_padPush( int argc, VALUE *argv, VALUE obj )
424+{
425+ VALUE vnumber, vbutton;
426+ int number, button, key = 0, keyold = 0;
427+
428+ rb_scan_args( argc, argv, "11", &vbutton, &vnumber);
429+
430+ button = NUM2INT( vbutton );
431+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
432+
433+ if( number < 0 || button < 0 || number >= PADMAX || button >= 20 )
434+ {
435+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_padPush" );
436+ }
437+
438+ if( g_PadState[number].PadConfig[button] != -1 )
439+ {
440+ if( g_diKeyState[g_PadState[number].PadConfig[button]] & 0x80 )
441+ {
442+ key = 1;
443+ }
444+ if( g_diKeyStateOld[g_PadState[number].PadConfig[button]] & 0x80 )
445+ {
446+ keyold = 1;
447+ }
448+ }
449+
450+ if( key == 1 || g_PadState[number].button[button] == 1 ) /* 入力されている */
451+ {
452+ if( keyold == 0 && g_PadStateOld[number].button[button] == 0 ) /* 前回OFFである */
453+ {
454+ g_PadState[number].count[button] = 0; /* カウント初期化 */
455+ return Qtrue; /* なにはともあれTrue */
456+ }
457+ else /* 前回ONだった */
458+ {
459+ g_PadState[number].count[button]++; /* カウント */
460+ if( g_PadState[number].wait[button] <= g_PadState[number].count[button] ) /* ウェイトタイムを超えたか */
461+ {
462+ if( g_PadState[number].interval[button] != 0 &&
463+ (g_PadState[number].count[button] - g_PadState[number].wait[button])
464+ % g_PadState[number].interval[button] == 0 ) /* インターバルタイムごとに */
465+ {
466+ return Qtrue; /* True */
467+ }
468+ }
469+ }
470+ }
471+
472+ return Qfalse;
473+}
474+
475+
476+/*--------------------------------------------------------------------
477+ パッドとキーの対応を設定する
478+ ---------------------------------------------------------------------*/
479+static void Input_SetConfig( int number, int pad, int key )
480+{
481+ int i, j;
482+
483+ if( pad == -1 ) /* キーに対するパッド割り当て解除処理 */
484+ {
485+ g_diKeyConfig[key] = -1;
486+ for( i = 0; i < PADMAX; i++)
487+ {
488+ for( j = 0; j < 20; j++)
489+ {
490+ if( g_PadState[i].PadConfig[j] == key )
491+ {
492+ g_PadState[i].PadConfig[j] = -1;
493+ }
494+ }
495+ }
496+ }
497+ else if( key == -1 || key == 0 ) /* パッドに対するキー割り当て解除処理 */
498+ {
499+ g_PadState[number].PadConfig[pad] = -1;
500+ for( i = 0; i < 256; i++)
501+ {
502+ if( g_diKeyConfig[i] == pad )
503+ {
504+ g_diKeyConfig[i] = -1;
505+ }
506+ }
507+ }
508+ else /* 割り当て処理 */
509+ {
510+ g_PadState[number].PadConfig[pad] = key;
511+ g_diKeyConfig[key] = number * 20 + pad;
512+ }
513+}
514+
515+static VALUE Input_setconfig( int argc, VALUE *argv, VALUE obj )
516+{
517+ VALUE vnumber, vpad, vkey;
518+ int number, pad, key;
519+
520+ rb_scan_args( argc, argv, "21", &vpad, &vkey, &vnumber);
521+
522+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
523+ pad = (vpad == Qnil ? -1 : NUM2INT( vpad ));
524+ key = (vkey == Qnil ? -1 : NUM2INT( vkey ));
525+
526+ if( number < 0 || pad < -1 || key < -1 || number >= PADMAX || pad >= 20 || key >= 256 )
527+ {
528+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setconfig" );
529+ }
530+
531+ if( pad != -1 || key != -1 )
532+ {
533+ Input_SetConfig( number, pad, key );
534+ }
535+
536+ return obj;
537+}
538+
539+
540+/*--------------------------------------------------------------------
541+ マウスホイールの状態を返す
542+ ---------------------------------------------------------------------*/
543+static VALUE Input_getmousewheelpos( VALUE obj )
544+{
545+ return INT2FIX(g_WindowInfo.mousewheelpos);
546+}
547+
548+
549+/*--------------------------------------------------------------------
550+ マウスホイールの状態を設定する
551+ ---------------------------------------------------------------------*/
552+static VALUE Input_setmousewheelpos( VALUE obj, VALUE wheelpos )
553+{
554+ g_WindowInfo.mousewheelpos = NUM2INT( wheelpos );
555+
556+ return obj;
557+}
558+
559+
560+/*--------------------------------------------------------------------
561+ マウスのボタン状態を返す
562+ ---------------------------------------------------------------------*/
563+static VALUE Input_mouseDown( VALUE obj, VALUE button )
564+{
565+
566+ switch( NUM2INT( button ) )
567+ {
568+ case M_LBUTTON:
569+ if( g_byMouseState_L & 0x80 )
570+ {
571+ return Qtrue;
572+ }
573+ else
574+ {
575+ return Qfalse;
576+ }
577+
578+ case M_RBUTTON:
579+ if( g_byMouseState_R & 0x80 )
580+ {
581+ return Qtrue;
582+ }
583+ else
584+ {
585+ return Qfalse;
586+ }
587+
588+ case M_MBUTTON:
589+ if( g_byMouseState_M & 0x80 )
590+ {
591+ return Qtrue;
592+ }
593+ else
594+ {
595+ return Qfalse;
596+ }
597+ }
598+
599+ return Qnil;
600+}
601+
602+
603+/*--------------------------------------------------------------------
604+ マウスのボタン状態を返す
605+ ---------------------------------------------------------------------*/
606+static VALUE Input_mousePush( VALUE obj, VALUE button )
607+{
608+
609+ switch( NUM2INT( button ) )
610+ {
611+ case M_LBUTTON:
612+ if( (g_byMouseState_L & 0x80) && !(g_byMouseStateOld_L & 0x80) )
613+ {
614+ return Qtrue;
615+ }
616+ else
617+ {
618+ return Qfalse;
619+ }
620+
621+ case M_RBUTTON:
622+ if( g_byMouseState_R & 0x80 && !(g_byMouseStateOld_R & 0x80) )
623+ {
624+ return Qtrue;
625+ }
626+ else
627+ {
628+ return Qfalse;
629+ }
630+
631+ case M_MBUTTON:
632+ if( g_byMouseState_M & 0x80 && !(g_byMouseStateOld_M & 0x80) )
633+ {
634+ return Qtrue;
635+ }
636+ else
637+ {
638+ return Qfalse;
639+ }
640+ }
641+
642+ return Qnil;
643+}
644+
645+
646+/*--------------------------------------------------------------------
647+ マウスカーソルの位置を返す
648+ ---------------------------------------------------------------------*/
649+static VALUE Input_getmouseposx( VALUE obj )
650+{
651+ POINT cursor;
652+
653+ GetCursorPos( &cursor );
654+ ScreenToClient( g_hWnd, &cursor );
655+ return INT2FIX( cursor.x );
656+}
657+
658+
659+/*--------------------------------------------------------------------
660+ マウスカーソルの位置を返す
661+ ---------------------------------------------------------------------*/
662+static VALUE Input_getmouseposy( VALUE obj )
663+{
664+ POINT cursor;
665+
666+ GetCursorPos( &cursor );
667+ ScreenToClient( g_hWnd, &cursor );
668+
669+ return INT2FIX( cursor.y );
670+}
671+
672+
673+/*--------------------------------------------------------------------
674+ マウスカーソルの位置を設定する
675+ ---------------------------------------------------------------------*/
676+static VALUE Input_setmousepos( VALUE klass, VALUE vx, VALUE vy )
677+{
678+ POINT cursor;
679+
680+ cursor.x = NUM2INT( vx );
681+ cursor.y = NUM2INT( vy );
682+ ClientToScreen( g_hWnd, &cursor );
683+ SetCursorPos( cursor.x, cursor.y );
684+
685+ return Qnil;
686+}
687+
688+
689+/*--------------------------------------------------------------------
690+ マウス描画するかどうかの設定
691+ ---------------------------------------------------------------------*/
692+static VALUE Input_enablemouse( VALUE obj, VALUE draw )
693+{
694+ VALUE flag = Qfalse;
695+ int c;
696+
697+ if( draw != Qnil && draw != Qfalse )
698+ {
699+ flag = Qtrue;
700+ }
701+
702+ if( flag == Qtrue )
703+ {
704+ c = ShowCursor( TRUE );
705+ while( c < 0 ) c = ShowCursor( TRUE );
706+ }
707+ else
708+ {
709+ c = ShowCursor( FALSE );
710+ while( c >= 0 ) c = ShowCursor( FALSE );
711+ }
712+
713+ g_WindowInfo.enablemouse = flag;
714+
715+ return draw;
716+}
717+
718+
719+/*--------------------------------------------------------------------
720+ Inputモジュールの全キーオートリピート状態設定
721+ ---------------------------------------------------------------------*/
722+static VALUE Input_setrepeat( VALUE obj , VALUE vwait, VALUE vinterval )
723+{
724+ int wait, interval, i, j;
725+
726+ wait = NUM2INT( vwait );
727+ interval = NUM2INT( vinterval );
728+
729+ for( i = 0; i < 256; i++)
730+ {
731+ g_diKeyWait[i] = wait;
732+ g_diKeyInterval[i] = interval;
733+ }
734+
735+ for( i = 0; i < PADMAX; i++)
736+ {
737+ for( j = 0; j < 20; j++)
738+ {
739+ g_PadState[i].wait[j] = wait;
740+ g_PadState[i].interval[j] = interval;
741+ }
742+ }
743+
744+ return obj;
745+}
746+
747+
748+/*--------------------------------------------------------------------
749+ Inputモジュールのキーオートリピート状態設定
750+ ---------------------------------------------------------------------*/
751+static VALUE Input_setkeyrepeat( VALUE obj , VALUE vkey, VALUE vwait, VALUE vinterval )
752+{
753+ int key, wait, interval;
754+
755+ key = NUM2INT( vkey );
756+ wait = NUM2INT( vwait );
757+ interval = NUM2INT( vinterval );
758+
759+ if( key < 0 || key >= 256 || wait < 0 || interval < 0 )
760+ {
761+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setKeyRepeat" );
762+ }
763+
764+ g_diKeyWait[key] = wait;
765+ g_diKeyInterval[key] = interval;
766+
767+ return obj;
768+}
769+
770+
771+/*--------------------------------------------------------------------
772+ Inputモジュールのパッドオートリピート状態設定
773+ ---------------------------------------------------------------------*/
774+static VALUE Input_setpadrepeat( int argc, VALUE *argv, VALUE obj )
775+{
776+ VALUE vpad, vwait, vinterval, vnumber;
777+ int pad, wait, interval, number;
778+
779+ rb_scan_args( argc, argv, "31", &vpad, &vwait, &vinterval, &vnumber );
780+
781+ pad = NUM2INT( vpad );
782+ wait = NUM2INT( vwait );
783+ interval = NUM2INT( vinterval );
784+ number = (vnumber == Qnil ? 0 : NUM2INT( vnumber ));
785+
786+ if( number < 0 || pad < 0 || number >= PADMAX || pad >= 20 ||
787+ wait < 0 || interval < 0 )
788+ {
789+ rb_raise( eDXRubyError, "値が範囲外です。 - Input_setPadRepeat" );
790+ }
791+
792+ g_PadState[number].wait[pad] = wait;
793+ g_PadState[number].interval[pad] = interval;
794+
795+ return obj;
796+}
797+
798+
799+/*--------------------------------------------------------------------
800+ Inputモジュールのデータ取得
801+
802+ 押されているキーの配列を返す。
803+ ---------------------------------------------------------------------*/
804+static VALUE Input_getKeys( VALUE obj )
805+{
806+ int i, j;
807+ VALUE buf[256];
808+
809+ for( i = 0, j = 0; i < 256; i++ )
810+ {
811+ if( g_diKeyState[i] & 0x80 ) /* 入力されている */
812+ {
813+ buf[j++] = INT2FIX( i );
814+ }
815+ }
816+
817+ return rb_ary_new4( j, buf );
818+}
819+
820+
821+/*--------------------------------------------------------------------
822+ Inputモジュールのデータ取得
823+
824+ 押されているパッドの配列を返す。
825+ ---------------------------------------------------------------------*/
826+static VALUE Input_getPads( int argc, VALUE *argv, VALUE obj )
827+{
828+ int i, j, number;
829+ VALUE buf[20];
830+ VALUE vnumber;
831+
832+ rb_scan_args( argc, argv, "01", &vnumber);
833+
834+ number = vnumber == Qnil ? 0 : NUM2INT( vnumber );
835+
836+ for( i = 0, j = 0; i < 20; i++ )
837+ {
838+ if( g_PadState[number].button[i] == 1 )
839+ {
840+ buf[j++] = INT2FIX( i );
841+ }
842+ }
843+
844+ return rb_ary_new4( j, buf );
845+}
846+
847+
848+/*--------------------------------------------------------------------
849+ パッドの数を返す
850+ ---------------------------------------------------------------------*/
851+static VALUE Input_getPadNum( VALUE obj )
852+{
853+ return INT2FIX( g_JoystickCount );
854+}
855+
856+
857+/* デバイス列挙関数 */
858+BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, void* pContext )
859+{
860+ HRESULT hr;
861+
862+ /* 列挙されたジョイスティックへのインターフェイスを取得する */
863+ hr = g_pDInput->lpVtbl->CreateDevice( g_pDInput,
864+ &pdidInstance->guidInstance,
865+ &g_pDIDJoyPad[g_JoystickCount],
866+ NULL );
867+ if( SUCCEEDED( hr ) )
868+ {
869+ return (++g_JoystickCount == PADMAX)?(DIENUM_STOP):(DIENUM_CONTINUE);
870+ }
871+
872+ return DIENUM_STOP;
873+}
874+
875+/* オブジェクト(軸)列挙関数 */
876+BOOL CALLBACK EnumAxisCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, void *pContext )
877+{
878+ HRESULT hr;
879+ DIPROPRANGE diprg = { sizeof(DIPROPRANGE), sizeof(DIPROPHEADER) };
880+ struct DXRubyPadInfo *pad;
881+
882+ pad = (struct DXRubyPadInfo *)pContext;
883+
884+ diprg.diph.dwHow = DIPH_BYID;
885+ diprg.diph.dwObj = pdidoi->dwType;
886+
887+ /*========================================================*/
888+ /* 取得 */
889+ hr = pad->pDIDJoyPad->lpVtbl->GetProperty( pad->pDIDJoyPad, DIPROP_RANGE, &diprg.diph );
890+
891+ if( FAILED( hr ) )
892+ {
893+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - GetProperty" );
894+ }
895+
896+ /* x軸 */
897+ if( memcmp( &pdidoi->guidType, &GUID_XAxis ,sizeof(GUID)) == 0 )
898+ {
899+ int xcenter;
900+ xcenter = (diprg.lMin + diprg.lMax) / 2;
901+ pad->left = (xcenter - diprg.lMin) / 2;
902+ pad->right = (diprg.lMax - xcenter) / 2 + xcenter;
903+ }
904+
905+ /* y軸 */
906+ if( memcmp( &pdidoi->guidType, &GUID_YAxis ,sizeof(GUID)) == 0 )
907+ {
908+ int ycenter;
909+ ycenter = (diprg.lMin + diprg.lMax) / 2;
910+ pad->up = (ycenter - diprg.lMin) / 2;
911+ pad->down = (diprg.lMax - ycenter) / 2 + ycenter;
912+ }
913+
914+ return DIENUM_CONTINUE;
915+}
916+
917+/*--------------------------------------------------------------------
918+ (内部関数)DirectInput初期化
919+ ---------------------------------------------------------------------*/
920+static void InitDirectInput( void )
921+{
922+ HRESULT hr;
923+ int i;
924+
925+/* DirectInput初期化 */
926+
927+ /* DirectInputオブジェクトの作成 */
928+ hr = DirectInput8Create( g_hInstance, DIRECTINPUT_VERSION,
929+ &IID_IDirectInput8, (void **)&g_pDInput, NULL );
930+
931+ if( FAILED( hr ) )
932+ {
933+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - DirectInput8Create" );
934+ }
935+
936+/* キーボード */
937+
938+ /* デバイス・オブジェクトを作成(キーボード) */
939+ hr = g_pDInput->lpVtbl->CreateDevice( g_pDInput, &GUID_SysKeyboard, &g_pDIDKeyBoard, NULL );
940+
941+ if( FAILED( hr ) )
942+ {
943+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - CreateDevice" );
944+ }
945+
946+ /* データ形式を設定(キーボードですよ) */
947+ hr = g_pDIDKeyBoard->lpVtbl->SetDataFormat( g_pDIDKeyBoard, &c_dfDIKeyboard );
948+
949+ if( FAILED( hr ) )
950+ {
951+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetDataFormat" );
952+ }
953+
954+ /* キーボードのモードを設定(フォアグラウンド&非排他モード) */
955+ hr = g_pDIDKeyBoard->lpVtbl->SetCooperativeLevel( g_pDIDKeyBoard, g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
956+
957+ if( FAILED( hr ) )
958+ {
959+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetCooperativeLevel" );
960+ }
961+
962+ /* 入力制御開始 */
963+ g_pDIDKeyBoard->lpVtbl->Acquire( g_pDIDKeyBoard );
964+
965+
966+/* ゲームパッド */
967+
968+ for( i = 0; i < PADMAX; i++)
969+ {
970+ g_pDIDJoyPad[i] = NULL;
971+ }
972+ g_JoystickCount = 0;
973+
974+ /* ゲームデバイス列挙 */
975+ hr = g_pDInput->lpVtbl->EnumDevices( g_pDInput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY );
976+
977+ if( FAILED( hr ) )
978+ {
979+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - EnumDevices" );
980+ }
981+
982+ /* ゲームデバイス初期化 */
983+ for ( i = 0; i < g_JoystickCount; i++ )
984+ {
985+ /* データ形式を設定 */
986+ hr = g_pDIDJoyPad[i]->lpVtbl->SetDataFormat( g_pDIDJoyPad[i], &c_dfDIJoystick );
987+
988+ if( FAILED( hr ) )
989+ {
990+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetDataFormat" );
991+ }
992+
993+ /* キーボードのモードを設定(フォアグラウンド&非排他モード) */
994+ hr = g_pDIDJoyPad[i]->lpVtbl->SetCooperativeLevel( g_pDIDJoyPad[i], g_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND );
995+
996+ if( FAILED( hr ) )
997+ {
998+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - SetCooperativeLevel" );
999+ }
1000+
1001+ /* オブジェクト列挙 */
1002+ g_PadInfo[i].pDIDJoyPad = g_pDIDJoyPad[i];
1003+ hr = g_pDIDJoyPad[i]->lpVtbl->EnumObjects( g_pDIDJoyPad[i], EnumAxisCallback, &g_PadInfo[i], DIDFT_AXIS );
1004+
1005+ if( FAILED( hr ) )
1006+ {
1007+ rb_raise( eDXRubyError, "DirectInputの初期化に失敗しました - EnumObjects" );
1008+ }
1009+
1010+ /* 入力制御開始 */
1011+ g_pDIDJoyPad[i]->lpVtbl->Acquire( g_pDIDJoyPad[i] );
1012+ }
1013+
1014+}
1015+
1016+
1017+void Input_release( void )
1018+{
1019+ int i;
1020+
1021+ for( i = 0 ; i < g_JoystickCount; i++ )
1022+ {
1023+ /* DirectInputDevice(JoyPad)オブジェクトの使用終了 */
1024+ if( g_pDIDJoyPad[i] )
1025+ {
1026+ g_pDIDJoyPad[i]->lpVtbl->Unacquire( g_pDIDJoyPad[i] );
1027+ }
1028+
1029+ /* DirectInputDevide(JoyPad)オブジェクトの破棄 */
1030+ RELEASE( g_pDIDJoyPad[i] );
1031+ }
1032+
1033+ /* DirectInputDevice(Keyboard)オブジェクトの使用終了 */
1034+ if( g_pDIDKeyBoard )
1035+ {
1036+ g_pDIDKeyBoard->lpVtbl->Unacquire( g_pDIDKeyBoard );
1037+ }
1038+
1039+ /* DirectInputDevide(Keyboard)オブジェクトの破棄 */
1040+ RELEASE( g_pDIDKeyBoard );
1041+
1042+ /* DirectInputオブジェクトの破棄 */
1043+ RELEASE( g_pDInput );
1044+}
1045+
1046+void Init_dxruby_Input( void )
1047+{
1048+ int i, j;
1049+
1050+ /* Inputモジュール登録 */
1051+ mInput = rb_define_module_under( mDXRuby, "Input" );
1052+
1053+ /* Inputモジュールにメソッド登録 */
1054+ rb_define_singleton_method( mInput, "x" , Input_x , -1 );
1055+ rb_define_singleton_method( mInput, "y" , Input_y , -1 );
1056+ rb_define_singleton_method( mInput, "set_mouse_pos" , Input_setmousepos , 2 );
1057+ rb_define_singleton_method( mInput, "setMousePos" , Input_setmousepos , 2 );
1058+ rb_define_singleton_method( mInput, "mouse_pos_x" , Input_getmouseposx , 0 );
1059+ rb_define_singleton_method( mInput, "mousePosX" , Input_getmouseposx , 0 );
1060+ rb_define_singleton_method( mInput, "mouse_pos_y" , Input_getmouseposy , 0 );
1061+ rb_define_singleton_method( mInput, "mousePosY" , Input_getmouseposy , 0 );
1062+ rb_define_singleton_method( mInput, "key_down?" , Input_keyDown , 1 );
1063+ rb_define_singleton_method( mInput, "keyDown?" , Input_keyDown , 1 );
1064+ rb_define_singleton_method( mInput, "key_push?" , Input_keyPush , 1 );
1065+ rb_define_singleton_method( mInput, "keyPush?" , Input_keyPush , 1 );
1066+ rb_define_singleton_method( mInput, "pad_down?" , Input_padDown , -1 );
1067+ rb_define_singleton_method( mInput, "padDown?" , Input_padDown , -1 );
1068+ rb_define_singleton_method( mInput, "pad_push?" , Input_padPush , -1 );
1069+ rb_define_singleton_method( mInput, "padPush?" , Input_padPush , -1 );
1070+ rb_define_singleton_method( mInput, "mouse_down?" , Input_mouseDown , 1 );
1071+ rb_define_singleton_method( mInput, "mouseDown?" , Input_mouseDown , 1 );
1072+ rb_define_singleton_method( mInput, "mouse_push?" , Input_mousePush , 1 );
1073+ rb_define_singleton_method( mInput, "mousePush?" , Input_mousePush , 1 );
1074+ rb_define_singleton_method( mInput, "mouse_enable=" , Input_enablemouse , 1 );
1075+ rb_define_singleton_method( mInput, "mouseEnable=" , Input_enablemouse , 1 );
1076+ rb_define_singleton_method( mInput, "mouse_wheel_pos" , Input_getmousewheelpos, 0 );
1077+ rb_define_singleton_method( mInput, "mouseWheelPos" , Input_getmousewheelpos, 0 );
1078+ rb_define_singleton_method( mInput, "mouse_wheel_pos=" , Input_setmousewheelpos, 1 );
1079+ rb_define_singleton_method( mInput, "mouseWheelPos=" , Input_setmousewheelpos, 1 );
1080+ rb_define_singleton_method( mInput, "set_config" , Input_setconfig , -1 );
1081+ rb_define_singleton_method( mInput, "setConfig" , Input_setconfig , -1 );
1082+ rb_define_singleton_method( mInput, "set_repeat" , Input_setrepeat , 2 );
1083+ rb_define_singleton_method( mInput, "setRepeat" , Input_setrepeat , 2 );
1084+ rb_define_singleton_method( mInput, "update" , Input_update , 0 );
1085+ rb_define_singleton_method( mInput, "set_key_repeat" , Input_setkeyrepeat , 3 );
1086+ rb_define_singleton_method( mInput, "setKeyRepeat" , Input_setkeyrepeat , 3 );
1087+ rb_define_singleton_method( mInput, "set_pad_repeat" , Input_setpadrepeat , -1 );
1088+ rb_define_singleton_method( mInput, "setPadRepeat" , Input_setpadrepeat , -1 );
1089+ rb_define_singleton_method( mInput, "keys" , Input_getKeys , 0 );
1090+ rb_define_singleton_method( mInput, "pads" , Input_getPads , -1 );
1091+ rb_define_singleton_method( mInput, "pad_num" , Input_getPadNum , 0 );
1092+
1093+ /* キーボードのスキャンコード定数設定 */
1094+ rb_define_const( mDXRuby, "K_ESCAPE" , INT2FIX(DIK_ESCAPE) );
1095+ rb_define_const( mDXRuby, "K_1" , INT2FIX(DIK_1) );
1096+ rb_define_const( mDXRuby, "K_2" , INT2FIX(DIK_2) );
1097+ rb_define_const( mDXRuby, "K_3" , INT2FIX(DIK_3) );
1098+ rb_define_const( mDXRuby, "K_4" , INT2FIX(DIK_4) );
1099+ rb_define_const( mDXRuby, "K_5" , INT2FIX(DIK_5) );
1100+ rb_define_const( mDXRuby, "K_6" , INT2FIX(DIK_6) );
1101+ rb_define_const( mDXRuby, "K_7" , INT2FIX(DIK_7) );
1102+ rb_define_const( mDXRuby, "K_8" , INT2FIX(DIK_8) );
1103+ rb_define_const( mDXRuby, "K_9" , INT2FIX(DIK_9) );
1104+ rb_define_const( mDXRuby, "K_0" , INT2FIX(DIK_0) );
1105+ rb_define_const( mDXRuby, "K_MINUS" , INT2FIX(DIK_MINUS) );
1106+ rb_define_const( mDXRuby, "K_EQUALS" , INT2FIX(DIK_EQUALS) );
1107+ rb_define_const( mDXRuby, "K_BACK" , INT2FIX(DIK_BACK) );
1108+ rb_define_const( mDXRuby, "K_TAB" , INT2FIX(DIK_TAB) );
1109+ rb_define_const( mDXRuby, "K_Q" , INT2FIX(DIK_Q) );
1110+ rb_define_const( mDXRuby, "K_W" , INT2FIX(DIK_W) );
1111+ rb_define_const( mDXRuby, "K_E" , INT2FIX(DIK_E) );
1112+ rb_define_const( mDXRuby, "K_R" , INT2FIX(DIK_R) );
1113+ rb_define_const( mDXRuby, "K_T" , INT2FIX(DIK_T) );
1114+ rb_define_const( mDXRuby, "K_Y" , INT2FIX(DIK_Y) );
1115+ rb_define_const( mDXRuby, "K_U" , INT2FIX(DIK_U) );
1116+ rb_define_const( mDXRuby, "K_I" , INT2FIX(DIK_I) );
1117+ rb_define_const( mDXRuby, "K_O" , INT2FIX(DIK_O) );
1118+ rb_define_const( mDXRuby, "K_P" , INT2FIX(DIK_P) );
1119+ rb_define_const( mDXRuby, "K_LBRACKET" , INT2FIX(DIK_LBRACKET) );
1120+ rb_define_const( mDXRuby, "K_RBRACKET" , INT2FIX(DIK_RBRACKET) );
1121+ rb_define_const( mDXRuby, "K_RETURN" , INT2FIX(DIK_RETURN) );
1122+ rb_define_const( mDXRuby, "K_LCONTROL" , INT2FIX(DIK_LCONTROL) );
1123+ rb_define_const( mDXRuby, "K_A" , INT2FIX(DIK_A) );
1124+ rb_define_const( mDXRuby, "K_S" , INT2FIX(DIK_S) );
1125+ rb_define_const( mDXRuby, "K_D" , INT2FIX(DIK_D) );
1126+ rb_define_const( mDXRuby, "K_F" , INT2FIX(DIK_F) );
1127+ rb_define_const( mDXRuby, "K_G" , INT2FIX(DIK_G) );
1128+ rb_define_const( mDXRuby, "K_H" , INT2FIX(DIK_H) );
1129+ rb_define_const( mDXRuby, "K_J" , INT2FIX(DIK_J) );
1130+ rb_define_const( mDXRuby, "K_K" , INT2FIX(DIK_K) );
1131+ rb_define_const( mDXRuby, "K_L" , INT2FIX(DIK_L) );
1132+ rb_define_const( mDXRuby, "K_SEMICOLON" , INT2FIX(DIK_SEMICOLON) );
1133+ rb_define_const( mDXRuby, "K_APOSTROPHE" , INT2FIX(DIK_APOSTROPHE) );
1134+ rb_define_const( mDXRuby, "K_GRAVE" , INT2FIX(DIK_GRAVE) );
1135+ rb_define_const( mDXRuby, "K_LSHIFT" , INT2FIX(DIK_LSHIFT) );
1136+ rb_define_const( mDXRuby, "K_BACKSLASH" , INT2FIX(DIK_BACKSLASH) );
1137+ rb_define_const( mDXRuby, "K_Z" , INT2FIX(DIK_Z) );
1138+ rb_define_const( mDXRuby, "K_X" , INT2FIX(DIK_X) );
1139+ rb_define_const( mDXRuby, "K_C" , INT2FIX(DIK_C) );
1140+ rb_define_const( mDXRuby, "K_V" , INT2FIX(DIK_V) );
1141+ rb_define_const( mDXRuby, "K_B" , INT2FIX(DIK_B) );
1142+ rb_define_const( mDXRuby, "K_N" , INT2FIX(DIK_N) );
1143+ rb_define_const( mDXRuby, "K_M" , INT2FIX(DIK_M) );
1144+ rb_define_const( mDXRuby, "K_COMMA" , INT2FIX(DIK_COMMA) );
1145+ rb_define_const( mDXRuby, "K_PERIOD" , INT2FIX(DIK_PERIOD) );
1146+ rb_define_const( mDXRuby, "K_SLASH" , INT2FIX(DIK_SLASH) );
1147+ rb_define_const( mDXRuby, "K_RSHIFT" , INT2FIX(DIK_RSHIFT) );
1148+ rb_define_const( mDXRuby, "K_MULTIPLY" , INT2FIX(DIK_MULTIPLY) );
1149+ rb_define_const( mDXRuby, "K_LMENU" , INT2FIX(DIK_LMENU) );
1150+ rb_define_const( mDXRuby, "K_SPACE" , INT2FIX(DIK_SPACE) );
1151+ rb_define_const( mDXRuby, "K_CAPITAL" , INT2FIX(DIK_CAPITAL) );
1152+ rb_define_const( mDXRuby, "K_F1" , INT2FIX(DIK_F1) );
1153+ rb_define_const( mDXRuby, "K_F2" , INT2FIX(DIK_F2) );
1154+ rb_define_const( mDXRuby, "K_F3" , INT2FIX(DIK_F3) );
1155+ rb_define_const( mDXRuby, "K_F4" , INT2FIX(DIK_F4) );
1156+ rb_define_const( mDXRuby, "K_F5" , INT2FIX(DIK_F5) );
1157+ rb_define_const( mDXRuby, "K_F6" , INT2FIX(DIK_F6) );
1158+ rb_define_const( mDXRuby, "K_F7" , INT2FIX(DIK_F7) );
1159+ rb_define_const( mDXRuby, "K_F8" , INT2FIX(DIK_F8) );
1160+ rb_define_const( mDXRuby, "K_F9" , INT2FIX(DIK_F9) );
1161+ rb_define_const( mDXRuby, "K_F10" , INT2FIX(DIK_F10) );
1162+ rb_define_const( mDXRuby, "K_NUMLOCK" , INT2FIX(DIK_NUMLOCK) );
1163+ rb_define_const( mDXRuby, "K_SCROLL" , INT2FIX(DIK_SCROLL) );
1164+ rb_define_const( mDXRuby, "K_NUMPAD7" , INT2FIX(DIK_NUMPAD7) );
1165+ rb_define_const( mDXRuby, "K_NUMPAD8" , INT2FIX(DIK_NUMPAD8) );
1166+ rb_define_const( mDXRuby, "K_NUMPAD9" , INT2FIX(DIK_NUMPAD9) );
1167+ rb_define_const( mDXRuby, "K_SUBTRACT" , INT2FIX(DIK_SUBTRACT) );
1168+ rb_define_const( mDXRuby, "K_NUMPAD4" , INT2FIX(DIK_NUMPAD4) );
1169+ rb_define_const( mDXRuby, "K_NUMPAD5" , INT2FIX(DIK_NUMPAD5) );
1170+ rb_define_const( mDXRuby, "K_NUMPAD6" , INT2FIX(DIK_NUMPAD6) );
1171+ rb_define_const( mDXRuby, "K_ADD" , INT2FIX(DIK_ADD) );
1172+ rb_define_const( mDXRuby, "K_NUMPAD1" , INT2FIX(DIK_NUMPAD1) );
1173+ rb_define_const( mDXRuby, "K_NUMPAD2" , INT2FIX(DIK_NUMPAD2) );
1174+ rb_define_const( mDXRuby, "K_NUMPAD3" , INT2FIX(DIK_NUMPAD3) );
1175+ rb_define_const( mDXRuby, "K_NUMPAD0" , INT2FIX(DIK_NUMPAD0) );
1176+ rb_define_const( mDXRuby, "K_DECIMAL" , INT2FIX(DIK_DECIMAL) );
1177+ rb_define_const( mDXRuby, "K_OEM_102" , INT2FIX(DIK_OEM_102) );
1178+ rb_define_const( mDXRuby, "K_F11" , INT2FIX(DIK_F11) );
1179+ rb_define_const( mDXRuby, "K_F12" , INT2FIX(DIK_F12) );
1180+ rb_define_const( mDXRuby, "K_F13" , INT2FIX(DIK_F13) );
1181+ rb_define_const( mDXRuby, "K_F14" , INT2FIX(DIK_F14) );
1182+ rb_define_const( mDXRuby, "K_F15" , INT2FIX(DIK_F15) );
1183+ rb_define_const( mDXRuby, "K_KANA" , INT2FIX(DIK_KANA) );
1184+ rb_define_const( mDXRuby, "K_ABNT_C1" , INT2FIX(DIK_ABNT_C1) );
1185+ rb_define_const( mDXRuby, "K_CONVERT" , INT2FIX(DIK_CONVERT) );
1186+ rb_define_const( mDXRuby, "K_NOCONVERT" , INT2FIX(DIK_NOCONVERT) );
1187+ rb_define_const( mDXRuby, "K_YEN" , INT2FIX(DIK_YEN) );
1188+ rb_define_const( mDXRuby, "K_ABNT_C2" , INT2FIX(DIK_ABNT_C2) );
1189+ rb_define_const( mDXRuby, "K_NUMPADEQUALS", INT2FIX(DIK_NUMPADEQUALS) );
1190+ rb_define_const( mDXRuby, "K_PREVTRACK" , INT2FIX(DIK_PREVTRACK) );
1191+ rb_define_const( mDXRuby, "K_AT" , INT2FIX(DIK_AT) );
1192+ rb_define_const( mDXRuby, "K_COLON" , INT2FIX(DIK_COLON) );
1193+ rb_define_const( mDXRuby, "K_UNDERLINE" , INT2FIX(DIK_UNDERLINE) );
1194+ rb_define_const( mDXRuby, "K_KANJI" , INT2FIX(DIK_KANJI) );
1195+ rb_define_const( mDXRuby, "K_STOP" , INT2FIX(DIK_STOP) );
1196+ rb_define_const( mDXRuby, "K_AX" , INT2FIX(DIK_AX) );
1197+ rb_define_const( mDXRuby, "K_UNLABELED" , INT2FIX(DIK_UNLABELED) );
1198+ rb_define_const( mDXRuby, "K_NEXTTRACK" , INT2FIX(DIK_NEXTTRACK) );
1199+ rb_define_const( mDXRuby, "K_NUMPADENTER", INT2FIX(DIK_NUMPADENTER) );
1200+ rb_define_const( mDXRuby, "K_RCONTROL" , INT2FIX(DIK_RCONTROL) );
1201+ rb_define_const( mDXRuby, "K_MUTE" , INT2FIX(DIK_MUTE) );
1202+ rb_define_const( mDXRuby, "K_CALCULATOR" , INT2FIX(DIK_CALCULATOR) );
1203+ rb_define_const( mDXRuby, "K_PLAYPAUSE" , INT2FIX(DIK_PLAYPAUSE) );
1204+ rb_define_const( mDXRuby, "K_MEDIASTOP" , INT2FIX(DIK_MEDIASTOP) );
1205+ rb_define_const( mDXRuby, "K_VOLUMEDOWN" , INT2FIX(DIK_VOLUMEDOWN) );
1206+ rb_define_const( mDXRuby, "K_VOLUMEUP" , INT2FIX(DIK_VOLUMEUP) );
1207+ rb_define_const( mDXRuby, "K_WEBHOME" , INT2FIX(DIK_WEBHOME) );
1208+ rb_define_const( mDXRuby, "K_NUMPADCOMMA", INT2FIX(DIK_NUMPADCOMMA) );
1209+ rb_define_const( mDXRuby, "K_DIVIDE" , INT2FIX(DIK_DIVIDE) );
1210+ rb_define_const( mDXRuby, "K_SYSRQ" , INT2FIX(DIK_SYSRQ) );
1211+ rb_define_const( mDXRuby, "K_RMENU" , INT2FIX(DIK_RMENU) );
1212+ rb_define_const( mDXRuby, "K_PAUSE" , INT2FIX(DIK_PAUSE) );
1213+ rb_define_const( mDXRuby, "K_HOME" , INT2FIX(DIK_HOME) );
1214+ rb_define_const( mDXRuby, "K_UP" , INT2FIX(DIK_UP) );
1215+ rb_define_const( mDXRuby, "K_PRIOR" , INT2FIX(DIK_PRIOR) );
1216+ rb_define_const( mDXRuby, "K_LEFT" , INT2FIX(DIK_LEFT) );
1217+ rb_define_const( mDXRuby, "K_RIGHT" , INT2FIX(DIK_RIGHT) );
1218+ rb_define_const( mDXRuby, "K_END" , INT2FIX(DIK_END) );
1219+ rb_define_const( mDXRuby, "K_DOWN" , INT2FIX(DIK_DOWN) );
1220+ rb_define_const( mDXRuby, "K_NEXT" , INT2FIX(DIK_NEXT) );
1221+ rb_define_const( mDXRuby, "K_INSERT" , INT2FIX(DIK_INSERT) );
1222+ rb_define_const( mDXRuby, "K_DELETE" , INT2FIX(DIK_DELETE) );
1223+ rb_define_const( mDXRuby, "K_LWIN" , INT2FIX(DIK_LWIN) );
1224+ rb_define_const( mDXRuby, "K_RWIN" , INT2FIX(DIK_RWIN) );
1225+ rb_define_const( mDXRuby, "K_APPS" , INT2FIX(DIK_APPS) );
1226+ rb_define_const( mDXRuby, "K_POWER" , INT2FIX(DIK_POWER) );
1227+ rb_define_const( mDXRuby, "K_SLEEP" , INT2FIX(DIK_SLEEP) );
1228+ rb_define_const( mDXRuby, "K_WAKE" , INT2FIX(DIK_WAKE) );
1229+ rb_define_const( mDXRuby, "K_WEBSEARCH" , INT2FIX(DIK_WEBSEARCH) );
1230+ rb_define_const( mDXRuby, "K_WEBFAVORITES", INT2FIX(DIK_WEBFAVORITES) );
1231+ rb_define_const( mDXRuby, "K_WEBREFRESH" , INT2FIX(DIK_WEBREFRESH) );
1232+ rb_define_const( mDXRuby, "K_WEBSTOP" , INT2FIX(DIK_WEBSTOP) );
1233+ rb_define_const( mDXRuby, "K_WEBFORWARD" , INT2FIX(DIK_WEBFORWARD) );
1234+ rb_define_const( mDXRuby, "K_WEBBACK" , INT2FIX(DIK_WEBBACK) );
1235+ rb_define_const( mDXRuby, "K_MYCOMPUTER" , INT2FIX(DIK_MYCOMPUTER) );
1236+ rb_define_const( mDXRuby, "K_MAIL" , INT2FIX(DIK_MAIL) );
1237+ rb_define_const( mDXRuby, "K_MEDIASELECT", INT2FIX(DIK_MEDIASELECT) );
1238+ rb_define_const( mDXRuby, "K_BACKSPACE" , INT2FIX(DIK_BACK) );
1239+ rb_define_const( mDXRuby, "K_NUMPADSTAR" , INT2FIX(DIK_MULTIPLY) );
1240+ rb_define_const( mDXRuby, "K_LALT" , INT2FIX(DIK_LMENU) );
1241+ rb_define_const( mDXRuby, "K_CAPSLOCK" , INT2FIX(DIK_CAPITAL) );
1242+ rb_define_const( mDXRuby, "K_NUMPADMINUS", INT2FIX(DIK_SUBTRACT) );
1243+ rb_define_const( mDXRuby, "K_NUMPADPLUS" , INT2FIX(DIK_ADD) );
1244+ rb_define_const( mDXRuby, "K_NUMPADPERIOD", INT2FIX(DIK_DECIMAL) );
1245+ rb_define_const( mDXRuby, "K_NUMPADSLASH", INT2FIX(DIK_DIVIDE) );
1246+ rb_define_const( mDXRuby, "K_RALT" , INT2FIX(DIK_RMENU) );
1247+ rb_define_const( mDXRuby, "K_UPARROW" , INT2FIX(DIK_UP) );
1248+ rb_define_const( mDXRuby, "K_PGUP" , INT2FIX(DIK_PRIOR) );
1249+ rb_define_const( mDXRuby, "K_LEFTARROW" , INT2FIX(DIK_LEFT) );
1250+ rb_define_const( mDXRuby, "K_RIGHTARROW" , INT2FIX(DIK_RIGHT) );
1251+ rb_define_const( mDXRuby, "K_DOWNARROW" , INT2FIX(DIK_DOWN) );
1252+ rb_define_const( mDXRuby, "K_PGDN" , INT2FIX(DIK_NEXT) );
1253+
1254+ rb_define_const( mDXRuby, "P_UP" , INT2FIX(P_UP) );
1255+ rb_define_const( mDXRuby, "P_LEFT" , INT2FIX(P_LEFT) );
1256+ rb_define_const( mDXRuby, "P_RIGHT" , INT2FIX(P_RIGHT) );
1257+ rb_define_const( mDXRuby, "P_DOWN" , INT2FIX(P_DOWN) );
1258+ rb_define_const( mDXRuby, "P_BUTTON0" , INT2FIX(P_BUTTON0) );
1259+ rb_define_const( mDXRuby, "P_BUTTON1" , INT2FIX(P_BUTTON1) );
1260+ rb_define_const( mDXRuby, "P_BUTTON2" , INT2FIX(P_BUTTON2) );
1261+ rb_define_const( mDXRuby, "P_BUTTON3" , INT2FIX(P_BUTTON3) );
1262+ rb_define_const( mDXRuby, "P_BUTTON4" , INT2FIX(P_BUTTON4) );
1263+ rb_define_const( mDXRuby, "P_BUTTON5" , INT2FIX(P_BUTTON5) );
1264+ rb_define_const( mDXRuby, "P_BUTTON6" , INT2FIX(P_BUTTON6) );
1265+ rb_define_const( mDXRuby, "P_BUTTON7" , INT2FIX(P_BUTTON7) );
1266+ rb_define_const( mDXRuby, "P_BUTTON8" , INT2FIX(P_BUTTON8) );
1267+ rb_define_const( mDXRuby, "P_BUTTON9" , INT2FIX(P_BUTTON9) );
1268+ rb_define_const( mDXRuby, "P_BUTTON10" , INT2FIX(P_BUTTON10) );
1269+ rb_define_const( mDXRuby, "P_BUTTON11" , INT2FIX(P_BUTTON11) );
1270+ rb_define_const( mDXRuby, "P_BUTTON12" , INT2FIX(P_BUTTON12) );
1271+ rb_define_const( mDXRuby, "P_BUTTON13" , INT2FIX(P_BUTTON13) );
1272+ rb_define_const( mDXRuby, "P_BUTTON14" , INT2FIX(P_BUTTON14) );
1273+ rb_define_const( mDXRuby, "P_BUTTON15" , INT2FIX(P_BUTTON15) );
1274+
1275+ rb_define_const( mDXRuby, "M_LBUTTON" , INT2FIX(M_LBUTTON) );
1276+ rb_define_const( mDXRuby, "M_RBUTTON" , INT2FIX(M_RBUTTON) );
1277+ rb_define_const( mDXRuby, "M_MBUTTON" , INT2FIX(M_MBUTTON) );
1278+
1279+ /* 割り当て初期化 */
1280+ for( i = 0; i < 256; i++)
1281+ {
1282+ g_diKeyConfig[i] = -1;
1283+ }
1284+ for( i = 0; i < PADMAX; i++)
1285+ {
1286+ for( j = 0; j < 20; j++)
1287+ {
1288+ g_PadState[i].PadConfig[j] = -1;
1289+ }
1290+ }
1291+
1292+ /* デフォルトの割り当て */
1293+ Input_SetConfig( 0, P_LEFT , DIK_LEFT );
1294+ Input_SetConfig( 0, P_RIGHT , DIK_RIGHT );
1295+ Input_SetConfig( 0, P_UP , DIK_UP );
1296+ Input_SetConfig( 0, P_DOWN , DIK_DOWN );
1297+ Input_SetConfig( 0, P_BUTTON0, DIK_Z );
1298+ Input_SetConfig( 0, P_BUTTON1, DIK_X );
1299+ Input_SetConfig( 0, P_BUTTON2, DIK_C );
1300+
1301+ /* DirectInput初期化 */
1302+ InitDirectInput();
1303+
1304+}
1305+
1306+
--- tags/1.2.2/input.h (nonexistent)
+++ tags/1.2.2/input.h (revision 276)
@@ -0,0 +1,3 @@
1+void Init_dxruby_Input( void );
2+void inputupdate_internal( void );
3+VALUE Input_update( VALUE obj );
--- tags/1.2.2/font.c (nonexistent)
+++ tags/1.2.2/font.c (revision 276)
@@ -0,0 +1,384 @@
1+#define WINVER 0x0500 /* バージョン定義 Windows2000以上 */
2+#define _WIN32_WINNT WINVER
3+
4+#include "ruby.h"
5+#ifndef RUBY_ST_H
6+#include "st.h"
7+#endif
8+
9+#define DXRUBY_EXTERN 1
10+#include "dxruby.h"
11+#include "font.h"
12+
13+static VALUE cFont; /* フォントクラス */
14+static VALUE symbol_italic = Qundef;
15+static VALUE symbol_weight = Qundef;
16+
17+/*********************************************************************
18+ * Fontクラス
19+ *
20+ * D3DXFontインターフェースを使用してフォントを描画する。
21+ * スプライト描画に混ぜ込むことでとりあえず実装。
22+ *********************************************************************/
23+/*--------------------------------------------------------------------
24+ 参照されなくなったときにGCから呼ばれる関数
25+ ---------------------------------------------------------------------*/
26+static void Font_free( struct DXRubyFont *font )
27+{
28+ RELEASE( font->pD3DXFont );
29+ DeleteObject( font->hFont );
30+}
31+void Font_release( struct DXRubyFont *font )
32+{
33+ /* フォントオブジェクトの開放 */
34+ if( font->pD3DXFont )
35+ {
36+ Font_free( font );
37+ }
38+ free( font );
39+ font = NULL;
40+
41+ g_iRefAll--;
42+ if( g_iRefAll == 0 )
43+ {
44+ CoUninitialize();
45+ }
46+}
47+
48+/*--------------------------------------------------------------------
49+ Fontクラスのdispose。
50+ ---------------------------------------------------------------------*/
51+static VALUE Font_dispose( VALUE self )
52+{
53+ struct DXRubyFont *font = DXRUBY_GET_STRUCT( Font, self );
54+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
55+ Font_free( font );
56+ return self;
57+}
58+
59+/*--------------------------------------------------------------------
60+ Fontクラスのdisposed?。
61+ ---------------------------------------------------------------------*/
62+static VALUE Font_check_disposed( VALUE self )
63+{
64+ if( DXRUBY_GET_STRUCT( Font, self )->pD3DXFont == NULL )
65+ {
66+ return Qtrue;
67+ }
68+
69+ return Qfalse;
70+}
71+
72+/*--------------------------------------------------------------------
73+ Fontクラスのmark
74+ ---------------------------------------------------------------------*/
75+static void Font_mark( struct DXRubyFont *font )
76+{
77+ rb_gc_mark( font->fontname );
78+ rb_gc_mark( font->italic );
79+ rb_gc_mark( font->weight );
80+}
81+
82+/*--------------------------------------------------------------------
83+ Fontクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
84+ ---------------------------------------------------------------------*/
85+static VALUE Font_allocate( VALUE klass )
86+{
87+ VALUE obj;
88+ struct DXRubyFont *font;
89+
90+ /* DXRubyFontのメモリ取得&Fontオブジェクト生成 */
91+ font = malloc( sizeof(struct DXRubyFont) );
92+ if( font == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Font_allocate" );
93+ obj = Data_Wrap_Struct(klass, Font_mark, Font_release, font);
94+ font->fontname = Qnil;
95+ font->italic = Qnil;
96+ font->weight = Qnil;
97+ return obj;
98+}
99+
100+
101+/*--------------------------------------------------------------------
102+ FontクラスのInitialize
103+ ---------------------------------------------------------------------*/
104+static VALUE Font_initialize( int argc, VALUE *argv, VALUE obj )
105+{
106+ struct DXRubyFont *font;
107+ HRESULT hr;
108+ D3DXFONT_DESC desc;
109+ VALUE size, vfontname, voption, hash, vweight, vitalic;
110+ LOGFONT logfont;
111+ int weight, italic;
112+
113+ g_iRefAll++;
114+
115+ rb_scan_args( argc, argv, "12", &size, &vfontname, &hash );
116+
117+ if( hash == Qnil )
118+ {
119+ voption = rb_hash_new();
120+ }
121+ else
122+ {
123+ Check_Type( hash, T_HASH );
124+ voption = hash;
125+ }
126+
127+ vweight = hash_lookup( voption, symbol_weight );
128+ vitalic = hash_lookup( voption, symbol_italic );
129+
130+ if( vweight == Qnil || vweight == Qfalse )
131+ {
132+ weight = 400;
133+ }
134+ else if( vweight == Qtrue )
135+ {
136+ weight = 1000;
137+ }
138+ else
139+ {
140+ weight = NUM2INT( vweight );
141+ }
142+
143+ if( vitalic == Qnil || vitalic == Qfalse )
144+ {
145+ italic = FALSE;
146+ }
147+ else
148+ {
149+ italic = TRUE;
150+ }
151+
152+ desc.Height = NUM2INT( size );
153+ desc.Width = 0;
154+ desc.Weight = weight;
155+ desc.MipLevels = 0;
156+ desc.Italic = italic;
157+ desc.CharSet = DEFAULT_CHARSET;
158+ desc.OutputPrecision = 0;
159+ desc.Quality = DEFAULT_QUALITY;
160+ desc.PitchAndFamily = DEFAULT_PITCH || FF_DONTCARE;
161+
162+ ZeroMemory( &logfont, sizeof(logfont) );
163+ logfont.lfHeight = NUM2INT( size );
164+ logfont.lfWidth = 0;
165+ logfont.lfWeight = weight;
166+ logfont.lfItalic = italic;
167+ logfont.lfCharSet = DEFAULT_CHARSET;
168+ logfont.lfQuality = ANTIALIASED_QUALITY;
169+
170+ if( vfontname == Qnil )
171+ {
172+ lstrcpy(desc.FaceName, "");
173+ lstrcpy(logfont.lfFaceName, "");
174+ }
175+ else
176+ {
177+ VALUE vsjisstr;
178+ Check_Type(vfontname, T_STRING);
179+#ifdef HAVE_RB_ENC_STR_NEW
180+ if( rb_enc_get_index( vfontname ) != 0 )
181+ {
182+ vsjisstr = rb_funcall( vfontname, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
183+ }
184+ else
185+ {
186+ vsjisstr = vfontname;
187+ }
188+#else
189+ vsjisstr = vfontname;
190+#endif
191+ lstrcpy(desc.FaceName, RSTRING_PTR( vsjisstr ));
192+ lstrcpy(logfont.lfFaceName, RSTRING_PTR( vsjisstr ));
193+ }
194+
195+ /* フォントオブジェクト取り出し */
196+ Data_Get_Struct( obj, struct DXRubyFont, font );
197+
198+ hr = D3DXCreateFontIndirect( g_pD3DDevice, &desc, &font->pD3DXFont );
199+
200+ if( FAILED( hr ) )
201+ {
202+ rb_raise( eDXRubyError, "フォントの作成に失敗しました - D3DXCreateFontIndirect" );
203+ }
204+
205+ font->hFont = CreateFontIndirect( &logfont );
206+
207+ if( font->hFont == NULL )
208+ {
209+ rb_raise( eDXRubyError, "フォントの作成に失敗しました - CreateFontIndirect" );
210+ }
211+
212+ font->size = NUM2INT( size );
213+ font->italic = vitalic;
214+ font->weight = vweight;
215+#ifdef HAVE_RB_ENC_STR_NEW
216+ font->fontname = vfontname == Qnil ? Qnil : rb_str_new_shared( vfontname );
217+#else
218+ font->fontname = vfontname == Qnil ? Qnil : rb_str_new2( RSTRING_PTR(vfontname) );
219+#endif
220+
221+ return obj;
222+}
223+
224+
225+/*--------------------------------------------------------------------
226+ Fontクラスのinstall
227+ ---------------------------------------------------------------------*/
228+static VALUE Font_install( VALUE klass, VALUE vstr )
229+{
230+ int result;
231+ VALUE vsjisstr;
232+ Check_Type( vstr, T_STRING );
233+
234+#ifdef HAVE_RB_ENC_STR_NEW
235+ if( rb_enc_get_index( vstr ) != 0 )
236+ {
237+ vsjisstr = rb_funcall( vstr, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
238+ }
239+ else
240+ {
241+ vsjisstr = vstr;
242+ }
243+#else
244+ vsjisstr = vstr;
245+#endif
246+ result = AddFontResourceEx( RSTRING_PTR( vsjisstr ), 0x10, 0 );
247+ if( result == 0 )
248+ {
249+ rb_raise( eDXRubyError, "フォントのインストールに失敗しました - Font_install" );
250+ }
251+
252+ return INT2FIX( result );
253+}
254+
255+
256+/*--------------------------------------------------------------------
257+ フォントの幅を取得する
258+ ---------------------------------------------------------------------*/
259+VALUE Font_getWidth( VALUE obj, VALUE vstr )
260+{
261+ HDC hDC;
262+ struct DXRubyFont *font;
263+ RECT rc;
264+ VALUE vsjisstr;
265+
266+ Check_Type( vstr, T_STRING );
267+
268+ /* フォントオブジェクト取り出し */
269+ Data_Get_Struct( obj, struct DXRubyFont, font );
270+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
271+
272+ hDC = GetDC( g_hWnd );
273+ if( hDC == NULL )
274+ {
275+ rb_raise( eDXRubyError, "DCの取得に失敗しました - GetDC" );
276+ }
277+
278+ SelectObject( hDC, font->hFont );
279+ SetRect( &rc, 0, 0, 1, 1 );
280+#ifdef HAVE_RB_ENC_STR_NEW
281+ if( rb_enc_get_index( vstr ) != 0 )
282+ {
283+ vsjisstr = rb_funcall( vstr, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
284+ }
285+ else
286+ {
287+ vsjisstr = vstr;
288+ }
289+#else
290+ vsjisstr = vstr;
291+#endif
292+ DrawText( hDC, RSTRING_PTR( vsjisstr ), -1, &rc, DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_CALCRECT | DT_SINGLELINE);
293+ ReleaseDC( g_hWnd, hDC );
294+
295+ return INT2FIX( rc.right );
296+}
297+
298+
299+/*--------------------------------------------------------------------
300+ フォントのサイズを取得する
301+ ---------------------------------------------------------------------*/
302+VALUE Font_getSize( VALUE obj )
303+{
304+ struct DXRubyFont *font;
305+
306+ /* フォントオブジェクト取り出し */
307+ Data_Get_Struct( obj, struct DXRubyFont, font );
308+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
309+
310+ return INT2FIX( font->size );
311+}
312+
313+
314+/*--------------------------------------------------------------------
315+ フォント名称を取得する
316+ ---------------------------------------------------------------------*/
317+static VALUE Font_getFontname( VALUE obj )
318+{
319+ struct DXRubyFont *font;
320+
321+ /* フォントオブジェクト取り出し */
322+ Data_Get_Struct( obj, struct DXRubyFont, font );
323+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
324+
325+ return font->fontname;
326+}
327+
328+
329+/*--------------------------------------------------------------------
330+ イタリックフラグを取得する
331+ ---------------------------------------------------------------------*/
332+static VALUE Font_getItalic( VALUE obj )
333+{
334+ struct DXRubyFont *font;
335+
336+ /* フォントオブジェクト取り出し */
337+ Data_Get_Struct( obj, struct DXRubyFont, font );
338+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
339+
340+ return font->italic;
341+}
342+
343+
344+/*--------------------------------------------------------------------
345+ フォントの太さを取得する
346+ ---------------------------------------------------------------------*/
347+static VALUE Font_getWeight( VALUE obj )
348+{
349+ struct DXRubyFont *font;
350+
351+ /* フォントオブジェクト取り出し */
352+ Data_Get_Struct( obj, struct DXRubyFont, font );
353+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
354+
355+ return font->weight;
356+}
357+
358+
359+void Init_dxruby_Font()
360+{
361+ /* Fontクラス登録 */
362+ cFont = rb_define_class_under( mDXRuby, "Font", rb_cObject );
363+
364+ /* Fontクラスにクラスメソッド登録*/
365+ rb_define_singleton_method(cFont, "install", Font_install, 1);
366+
367+ /* Fontクラスにメソッド登録*/
368+ rb_define_private_method( cFont, "initialize", Font_initialize, -1 );
369+ rb_define_method( cFont, "dispose" , Font_dispose , 0 );
370+ rb_define_method( cFont, "disposed?" , Font_check_disposed, 0 );
371+ rb_define_method( cFont, "get_width" , Font_getWidth , 1 );
372+ rb_define_method( cFont, "getWidth" , Font_getWidth , 1 );
373+ rb_define_method( cFont, "fontname", Font_getFontname , 0 );
374+ rb_define_method( cFont, "italic", Font_getItalic , 0 );
375+ rb_define_method( cFont, "weight" , Font_getWeight , 0 );
376+ rb_define_method( cFont, "size" , Font_getSize , 0 );
377+
378+ /* Fontオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
379+ rb_define_alloc_func( cFont, Font_allocate );
380+
381+ symbol_italic = ID2SYM(rb_intern("italic"));
382+ symbol_weight = ID2SYM(rb_intern("weight"));
383+}
384+
--- tags/1.2.2/font.h (nonexistent)
+++ tags/1.2.2/font.h (revision 276)
@@ -0,0 +1,15 @@
1+/* フォントデータ */
2+struct DXRubyFont {
3+ LPD3DXFONT pD3DXFont; /* フォントオブジェクト */
4+ HFONT hFont; /* Image描画に使うフォント */
5+ int size; /* フォントサイズ */
6+ VALUE fontname; /* フォント名称 */
7+ VALUE weight; /* 太さ */
8+ VALUE italic; /* イタリックフラグ */
9+};
10+
11+void Init_dxruby_Font( void );
12+void Font_release( struct DXRubyFont* font );
13+VALUE Font_getWidth( VALUE obj, VALUE vstr );
14+VALUE Font_getSize( VALUE obj );
15+
--- tags/1.2.2/dxruby.c (nonexistent)
+++ tags/1.2.2/dxruby.c (revision 276)
@@ -0,0 +1,5031 @@
1+/*
2+###################################
3+#
4+# dxruby.c Ver. 1.2.2
5+#
6+###################################
7+*/
8+#define DXRUBY_VERSION "1.2.2"
9+
10+#define WINVER 0x0500 /* バージョン定義 Windows2000以上 */
11+#define _WIN32_WINNT WINVER
12+
13+#include "ruby.h"
14+#ifndef RUBY_ST_H
15+#include "st.h"
16+#endif
17+
18+#include "dxruby.h"
19+#include "image.h"
20+#include "input.h"
21+#include "sound.h"
22+#include "font.h"
23+
24+VALUE mDXRuby; /* DXRubyモジュール */
25+VALUE eDXRubyError; /* 例外 */
26+static VALUE mWindow; /* ウィンドウモジュール */
27+static VALUE cRenderTarget; /* レンダーターゲットクラス */
28+//static VALUE cShaderCore; /* シェーダコアクラス */
29+//static VALUE cShader; /* シェーダクラス */
30+
31+extern VALUE cImage;
32+
33+/* グローバル変数たち */
34+HINSTANCE g_hInstance = NULL; /* アプリケーションインスタンス */
35+HANDLE g_hWnd = NULL; /* ウィンドウハンドル */
36+LPDIRECT3D9 g_pD3D = NULL; /* Direct3Dインターフェイス */
37+LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; /* Direct3DDeviceインターフェイス */
38+D3DPRESENT_PARAMETERS g_D3DPP; /* D3DDeviceの設定 */
39+static LPD3DXSPRITE g_pD3DXSprite = NULL; /* D3DXSprite */
40+
41+int g_iRefAll = 1; /* インターフェースの参照カウント */
42+
43+/* フレーム調整用 */
44+static __int64 g_OneSecondCount = 0; /* 一秒間にカウンタが数える数 */
45+static int g_isPerformanceCounter = 0; /* パフォーマンスカウンタがあったら1 */
46+static __int64 g_OldTime = 0; /* 前回のフレームが終わった時間 */
47+static __int64 g_OneFrameCount = 0; /* 1フレームの処理にかかった時間 */
48+static __int64 g_DrawTime = 0; /* 描画にかかった時間 */
49+
50+#ifdef HAVE_RB_ENC_STR_NEW
51+/* システムエンコード */
52+char sys_encode[256];
53+#endif
54+
55+/* ウィンドウ情報 */
56+struct DXRubyWindowInfo g_WindowInfo;
57+
58+/* Picture系基底構造体 */
59+struct DXRubyPicture {
60+ void (*func)(void*);
61+ VALUE value;
62+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
63+ char reserve1;
64+ char reserve2;
65+ char reserve3;
66+};
67+
68+typedef struct tag_dx_TLVERTEX {
69+ float x, y, z;
70+ D3DCOLOR color;
71+ float tu, tv;
72+}TLVERTX, *LPTLVERTEX;
73+
74+/* デバイスロストで解放・復元するもの */
75+static struct DXRubyLostList {
76+ void **pointer;
77+ int allocate_size;
78+ int count;
79+} g_RenderTargetList, g_ShaderCoreList;
80+
81+/* シンボル */
82+VALUE symbol_blend = Qundef;
83+VALUE symbol_angle = Qundef;
84+VALUE symbol_alpha = Qundef;
85+VALUE symbol_scalex = Qundef;
86+VALUE symbol_scaley = Qundef;
87+VALUE symbol_centerx = Qundef;
88+VALUE symbol_centery = Qundef;
89+VALUE symbol_z = Qundef;
90+VALUE symbol_color = Qundef;
91+VALUE symbol_add = Qundef;
92+VALUE symbol_add2 = Qundef;
93+VALUE symbol_sub = Qundef;
94+VALUE symbol_sub2 = Qundef;
95+VALUE symbol_none = Qundef;
96+VALUE symbol_dividex = Qundef;
97+VALUE symbol_dividey = Qundef;
98+VALUE symbol_edge = Qundef;
99+VALUE symbol_edge_color = Qundef;
100+VALUE symbol_edge_width = Qundef;
101+VALUE symbol_edge_level = Qundef;
102+VALUE symbol_shadow = Qundef;
103+VALUE symbol_shadow_color = Qundef;
104+VALUE symbol_shadow_x = Qundef;
105+VALUE symbol_shadow_y = Qundef;
106+VALUE symbol_shadow_edge = Qundef;
107+//VALUE symbol_shader = Qundef;
108+VALUE symbol_int = Qundef;
109+VALUE symbol_float = Qundef;
110+VALUE symbol_texture = Qundef;
111+VALUE symbol_technique = Qundef;
112+VALUE symbol_discard = Qundef;
113+
114+/* プロトタイプ宣言 */
115+static void InitWindow( void );
116+static void InitDXGraphics( void );
117+LRESULT CALLBACK MainWndProc( HWND hWnd,UINT msg,UINT wParam,LONG lParam );
118+static void InitSync( void );
119+static __int64 GetSystemCounter( void );
120+static void Window_DirectXRelease( void );
121+static void ChangeSize( void );
122+static VALUE Window_update( VALUE );
123+static VALUE Window_sync( VALUE );
124+static VALUE Window_create( VALUE );
125+static VALUE RenderTarget_update( VALUE );
126+
127+//static void ShaderCore_release( struct DXRubyShaderCore *core );
128+
129+static VALUE RenderTarget_draw ( int argc, VALUE *argv, VALUE obj );
130+static VALUE RenderTarget_drawAlpha( int argc, VALUE *argv, VALUE obj );
131+static VALUE RenderTarget_drawAdd ( int argc, VALUE *argv, VALUE obj );
132+static VALUE RenderTarget_drawSub ( int argc, VALUE *argv, VALUE obj );
133+//static VALUE RenderTarget_drawShader( int argc, VALUE *argv, VALUE obj );
134+static VALUE RenderTarget_drawScale( int argc, VALUE *argv, VALUE obj );
135+static VALUE RenderTarget_drawRot ( int argc, VALUE *argv, VALUE obj );
136+static VALUE RenderTarget_drawEx ( int argc, VALUE *argv, VALUE obj );
137+static VALUE RenderTarget_drawFont ( int argc, VALUE *argv, VALUE obj );
138+static VALUE RenderTarget_drawFontEx ( int argc, VALUE *argv, VALUE obj );
139+static VALUE RenderTarget_drawMorph( int argc, VALUE *argv, VALUE obj );
140+static VALUE RenderTarget_drawTile ( int argc, VALUE *argv, VALUE obj );
141+static VALUE RenderTarget_getMinFilter( VALUE self );
142+static VALUE RenderTarget_setMinFilter( VALUE self, VALUE filter );
143+static VALUE RenderTarget_getMagFilter( VALUE self );
144+static VALUE RenderTarget_setMagFilter( VALUE self, VALUE filter );
145+
146+/*********************************************************************
147+ * Windowモジュール
148+ * ウィンドウの管理・描画を行う。
149+ *********************************************************************/
150+
151+/*--------------------------------------------------------------------
152+ ウィンドウの生成と初期化
153+ ---------------------------------------------------------------------*/
154+static VALUE Window_create( VALUE obj )
155+{
156+ HRESULT hr;
157+ RECT rect;
158+ VALUE vrender_target;
159+ struct DXRubyRenderTarget *rt;
160+
161+ if( g_WindowInfo.created == Qtrue )
162+ {
163+ rb_raise( eDXRubyError, "ウィンドウ作成後に実行することはできません - Window_create" );
164+ }
165+
166+ /* ウィンドウのサイズ設定 */
167+ rect.top = 0;
168+ rect.left = 0;
169+ rect.right = g_WindowInfo.width * g_WindowInfo.scale;
170+ rect.bottom = g_WindowInfo.height * g_WindowInfo.scale;
171+
172+ /* ウィンドウのサイズ修正 */
173+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
174+ { /* フルスクリーン */
175+ SetWindowLong( g_hWnd, GWL_STYLE, WS_POPUP );
176+ SetWindowPos( g_hWnd, HWND_TOP, 0, 0, g_WindowInfo.width, g_WindowInfo.height, SWP_NOZORDER);
177+ }
178+ else
179+ { /* ウィンドウモード */
180+ SetWindowLong( g_hWnd, GWL_STYLE, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
181+ AdjustWindowRect( &rect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE );
182+
183+ /* 幅と高さ計算 */
184+ rect.right = rect.right - rect.left;
185+ rect.bottom = rect.bottom - rect.top;
186+
187+ /* ウィンドウ移動/サイズ設定 */
188+ if( g_WindowInfo.x == CW_USEDEFAULT )
189+ { /* 位置がデフォルトの場合 */
190+ SetWindowPos( g_hWnd, HWND_TOP, 0, 0, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
191+ }
192+ else
193+ { /* 位置指定の場合 */
194+ SetWindowPos( g_hWnd, HWND_TOP, g_WindowInfo.x, g_WindowInfo.y, rect.right, rect.bottom, SWP_NOZORDER );
195+ }
196+ }
197+
198+ /* DirectXのスクリーンサイズ変更 */
199+ ChangeSize();
200+
201+ /* ウィンドウ表示 */
202+ ShowWindow( g_hWnd, SW_SHOWNORMAL );
203+// InvalidateRect( g_hWnd, NULL, TRUE );
204+ InvalidateRect( NULL, NULL, TRUE );
205+ UpdateWindow( g_hWnd );
206+
207+ {
208+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
209+
210+ /* シーンのクリア */
211+ g_pD3DDevice->lpVtbl->SetRenderTarget( g_pD3DDevice, 0, rt->surface );
212+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
213+ D3DCOLOR_XRGB( rt->r, rt->g, rt->b ), 0, 0 );
214+ g_pD3DDevice->lpVtbl->Present( g_pD3DDevice, NULL, NULL, NULL, NULL );
215+ }
216+
217+ /* フレーム調整処理初期化 */
218+ InitSync();
219+
220+ g_WindowInfo.created = Qtrue;
221+
222+ return obj;
223+}
224+
225+
226+// /*--------------------------------------------------------------------
227+// (内部関数)RenderTarget復帰
228+// ---------------------------------------------------------------------*/
229+// static void rt_redraw( struct DXRubyRenderTarget *rt, LPDIRECT3DTEXTURE9 pD3DTexture )
230+// {
231+// HRESULT hr;
232+// int x_2d, width_2d;
233+// int y_2d, height_2d;
234+//
235+// {
236+// D3DVIEWPORT9 vp;
237+// vp.X = x_2d = 0;
238+// vp.Y = y_2d = 0;
239+// vp.Width = width_2d = rt->texture->width;
240+// vp.Height = height_2d = rt->texture->height;
241+// vp.MinZ = 0.0f;
242+// vp.MaxZ = 1.0f;
243+// g_pD3DDevice->lpVtbl->SetRenderTarget( g_pD3DDevice, 0, rt->surface );
244+// g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
245+// g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
246+// D3DCOLOR_ARGB( rt->a, rt->r, rt->g, rt->b ), 1.0f, 0 );
247+// }
248+// //return;
249+// /* シーンの描画開始 */
250+// if( SUCCEEDED( g_pD3DDevice->lpVtbl->BeginScene( g_pD3DDevice ) ) )
251+// {
252+// g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ZENABLE,D3DZB_FALSE );
253+// g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ZWRITEENABLE, FALSE );
254+// g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_LIGHTING, FALSE);
255+// g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_FOGENABLE, FALSE );
256+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
257+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRGBWRITEENABLE, FALSE );
258+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_VERTEXBLEND, FALSE );
259+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_WRAP0, 0 );
260+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_CULLMODE, D3DCULL_NONE);
261+//
262+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
263+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
264+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
265+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
266+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
267+// g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
268+//
269+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ALPHABLENDENABLE, TRUE );
270+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE );
271+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ZERO );
272+//
273+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SEPARATEALPHABLENDENABLE, FALSE );
274+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
275+// // g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
276+//
277+// /* 拡大縮小フィルタ設定 */
278+// // g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MINFILTER,
279+// // rt->minfilter);
280+// // g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MAGFILTER,
281+// // rt->magfilter);
282+// {
283+// D3DMATRIX matrix, matrix_t;
284+//
285+// /* 2D描画 */
286+// D3DXMatrixScaling ( &matrix, 1, -1, 1 );
287+// D3DXMatrixTranslation( &matrix_t, (float)-(width_2d)/2.0f, (float)(height_2d)/2.0f, 0 );
288+// D3DXMatrixMultiply( &matrix, &matrix, &matrix_t );
289+// g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_VIEW, &matrix );
290+// matrix._11 = 2.0f / width_2d;
291+// matrix._12 = matrix._13 = matrix._14 = 0;
292+// matrix._22 = 2.0f / height_2d;
293+// matrix._21 = matrix._23 = matrix._24 = 0;
294+// matrix._31 = matrix._32 = 0;matrix._33 = 0; matrix._34 = 0;
295+// matrix._41 = matrix._42 = 0;matrix._43 = 1; matrix._44 = 1;
296+// g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_PROJECTION, &matrix );
297+// }
298+//
299+// {
300+// TLVERTX VertexDataTbl[6];
301+// float basex = -0.5f;
302+// float basey = -0.5f;
303+// float width = rt->texture->width;
304+// float height = rt->texture->height;
305+//
306+// /* 頂点1 */
307+// VertexDataTbl[0].x = basex;
308+// VertexDataTbl[0].y = basey;
309+// /* 頂点2 */
310+// VertexDataTbl[1].x = VertexDataTbl[3].x = basex + width;
311+// VertexDataTbl[1].y = VertexDataTbl[3].y = basey;
312+// /* 頂点3 */
313+// VertexDataTbl[4].x = basex + width;
314+// VertexDataTbl[4].y = basey + height;
315+// /* 頂点4 */
316+// VertexDataTbl[2].x = VertexDataTbl[5].x = basex;
317+// VertexDataTbl[2].y = VertexDataTbl[5].y = basey + height;
318+// /* 頂点色 */
319+// VertexDataTbl[0].color = VertexDataTbl[1].color =
320+// VertexDataTbl[2].color = VertexDataTbl[3].color =
321+// VertexDataTbl[4].color = VertexDataTbl[5].color = D3DCOLOR_ARGB(255,255,255,255);
322+// /* Z座標 */
323+// VertexDataTbl[0].z = VertexDataTbl[1].z =
324+// VertexDataTbl[2].z = VertexDataTbl[3].z =
325+// VertexDataTbl[4].z = VertexDataTbl[5].z = 0.0f;
326+// /* テクスチャ座標 */
327+// VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = 0.0f;
328+// VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = 0.0f;
329+// VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = 1.0f;
330+// VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = 1.0f;
331+//
332+// /* テクスチャをセット */
333+// g_pD3DDevice->lpVtbl->SetTexture(g_pD3DDevice, 0, (IDirect3DBaseTexture9*)pD3DTexture);
334+//
335+// /* デバイスに使用する頂点フォーマットをセット */
336+// g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
337+//
338+// /* 描画 */
339+// g_pD3DDevice->lpVtbl->DrawPrimitiveUP(g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX));
340+// }
341+//
342+// /* シーンの描画終了 */
343+// g_pD3DDevice->lpVtbl->EndScene( g_pD3DDevice );
344+// }
345+//
346+// return;
347+// }
348+//
349+//
350+// static LPDIRECT3DTEXTURE9 to_image( struct DXRubyRenderTarget *rt )
351+// {
352+// LPDIRECT3DTEXTURE9 pD3DTexture;
353+// LPDIRECT3DTEXTURE9 pD3DTexture_r;
354+// IDirect3DSurface9 *surface;
355+// D3DLOCKED_RECT srctrect;
356+// D3DLOCKED_RECT dsttrect;
357+// int i, j;
358+// RECT srect;
359+// RECT drect;
360+// HRESULT hr;
361+// int *psrc;
362+// int *pdst;
363+// D3DSURFACE_DESC desc;
364+//
365+// /* テクスチャオブジェクトを作成する */
366+// hr = D3DXCreateTexture( g_pD3DDevice, rt->texture->width, rt->texture->height,
367+// 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
368+// &pD3DTexture_r);
369+// if( FAILED( hr ) ) rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - to_image" );
370+//
371+// /* テクスチャオブジェクトを作成する */
372+// hr = D3DXCreateTexture( g_pD3DDevice, rt->texture->width, rt->texture->height,
373+// 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
374+// &pD3DTexture);
375+// if( FAILED( hr ) ) rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - to_image" );
376+//
377+// /* テクスチャのサーフェイスを取得 */
378+// hr = pD3DTexture->lpVtbl->GetSurfaceLevel( pD3DTexture, 0, &surface );
379+// if( FAILED( hr ) ) rb_raise( eDXRubyError, "サーフェイスの作成に失敗しました - to_image" );
380+//
381+// /* レンダーターゲットのイメージ取得 */
382+// hr = g_pD3DDevice->lpVtbl->GetRenderTargetData( g_pD3DDevice, rt->surface, surface );
383+// if( FAILED( hr ) ) rb_raise( eDXRubyError, "イメージの取得に失敗しました - to_image" );
384+//
385+// /* イメージのコピー */
386+// srect.left = rt->x;
387+// srect.top = rt->y;
388+// srect.right = rt->width;
389+// srect.bottom = rt->height;
390+// drect.left = 0;
391+// drect.top = 0;
392+// drect.right = rt->width;
393+// drect.bottom = rt->height;
394+//
395+// hr = pD3DTexture->lpVtbl->LockRect( pD3DTexture, 0, &srctrect, &srect, D3DLOCK_READONLY );
396+// hr = pD3DTexture_r->lpVtbl->LockRect( pD3DTexture_r, 0, &dsttrect, &drect, 0 );
397+//
398+// for( i = 0; i < rt->height; i++)
399+// {
400+// psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
401+// pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
402+// for( j = 0; j < rt->width; j++)
403+// {
404+// *(pdst++) = *(psrc++);
405+// }
406+// }
407+//
408+// pD3DTexture->lpVtbl->UnlockRect( pD3DTexture, 0 );
409+// pD3DTexture_r->lpVtbl->UnlockRect( pD3DTexture_r, 0 );
410+//
411+// RELEASE( surface );
412+// RELEASE( pD3DTexture );
413+//
414+// return pD3DTexture_r;
415+// }
416+
417+/*--------------------------------------------------------------------
418+ (内部関数)スクリーンサイズ変更
419+ ---------------------------------------------------------------------*/
420+static void ChangeSize( void )
421+{
422+ D3DVIEWPORT9 vp;
423+ HRESULT hr;
424+ int i;
425+// LPDIRECT3DTEXTURE9 *ppD3DTexture;
426+
427+ g_D3DPP.BackBufferWidth = g_WindowInfo.width;
428+ g_D3DPP.BackBufferHeight = g_WindowInfo.height;
429+
430+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
431+ {
432+ /* フルスクリーン時(32bitColor/60Hz固定) */
433+ g_D3DPP.BackBufferFormat = D3DFMT_X8R8G8B8;
434+ g_D3DPP.Windowed = FALSE;
435+ g_D3DPP.FullScreen_RefreshRateInHz = 60;
436+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
437+ g_WindowInfo.RefreshRate = 60;
438+ }
439+ else
440+ {
441+ /* ウィンドウモード時 */
442+ g_D3DPP.BackBufferFormat = D3DFMT_UNKNOWN;
443+ g_D3DPP.Windowed = TRUE;
444+ g_D3DPP.FullScreen_RefreshRateInHz = 0;
445+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
446+ g_WindowInfo.RefreshRate = 0;
447+ }
448+
449+ /* D3DXSpriteをロストさせる */
450+ if( g_pD3DXSprite )
451+ {
452+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
453+ }
454+
455+ /* メインレンダーターゲットの解放 */
456+ {
457+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
458+ RELEASE( rt->surface );
459+ }
460+
461+ /* ユーザーレンダーターゲットの解放 */
462+// ppD3DTexture = (LPDIRECT3DTEXTURE9 *)alloca( g_RenderTargetList.count * sizeof(LPDIRECT3DTEXTURE9 *) );
463+ for( i = 0; i < g_RenderTargetList.count; i++ )
464+ {
465+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_RenderTargetList.pointer[i];
466+
467+// ppD3DTexture[i] = to_image( rt );
468+ RELEASE( rt->surface );
469+ RELEASE( rt->texture->pD3DTexture );
470+ }
471+
472+// /* シェーダのロスト */
473+// for( i = 0; i < g_ShaderCoreList.count; i++ )
474+// {
475+// struct DXRubyShaderCore *core = (struct DXRubyShaderCore *)g_ShaderCoreList.pointer[i];
476+// core->pD3DXEffect->lpVtbl->OnLostDevice( core->pD3DXEffect );
477+// }
478+
479+ /* 設定変更 */
480+ hr = g_pD3DDevice->lpVtbl->Reset( g_pD3DDevice, &g_D3DPP );
481+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "設定に失敗しました - Reset" );
482+
483+ /* メインレンダーターゲットの復元 */
484+ {
485+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
486+ g_pD3DDevice->lpVtbl->GetRenderTarget( g_pD3DDevice, 0, &rt->surface );
487+ }
488+
489+ /* ユーザーレンダーターゲットの復元 */
490+ for( i = 0; i < g_RenderTargetList.count; i++ )
491+ {
492+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_RenderTargetList.pointer[i];
493+
494+ /* テクスチャオブジェクトを作成する */
495+ hr = D3DXCreateTexture( g_pD3DDevice, rt->texture->width, rt->texture->height,
496+ 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
497+ &rt->texture->pD3DTexture);
498+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "RenderTargetの復元に失敗しました" );
499+
500+ hr = rt->texture->pD3DTexture->lpVtbl->GetSurfaceLevel( rt->texture->pD3DTexture, 0, &rt->surface );
501+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "RenderTargetの復元に失敗しました" );
502+ }
503+
504+// /* シェーダの復帰 */
505+// for( i = 0; i < g_ShaderCoreList.count; i++ )
506+// {
507+// struct DXRubyShaderCore *core = (struct DXRubyShaderCore *)g_ShaderCoreList.pointer[i];
508+// core->pD3DXEffect->lpVtbl->OnResetDevice( core->pD3DXEffect );
509+// }
510+
511+ /* D3DXSprite復帰 */
512+ if( g_pD3DXSprite )
513+ {
514+ g_pD3DXSprite->lpVtbl->OnResetDevice( g_pD3DXSprite );
515+ }
516+
517+ /* ビューポートの設定 */
518+// vp.X = 0;
519+// vp.Y = 0;
520+// vp.Width = g_D3DPP.BackBufferWidth;
521+// vp.Height = g_D3DPP.BackBufferHeight;
522+// vp.MinZ = 0.0f;
523+// vp.MaxZ = 1.0f;
524+
525+// hr = g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
526+
527+// if( FAILED( hr ) )
528+// {
529+// rb_raise( eDXRubyError, "設定に失敗しました - SetViewport" );
530+// }
531+// for( i = 0; i < g_RenderTargetList.count; i++ )
532+// {
533+// struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_RenderTargetList.pointer[i];
534+// rt_redraw( rt, ppD3DTexture[i] );
535+// RELEASE( ppD3DTexture[i] );
536+// }
537+}
538+
539+
540+/*--------------------------------------------------------------------
541+ Windowsのメッセージループ
542+ ---------------------------------------------------------------------*/
543+static VALUE Window_loop( VALUE obj )
544+{
545+ MSG msg;
546+ msg.message = WM_NULL;
547+
548+ if( g_WindowInfo.created == Qtrue )
549+ {
550+ rb_raise( eDXRubyError, "ウィンドウ作成後に実行することはできません - Window_loop" );
551+ }
552+
553+ g_WindowInfo.userloop = 2;
554+ Window_create( obj );
555+
556+ /* メッセージループ */
557+ /* WM_QUITが届くまでメッセージ処理をし続ける */
558+ /* メッセージが無い時はブロックをyieldする */
559+ while( msg.message != WM_QUIT )
560+ {
561+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
562+ {
563+ /* メッセージがある時 */
564+ TranslateMessage( &msg );
565+ DispatchMessage( &msg );
566+ }
567+ else
568+ {
569+ /* メッセージが無い時 */
570+ /* 入力状態更新 */
571+ inputupdate_internal();
572+ /* ブロック実行 */
573+ rb_yield( obj );
574+ /* fps調整 */
575+ Window_sync( obj );
576+ /* 描画 */
577+ Window_update( mWindow );
578+ }
579+ }
580+
581+ return Qtrue;
582+}
583+
584+
585+/*--------------------------------------------------------------------
586+ (内部関数)ウィンドウプロシージャ
587+ ---------------------------------------------------------------------*/
588+LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
589+{
590+ RECT rect;
591+ VALUE temp;
592+
593+ switch( msg )
594+ {
595+ /* ウィンドウアクティブ/非アクティブ化 */
596+ case WM_ACTIVATE:
597+ g_WindowInfo.active = (LOWORD(wParam) != 0);
598+ break;
599+ case WM_CLOSE:
600+ /* 自前ループの場合は無条件でキャセルする */
601+ if( g_WindowInfo.userloop == 1 )
602+ {
603+ g_WindowInfo.requestclose = 1;
604+ return 0;
605+ }
606+ break;
607+ /* ウィンドウ破棄 */
608+ case WM_DESTROY:
609+ /* ウインドウを閉じる */
610+ PostQuitMessage( 0 );
611+ g_hWnd = NULL;
612+ return 0;
613+
614+ case WM_MOUSEWHEEL:
615+ g_WindowInfo.mousewheelpos += (short)HIWORD(wParam);
616+ break;
617+/*
618+ case WM_SETCURSOR:
619+ if( g_pD3DDevice )
620+ {
621+ if( LOWORD( lParam ) == HTCLIENT ) // クライアント領域のみ
622+ {
623+ if( g_WindowInfo.enablemouse == Qfalse )
624+ {
625+ SetCursor( NULL ); // ウインドウの標準カーソルを消す
626+ return TRUE; // 設定を終えたことを通知
627+ }
628+ }
629+ }
630+ break;
631+*/
632+ }
633+
634+ /* デフォルト処理 */
635+ return DefWindowProc( hWnd, msg, wParam, lParam );
636+}
637+
638+
639+/*--------------------------------------------------------------------
640+ 画面クリア色取得
641+ ---------------------------------------------------------------------*/
642+static VALUE Window_get_bgcolor( VALUE obj )
643+{
644+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
645+ return rb_ary_new3( 3, INT2FIX( rt->r ), INT2FIX( rt->g ), INT2FIX( rt->b ) );
646+}
647+
648+
649+/*--------------------------------------------------------------------
650+ 画面クリア色指定
651+ ---------------------------------------------------------------------*/
652+static VALUE Window_set_bgcolor( VALUE obj, VALUE array )
653+{
654+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
655+
656+ Check_Type(array, T_ARRAY);
657+
658+ if( RARRAY_LEN(array) == 4 )
659+ {
660+ rt->a = NUM2INT( rb_ary_entry(array, 0) );
661+ rt->r = NUM2INT( rb_ary_entry(array, 1) );
662+ rt->g = NUM2INT( rb_ary_entry(array, 2) );
663+ rt->b = NUM2INT( rb_ary_entry(array, 3) );
664+ }
665+ else
666+ {
667+ rt->a = 255;
668+ rt->r = NUM2INT( rb_ary_entry(array, 0) );
669+ rt->g = NUM2INT( rb_ary_entry(array, 1) );
670+ rt->b = NUM2INT( rb_ary_entry(array, 2) );
671+ }
672+
673+ return array;
674+}
675+
676+/*--------------------------------------------------------------------
677+ 描画設定(通常描画)
678+ ---------------------------------------------------------------------*/
679+static VALUE Window_draw( int argc, VALUE *argv, VALUE obj )
680+{
681+ RenderTarget_draw( argc, argv, g_WindowInfo.render_target );
682+ return Qnil;
683+}
684+
685+/*--------------------------------------------------------------------
686+ 描画設定(半透明描画)
687+ ---------------------------------------------------------------------*/
688+static VALUE Window_drawAlpha( int argc, VALUE *argv, VALUE obj )
689+{
690+ RenderTarget_drawAlpha( argc, argv, g_WindowInfo.render_target );
691+ return Qnil;
692+}
693+
694+
695+/*--------------------------------------------------------------------
696+ 描画設定(加算合成描画)
697+ ---------------------------------------------------------------------*/
698+static VALUE Window_drawAdd( int argc, VALUE *argv, VALUE obj )
699+{
700+ RenderTarget_drawAdd( argc, argv, g_WindowInfo.render_target );
701+ return Qnil;
702+}
703+
704+
705+/*--------------------------------------------------------------------
706+ 描画設定(減算合成描画)
707+ ---------------------------------------------------------------------*/
708+static VALUE Window_drawSub( int argc, VALUE *argv, VALUE obj )
709+{
710+ RenderTarget_drawSub( argc, argv, g_WindowInfo.render_target );
711+ return Qnil;
712+}
713+
714+
715+///*--------------------------------------------------------------------
716+// 描画設定(シェーダ描画)
717+// ---------------------------------------------------------------------*/
718+//static VALUE Window_drawShader( int argc, VALUE *argv, VALUE obj )
719+//{
720+// RenderTarget_drawShader( argc, argv, g_WindowInfo.render_target );
721+// return Qnil;
722+//}
723+
724+
725+/*--------------------------------------------------------------------
726+ 描画設定(拡大縮小描画)
727+ ---------------------------------------------------------------------*/
728+static VALUE Window_drawScale( int argc, VALUE *argv, VALUE obj )
729+{
730+ RenderTarget_drawScale( argc, argv, g_WindowInfo.render_target );
731+ return Qnil;
732+}
733+
734+/*--------------------------------------------------------------------
735+ 描画設定(回転描画)
736+ ---------------------------------------------------------------------*/
737+static VALUE Window_drawRot( int argc, VALUE *argv, VALUE obj )
738+{
739+ RenderTarget_drawRot( argc, argv, g_WindowInfo.render_target );
740+ return Qnil;
741+}
742+
743+/*--------------------------------------------------------------------
744+ 描画設定(フルオプション)
745+ ---------------------------------------------------------------------*/
746+static VALUE Window_drawEx( int argc, VALUE *argv, VALUE obj )
747+{
748+ RenderTarget_drawEx( argc, argv, g_WindowInfo.render_target );
749+ return Qnil;
750+}
751+
752+
753+/*--------------------------------------------------------------------
754+ フォント描画
755+ ---------------------------------------------------------------------*/
756+static VALUE Window_drawFont( int argc, VALUE *argv, VALUE obj )
757+{
758+ RenderTarget_drawFont( argc, argv, g_WindowInfo.render_target );
759+ return Qnil;
760+}
761+
762+/*--------------------------------------------------------------------
763+ 高品質フォント描画
764+ ---------------------------------------------------------------------*/
765+static VALUE Window_drawFontEx( int argc, VALUE *argv, VALUE obj )
766+{
767+ RenderTarget_drawFontEx( argc, argv, g_WindowInfo.render_target );
768+ return Qnil;
769+}
770+
771+
772+/*--------------------------------------------------------------------
773+ 描画設定(4点指定)
774+ ---------------------------------------------------------------------*/
775+static VALUE Window_drawMorph( int argc, VALUE *argv, VALUE obj )
776+{
777+ RenderTarget_drawMorph( argc, argv, g_WindowInfo.render_target );
778+ return Qnil;
779+}
780+
781+
782+/*--------------------------------------------------------------------
783+ マップ描画
784+ ---------------------------------------------------------------------*/
785+static VALUE Window_drawTile( int argc, VALUE *argv, VALUE obj )
786+{
787+ RenderTarget_drawTile( argc, argv, g_WindowInfo.render_target );
788+ return Qnil;
789+}
790+
791+
792+/*--------------------------------------------------------------------
793+ (内部関数)画面更新
794+ ---------------------------------------------------------------------*/
795+static VALUE Window_update( VALUE obj )
796+{
797+ HRESULT hr;
798+ __int64 drawStartCounter;
799+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
800+
801+ while( 1 )
802+ {
803+ hr = g_pD3DDevice->lpVtbl->TestCooperativeLevel( g_pD3DDevice );
804+ if( FAILED( hr ) )
805+ {
806+ if( hr == D3DERR_DEVICELOST ) /* デバイスはロスト状態である */
807+ {
808+ MSG msg;
809+ if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) != 0)
810+ {
811+ /* メッセージがある時 */
812+ TranslateMessage( &msg );
813+ DispatchMessage( &msg );
814+ }
815+ Sleep( 100 );
816+ continue;
817+ }
818+ else if( hr == D3DERR_DEVICENOTRESET ) /* デバイスはロスト状態であるがリセット可能である */
819+ {
820+ int i;
821+ /* ここへ来た時はデバイスがリセット可能状態である */
822+ /* D3DXSpriteをロストさせる */
823+ if( g_pD3DXSprite )
824+ {
825+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
826+ }
827+
828+ /* レンダーターゲットの解放 */
829+ {
830+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_WindowInfo.render_target;
831+ RELEASE( rt->surface );
832+ }
833+ for( i = 0; i < g_RenderTargetList.count; i++ )
834+ {
835+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_RenderTargetList.pointer[i];
836+ RELEASE( rt->surface );
837+ RELEASE( rt->texture->pD3DTexture );
838+ }
839+
840+// /* シェーダのロスト */
841+// for( i = 0; i < g_ShaderCoreList.count; i++ )
842+// {
843+// struct DXRubyShaderCore *core = (struct DXRubyShaderCore *)g_ShaderCoreList.pointer[i];
844+// core->pD3DXEffect->lpVtbl->OnLostDevice( core->pD3DXEffect );
845+// }
846+
847+ hr = g_pD3DDevice->lpVtbl->Reset( g_pD3DDevice, &g_D3DPP ); /* 復元を試みる */
848+ if( FAILED( hr ) )
849+ {
850+ if( hr == D3DERR_DEVICELOST )
851+ {
852+ return obj; /* またロストした */
853+ }
854+ rb_raise( eDXRubyError, "DirectX APIの呼び出しに失敗しました - Reset" );
855+ }
856+
857+ /* レンダーターゲットの復元 */
858+ {
859+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_WindowInfo.render_target;
860+ g_pD3DDevice->lpVtbl->GetRenderTarget( g_pD3DDevice, 0, &rt->surface );
861+ }
862+ for( i = 0; i < g_RenderTargetList.count; i++ )
863+ {
864+ struct DXRubyRenderTarget *rt = (struct DXRubyRenderTarget *)g_RenderTargetList.pointer[i];
865+
866+ /* テクスチャオブジェクトを作成する */
867+ hr = D3DXCreateTexture( g_pD3DDevice, rt->texture->width, rt->texture->height,
868+ 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
869+ &rt->texture->pD3DTexture);
870+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "RenderTargetの復元に失敗しました" );
871+
872+ hr = rt->texture->pD3DTexture->lpVtbl->GetSurfaceLevel( rt->texture->pD3DTexture, 0, &rt->surface );
873+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "RenderTargetの復元に失敗しました" );
874+ }
875+
876+// /* シェーダの復帰 */
877+// for( i = 0; i < g_ShaderCoreList.count; i++ )
878+// {
879+// struct DXRubyShaderCore *core = (struct DXRubyShaderCore *)g_ShaderCoreList.pointer[i];
880+// core->pD3DXEffect->lpVtbl->OnResetDevice( core->pD3DXEffect );
881+// }
882+
883+ if( g_pD3DXSprite ) /* D3DXSprite復帰 */
884+ {
885+ g_pD3DXSprite->lpVtbl->OnResetDevice( g_pD3DXSprite );
886+ }
887+ break;
888+ }
889+ else /* DirectXの内部エラー */
890+ {
891+ rb_raise( eDXRubyError, "DirectX APIの内部エラーが発生しました - TestCooperativeLevel" );
892+ }
893+ }
894+ else
895+ {
896+ break;
897+ }
898+ }
899+
900+ drawStartCounter = GetSystemCounter();
901+
902+ RenderTarget_update( g_WindowInfo.render_target );
903+
904+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
905+ {
906+ g_DrawTime = GetSystemCounter() - drawStartCounter;
907+ }
908+
909+ /* シーンの表示 */
910+ hr = g_pD3DDevice->lpVtbl->Present( g_pD3DDevice, NULL, NULL, NULL, NULL );
911+
912+ if( g_WindowInfo.windowed == Qnil || g_WindowInfo.windowed == Qfalse )
913+ {
914+ g_OldTime = GetSystemCounter();
915+ }
916+
917+ return Qnil;
918+}
919+
920+
921+/*--------------------------------------------------------------------
922+ (内部関数)フレーム調整
923+ ---------------------------------------------------------------------*/
924+static VALUE Window_sync( VALUE obj )
925+{
926+ __int64 NowTime;
927+ __int64 WaitTime;
928+ static __int64 BeforeSecond = 0;
929+ static int fps = 0;
930+ static int skip = 0;
931+
932+ NowTime = GetSystemCounter();
933+
934+ /* ウィンドウモード時 */
935+ if( g_WindowInfo.windowed != Qnil && g_WindowInfo.windowed != Qfalse )
936+ {
937+ g_OneFrameCount = NowTime - g_OldTime;
938+ if ( g_WindowInfo.fps > 0 ) /* fps指定がnil or 0の時はWait処理しない */
939+ {
940+ __int64 SleepTime;
941+
942+ WaitTime = g_OneSecondCount / g_WindowInfo.fps;
943+
944+ /* もう既に前回から1フレーム分の時間が経っていたら */
945+ if( g_OldTime + WaitTime < NowTime && skip == 0 )
946+ {
947+ /* コマ落ち制御しない場合 */
948+ if( g_WindowInfo.frameskip == Qfalse )
949+ {
950+ fps++;
951+ g_OldTime = NowTime;
952+ }
953+ else /* する場合 */
954+ {
955+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
956+ /* 今回はウェイトも描画もしない */
957+ skip++;
958+ rt->PictureCount = 0;
959+ rt->PictureSize = 0;
960+ rt->PictureDecideCount = 0;
961+ rt->PictureDecideSize = 0;
962+ g_OldTime = g_OldTime + WaitTime;
963+ }
964+ }
965+ else
966+ {
967+ /* 前回描画を飛ばしたのに今回も間に合ってない場合 */
968+ if( g_OldTime + WaitTime < NowTime && skip == 1 )
969+ {
970+ /* 諦めて処理落ち */
971+ g_OldTime = NowTime;
972+ }
973+ else
974+ {
975+ __int64 TempTime;
976+ /* おおまかな時間をSleepで待つ */
977+ TempTime = GetSystemCounter();
978+ SleepTime = (WaitTime - (TempTime - g_OldTime)) * 1000 / g_OneSecondCount;
979+ if( SleepTime > 2 )
980+ {
981+ Sleep( (unsigned long)(SleepTime - 2) );
982+ }
983+
984+ TempTime = GetSystemCounter();
985+
986+ /* ループで厳密に処理をする */
987+ for ( ; ; )
988+ {
989+ TempTime = GetSystemCounter();
990+ if( g_OldTime + WaitTime < TempTime )
991+ {
992+ break;
993+ }
994+ }
995+ g_OldTime = g_OldTime + WaitTime;
996+ }
997+ skip = 0;
998+ fps++;
999+ }
1000+ }
1001+ else
1002+ {
1003+ g_OldTime = NowTime;
1004+ fps++;
1005+ }
1006+
1007+ /* FPS値設定 */
1008+ if( (NowTime - BeforeSecond) >= g_OneSecondCount )
1009+ {
1010+ BeforeSecond = NowTime;
1011+ g_WindowInfo.fpscheck = fps;
1012+ fps = 0;
1013+ }
1014+ }
1015+ else
1016+ {
1017+ g_OneFrameCount = NowTime - g_OldTime + g_DrawTime;
1018+ WaitTime = g_OneSecondCount / g_WindowInfo.RefreshRate;
1019+
1020+ /* もう既に前回から1フレーム分の時間が経っていたら */
1021+ if( g_OldTime + WaitTime - g_DrawTime < NowTime && skip == 0 )
1022+ {
1023+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1024+ /* 今回はウェイトも描画もしない */
1025+ skip++;
1026+ rt->PictureCount = 0;
1027+ rt->PictureSize = 0;
1028+ rt->PictureDecideCount = 0;
1029+ rt->PictureDecideSize = 0;
1030+// g_OldTime = NowTime;
1031+ return obj;
1032+ }
1033+
1034+ skip = 0;
1035+
1036+// g_OldTime = g_OldTime + WaitTime;
1037+ fps++;
1038+
1039+ /* FPS値設定 */
1040+ if( (NowTime - BeforeSecond) >= g_OneSecondCount )
1041+ {
1042+ BeforeSecond = NowTime;
1043+ g_WindowInfo.fpscheck = fps;
1044+ fps = 0;
1045+ }
1046+ }
1047+
1048+ return obj;
1049+}
1050+
1051+
1052+/*--------------------------------------------------------------------
1053+ (内部関数)フレーム調整用カウンタ値取得
1054+ ---------------------------------------------------------------------*/
1055+static __int64 GetSystemCounter( void )
1056+{
1057+ __int64 time;
1058+
1059+ if( g_isPerformanceCounter == 1 )
1060+ {
1061+ QueryPerformanceCounter( (LARGE_INTEGER *)&time );
1062+ return time;
1063+ }
1064+ else
1065+ {
1066+ return timeGetTime();
1067+ }
1068+}
1069+
1070+
1071+/*--------------------------------------------------------------------
1072+ ウィンドウのサイズを変更する。
1073+ ---------------------------------------------------------------------*/
1074+static VALUE Window_resize( VALUE klass, VALUE vwidth, VALUE vheight )
1075+{
1076+ g_WindowInfo.width = NUM2INT( vwidth );
1077+ g_WindowInfo.height = NUM2INT( vheight );
1078+ if( g_WindowInfo.created == Qtrue )
1079+ {
1080+ g_WindowInfo.created = Qfalse;
1081+ Window_create( klass );
1082+ }
1083+ return Qnil;
1084+}
1085+
1086+
1087+/*--------------------------------------------------------------------
1088+ ウィンドウのモード(ウィンドウ/全画面)を設定する。
1089+ ---------------------------------------------------------------------*/
1090+static VALUE Window_setwindowed( VALUE klass, VALUE windowed )
1091+{
1092+ g_WindowInfo.windowed = windowed;
1093+
1094+ if( g_WindowInfo.created == Qtrue )
1095+ {
1096+ g_WindowInfo.created = Qfalse;
1097+ Window_create( klass );
1098+ }
1099+
1100+ return g_WindowInfo.windowed;
1101+}
1102+
1103+
1104+/*--------------------------------------------------------------------
1105+ ウィンドウのモード(ウィンドウ/全画面)を取得する。
1106+ ---------------------------------------------------------------------*/
1107+static VALUE Window_getwindowed( VALUE klass )
1108+{
1109+ return g_WindowInfo.windowed;
1110+}
1111+
1112+
1113+/*--------------------------------------------------------------------
1114+ ウィンドウの位置(x座標)を設定する。
1115+ ---------------------------------------------------------------------*/
1116+static VALUE Window_setx( VALUE klass, VALUE x )
1117+{
1118+ if( g_WindowInfo.created == Qtrue )
1119+ {
1120+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setx" );
1121+ }
1122+
1123+ g_WindowInfo.x = NUM2INT( x );
1124+ return x;
1125+}
1126+
1127+
1128+/*--------------------------------------------------------------------
1129+ ウィンドウの位置(y座標)を設定する。
1130+ ---------------------------------------------------------------------*/
1131+static VALUE Window_sety( VALUE klass , VALUE y )
1132+{
1133+ if( g_WindowInfo.created == Qtrue )
1134+ {
1135+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_sety" );
1136+ }
1137+
1138+ g_WindowInfo.y = NUM2INT( y );
1139+ return y;
1140+}
1141+
1142+
1143+/*--------------------------------------------------------------------
1144+ ウィンドウのサイズ(幅)を設定する。
1145+ ---------------------------------------------------------------------*/
1146+static VALUE Window_setwidth( VALUE klass, VALUE vwidth )
1147+{
1148+ int width;
1149+
1150+ if( g_WindowInfo.created == Qtrue )
1151+ {
1152+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setwidth" );
1153+ }
1154+
1155+ width = NUM2INT( vwidth );
1156+ if( width < 0 )
1157+ {
1158+ width = 0;
1159+ }
1160+
1161+ g_WindowInfo.width = width;
1162+ return vwidth;
1163+}
1164+
1165+
1166+/*--------------------------------------------------------------------
1167+ ウィンドウのサイズ(高さ)を設定する。
1168+ ---------------------------------------------------------------------*/
1169+static VALUE Window_setheight( VALUE klass , VALUE vheight)
1170+{
1171+ int height;
1172+
1173+ if( g_WindowInfo.created == Qtrue )
1174+ {
1175+ rb_raise( eDXRubyError, "ウィンドウ作成後に設定を変更することはできません - Window_setheight" );
1176+ }
1177+
1178+ height = NUM2INT( vheight );
1179+ if( height < 0 )
1180+ {
1181+ height = 0;
1182+ }
1183+
1184+ g_WindowInfo.height = height;
1185+ return vheight;
1186+}
1187+
1188+
1189+/*--------------------------------------------------------------------
1190+ ウィンドウの位置(x座標)を返す。
1191+ ---------------------------------------------------------------------*/
1192+static VALUE Window_x( VALUE klass )
1193+{
1194+ return INT2FIX( g_WindowInfo.x );
1195+}
1196+
1197+
1198+/*--------------------------------------------------------------------
1199+ ウィンドウの位置(y座標)を返す。
1200+ ---------------------------------------------------------------------*/
1201+static VALUE Window_y( VALUE klass )
1202+{
1203+ return INT2FIX( g_WindowInfo.y );
1204+}
1205+
1206+
1207+/*--------------------------------------------------------------------
1208+ ウィンドウのサイズ(幅)を返す。
1209+ ---------------------------------------------------------------------*/
1210+static VALUE Window_width( VALUE klass )
1211+{
1212+ return INT2FIX( g_WindowInfo.width );
1213+}
1214+
1215+
1216+/*--------------------------------------------------------------------
1217+ ウィンドウのサイズ(高さ)を返す。
1218+ ---------------------------------------------------------------------*/
1219+static VALUE Window_height( VALUE klass )
1220+{
1221+ return INT2FIX( g_WindowInfo.height );
1222+}
1223+
1224+
1225+/*--------------------------------------------------------------------
1226+ ウィンドウタイトル取得
1227+ ---------------------------------------------------------------------*/
1228+static VALUE Window_getCaption( VALUE klass )
1229+{
1230+ char buf[256];
1231+
1232+ GetWindowText( g_hWnd, buf, 256 );
1233+
1234+#ifdef HAVE_RB_ENC_STR_NEW
1235+ return rb_funcall( rb_str_new2( buf ), rb_intern( "force_encoding" ), 1, rb_str_new2( sys_encode ) );
1236+#else
1237+ return rb_str_new2( buf );
1238+#endif
1239+}
1240+
1241+
1242+/*--------------------------------------------------------------------
1243+ ウィンドウタイトル設定
1244+ ---------------------------------------------------------------------*/
1245+static VALUE Window_setCaption( VALUE klass, VALUE vcaption )
1246+{
1247+ VALUE vsjisstr;
1248+ Check_Type(vcaption, T_STRING);
1249+
1250+#ifdef HAVE_RB_ENC_STR_NEW
1251+ if( rb_enc_get_index( vcaption ) != 0 )
1252+ {
1253+ vsjisstr = rb_funcall( vcaption, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1254+ }
1255+ else
1256+ {
1257+ vsjisstr = vcaption;
1258+ }
1259+#else
1260+ vsjisstr = vcaption;
1261+#endif
1262+ SetWindowText( g_hWnd, RSTRING_PTR( vsjisstr ) );
1263+
1264+ return vcaption;
1265+}
1266+
1267+
1268+/*--------------------------------------------------------------------
1269+ ウィンドウのサイズ倍率を取得する
1270+ ---------------------------------------------------------------------*/
1271+static VALUE Window_getScale( VALUE klass )
1272+{
1273+ return rb_float_new( g_WindowInfo.scale );
1274+}
1275+
1276+
1277+/*--------------------------------------------------------------------
1278+ ウィンドウのサイズ倍率を設定する
1279+ ---------------------------------------------------------------------*/
1280+static VALUE Window_setScale( VALUE klass, VALUE scale )
1281+{
1282+ g_WindowInfo.scale = NUM2FLOAT( scale );
1283+
1284+ return scale;
1285+}
1286+
1287+
1288+/*--------------------------------------------------------------------
1289+ fps値を設定する
1290+ ---------------------------------------------------------------------*/
1291+static VALUE Window_getrealfps( VALUE obj )
1292+{
1293+ return INT2FIX( g_WindowInfo.fpscheck );
1294+}
1295+
1296+
1297+/*--------------------------------------------------------------------
1298+ fps値を取得する
1299+ ---------------------------------------------------------------------*/
1300+static VALUE Window_getfps( VALUE obj )
1301+{
1302+ return INT2FIX( g_WindowInfo.fpscheck );
1303+}
1304+
1305+
1306+/*--------------------------------------------------------------------
1307+ fps値を設定する
1308+ ---------------------------------------------------------------------*/
1309+static VALUE Window_setfps( VALUE obj, VALUE fps )
1310+{
1311+ g_WindowInfo.fps = fps == Qnil ? 0 : NUM2INT(fps);
1312+
1313+ return fps;
1314+}
1315+
1316+
1317+/*--------------------------------------------------------------------
1318+ 縮小フィルタ取得
1319+ ---------------------------------------------------------------------*/
1320+static VALUE Window_getMinFilter( VALUE obj )
1321+{
1322+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1323+ return INT2FIX( rt->minfilter );
1324+}
1325+
1326+
1327+/*--------------------------------------------------------------------
1328+ 縮小フィルタ設定
1329+ ---------------------------------------------------------------------*/
1330+static VALUE Window_setMinFilter( VALUE obj, VALUE vminfilter )
1331+{
1332+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1333+ rt->minfilter = FIX2INT( vminfilter );
1334+ return vminfilter;
1335+}
1336+
1337+
1338+/*--------------------------------------------------------------------
1339+ 拡大フィルタ取得
1340+ ---------------------------------------------------------------------*/
1341+static VALUE Window_getMagFilter( VALUE obj )
1342+{
1343+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1344+ return INT2FIX( rt->magfilter );
1345+}
1346+
1347+
1348+/*--------------------------------------------------------------------
1349+ 拡大フィルタ設定
1350+ ---------------------------------------------------------------------*/
1351+static VALUE Window_setMagFilter( VALUE obj, VALUE vmagfilter )
1352+{
1353+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1354+ rt->magfilter = FIX2INT( vmagfilter );
1355+ return vmagfilter;
1356+}
1357+
1358+
1359+/*--------------------------------------------------------------------
1360+ 描画予約確定
1361+ ---------------------------------------------------------------------*/
1362+static VALUE Window_decide( VALUE obj )
1363+{
1364+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1365+ rt->PictureDecideCount = rt->PictureCount;
1366+ rt->PictureDecideSize = rt->PictureSize;
1367+ return Qnil;
1368+}
1369+
1370+
1371+/*--------------------------------------------------------------------
1372+ 描画予約破棄
1373+ ---------------------------------------------------------------------*/
1374+static VALUE Window_discard( VALUE obj )
1375+{
1376+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1377+ rt->PictureCount = rt->PictureDecideCount;
1378+ rt->PictureSize = rt->PictureDecideSize;
1379+ return Qnil;
1380+}
1381+
1382+
1383+/*--------------------------------------------------------------------
1384+ 1フレームの処理負荷を%で取得する
1385+ ---------------------------------------------------------------------*/
1386+static VALUE Window_getload( VALUE obj )
1387+{
1388+ if( g_WindowInfo.fps == 0 )
1389+ {
1390+ return INT2FIX( 0 );
1391+ }
1392+ return rb_float_new( (double) ( (double)g_OneFrameCount * 100.0 / ((double)g_OneSecondCount / (double)g_WindowInfo.fps )) );
1393+}
1394+
1395+
1396+/*--------------------------------------------------------------------
1397+ ウィンドウハンドルを取得する
1398+ ---------------------------------------------------------------------*/
1399+static VALUE Window_gethWnd( VALUE obj )
1400+{
1401+ return INT2NUM( (int)g_hWnd );
1402+}
1403+
1404+
1405+/*--------------------------------------------------------------------
1406+ フレームスキップon/offを取得する
1407+ ---------------------------------------------------------------------*/
1408+static VALUE Window_getframeskip( VALUE obj )
1409+{
1410+ return g_WindowInfo.frameskip;
1411+}
1412+
1413+
1414+/*--------------------------------------------------------------------
1415+ フレームスキップon/offを設定する
1416+ ---------------------------------------------------------------------*/
1417+static VALUE Window_setframeskip( VALUE obj, VALUE skip )
1418+{
1419+ g_WindowInfo.frameskip = (skip == Qnil || skip == Qfalse) ? Qfalse : Qtrue;
1420+
1421+ return skip;
1422+}
1423+
1424+
1425+/*--------------------------------------------------------------------
1426+ ウィンドウのアクティブ状態を取得
1427+ ---------------------------------------------------------------------*/
1428+static VALUE Window_get_active( VALUE obj )
1429+{
1430+ return ( g_WindowInfo.active != 0 ? Qtrue : Qfalse );
1431+}
1432+
1433+
1434+/*--------------------------------------------------------------------
1435+ ウィンドウアイコンを設定する
1436+ ---------------------------------------------------------------------*/
1437+static VALUE Window_loadIcon( VALUE obj, VALUE vfilename )
1438+{
1439+ VALUE vsjisstr;
1440+ Check_Type( vfilename, T_STRING );
1441+#ifdef HAVE_RB_ENC_STR_NEW
1442+ if( rb_enc_get_index( vfilename ) != 0 )
1443+ {
1444+ vsjisstr = rb_funcall( vfilename, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1445+ }
1446+ else
1447+ {
1448+ vsjisstr = vfilename;
1449+ }
1450+#else
1451+ vsjisstr = vfilename;
1452+#endif
1453+ g_WindowInfo.hIcon = LoadImage( 0, RSTRING_PTR(vsjisstr), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE|LR_LOADFROMFILE );
1454+ if( g_WindowInfo.hIcon == NULL )
1455+ {
1456+ rb_raise( eDXRubyError, "アイコン画像ファイルのロードに失敗しました - Window_loadIcon" );
1457+ }
1458+
1459+ SendMessage(g_hWnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)g_WindowInfo.hIcon);
1460+
1461+ return Qnil;
1462+}
1463+
1464+
1465+/*--------------------------------------------------------------------
1466+ ファイルオープンダイアログを表示する
1467+ ---------------------------------------------------------------------*/
1468+static VALUE Window_openDialog(VALUE obj, VALUE vfilter, VALUE vtitle)
1469+{
1470+ OPENFILENAME OFN;
1471+ char buf[MAX_PATH*2];
1472+ VALUE filter;
1473+ VALUE vsjisstr;
1474+ buf[0] = 0;
1475+
1476+ Check_Type(vfilter, T_ARRAY);
1477+ Check_Type(vtitle, T_STRING);
1478+
1479+ ZeroMemory(&OFN,sizeof(OPENFILENAME));
1480+ OFN.lStructSize = sizeof(OPENFILENAME);
1481+ OFN.hwndOwner = g_hWnd;
1482+
1483+#ifdef HAVE_RB_ENC_STR_NEW
1484+ {
1485+ int i;
1486+ VALUE base_array = rb_ary_new();
1487+ for( i = 0; i < RARRAY_LEN( vfilter ); i++ )
1488+ {
1489+ VALUE child_array = rb_ary_new();
1490+ Check_Type(RARRAY_PTR( vfilter )[i], T_ARRAY);
1491+ rb_ary_push( base_array, child_array );
1492+ if( rb_enc_get_index( rb_ary_entry( RARRAY_PTR( vfilter )[i], 0) ) != 0 )
1493+ {
1494+ vsjisstr = rb_funcall( rb_ary_entry( RARRAY_PTR( vfilter )[i], 0), rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1495+ }
1496+ else
1497+ {
1498+ vsjisstr = rb_ary_entry( RARRAY_PTR( vfilter )[i], 0);
1499+ }
1500+ rb_ary_push( child_array, vsjisstr );
1501+ if( rb_enc_get_index( rb_ary_entry( RARRAY_PTR( vfilter )[i], 1) ) != 0 )
1502+ {
1503+ vsjisstr = rb_funcall( rb_ary_entry( RARRAY_PTR( vfilter )[i], 1), rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1504+ }
1505+ else
1506+ {
1507+ vsjisstr = rb_ary_entry( RARRAY_PTR( vfilter )[i], 1);
1508+ }
1509+ rb_ary_push( child_array, vsjisstr );
1510+ }
1511+ filter = rb_ary_join( base_array, rb_str_new( "\0", 1 ) );
1512+ filter = rb_str_cat( filter, "\0", 1 );
1513+ OFN.lpstrFilter = RSTRING_PTR( filter );
1514+ }
1515+#else
1516+ filter = rb_ary_join( vfilter, rb_str_new( "\0", 1 ) );
1517+ filter = rb_str_cat( filter, "\0", 1 );
1518+ OFN.lpstrFilter = RSTRING_PTR( filter );
1519+#endif
1520+ OFN.lpstrFile = buf;
1521+ OFN.nMaxFile = MAX_PATH*2;
1522+ OFN.Flags = OFN_FILEMUSTEXIST;
1523+#ifdef HAVE_RB_ENC_STR_NEW
1524+ if( rb_enc_get_index( vtitle ) != 0 )
1525+ {
1526+ vsjisstr = rb_funcall( vtitle, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1527+ }
1528+ else
1529+ {
1530+ vsjisstr = vtitle;
1531+ }
1532+#else
1533+ vsjisstr = vtitle;
1534+#endif
1535+ OFN.lpstrTitle = RSTRING_PTR(vsjisstr);
1536+ OFN.lpstrDefExt = 0;
1537+ if( !GetOpenFileName(&OFN) )
1538+ {
1539+ return Qnil;
1540+ }
1541+
1542+#ifdef HAVE_RB_ENC_STR_NEW
1543+ return rb_funcall( rb_str_new2( buf ), rb_intern( "force_encoding" ), 1, rb_str_new2( sys_encode ) );
1544+#else
1545+ return rb_str_new2( buf );
1546+#endif
1547+}
1548+
1549+
1550+/*--------------------------------------------------------------------
1551+ ファイルセーブダイアログを表示する
1552+ ---------------------------------------------------------------------*/
1553+static VALUE Window_saveDialog(VALUE obj, VALUE vfilter, VALUE vtitle)
1554+{
1555+ OPENFILENAME OFN;
1556+ char buf[MAX_PATH*2];
1557+ VALUE filter;
1558+ VALUE vsjisstr;
1559+ buf[0] = 0;
1560+
1561+ Check_Type(vfilter, T_ARRAY);
1562+ Check_Type(vtitle, T_STRING);
1563+
1564+ ZeroMemory(&OFN,sizeof(OPENFILENAME));
1565+ OFN.lStructSize = sizeof(OPENFILENAME);
1566+ OFN.hwndOwner = g_hWnd;
1567+
1568+#ifdef HAVE_RB_ENC_STR_NEW
1569+ {
1570+ int i;
1571+ VALUE base_array = rb_ary_new();
1572+ for( i = 0; i < RARRAY_LEN( vfilter ); i++ )
1573+ {
1574+ VALUE child_array = rb_ary_new();
1575+ Check_Type(RARRAY_PTR( vfilter )[i], T_ARRAY);
1576+ rb_ary_push( base_array, child_array );
1577+ if( rb_enc_get_index( rb_ary_entry( RARRAY_PTR( vfilter )[i], 0) ) != 0 )
1578+ {
1579+ vsjisstr = rb_funcall( rb_ary_entry( RARRAY_PTR( vfilter )[i], 0), rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1580+ }
1581+ else
1582+ {
1583+ vsjisstr = rb_ary_entry( RARRAY_PTR( vfilter )[i], 0);
1584+ }
1585+ rb_ary_push( child_array, vsjisstr );
1586+ if( rb_enc_get_index( rb_ary_entry( RARRAY_PTR( vfilter )[i], 1) ) != 0 )
1587+ {
1588+ vsjisstr = rb_funcall( rb_ary_entry( RARRAY_PTR( vfilter )[i], 1), rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1589+ }
1590+ else
1591+ {
1592+ vsjisstr = rb_ary_entry( RARRAY_PTR( vfilter )[i], 1);
1593+ }
1594+ rb_ary_push( child_array, vsjisstr );
1595+ }
1596+ filter = rb_ary_join( base_array, rb_str_new( "\0", 1 ) );
1597+ filter = rb_str_cat( filter, "\0", 1 );
1598+ OFN.lpstrFilter = RSTRING_PTR( filter );
1599+ }
1600+#else
1601+ filter = rb_ary_join( vfilter, rb_str_new( "\0", 1 ) );
1602+ filter = rb_str_cat( filter, "\0", 1 );
1603+ OFN.lpstrFilter = RSTRING_PTR( filter );
1604+#endif
1605+ OFN.lpstrFile = buf;
1606+ OFN.nMaxFile = MAX_PATH*2;
1607+ OFN.Flags = OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT;
1608+#ifdef HAVE_RB_ENC_STR_NEW
1609+ if( rb_enc_get_index( vtitle ) != 0 )
1610+ {
1611+ vsjisstr = rb_funcall( vtitle, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1612+ }
1613+ else
1614+ {
1615+ vsjisstr = vtitle;
1616+ }
1617+#else
1618+ vsjisstr = vtitle;
1619+#endif
1620+ OFN.lpstrTitle = RSTRING_PTR(vsjisstr);
1621+ OFN.lpstrDefExt = 0;
1622+ if( !GetSaveFileName(&OFN) )
1623+ {
1624+ return Qnil;
1625+ }
1626+
1627+#ifdef HAVE_RB_ENC_STR_NEW
1628+ return rb_funcall( rb_str_new2( buf ), rb_intern( "force_encoding" ), 1, rb_str_new2( sys_encode ) );
1629+#else
1630+ return rb_str_new2( buf );
1631+#endif
1632+}
1633+
1634+
1635+/*--------------------------------------------------------------------
1636+ 終了時に実行する
1637+ ---------------------------------------------------------------------*/
1638+static VALUE Window_shutdown( VALUE obj )
1639+{
1640+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
1641+
1642+ /* アイコンリソース解放 */
1643+ if( g_WindowInfo.hIcon != 0 )
1644+ {
1645+ DestroyIcon(g_WindowInfo.hIcon);
1646+ }
1647+
1648+ /* マウス状態復元 */
1649+ if( g_WindowInfo.enablemouse == Qfalse )
1650+ {
1651+ int c;
1652+ c = ShowCursor( TRUE );
1653+ while( c < 0 ) c = ShowCursor( TRUE );
1654+ }
1655+
1656+ /* リスト解放 */
1657+ free( rt->PictureList );
1658+ free( rt->PictureStruct );
1659+ rt->PictureCount = 0;
1660+ rt->array = Qnil;
1661+
1662+// /* 動画再生用インターフェイスの解放 */
1663+// if( g_pGraphBuilder != NULL )
1664+// {
1665+// g_pMediaControl->lpVtbl->Stop( g_pMediaControl );
1666+// RELEASE( g_pMediaEventEx );
1667+// RELEASE( g_pVideoWindow );
1668+// RELEASE( g_pMediaControl );
1669+// RELEASE( g_pGraphBuilder );
1670+// }
1671+
1672+ /* DirectX解放 */
1673+ Window_DirectXRelease();
1674+
1675+ /* ウインドウ・クラスの登録解除 */
1676+ UnregisterClass( "DXRuby", g_hInstance );
1677+
1678+ /* フレーム調整の後始末 */
1679+ timeEndPeriod( 1 );
1680+
1681+ g_iRefAll--;
1682+ if( g_iRefAll == 0 )
1683+ {
1684+ CoUninitialize();
1685+ }
1686+
1687+ return obj;
1688+}
1689+
1690+
1691+/*--------------------------------------------------------------------
1692+ DirectXオブジェクトを解放する
1693+ ---------------------------------------------------------------------*/
1694+void Window_DirectXRelease()
1695+{
1696+ int i;
1697+ HRESULT hr;
1698+
1699+ /* D3DXSpriteオブジェクトの使用終了 */
1700+ if( g_pD3DXSprite )
1701+ {
1702+ g_pD3DXSprite->lpVtbl->OnLostDevice( g_pD3DXSprite );
1703+ }
1704+
1705+ /* D3DXSpriteオブジェクト破棄 */
1706+ RELEASE( g_pD3DXSprite );
1707+
1708+ /* DirectInput解放 */
1709+ Input_release();
1710+
1711+ /* Direct3D Deviceオブジェクトの破棄 */
1712+ RELEASE( g_pD3DDevice );
1713+
1714+ /* Direct3Dオブジェクトの破棄 */
1715+ RELEASE( g_pD3D );
1716+}
1717+
1718+
1719+/*--------------------------------------------------------------------
1720+ スクリーンショットを撮る
1721+ ---------------------------------------------------------------------*/
1722+static VALUE Window_getScreenShot( int argc, VALUE *argv, VALUE obj )
1723+{
1724+ HRESULT hr;
1725+ D3DDISPLAYMODE dmode;
1726+ LPDIRECT3DSURFACE9 pSurface;
1727+ RECT rect;
1728+ VALUE vfilename, vformat, vsjisstr;
1729+ int dispx;
1730+ int dispy;
1731+
1732+ rb_scan_args( argc, argv, "11", &vfilename, &vformat );
1733+
1734+ Check_Type( vfilename, T_STRING );
1735+
1736+ /* 現在のディスプレイのフォーマットなどを取得 */
1737+ hr = g_pD3D->lpVtbl->GetAdapterDisplayMode(g_pD3D, D3DADAPTER_DEFAULT, &dmode);
1738+ if( FAILED( hr ) )
1739+ {
1740+ rb_raise( eDXRubyError, "キャプチャに失敗しました - GetAdapterDisplayMode" );
1741+ }
1742+
1743+ /* キャプチャ用サーフェス作成 */
1744+ hr = g_pD3DDevice->lpVtbl->CreateOffscreenPlainSurface(g_pD3DDevice,
1745+ dmode.Width,
1746+ dmode.Height,
1747+ D3DFMT_A8R8G8B8,
1748+ D3DPOOL_SCRATCH, &pSurface, NULL);
1749+ if( FAILED( hr ) )
1750+ {
1751+ rb_raise( eDXRubyError, "キャプチャに失敗しました - CreateOffscreenPlainSurface" );
1752+ }
1753+ /* キャプチャ */
1754+ hr = g_pD3DDevice->lpVtbl->GetFrontBufferData(g_pD3DDevice, 0, pSurface);
1755+ if( FAILED( hr ) )
1756+ {
1757+ RELEASE(pSurface);
1758+ rb_raise( eDXRubyError, "キャプチャに失敗しました - GetFrontBufferData" );
1759+ }
1760+
1761+ /* サーフェスの保存 */
1762+ if( g_D3DPP.Windowed )
1763+ {
1764+ POINT p = { 0, 0 };
1765+ /* ウィンドウ左上の設定 */
1766+ ClientToScreen(g_hWnd , &p);
1767+ if( p.x < 0 )
1768+ {
1769+ p.x = 0;
1770+ }
1771+ if( p.y < 0 )
1772+ {
1773+ p.y = 0;
1774+ }
1775+ rect.left = p.x; rect.top = p.y;
1776+ /* ウィンドウ右下の設定 */
1777+ p.x = g_D3DPP.BackBufferWidth * g_WindowInfo.scale;
1778+ p.y = g_D3DPP.BackBufferHeight * g_WindowInfo.scale;
1779+ ClientToScreen(g_hWnd, &p);
1780+ dispx = GetSystemMetrics(SM_CXSCREEN);
1781+ dispy = GetSystemMetrics(SM_CYSCREEN);
1782+ if( p.x >= dispx )
1783+ {
1784+ p.x = dispx - 1;
1785+ }
1786+ if( p.y >= dispy )
1787+ {
1788+ p.y = dispy - 1;
1789+ }
1790+ rect.right = p.x; rect.bottom = p.y;
1791+ }
1792+#ifdef HAVE_RB_ENC_STR_NEW
1793+ if( rb_enc_get_index( vfilename ) != 0 )
1794+ {
1795+ vsjisstr = rb_funcall( vfilename, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
1796+ }
1797+ else
1798+ {
1799+ vsjisstr = vfilename;
1800+ }
1801+#else
1802+ vsjisstr = vfilename;
1803+#endif
1804+ hr = D3DXSaveSurfaceToFile(
1805+ RSTRING_PTR( vsjisstr ), /* 保存ファイル名 */
1806+ vformat == Qnil ? D3DXIFF_JPG : FIX2INT( vformat ), /* ファイルフォーマット */
1807+ pSurface, /* 保存するサーフェス */
1808+ NULL, /* パレット */
1809+ g_D3DPP.Windowed ? &rect : NULL); /* 保存領域 */
1810+ RELEASE(pSurface);
1811+ if( FAILED( hr ) )
1812+ {
1813+ rb_raise( eDXRubyError, "キャプチャに失敗しました - D3DXSaveSurfaceToFile" );
1814+ }
1815+
1816+ return obj;
1817+}
1818+
1819+
1820+/*--------------------------------------------------------------------
1821+ 使用可能なスクリーンサイズを取得する
1822+ ---------------------------------------------------------------------*/
1823+static VALUE Window_getScreenModes( VALUE obj )
1824+{
1825+ D3DDISPLAYMODE d3ddm;
1826+ int count , max, oldHeight, oldWidth;
1827+ VALUE ary, temp;
1828+
1829+ ary = rb_ary_new();
1830+ max = g_pD3D->lpVtbl->GetAdapterModeCount( g_pD3D, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
1831+
1832+ for( count = 0 ; count < max ; count++ )
1833+ {
1834+ temp = rb_ary_new();
1835+ g_pD3D->lpVtbl->EnumAdapterModes( g_pD3D, D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 , count , &d3ddm);
1836+ rb_ary_push( temp, INT2NUM(d3ddm.Width) );
1837+ rb_ary_push( temp, INT2NUM(d3ddm.Height) );
1838+// rb_ary_push( temp, INT2NUM(d3ddm.RefreshRate) );
1839+ rb_ary_push( ary, temp );
1840+ }
1841+
1842+ rb_funcall( ary, rb_intern("uniq!"), 0 );
1843+
1844+ return ary;
1845+}
1846+
1847+
1848+///*********************************************************************
1849+// * ShaderCoreクラス
1850+// *
1851+// * シェーダプログラムを管理する。
1852+// *********************************************************************/
1853+//
1854+//static void AddShaderCoreList( struct DXRubyShaderCore *core )
1855+//{
1856+// if( g_ShaderCoreList.allocate_size <= g_ShaderCoreList.count )
1857+// {
1858+// g_ShaderCoreList.allocate_size = g_ShaderCoreList.allocate_size * 3 / 2; /* 1.5倍にする */
1859+// g_ShaderCoreList.pointer = realloc( g_ShaderCoreList.pointer, sizeof( void* ) * g_ShaderCoreList.allocate_size );
1860+// }
1861+//
1862+// g_ShaderCoreList.pointer[g_ShaderCoreList.count] = core;
1863+// g_ShaderCoreList.count++;
1864+//}
1865+//static void DeleteShaderCoreList( struct DXRubyShaderCore *rt )
1866+//{
1867+// int i;
1868+//
1869+// for( i = 0; i < g_ShaderCoreList.count; i++ )
1870+// {
1871+// if( g_ShaderCoreList.pointer[i] == rt )
1872+// {
1873+// break;
1874+// }
1875+// }
1876+// if( i == g_ShaderCoreList.count )
1877+// {
1878+// rb_raise( eDXRubyError, "内部エラー - DeleteShaderCoreList" );
1879+// }
1880+//
1881+// i++;
1882+// for( ; i < g_ShaderCoreList.count; i++ )
1883+// {
1884+// g_ShaderCoreList.pointer[i - 1] = g_ShaderCoreList.pointer[i];
1885+// }
1886+//
1887+// g_ShaderCoreList.count--;
1888+//}
1889+//
1890+///*--------------------------------------------------------------------
1891+// 参照されなくなったときにGCから呼ばれる関数
1892+// ---------------------------------------------------------------------*/
1893+//static void ShaderCore_free( struct DXRubyShaderCore *core)
1894+//{
1895+// RELEASE( core->pD3DXEffect );
1896+// DeleteShaderCoreList( core );
1897+// core->vtype = Qnil;
1898+//}
1899+//void ShaderCore_release( struct DXRubyShaderCore *core )
1900+//{
1901+// if( core->pD3DXEffect )
1902+// {
1903+// ShaderCore_free( core );
1904+// }
1905+// free( core );
1906+//}
1907+//
1908+///*--------------------------------------------------------------------
1909+// GCから呼ばれるマーク関数
1910+// ---------------------------------------------------------------------*/
1911+//static void ShaderCore_mark( struct DXRubyShaderCore* core )
1912+//{
1913+// rb_gc_mark( core->vtype );
1914+//}
1915+//
1916+///*--------------------------------------------------------------------
1917+// ShaderCoreクラスのdispose。
1918+// ---------------------------------------------------------------------*/
1919+//static VALUE ShaderCore_dispose( VALUE self )
1920+//{
1921+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, self );
1922+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
1923+// ShaderCore_free( core );
1924+// return self;
1925+//}
1926+//
1927+///*--------------------------------------------------------------------
1928+// ShaderCoreクラスのdisposed?。
1929+// ---------------------------------------------------------------------*/
1930+//static VALUE ShaderCore_check_disposed( VALUE self )
1931+//{
1932+// if( DXRUBY_GET_STRUCT( ShaderCore, self )->pD3DXEffect == NULL )
1933+// {
1934+// return Qtrue;
1935+// }
1936+//
1937+// return Qfalse;
1938+//}
1939+//
1940+///*--------------------------------------------------------------------
1941+// ShaderCoreクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
1942+// ---------------------------------------------------------------------*/
1943+//static VALUE ShaderCore_allocate( VALUE klass )
1944+//{
1945+// VALUE obj;
1946+// struct DXRubyShaderCore *core;
1947+//
1948+// /* DXRubyShaderCoreのメモリ取得&ShaderCoreオブジェクト生成 */
1949+// core = malloc( sizeof( struct DXRubyShaderCore ) );
1950+// if( core == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - ShaderCore_allocate" );
1951+// obj = Data_Wrap_Struct( klass, ShaderCore_mark, ShaderCore_release, core );
1952+//
1953+// /* とりあえず各オブジェクトはNULLにしておく */
1954+// core->pD3DXEffect = NULL;
1955+// core->vtype = Qnil;
1956+//
1957+// return obj;
1958+//}
1959+//
1960+///*--------------------------------------------------------------------
1961+// ShaderCoreクラスのgetParam。
1962+// ---------------------------------------------------------------------*/
1963+//static VALUE ShaderCore_getParam( VALUE self )
1964+//{
1965+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, self );
1966+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
1967+// return core->vtype;
1968+//}
1969+//
1970+//
1971+///*--------------------------------------------------------------------
1972+// ShaderCoreクラスのInitialize
1973+// ---------------------------------------------------------------------*/
1974+//static VALUE ShaderCore_initialize( VALUE self, VALUE vhlsl, VALUE vparam )
1975+//{
1976+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, self );
1977+// LPD3DXBUFFER pErr=NULL;
1978+//
1979+// Check_Type( vhlsl, T_STRING );
1980+// Check_Type( vparam, T_HASH );
1981+//
1982+// if( FAILED( D3DXCreateEffect(
1983+// g_pD3DDevice, RSTRING_PTR( vhlsl ), RSTRING_LEN( vhlsl ), NULL, NULL,
1984+// 0 , NULL, &core->pD3DXEffect, &pErr )))
1985+// {
1986+// // シェーダの読み込みの失敗
1987+// rb_raise( eDXRubyError, pErr->lpVtbl->GetBufferPointer( pErr ) );
1988+// }
1989+// RELEASE( pErr );
1990+//
1991+// core->vtype = vparam;
1992+// rb_hash_aset( vparam, symbol_technique, symbol_technique );
1993+//
1994+// AddShaderCoreList( core );
1995+// return self;
1996+//}
1997+//
1998+//
1999+///*********************************************************************
2000+// * Shaderクラス
2001+// *
2002+// * ShaderCoreオブジェクトとシェーダパラメータを関連付けて管理する。
2003+// *********************************************************************/
2004+//
2005+///*--------------------------------------------------------------------
2006+// 参照されなくなったときにGCから呼ばれる関数
2007+// ---------------------------------------------------------------------*/
2008+//void Shader_release( struct DXRubyShader *shader )
2009+//{
2010+// free( shader );
2011+//}
2012+//
2013+///*--------------------------------------------------------------------
2014+// GCから呼ばれるマーク関数
2015+// ---------------------------------------------------------------------*/
2016+//static void Shader_mark( struct DXRubyShader *shader )
2017+//{
2018+// rb_gc_mark( shader->vcore );
2019+// rb_gc_mark( shader->vparam );
2020+// rb_gc_mark( shader->vname );
2021+//}
2022+//
2023+///*--------------------------------------------------------------------
2024+// Shaderクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
2025+// ---------------------------------------------------------------------*/
2026+//static VALUE Shader_allocate( VALUE klass )
2027+//{
2028+// VALUE obj;
2029+// struct DXRubyShader *shader;
2030+//
2031+// /* DXRubyShaderのメモリ取得&ShaderCoreオブジェクト生成 */
2032+// shader = malloc( sizeof( struct DXRubyShader ) );
2033+// if( shader == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Shader_allocate" );
2034+// obj = Data_Wrap_Struct( klass, Shader_mark, Shader_release, shader );
2035+//
2036+// /* とりあえず各オブジェクトはNULLにしておく */
2037+// shader->vcore = Qnil;
2038+// shader->vparam = Qnil;
2039+// shader->vname = Qnil;
2040+//
2041+// return obj;
2042+//}
2043+//
2044+///* 動的生成したGetter */
2045+//static VALUE Shader_ref( VALUE self )
2046+//{
2047+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2048+// return hash_lookup( shader->vparam, ID2SYM( rb_frame_this_func() ) );
2049+//}
2050+//
2051+///* 動的生成したSetter */
2052+//static VALUE Shader_set( VALUE self, VALUE val )
2053+//{
2054+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2055+// rb_hash_aset( shader->vparam, hash_lookup( shader->vname, ID2SYM( rb_id_attrset( rb_frame_this_func() ) ) ), val );
2056+// return val;
2057+//}
2058+//
2059+///*--------------------------------------------------------------------
2060+// ShaderクラスのInitialize
2061+// ---------------------------------------------------------------------*/
2062+//static int Shader_foreach( VALUE key, VALUE value, VALUE self )
2063+//{
2064+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2065+// if (key == Qundef) return ST_CONTINUE;
2066+// rb_hash_aset( shader->vparam, key, Qnil );
2067+// rb_hash_aset( shader->vname, ID2SYM(rb_id_attrset(SYM2ID(key))), key );
2068+// rb_define_singleton_method( self, rb_id2name( SYM2ID( key ) ), Shader_ref, 0 );
2069+// rb_define_singleton_method( self, rb_id2name( rb_id_attrset( SYM2ID( key ) ) ), Shader_set, 1 );
2070+// return ST_CONTINUE;
2071+//}
2072+//
2073+//static VALUE Shader_initialize( VALUE self, VALUE vcore, VALUE vtech )
2074+//{
2075+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, vcore );
2076+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2077+//
2078+// DXRUBY_CHECK_TYPE( ShaderCore, vcore );
2079+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
2080+//
2081+// shader->vcore = vcore;
2082+// shader->vparam = rb_hash_new();
2083+// shader->vname = rb_hash_new();
2084+//
2085+// rb_hash_foreach( core->vtype, Shader_foreach, self );
2086+//
2087+// rb_hash_aset( shader->vparam, symbol_technique, vtech );
2088+//
2089+// return self;
2090+//}
2091+//
2092+///* technique名取得 */
2093+//static VALUE Shader_getTechnique( VALUE self )
2094+//{
2095+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2096+// return hash_lookup( shader->vparam, symbol_technique );
2097+//}
2098+//
2099+///* technique名設定 */
2100+//static VALUE Shader_setTechnique( VALUE self, VALUE vtech )
2101+//{
2102+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, self );
2103+// Check_Type( vtech, T_STRING );
2104+// rb_hash_aset( shader->vparam, symbol_technique, vtech );
2105+// return vtech;
2106+//}
2107+
2108+
2109+/*********************************************************************
2110+ * RenderTargetクラス
2111+ *
2112+ * レンダーターゲットになれるImageクラス。
2113+ * 直接編集機能は無いが、draw系メソッドでハードウェア描画ができる。
2114+ *********************************************************************/
2115+
2116+static void AddRenderTargetList( struct DXRubyRenderTarget *rt )
2117+{
2118+ if( g_RenderTargetList.allocate_size <= g_RenderTargetList.count )
2119+ {
2120+ g_RenderTargetList.allocate_size = g_RenderTargetList.allocate_size * 3 / 2; /* 1.5倍にする */
2121+ g_RenderTargetList.pointer = realloc( g_RenderTargetList.pointer, sizeof( void* ) * g_RenderTargetList.allocate_size );
2122+ }
2123+
2124+ g_RenderTargetList.pointer[g_RenderTargetList.count] = rt;
2125+ g_RenderTargetList.count++;
2126+}
2127+
2128+static void DeleteRenderTargetList( struct DXRubyRenderTarget *rt )
2129+{
2130+ int i;
2131+
2132+ for( i = 0; i < g_RenderTargetList.count; i++ )
2133+ {
2134+ if( g_RenderTargetList.pointer[i] == rt )
2135+ {
2136+ break;
2137+ }
2138+ }
2139+// if( i == g_RenderTargetList.count )
2140+// {
2141+// rb_raise( eDXRubyError, "内部エラー - DeleteRenderTargetList" );
2142+// }
2143+
2144+ i++;
2145+ for( ; i < g_RenderTargetList.count; i++ )
2146+ {
2147+ g_RenderTargetList.pointer[i - 1] = g_RenderTargetList.pointer[i];
2148+ }
2149+
2150+ g_RenderTargetList.count--;
2151+}
2152+
2153+/*--------------------------------------------------------------------
2154+ 参照されなくなったときにGCから呼ばれる関数
2155+ ---------------------------------------------------------------------*/
2156+static void RenderTarget_free( struct DXRubyRenderTarget *rt )
2157+{
2158+ RELEASE( rt->surface );
2159+ if( rt->texture != NULL )
2160+ {
2161+ RELEASE( rt->texture->pD3DTexture );
2162+ free( rt->texture );
2163+ rt->texture = NULL;
2164+ };
2165+ free( rt->PictureList );
2166+ free( rt->PictureStruct );
2167+ DeleteRenderTargetList( rt );
2168+ rt->PictureCount = 0;
2169+ rt->PictureSize = 0;
2170+ rt->PictureDecideCount = 0;
2171+ rt->PictureDecideSize = 0;
2172+ rt->array = Qnil;
2173+}
2174+
2175+void RenderTarget_release( struct DXRubyRenderTarget *rt )
2176+{
2177+ /* テクスチャオブジェクトの開放 */
2178+ if( rt->texture )
2179+ {
2180+ RenderTarget_free( rt );
2181+ }
2182+ free( rt );
2183+ rt = NULL;
2184+
2185+ g_iRefAll--;
2186+ if( g_iRefAll == 0 )
2187+ {
2188+ CoUninitialize();
2189+ }
2190+}
2191+
2192+/*--------------------------------------------------------------------
2193+ RenderTargetクラスのdispose。
2194+ ---------------------------------------------------------------------*/
2195+static VALUE RenderTarget_dispose( VALUE self )
2196+{
2197+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2198+ DXRUBY_CHECK_DISPOSE( rt, surface );
2199+ RenderTarget_free( rt );
2200+ return self;
2201+}
2202+
2203+/*--------------------------------------------------------------------
2204+ RenderTargetクラスのdisposed?。
2205+ ---------------------------------------------------------------------*/
2206+static VALUE RenderTarget_check_disposed( VALUE self )
2207+{
2208+ if( DXRUBY_GET_STRUCT( RenderTarget, self )->surface == NULL )
2209+ {
2210+ return Qtrue;
2211+ }
2212+
2213+ return Qfalse;
2214+}
2215+
2216+/*--------------------------------------------------------------------
2217+ RenderTargetクラスのmark
2218+ ---------------------------------------------------------------------*/
2219+static void RenderTarget_mark( struct DXRubyRenderTarget *rt )
2220+{
2221+ int i;
2222+
2223+ for( i = 0; i < rt->PictureCount; i++ )
2224+ {
2225+ rb_gc_mark( rt->PictureList[i].picture->value );
2226+ }
2227+
2228+ rb_gc_mark( rt->array );
2229+}
2230+
2231+/*--------------------------------------------------------------------
2232+ RenderTargetクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
2233+ ---------------------------------------------------------------------*/
2234+static VALUE RenderTarget_allocate( VALUE klass )
2235+{
2236+ VALUE obj;
2237+ struct DXRubyRenderTarget *rt;
2238+
2239+ /* DXRubyRenderTargetのメモリ取得&RenderTargetオブジェクト生成 */
2240+ rt = malloc(sizeof(struct DXRubyRenderTarget));
2241+ if( rt == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - RenderTarget_allocate" );
2242+ obj = Data_Wrap_Struct(klass, RenderTarget_mark, RenderTarget_release, rt);
2243+
2244+ /* とりあえずテクスチャオブジェクトはNULLにしておく */
2245+ rt->texture = NULL;
2246+ rt->surface = NULL;
2247+
2248+ /* ピクチャ構造体の初期値設定 */
2249+ rt->PictureCount = 0;
2250+ rt->PictureAllocateCount = 128;
2251+ rt->PictureSize = 0;
2252+ rt->PictureAllocateSize = 128*32;
2253+ rt->PictureList = malloc( rt->PictureAllocateCount * sizeof(struct DXRubyPictureList) );
2254+ rt->PictureStruct = malloc( rt->PictureAllocateSize );
2255+ rt->PictureDecideCount = 0;
2256+ rt->PictureDecideSize = 0;
2257+
2258+ rt->minfilter = D3DTEXF_LINEAR;
2259+ rt->magfilter = D3DTEXF_LINEAR;
2260+
2261+ rt->a = 0;
2262+ rt->r = 0;
2263+ rt->g = 0;
2264+ rt->b = 0;
2265+ rt->array = Qnil;
2266+ rt->array = rb_ary_new();
2267+
2268+ return obj;
2269+}
2270+
2271+
2272+/*--------------------------------------------------------------------
2273+ RenderTargetクラスのInitialize
2274+ ---------------------------------------------------------------------*/
2275+static VALUE RenderTarget_initialize( int argc, VALUE *argv, VALUE self )
2276+{
2277+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2278+ struct DXRubyTexture *texture;
2279+ HRESULT hr;
2280+ D3DSURFACE_DESC desc;
2281+ VALUE vwidth, vheight, vary;
2282+ int width, height;
2283+
2284+ g_iRefAll++;
2285+
2286+ rb_scan_args( argc, argv, "21", &vwidth, &vheight, &vary );
2287+
2288+ width = NUM2INT( vwidth );
2289+ height = NUM2INT( vheight );
2290+
2291+ if( width <= 0 || height <= 0 )
2292+ {
2293+ rb_raise( eDXRubyError, "RenderTargetオブジェクトの作成に失敗しました - RenderTarget_initialize" );
2294+ }
2295+
2296+ /* テクスチャメモリ取得 */
2297+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
2298+
2299+ if( texture == NULL )
2300+ {
2301+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - RenderTarget_initialize" );
2302+ }
2303+
2304+ /* テクスチャオブジェクトを作成する */
2305+ hr = D3DXCreateTexture( g_pD3DDevice, width, height,
2306+ 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
2307+ &texture->pD3DTexture);
2308+
2309+ if( FAILED( hr ) )
2310+ {
2311+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - RenderTarget_initialize" );
2312+ }
2313+
2314+ texture->pD3DTexture->lpVtbl->GetSurfaceLevel( texture->pD3DTexture, 0, &rt->surface );
2315+ texture->pD3DTexture->lpVtbl->GetLevelDesc( texture->pD3DTexture, 0, &desc );
2316+ texture->width = desc.Width;
2317+ texture->height = desc.Height;
2318+
2319+ rt->texture = texture;
2320+ rt->x = 0;
2321+ rt->y = 0;
2322+ rt->width = width;
2323+ rt->height = height;
2324+ if( vary != Qnil )
2325+ {
2326+ Check_Type( vary, T_ARRAY );
2327+ if( RARRAY_LEN( vary ) == 4 )
2328+ {
2329+ rt->a = NUM2INT( rb_ary_entry(vary, 0) );
2330+ rt->r = NUM2INT( rb_ary_entry(vary, 1) );
2331+ rt->g = NUM2INT( rb_ary_entry(vary, 2) );
2332+ rt->b = NUM2INT( rb_ary_entry(vary, 3) );
2333+ }
2334+ else
2335+ {
2336+ rt->a = 255;
2337+ rt->r = NUM2INT( rb_ary_entry(vary, 0) );
2338+ rt->g = NUM2INT( rb_ary_entry(vary, 1) );
2339+ rt->b = NUM2INT( rb_ary_entry(vary, 2) );
2340+ }
2341+ }
2342+
2343+ AddRenderTargetList( rt );
2344+
2345+ g_pD3DDevice->lpVtbl->SetRenderTarget( g_pD3DDevice, 0, rt->surface );
2346+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
2347+ D3DCOLOR_ARGB( rt->a, rt->r, rt->g, rt->b ), 1.0f, 0 );
2348+
2349+ return self;
2350+}
2351+
2352+
2353+/*--------------------------------------------------------------------
2354+ RenderTargetクラスのImageオブジェクト化
2355+ ---------------------------------------------------------------------*/
2356+static VALUE RenderTarget_to_image( VALUE self )
2357+{
2358+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2359+ VALUE vimage;
2360+ struct DXRubyImage *image;
2361+ LPDIRECT3DTEXTURE9 pD3DTexture;
2362+ VALUE ary[2];
2363+ IDirect3DSurface9 *surface;
2364+ D3DLOCKED_RECT srctrect;
2365+ D3DLOCKED_RECT dsttrect;
2366+ int i, j;
2367+ RECT srect;
2368+ RECT drect;
2369+ HRESULT hr;
2370+ int *psrc;
2371+ int *pdst;
2372+ D3DSURFACE_DESC desc;
2373+
2374+ DXRUBY_CHECK_DISPOSE( rt, surface );
2375+
2376+ vimage = Image_allocate( cImage );
2377+ ary[0] = INT2FIX( rt->width );
2378+ ary[1] = INT2FIX( rt->height );
2379+ Image_initialize( 2, ary, vimage );
2380+ image = DXRUBY_GET_STRUCT( Image, vimage );
2381+
2382+ /* テクスチャオブジェクトを作成する */
2383+ hr = D3DXCreateTexture( g_pD3DDevice, rt->texture->width, rt->texture->height,
2384+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
2385+ &pD3DTexture);
2386+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - RenderTarget_to_image" );
2387+
2388+ /* テクスチャのサーフェイスを取得 */
2389+ hr = pD3DTexture->lpVtbl->GetSurfaceLevel( pD3DTexture, 0, &surface );
2390+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "サーフェイスの作成に失敗しました - RenderTarget_to_image" );
2391+
2392+ /* レンダーターゲットのイメージ取得 */
2393+ hr = g_pD3DDevice->lpVtbl->GetRenderTargetData( g_pD3DDevice, rt->surface, surface );
2394+ if( FAILED( hr ) ) rb_raise( eDXRubyError, "イメージの取得に失敗しました - RenderTarget_to_image" );
2395+
2396+ /* イメージのコピー */
2397+ srect.left = rt->x;
2398+ srect.top = rt->y;
2399+ srect.right = rt->width;
2400+ srect.bottom = rt->height;
2401+ drect.left = 0;
2402+ drect.top = 0;
2403+ drect.right = rt->width;
2404+ drect.bottom = rt->height;
2405+
2406+ hr = pD3DTexture->lpVtbl->LockRect( pD3DTexture, 0, &srctrect, &srect, D3DLOCK_READONLY );
2407+ hr = image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &dsttrect, &drect, 0 );
2408+
2409+ for( i = 0; i < rt->height; i++)
2410+ {
2411+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
2412+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
2413+ for( j = 0; j < rt->width; j++)
2414+ {
2415+ *(pdst++) = *(psrc++);
2416+ }
2417+ }
2418+
2419+ pD3DTexture->lpVtbl->UnlockRect( pD3DTexture, 0 );
2420+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
2421+
2422+ RELEASE( surface );
2423+ RELEASE( pD3DTexture );
2424+
2425+ return vimage;
2426+}
2427+
2428+
2429+/*--------------------------------------------------------------------
2430+ レンダーターゲットの開始位置xを返す。
2431+ ---------------------------------------------------------------------*/
2432+static VALUE RenderTarget_getX( VALUE self )
2433+{
2434+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2435+ DXRUBY_CHECK_DISPOSE( rt, surface );
2436+ return INT2FIX( rt->x );
2437+}
2438+
2439+
2440+/*--------------------------------------------------------------------
2441+ レンダーターゲットの開始位置yを返す。
2442+ ---------------------------------------------------------------------*/
2443+static VALUE RenderTarget_getY( VALUE self )
2444+{
2445+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2446+ DXRUBY_CHECK_DISPOSE( rt, surface );
2447+ return INT2FIX( rt->y );
2448+}
2449+
2450+
2451+/*--------------------------------------------------------------------
2452+ レンダーターゲットのサイズ(幅)を返す。
2453+ ---------------------------------------------------------------------*/
2454+static VALUE RenderTarget_getWidth( VALUE self )
2455+{
2456+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2457+ DXRUBY_CHECK_DISPOSE( rt, surface );
2458+ return INT2FIX( rt->width );
2459+}
2460+
2461+
2462+/*--------------------------------------------------------------------
2463+ レンダーターゲットのサイズ(高さ)を返す。
2464+ ---------------------------------------------------------------------*/
2465+static VALUE RenderTarget_getHeight( VALUE self )
2466+{
2467+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2468+ DXRUBY_CHECK_DISPOSE( rt, surface );
2469+ return INT2FIX( rt->height );
2470+}
2471+
2472+
2473+/*--------------------------------------------------------------------
2474+ レンダーターゲットの開始位置xを設定する。
2475+ ---------------------------------------------------------------------*/
2476+static VALUE RenderTarget_setX( VALUE self, VALUE vx )
2477+{
2478+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2479+ DXRUBY_CHECK_DISPOSE( rt, surface );
2480+ rt->x = NUM2INT( vx );
2481+ return vx;
2482+}
2483+
2484+
2485+/*--------------------------------------------------------------------
2486+ レンダーターゲットの開始位置yを設定する。
2487+ ---------------------------------------------------------------------*/
2488+static VALUE RenderTarget_setY( VALUE self, VALUE vy )
2489+{
2490+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2491+ DXRUBY_CHECK_DISPOSE( rt, surface );
2492+ rt->y = NUM2INT( vy );
2493+ return vy;
2494+}
2495+
2496+
2497+/*--------------------------------------------------------------------
2498+ レンダーターゲットのサイズ(幅)を設定する。
2499+ ---------------------------------------------------------------------*/
2500+static VALUE RenderTarget_setWidth( VALUE self, VALUE vwidth )
2501+{
2502+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2503+ DXRUBY_CHECK_DISPOSE( rt, surface );
2504+ rt->width = NUM2INT( vwidth );
2505+ return vwidth;
2506+}
2507+
2508+
2509+/*--------------------------------------------------------------------
2510+ レンダーターゲットのサイズ(高さ)を設定する。
2511+ ---------------------------------------------------------------------*/
2512+static VALUE RenderTarget_setHeight( VALUE self, VALUE vheight )
2513+{
2514+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2515+ DXRUBY_CHECK_DISPOSE( rt, surface );
2516+ rt->height = NUM2INT( vheight );
2517+ return vheight;
2518+}
2519+
2520+
2521+/*--------------------------------------------------------------------
2522+ ピクチャリストのメモリ確保
2523+ ---------------------------------------------------------------------*/
2524+void *RenderTarget_AllocPictureList( struct DXRubyRenderTarget *rt, int size )
2525+{
2526+ void* result = rt->PictureStruct + rt->PictureSize;
2527+ int i;
2528+
2529+ rt->PictureSize += size;
2530+
2531+ if( rt->PictureSize > rt->PictureAllocateSize )
2532+ {
2533+ char *temp = rt->PictureStruct;
2534+ rt->PictureAllocateSize = rt->PictureAllocateSize * 3 / 2; /* 1.5倍にする */
2535+ rt->PictureStruct = realloc( rt->PictureStruct, rt->PictureAllocateSize );
2536+ if( rt->PictureStruct == NULL ) rb_raise(eDXRubyError, "メモリが取得できませんでした - RenderTarget_draw");
2537+ for( i = 0; i < rt->PictureCount; i++)
2538+ {
2539+ rt->PictureList[i].picture = (struct DXRubyPicture *)((char *)rt->PictureList[i].picture + ((char*)rt->PictureStruct - temp));
2540+ }
2541+ rt->PictureDecideSize += (char*)rt->PictureStruct - temp;
2542+ result = rt->PictureStruct + rt->PictureSize - size;
2543+ }
2544+
2545+ if( rt->PictureCount >= rt->PictureAllocateCount )
2546+ {
2547+ rt->PictureAllocateCount = rt->PictureAllocateCount * 3 / 2; /* 1.5倍にする */
2548+ rt->PictureList = realloc( rt->PictureList, rt->PictureAllocateCount * sizeof(struct DXRubyPictureList) );
2549+ if( rt->PictureList == NULL ) rb_raise(eDXRubyError, "メモリが取得できませんでした - RenderTarget_draw");
2550+ }
2551+
2552+ return result;
2553+}
2554+
2555+
2556+/* マージソート */
2557+void merge( struct DXRubyPictureList *list, struct DXRubyPictureList *temp, int left, int mid, int right )
2558+{
2559+ int left_end, num_elements, tmp_pos;
2560+
2561+ left_end = mid - 1;
2562+ tmp_pos = left;
2563+ num_elements = right - left + 1;
2564+
2565+ while ((left <= left_end) && (mid <= right))
2566+ {
2567+ if (list[left].z <= list[mid].z)
2568+ temp[tmp_pos++] = list[left++];
2569+ else
2570+ temp[tmp_pos++] = list[mid++];
2571+ }
2572+
2573+ while (left <= left_end)
2574+ {
2575+ temp[tmp_pos++] = list[left++];
2576+ }
2577+ while (mid <= right)
2578+ {
2579+ temp[tmp_pos++] = list[mid++];
2580+ }
2581+
2582+ while (num_elements--)
2583+ {
2584+ list[right] = temp[right--];
2585+ }
2586+}
2587+
2588+
2589+void m_sort( struct DXRubyPictureList *list, struct DXRubyPictureList *temp, int left, int right )
2590+{
2591+ int mid;
2592+
2593+ if( right > left )
2594+ {
2595+ mid = (right + left) / 2;
2596+ m_sort( list, temp, left, mid );
2597+ m_sort( list, temp, mid+1, right );
2598+
2599+ merge( list, temp, left, mid+1, right );
2600+ }
2601+}
2602+
2603+
2604+void RenderTarget_SortPictureList( struct DXRubyRenderTarget *rt )
2605+{
2606+ struct DXRubyPictureList *temp;
2607+ int i;
2608+
2609+ for( i = 0; i < rt->PictureCount; i++ )
2610+ {
2611+ if( rt->PictureList[i].z != 0.0f )
2612+ {
2613+ temp = malloc( sizeof(struct DXRubyPictureList)* rt->PictureCount );
2614+ m_sort( rt->PictureList, temp, 0, rt->PictureCount - 1 );
2615+ free(temp);
2616+ break;
2617+ }
2618+ }
2619+}
2620+
2621+
2622+/*--------------------------------------------------------------------
2623+ 画面クリア色取得
2624+ ---------------------------------------------------------------------*/
2625+static VALUE RenderTarget_get_bgcolor( VALUE self )
2626+{
2627+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2628+ DXRUBY_CHECK_DISPOSE( rt, surface );
2629+ return rb_ary_new3( 4, INT2FIX( rt->a ), INT2FIX( rt->r ), INT2FIX( rt->g ), INT2FIX( rt->b ) );
2630+}
2631+
2632+
2633+/*--------------------------------------------------------------------
2634+ 画面クリア色指定
2635+ ---------------------------------------------------------------------*/
2636+static VALUE RenderTarget_set_bgcolor( VALUE self, VALUE array )
2637+{
2638+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
2639+ DXRUBY_CHECK_DISPOSE( rt, surface );
2640+
2641+ Check_Type( array, T_ARRAY );
2642+
2643+ if( RARRAY_LEN( array ) == 4 )
2644+ {
2645+ rt->a = NUM2INT( rb_ary_entry(array, 0) );
2646+ rt->r = NUM2INT( rb_ary_entry(array, 1) );
2647+ rt->g = NUM2INT( rb_ary_entry(array, 2) );
2648+ rt->b = NUM2INT( rb_ary_entry(array, 3) );
2649+ }
2650+ else
2651+ {
2652+ rt->a = 255;
2653+ rt->r = NUM2INT( rb_ary_entry(array, 0) );
2654+ rt->g = NUM2INT( rb_ary_entry(array, 1) );
2655+ rt->b = NUM2INT( rb_ary_entry(array, 2) );
2656+ }
2657+
2658+ return array;
2659+}
2660+
2661+void RenderTarget_draw_func( struct DXRubyPicture_draw *picture )
2662+{
2663+ TLVERTX VertexDataTbl[6];
2664+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, picture->value );
2665+ float basex = picture->x - 0.5f;
2666+ float basey = picture->y - 0.5f;
2667+ float width = image->width;
2668+ float height = image->height;
2669+ float tu1;
2670+ float tu2;
2671+ float tv1;
2672+ float tv2;
2673+
2674+ DXRUBY_CHECK_DISPOSE( image, texture );
2675+ tu1 = image->x / image->texture->width;
2676+ tu2 = (image->x + width) / image->texture->width;
2677+ tv1 = image->y / image->texture->height;
2678+ tv2 = (image->y + height) / image->texture->height;
2679+
2680+ /* 頂点1 */
2681+ VertexDataTbl[0].x = basex;
2682+ VertexDataTbl[0].y = basey;
2683+ /* 頂点2 */
2684+ VertexDataTbl[1].x = VertexDataTbl[3].x = basex + width;
2685+ VertexDataTbl[1].y = VertexDataTbl[3].y = basey;
2686+ /* 頂点3 */
2687+ VertexDataTbl[4].x = basex + width;
2688+ VertexDataTbl[4].y = basey + height;
2689+ /* 頂点4 */
2690+ VertexDataTbl[2].x = VertexDataTbl[5].x = basex;
2691+ VertexDataTbl[2].y = VertexDataTbl[5].y = basey + height;
2692+ /* 頂点色 */
2693+ VertexDataTbl[0].color = VertexDataTbl[1].color =
2694+ VertexDataTbl[2].color = VertexDataTbl[3].color =
2695+ VertexDataTbl[4].color = VertexDataTbl[5].color = D3DCOLOR_ARGB(picture->alpha,255,255,255);
2696+ /* Z座標 */
2697+ VertexDataTbl[0].z = VertexDataTbl[1].z =
2698+ VertexDataTbl[2].z = VertexDataTbl[3].z =
2699+ VertexDataTbl[4].z = VertexDataTbl[5].z = picture->z;
2700+ /* テクスチャ座標 */
2701+ VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = tu1;
2702+ VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = tv1;
2703+ VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = tu2;
2704+ VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = tv2;
2705+
2706+ /* テクスチャをセット */
2707+ g_pD3DDevice->lpVtbl->SetTexture(g_pD3DDevice, 0, (IDirect3DBaseTexture9*)image->texture->pD3DTexture);
2708+
2709+ /* デバイスに使用する頂点フォーマットをセット */
2710+ g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
2711+
2712+ /* 描画 */
2713+ g_pD3DDevice->lpVtbl->DrawPrimitiveUP(g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX));
2714+}
2715+
2716+/*--------------------------------------------------------------------
2717+ 描画設定(通常描画)
2718+ ---------------------------------------------------------------------*/
2719+static VALUE RenderTarget_draw( int argc, VALUE *argv, VALUE obj )
2720+{
2721+ struct DXRubyImage *image;
2722+ struct DXRubyPicture_draw *picture;
2723+ float z;
2724+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
2725+ DXRUBY_CHECK_DISPOSE( rt, surface );
2726+
2727+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
2728+
2729+ /* 引数のイメージオブジェクトから中身を取り出す */
2730+ DXRUBY_CHECK_IMAGE( argv[2] );
2731+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
2732+ DXRUBY_CHECK_DISPOSE( image, texture );
2733+
2734+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
2735+
2736+ /* DXRubyPictureオブジェクト設定 */
2737+ picture->func = RenderTarget_draw_func;
2738+ picture->x = NUM2INT( argv[0] );
2739+ picture->y = NUM2INT( argv[1] );
2740+ picture->value = argv[2];
2741+ picture->alpha = 0xff;
2742+ picture->blendflag = 0;
2743+
2744+ /* リストデータに追加 */
2745+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
2746+ z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2FLOAT( argv[3] );
2747+ rt->PictureList[rt->PictureCount].z = z;
2748+ picture->z = z;
2749+ rt->PictureCount++;
2750+
2751+ return obj;
2752+}
2753+
2754+/*--------------------------------------------------------------------
2755+ 描画設定(半透明描画)
2756+ ---------------------------------------------------------------------*/
2757+static VALUE RenderTarget_drawAlpha( int argc, VALUE *argv, VALUE obj )
2758+{
2759+ struct DXRubyImage *image;
2760+ struct DXRubyPicture_draw *picture;
2761+ float z;
2762+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
2763+ DXRUBY_CHECK_DISPOSE( rt, surface );
2764+
2765+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
2766+
2767+ /* 引数のイメージオブジェクトから中身を取り出す */
2768+ DXRUBY_CHECK_IMAGE( argv[2] );
2769+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
2770+ DXRUBY_CHECK_DISPOSE( image, texture );
2771+
2772+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
2773+
2774+ /* DXRubyPictureオブジェクト設定 */
2775+ picture->func = RenderTarget_draw_func;
2776+ picture->x = NUM2INT( argv[0] );
2777+ picture->y = NUM2INT( argv[1] );
2778+ picture->value = argv[2];
2779+ picture->alpha = NUM2INT( argv[3] );
2780+ picture->blendflag = 0;
2781+
2782+ /* リストデータに追加 */
2783+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
2784+ z = argc < 5 || argv[4] == Qnil ? 0.0f : NUM2FLOAT( argv[4] );
2785+ rt->PictureList[rt->PictureCount].z = z;
2786+ picture->z = z;
2787+ rt->PictureCount++;
2788+
2789+ return obj;
2790+}
2791+
2792+
2793+/*--------------------------------------------------------------------
2794+ 描画設定(加算合成描画)
2795+ ---------------------------------------------------------------------*/
2796+static VALUE RenderTarget_drawAdd( int argc, VALUE *argv, VALUE obj )
2797+{
2798+ struct DXRubyImage *image;
2799+ struct DXRubyPicture_draw *picture;
2800+ float z;
2801+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
2802+ DXRUBY_CHECK_DISPOSE( rt, surface );
2803+
2804+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
2805+
2806+ /* 引数のイメージオブジェクトから中身を取り出す */
2807+ DXRUBY_CHECK_IMAGE( argv[2] );
2808+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
2809+ DXRUBY_CHECK_DISPOSE( image, texture );
2810+
2811+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
2812+
2813+ /* DXRubyPictureオブジェクト設定 */
2814+ picture->func = RenderTarget_draw_func;
2815+ picture->x = NUM2INT( argv[0] );
2816+ picture->y = NUM2INT( argv[1] );
2817+ picture->value = argv[2];
2818+ picture->alpha = 0xff;
2819+ picture->blendflag = 4;
2820+
2821+ /* リストデータに追加 */
2822+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
2823+ z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2FLOAT( argv[3] );
2824+ rt->PictureList[rt->PictureCount].z = z;
2825+ picture->z = z;
2826+ rt->PictureCount++;
2827+
2828+ return obj;
2829+}
2830+
2831+
2832+/*--------------------------------------------------------------------
2833+ 描画設定(減算合成描画)
2834+ ---------------------------------------------------------------------*/
2835+static VALUE RenderTarget_drawSub( int argc, VALUE *argv, VALUE obj )
2836+{
2837+ struct DXRubyImage *image;
2838+ struct DXRubyPicture_draw *picture;
2839+ float z;
2840+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
2841+ DXRUBY_CHECK_DISPOSE( rt, surface );
2842+
2843+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
2844+
2845+ /* 引数のイメージオブジェクトから中身を取り出す */
2846+ DXRUBY_CHECK_IMAGE( argv[2] );
2847+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
2848+ DXRUBY_CHECK_DISPOSE( image, texture );
2849+
2850+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
2851+
2852+ /* DXRubyPictureオブジェクト設定 */
2853+ picture->func = RenderTarget_draw_func;
2854+ picture->x = NUM2INT( argv[0] );
2855+ picture->y = NUM2INT( argv[1] );
2856+ picture->value = argv[2];
2857+ picture->alpha = 0xff;
2858+ picture->blendflag = 6;
2859+
2860+ /* リストデータに追加 */
2861+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
2862+ z = argc < 4 || argv[3] == Qnil ? 0.0f : NUM2FLOAT( argv[3] );
2863+ rt->PictureList[rt->PictureCount].z = z;
2864+ picture->z = z;
2865+ rt->PictureCount++;
2866+
2867+ return obj;
2868+}
2869+
2870+
2871+//static int Window_drawShader_func_foreach( VALUE key, VALUE value, VALUE obj ) /* key、valueはShader、objはShaderCore */
2872+//{
2873+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, obj );
2874+// const char *str;
2875+// D3DXHANDLE h;
2876+// int i;
2877+// VALUE vtype;
2878+//
2879+// if ( key == Qundef ) return ST_CONTINUE;
2880+// if ( TYPE( key ) != T_SYMBOL ) return ST_CONTINUE;
2881+//
2882+//
2883+// str = rb_id2name( SYM2ID( key ) );
2884+// vtype = hash_lookup( core->vtype, key );
2885+// if( vtype == symbol_float )
2886+// {
2887+// float *temp;
2888+// h = core->pD3DXEffect->lpVtbl->GetParameterByName( core->pD3DXEffect, NULL, str );
2889+// if( TYPE( value ) == T_ARRAY )
2890+// {
2891+// temp = alloca( sizeof(float) * RARRAY_LEN( value ) );
2892+// for( i = 0; i < RARRAY_LEN( value ); i++ )
2893+// {
2894+// temp[i] = NUM2FLOAT( RARRAY_PTR( value )[i] );
2895+// }
2896+// core->pD3DXEffect->lpVtbl->SetFloatArray( core->pD3DXEffect, h, temp, i );
2897+// }
2898+// else
2899+// {
2900+// core->pD3DXEffect->lpVtbl->SetFloat( core->pD3DXEffect, h, NUM2FLOAT( value ) );
2901+// }
2902+// }
2903+// else if( vtype == symbol_texture )
2904+// {
2905+// if ( RDATA( value )->dfree == (RUBY_DATA_FUNC)Image_release || RDATA( value )->dfree == (RUBY_DATA_FUNC)RenderTarget_release )
2906+// {
2907+// DXRUBY_CHECK_DISPOSE( DXRUBY_GET_STRUCT( Image, value ), texture );
2908+// core->pD3DXEffect->lpVtbl->SetTexture( core->pD3DXEffect, str ,
2909+// (IDirect3DBaseTexture9*)(DXRUBY_GET_STRUCT( Image, value )->texture->pD3DTexture) );
2910+// }
2911+// else
2912+// {
2913+// rb_raise( eDXRubyError, "textureパラメータに画像以外が渡されています - Window_draw" );
2914+// }
2915+// }
2916+// else if( vtype == symbol_int )
2917+// {
2918+// int *temp;
2919+// h = core->pD3DXEffect->lpVtbl->GetParameterByName( core->pD3DXEffect, NULL, str );
2920+// if( TYPE( value ) == T_ARRAY )
2921+// {
2922+// temp = alloca( sizeof(int) * RARRAY_LEN( value ) );
2923+// for( i = 0; i < RARRAY_LEN( value ); i++ )
2924+// {
2925+// temp[i] = NUM2INT( RARRAY_PTR( value )[i] );
2926+// }
2927+// core->pD3DXEffect->lpVtbl->SetIntArray( core->pD3DXEffect, h, temp, i );
2928+// }
2929+// else
2930+// {
2931+// core->pD3DXEffect->lpVtbl->SetInt( core->pD3DXEffect, h, NUM2INT( value ) );
2932+// }
2933+// }
2934+// else if( vtype == symbol_technique )
2935+// {
2936+// h = core->pD3DXEffect->lpVtbl->GetTechniqueByName( core->pD3DXEffect, RSTRING_PTR( value ) );
2937+// core->pD3DXEffect->lpVtbl->SetTechnique( core->pD3DXEffect, h );
2938+// }
2939+// else
2940+// {
2941+// rb_raise( eDXRubyError, "Shaderオブジェクトのパラメータの型が不明です - Window_draw" );
2942+// }
2943+//
2944+// return ST_CONTINUE;
2945+//}
2946+//
2947+//void RenderTarget_drawShader_func( struct DXRubyPicture_draw *picture )
2948+//{
2949+// TLVERTX VertexDataTbl[6];
2950+// struct DXRubyImage *image;
2951+// struct DXRubyShaderCore *core;
2952+// float basex = picture->x;
2953+// float basey = picture->y;
2954+// float width;
2955+// float height;
2956+// float tu1;
2957+// float tu2;
2958+// float tv1;
2959+// float tv2;
2960+// int i;
2961+// UINT pass;
2962+//
2963+// image = DXRUBY_GET_STRUCT( Image, RARRAY_PTR( picture->value )[0] );
2964+// core = DXRUBY_GET_STRUCT( ShaderCore, RARRAY_PTR( picture->value )[1] );
2965+// DXRUBY_CHECK_DISPOSE( image, texture );
2966+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
2967+//
2968+// width = image->width;
2969+// height = image->height;
2970+// tu1 = image->x / image->texture->width;
2971+// tu2 = (image->x + width) / image->texture->width;
2972+// tv1 = image->y / image->texture->height;
2973+// tv2 = (image->y + height) / image->texture->height;
2974+//
2975+// /* 頂点1 */
2976+// VertexDataTbl[0].x = basex-0.5f;
2977+// VertexDataTbl[0].y = basey-0.5f;
2978+// /* 頂点2 */
2979+// VertexDataTbl[1].x = VertexDataTbl[3].x = basex + width-0.5f;
2980+// VertexDataTbl[1].y = VertexDataTbl[3].y = basey-0.5f;
2981+// /* 頂点3 */
2982+// VertexDataTbl[4].x = basex + width-0.5f;
2983+// VertexDataTbl[4].y = basey + height-0.5f;
2984+// /* 頂点4 */
2985+// VertexDataTbl[2].x = VertexDataTbl[5].x = basex-0.5f;
2986+// VertexDataTbl[2].y = VertexDataTbl[5].y = basey + height-0.5f;
2987+// /* 頂点色 */
2988+// VertexDataTbl[0].color = VertexDataTbl[1].color =
2989+// VertexDataTbl[2].color = VertexDataTbl[3].color =
2990+// VertexDataTbl[4].color = VertexDataTbl[5].color = D3DCOLOR_ARGB(picture->alpha,255,255,255);
2991+// /* Z座標 */
2992+// VertexDataTbl[0].z = VertexDataTbl[1].z =
2993+// VertexDataTbl[2].z = VertexDataTbl[3].z =
2994+// VertexDataTbl[4].z = VertexDataTbl[5].z = picture->z;
2995+// /* テクスチャ座標 */
2996+// VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = tu1;
2997+// VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = tv1;
2998+// VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = tu2;
2999+// VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = tv2;
3000+//
3001+// /* デバイスに使用する頂点フォーマットをセット */
3002+// g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
3003+//
3004+// rb_hash_foreach( RARRAY_PTR( picture->value )[2], Window_drawShader_func_foreach, RARRAY_PTR( picture->value )[1]);
3005+//
3006+// DXRUBY_CHECK_DISPOSE( DXRUBY_GET_STRUCT( Image, RARRAY_PTR( picture->value )[0] ), texture );
3007+// core->pD3DXEffect->lpVtbl->SetTexture( core->pD3DXEffect, "tex0",
3008+// (IDirect3DBaseTexture9*)(DXRUBY_GET_STRUCT( Image, RARRAY_PTR( picture->value )[0] )->texture->pD3DTexture) );
3009+//
3010+// core->pD3DXEffect->lpVtbl->Begin( core->pD3DXEffect, &pass, 0 );
3011+// for( i = 0; i < pass; i++ )
3012+// {
3013+// /* 描画 */
3014+// core->pD3DXEffect->lpVtbl->BeginPass( core->pD3DXEffect, i );
3015+// g_pD3DDevice->lpVtbl->DrawPrimitiveUP( g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX) );
3016+// core->pD3DXEffect->lpVtbl->EndPass( core->pD3DXEffect );
3017+// }
3018+// core->pD3DXEffect->lpVtbl->End( core->pD3DXEffect );
3019+//}
3020+//
3021+///*--------------------------------------------------------------------
3022+// 描画設定(シェーダ描画)
3023+// ---------------------------------------------------------------------*/
3024+//static VALUE RenderTarget_drawShader( int argc, VALUE *argv, VALUE obj )
3025+//{
3026+// struct DXRubyPicture_draw *picture;
3027+// struct DXRubyShaderCore *core;
3028+// struct DXRubyShader *shader;
3029+// float z;
3030+// volatile VALUE temp;
3031+// int i;
3032+// struct DXRubyRenderTarget *rt;
3033+//
3034+// if( obj == mWindow )
3035+// {
3036+// rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
3037+// }
3038+// else
3039+// {
3040+// rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3041+// }
3042+//
3043+// if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
3044+//
3045+// picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
3046+//
3047+// DXRUBY_CHECK_TYPE( Shader, argv[3] );
3048+// shader = DXRUBY_GET_STRUCT( Shader, argv[3] );
3049+// core = DXRUBY_GET_STRUCT( ShaderCore, shader->vcore );
3050+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
3051+//
3052+// /* 引数のイメージオブジェクトから中身を取り出す */
3053+// DXRUBY_CHECK_IMAGE( argv[2] );
3054+// DXRUBY_CHECK_DISPOSE( DXRUBY_GET_STRUCT( Image, argv[2] ), texture );
3055+//
3056+// temp = rb_ary_new3( 3, argv[2], shader->vcore, shader->vparam );
3057+// picture->value = temp;
3058+//
3059+// /* DXRubyPictureオブジェクト設定 */
3060+// picture->func = RenderTarget_drawShader_func;
3061+// picture->x = NUM2INT( argv[0] );
3062+// picture->y = NUM2INT( argv[1] );
3063+// picture->alpha = 0xff;
3064+// picture->blendflag = 0;
3065+//
3066+// /* リストデータに追加 */
3067+// rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3068+// z = argc < 5 || argv[4] == Qnil ? 0.0f : NUM2FLOAT( argv[4] );
3069+// rt->PictureList[rt->PictureCount].z = z;
3070+// picture->z = z;
3071+// rt->PictureCount++;
3072+//
3073+// return obj;
3074+//}
3075+
3076+
3077+void RenderTarget_drawEx_func( struct DXRubyPicture_drawEx *picture )
3078+{
3079+ TLVERTX VertexDataTbl[6];
3080+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, RARRAY_PTR( picture->value )[0] );
3081+ float angle = 3.141592653589793115997963468544185161590576171875f / 180.0f * picture->angle;
3082+ float sina = sin(angle);
3083+ float cosa = cos(angle);
3084+ float data1x = picture->scalex * cosa;
3085+ float data2x = picture->scalex * sina;
3086+ float data1y = picture->scaley * sina;
3087+ float data2y = picture->scaley * cosa;
3088+ float tu1;
3089+ float tu2;
3090+ float tv1;
3091+ float tv2;
3092+ float centerx = -picture->centerx;
3093+ float centery = -picture->centery;
3094+ float width = image->width;
3095+ float height = image->height;
3096+ float basex = picture->x - centerx;
3097+ float basey = picture->y - centery;
3098+ int i;
3099+ UINT pass;
3100+
3101+ DXRUBY_CHECK_DISPOSE( image, texture );
3102+ tu1 = (image->x) / image->texture->width;
3103+ tu2 = (image->x + image->width) / image->texture->width;
3104+ tv1 = (image->y) / image->texture->height;
3105+ tv2 = (image->y + image->height) / image->texture->height;
3106+
3107+ /* 頂点1 */
3108+ VertexDataTbl[0].x = centerx * data1x - centery * data1y + basex - 0.5f;
3109+ VertexDataTbl[0].y = centerx * data2x + centery * data2y + basey - 0.5f;
3110+ /* 頂点2 */
3111+ VertexDataTbl[1].x = VertexDataTbl[3].x = (centerx+width) * data1x - centery * data1y + basex - 0.5f;
3112+ VertexDataTbl[1].y = VertexDataTbl[3].y = (centerx+width) * data2x + centery * data2y + basey - 0.5f;
3113+ /* 頂点3 */
3114+ VertexDataTbl[4].x = (centerx+width) * data1x - (centery+height) * data1y + basex - 0.5f;
3115+ VertexDataTbl[4].y = (centerx+width) * data2x + (centery+height) * data2y + basey - 0.5f;
3116+ /* 頂点4 */
3117+ VertexDataTbl[2].x = VertexDataTbl[5].x = centerx * data1x - (centery+height) * data1y + basex - 0.5f;
3118+ VertexDataTbl[2].y = VertexDataTbl[5].y = centerx * data2x + (centery+height) * data2y + basey - 0.5f;
3119+ /* 頂点色 */
3120+ VertexDataTbl[0].color = VertexDataTbl[1].color =
3121+ VertexDataTbl[2].color = VertexDataTbl[3].color =
3122+ VertexDataTbl[4].color = VertexDataTbl[5].color = D3DCOLOR_ARGB(picture->alpha,255,255,255);
3123+ /* Z座標 */
3124+ VertexDataTbl[0].z = VertexDataTbl[1].z =
3125+ VertexDataTbl[2].z = VertexDataTbl[3].z =
3126+ VertexDataTbl[4].z = VertexDataTbl[5].z = picture->z;
3127+ /* テクスチャ座標 */
3128+ VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = tu1;
3129+ VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = tv1;
3130+ VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = tu2;
3131+ VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = tv2;
3132+
3133+ /* デバイスに使用する頂点フォーマットをセット */
3134+ g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
3135+
3136+// if( RARRAY_LEN( picture->value ) != 1 ) /* Shaderあり */
3137+// {
3138+// struct DXRubyShaderCore *core = DXRUBY_GET_STRUCT( ShaderCore, RARRAY_PTR( picture->value )[1] );
3139+// DXRUBY_CHECK_DISPOSE( core, pD3DXEffect );
3140+//
3141+// rb_hash_foreach( RARRAY_PTR( picture->value )[2], Window_drawShader_func_foreach, RARRAY_PTR( picture->value )[1] );
3142+//
3143+// core->pD3DXEffect->lpVtbl->SetTexture( core->pD3DXEffect, "tex0",
3144+// (IDirect3DBaseTexture9*)image->texture->pD3DTexture );
3145+//
3146+// core->pD3DXEffect->lpVtbl->Begin( core->pD3DXEffect, &pass, 0 );
3147+// for( i = 0; i < pass; i++ )
3148+// {
3149+// /* 描画 */
3150+// core->pD3DXEffect->lpVtbl->BeginPass( core->pD3DXEffect, i );
3151+// g_pD3DDevice->lpVtbl->DrawPrimitiveUP( g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX) );
3152+// core->pD3DXEffect->lpVtbl->EndPass( core->pD3DXEffect );
3153+// }
3154+// core->pD3DXEffect->lpVtbl->End( core->pD3DXEffect );
3155+// }
3156+// else
3157+ {
3158+ /* テクスチャをセット */
3159+ g_pD3DDevice->lpVtbl->SetTexture( g_pD3DDevice, 0, (IDirect3DBaseTexture9*)image->texture->pD3DTexture );
3160+
3161+ /* 描画 */
3162+ g_pD3DDevice->lpVtbl->DrawPrimitiveUP( g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX) );
3163+ }
3164+}
3165+
3166+/*--------------------------------------------------------------------
3167+ 描画設定(拡大縮小描画)
3168+ ---------------------------------------------------------------------*/
3169+static VALUE RenderTarget_drawScale( int argc, VALUE *argv, VALUE obj )
3170+{
3171+ struct DXRubyImage *image;
3172+ struct DXRubyPicture_drawEx *picture;
3173+ float z;
3174+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3175+ volatile VALUE temp;
3176+ DXRUBY_CHECK_DISPOSE( rt, surface );
3177+
3178+ if( argc < 5 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 5);
3179+
3180+ /* 引数のイメージオブジェクトから中身を取り出す */
3181+ DXRUBY_CHECK_IMAGE( argv[2] );
3182+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
3183+ DXRUBY_CHECK_DISPOSE( image, texture );
3184+
3185+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
3186+
3187+ /* DXRubyPictureオブジェクト設定 */
3188+ picture->func = RenderTarget_drawEx_func;
3189+ picture->x = NUM2INT( argv[0] );
3190+ picture->y = NUM2INT( argv[1] );
3191+ temp = rb_ary_new3( 1, argv[2] );
3192+ picture->value = temp;
3193+ picture->alpha = 0xff;
3194+ picture->blendflag = 0;
3195+ picture->angle = 0.0f;
3196+ picture->scalex = NUM2FLOAT( argv[3] );
3197+ picture->scaley = NUM2FLOAT( argv[4] );
3198+ picture->centerx = argc < 6 || argv[5] == Qnil ? image->width / 2 : NUM2FLOAT( argv[5] );
3199+ picture->centery = argc < 7 || argv[6] == Qnil ? image->height / 2 : NUM2FLOAT( argv[6] );
3200+
3201+ /* リストデータに追加 */
3202+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3203+ z = argc < 8 || argv[7] == Qnil ? 0.0f : NUM2FLOAT( argv[7] );
3204+ rt->PictureList[rt->PictureCount].z = z;
3205+ picture->z = z;
3206+ rt->PictureCount++;
3207+
3208+ return obj;
3209+}
3210+
3211+/*--------------------------------------------------------------------
3212+ 描画設定(回転描画)
3213+ ---------------------------------------------------------------------*/
3214+static VALUE RenderTarget_drawRot( int argc, VALUE *argv, VALUE obj )
3215+{
3216+ struct DXRubyImage *image;
3217+ struct DXRubyPicture_drawEx *picture;
3218+ float z;
3219+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3220+ volatile VALUE temp;
3221+ DXRUBY_CHECK_DISPOSE( rt, surface );
3222+
3223+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
3224+
3225+ /* 引数のイメージオブジェクトから中身を取り出す */
3226+ DXRUBY_CHECK_IMAGE( argv[2] );
3227+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
3228+ DXRUBY_CHECK_DISPOSE( image, texture );
3229+
3230+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
3231+
3232+ /* DXRubyPictureオブジェクト設定 */
3233+ picture->func = RenderTarget_drawEx_func;
3234+ picture->x = NUM2INT( argv[0] );
3235+ picture->y = NUM2INT( argv[1] );
3236+ temp = rb_ary_new3( 1, argv[2] );
3237+ picture->value = temp;
3238+ picture->alpha = 0xff;
3239+ picture->blendflag = 0;
3240+ picture->angle = NUM2FLOAT( argv[3] );
3241+ picture->scalex = 1.0f;
3242+ picture->scaley = 1.0f;
3243+ picture->centerx = argc < 5 || argv[4] == Qnil ? image->width / 2 : NUM2FLOAT( argv[4] );
3244+ picture->centery = argc < 5 || argv[5] == Qnil ? image->height / 2 : NUM2FLOAT( argv[5] );
3245+
3246+ /* リストデータに追加 */
3247+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3248+ z = argc < 7 || argv[6] == Qnil ? 0.0f : NUM2FLOAT( argv[6] );
3249+ rt->PictureList[rt->PictureCount].z = z;
3250+ picture->z = z;
3251+ rt->PictureCount++;
3252+
3253+ return obj;
3254+}
3255+
3256+/*--------------------------------------------------------------------
3257+ 描画設定(フルオプション)
3258+ ---------------------------------------------------------------------*/
3259+static VALUE RenderTarget_drawEx( int argc, VALUE *argv, VALUE obj )
3260+{
3261+ struct DXRubyImage *image;
3262+ VALUE vx, vy, vz, val, vangle, vscalex, vscaley, valpha, vcenterx, vcentery, vblend, vshader;
3263+ VALUE option;
3264+ float z;
3265+ volatile VALUE temp;
3266+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3267+ DXRUBY_CHECK_DISPOSE( rt, surface );
3268+
3269+ if( argc < 3 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 3);
3270+
3271+ if( argc < 4 || argv[3] == Qnil )
3272+ {
3273+ option = rb_hash_new();
3274+ }
3275+ else
3276+ {
3277+ Check_Type( argv[3], T_HASH );
3278+ option = argv[3];
3279+ }
3280+
3281+ vblend = hash_lookup( option, symbol_blend );
3282+ vangle = hash_lookup( option, symbol_angle );
3283+ valpha = hash_lookup( option, symbol_alpha );
3284+ vscalex = hash_lookup( option, symbol_scalex );
3285+ vscaley = hash_lookup( option, symbol_scaley );
3286+ vcenterx = hash_lookup( option, symbol_centerx );
3287+ vcentery = hash_lookup( option, symbol_centery );
3288+// vshader = hash_lookup( option, symbol_shader );
3289+ vz = hash_lookup( option, symbol_z );
3290+// if( vshader != Qnil )
3291+// {
3292+// DXRUBY_CHECK_TYPE( Shader, vshader );
3293+// }
3294+
3295+ {
3296+ struct DXRubyPicture_drawEx *picture;
3297+
3298+ /* 引数のイメージオブジェクトから中身を取り出す */
3299+ DXRUBY_CHECK_IMAGE( argv[2] );
3300+ image = DXRUBY_GET_STRUCT( Image, argv[2] );
3301+ DXRUBY_CHECK_DISPOSE( image, texture );
3302+
3303+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
3304+
3305+ /* DXRubyPictureオブジェクト設定 */
3306+ picture->func = RenderTarget_drawEx_func;
3307+ picture->x = NUM2INT( argv[0] );
3308+ picture->y = NUM2INT( argv[1] );
3309+ picture->angle = (vangle == Qnil ? 0.0f : NUM2FLOAT( vangle ));
3310+ picture->scalex = (vscalex == Qnil ? 1.0f : NUM2FLOAT( vscalex ));
3311+ picture->scaley = (vscaley == Qnil ? 1.0f : NUM2FLOAT( vscaley ));
3312+ picture->centerx = (vcenterx == Qnil ? image->width / 2 : NUM2FLOAT( vcenterx ));
3313+ picture->centery = (vcentery == Qnil ? image->height / 2 : NUM2FLOAT( vcentery ));
3314+ picture->alpha = (valpha == Qnil ? 0xff : NUM2INT( valpha ));
3315+ picture->blendflag = (vblend == Qnil ? 0 :
3316+ (vblend == symbol_add ? 4 :
3317+ (vblend == symbol_none ? 1 :
3318+ (vblend == symbol_add2 ? 5 :
3319+ (vblend == symbol_sub ? 6 :
3320+ (vblend == symbol_sub2 ? 7 : 0))))));
3321+// if( vshader != Qnil )
3322+// {
3323+// struct DXRubyShader *shader = DXRUBY_GET_STRUCT( Shader, vshader );
3324+// temp = rb_ary_new3( 3, argv[2], shader->vcore, shader->vparam );
3325+// }
3326+// else
3327+ {
3328+ temp = rb_ary_new3( 1, argv[2] );
3329+ }
3330+ picture->value = temp;
3331+ /* リストデータに追加 */
3332+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3333+ z = vz == Qnil ? 0.0f : NUM2FLOAT( vz );
3334+ rt->PictureList[rt->PictureCount].z = z;
3335+ picture->z = z;
3336+ }
3337+
3338+ rt->PictureCount++;
3339+
3340+ return obj;
3341+}
3342+
3343+
3344+static void RenderTarget_drawFont_func( struct DXRubyPicture_drawFont *picture )
3345+{
3346+ D3DVECTOR vector;
3347+ D3DXMATRIX matrix;
3348+ D3DXMATRIX matrix_t;
3349+ RECT rect;
3350+ struct DXRubyFont *font = DXRUBY_GET_STRUCT( Font, picture->value );
3351+ float angle = 3.141592653589793115997963468544185161590576171875f / 180.0f * picture->angle;
3352+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
3353+
3354+ /* D3DXSpriteの描画開始 */
3355+ g_pD3DXSprite->lpVtbl->Begin( g_pD3DXSprite, D3DXSPRITE_ALPHABLEND );
3356+
3357+ /* 回転及び拡大縮小 */
3358+ D3DXMatrixScaling ( &matrix_t, picture->scalex, picture->scaley, 1 );
3359+ D3DXMatrixRotationZ ( &matrix , angle );
3360+ D3DXMatrixMultiply ( &matrix , &matrix_t, &matrix );
3361+
3362+ /* 平行移動 */
3363+ D3DXMatrixTranslation( &matrix_t, (float)picture->x + picture->centerx, (float)picture->y + picture->centery, 0 );
3364+ D3DXMatrixMultiply ( &matrix , &matrix, &matrix_t );
3365+
3366+ g_pD3DXSprite->lpVtbl->SetTransform( g_pD3DXSprite, &matrix );
3367+
3368+ rect.left = -picture->centerx;
3369+ rect.top = -picture->centery;
3370+ rect.right = picture->centerx;
3371+ rect.bottom = picture->centery;
3372+ font->pD3DXFont->lpVtbl->DrawText( font->pD3DXFont, g_pD3DXSprite, picture->str, -1, &rect, DT_LEFT | DT_NOCLIP,
3373+ ((int)picture->alpha << 24) | picture->color & 0x00ffffff);
3374+ g_pD3DXSprite->lpVtbl->Flush( g_pD3DXSprite );
3375+
3376+ /* ピクチャの描画終了 */
3377+ g_pD3DXSprite->lpVtbl->End( g_pD3DXSprite );
3378+}
3379+/*--------------------------------------------------------------------
3380+ フォント描画
3381+ ---------------------------------------------------------------------*/
3382+static VALUE RenderTarget_drawFont( int argc, VALUE *argv, VALUE obj )
3383+{
3384+ struct DXRubyPicture_drawFont *picture;
3385+ struct DXRubyFont *font;
3386+ VALUE vcolor;
3387+ int cr, cg, cb;
3388+ VALUE vz, vangle, vscalex, vscaley, valpha, vcenterx, vcentery, vblend;
3389+ VALUE voption;
3390+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3391+ VALUE vsjisstr;
3392+
3393+ DXRUBY_CHECK_DISPOSE( rt, surface );
3394+
3395+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
3396+ Check_Type(argv[2], T_STRING);
3397+
3398+ if( argc < 5 || argv[4] == Qnil )
3399+ {
3400+ voption = rb_hash_new();
3401+ }
3402+ else
3403+ {
3404+ Check_Type( argv[4], T_HASH );
3405+ voption = argv[4];
3406+ }
3407+
3408+ vblend = hash_lookup( voption, symbol_blend );
3409+ vangle = hash_lookup( voption, symbol_angle );
3410+ valpha = hash_lookup( voption, symbol_alpha );
3411+ vscalex = hash_lookup( voption, symbol_scalex );
3412+ vscaley = hash_lookup( voption, symbol_scaley );
3413+ vcenterx = hash_lookup( voption, symbol_centerx );
3414+ vcentery = hash_lookup( voption, symbol_centery );
3415+ vz = hash_lookup( voption, symbol_z );
3416+ vcolor = hash_lookup( voption, symbol_color );
3417+
3418+ DXRUBY_CHECK_TYPE( Font, argv[3] );
3419+ font = DXRUBY_GET_STRUCT( Font, argv[3] );
3420+ DXRUBY_CHECK_DISPOSE( font, pD3DXFont );
3421+
3422+ picture = (struct DXRubyPicture_drawFont *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawFont ) + RSTRING_LEN(argv[2]) + 2 );
3423+ if( picture == NULL )
3424+ {
3425+ rb_raise( eDXRubyError, "フォント用メモリの確保に失敗しました" );
3426+ }
3427+
3428+ /* DXRubyPictureオブジェクト設定 */
3429+ picture->func = RenderTarget_drawFont_func;
3430+ picture->x = NUM2INT( argv[0] );
3431+ picture->y = NUM2INT( argv[1] );
3432+ picture->angle = (vangle == Qnil ? 0.0f : NUM2FLOAT( vangle ));
3433+ picture->scalex = (vscalex == Qnil ? 1.0f : NUM2FLOAT( vscalex ));
3434+ picture->scaley = (vscaley == Qnil ? 1.0f : NUM2FLOAT( vscaley ));
3435+ picture->centerx = (vcenterx == Qnil ? 0.0f : NUM2FLOAT( vcenterx ));;
3436+ picture->centery = (vcentery == Qnil ? 0.0f : NUM2FLOAT( vcentery ));;
3437+ picture->alpha = (valpha == Qnil ? 0xff : NUM2INT( valpha ));
3438+ picture->blendflag = (vblend == Qnil ? 0 :
3439+ (vblend == symbol_add ? 4 :
3440+ (vblend == symbol_none ? 1 :
3441+ (vblend == symbol_add2 ? 5 :
3442+ (vblend == symbol_sub ? 6 :
3443+ (vblend == symbol_sub2 ? 7 : 0))))));
3444+ picture->value = argv[3];
3445+
3446+#ifdef HAVE_RB_ENC_STR_NEW
3447+ if( rb_enc_get_index( argv[2] ) != 0 )
3448+ {
3449+ vsjisstr = rb_funcall( argv[2], rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
3450+ }
3451+ else
3452+ {
3453+ vsjisstr = argv[2];
3454+ }
3455+#else
3456+ vsjisstr = argv[2];
3457+#endif
3458+ lstrcpy( picture->str, RSTRING_PTR( vsjisstr ) ); /* 文字列の保存 */
3459+ picture->str[RSTRING_LEN(vsjisstr)] = ' '; /* イタリック対策にスペース追加 */
3460+ picture->str[RSTRING_LEN(vsjisstr)+1] = 0;
3461+
3462+ if( vcolor != Qnil )
3463+ {
3464+ Check_Type( vcolor, T_ARRAY );
3465+ if( RARRAY_LEN( vcolor ) == 4 )
3466+ {
3467+ picture->alpha = NUM2INT( rb_ary_entry( vcolor, 0 ) );
3468+ cr = NUM2INT( rb_ary_entry( vcolor, 1 ) );
3469+ cg = NUM2INT( rb_ary_entry( vcolor, 2 ) );
3470+ cb = NUM2INT( rb_ary_entry( vcolor, 3 ) );
3471+ }
3472+ else
3473+ {
3474+ cr = NUM2INT( rb_ary_entry( vcolor, 0 ) );
3475+ cg = NUM2INT( rb_ary_entry( vcolor, 1 ) );
3476+ cb = NUM2INT( rb_ary_entry( vcolor, 2 ) );
3477+ }
3478+ }
3479+ else
3480+ {
3481+ cr = 255;
3482+ cg = 255;
3483+ cb = 255;
3484+ }
3485+ picture->color = D3DCOLOR_XRGB(cr, cg, cb);
3486+ picture->value = argv[3];
3487+ picture->z = 0;
3488+
3489+ /* リストデータに追加 */
3490+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3491+ rt->PictureList[rt->PictureCount].z = vz == Qnil ? 0.0f : NUM2FLOAT( vz );
3492+ rt->PictureCount++;
3493+
3494+ return obj;
3495+}
3496+
3497+
3498+/*--------------------------------------------------------------------
3499+ 高品質フォント描画
3500+ ---------------------------------------------------------------------*/
3501+static VALUE RenderTarget_drawFontEx( int argc, VALUE *argv, VALUE obj )
3502+{
3503+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3504+ int fontsize, edge_width, shadow_x, shadow_y;
3505+ VALUE vimage, voption, vedge_width, vedge, vshadow;
3506+
3507+ DXRUBY_CHECK_DISPOSE( rt, surface );
3508+ DXRUBY_CHECK_TYPE( Font, argv[3] );
3509+
3510+ if( argc < 4 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 4);
3511+ Check_Type(argv[2], T_STRING);
3512+
3513+ if( argc < 5 || argv[4] == Qnil )
3514+ {
3515+ voption = rb_hash_new();
3516+ }
3517+ else
3518+ {
3519+ Check_Type( argv[4], T_HASH );
3520+ voption = argv[4];
3521+ }
3522+
3523+ /* 内部Imageオブジェクト生成*/
3524+
3525+ /* エッジオプション補正 */
3526+ vedge = hash_lookup( voption, symbol_edge );
3527+ if( vedge == Qnil || vedge == Qfalse )
3528+ {
3529+ edge_width = 0;
3530+ }
3531+ else
3532+ {
3533+ vedge_width = hash_lookup( voption, symbol_edge_width );
3534+ edge_width = vedge_width == Qnil ? 2 : NUM2INT( vedge_width );
3535+ }
3536+
3537+ /* 影オプション補正 */
3538+ vshadow = hash_lookup( voption, symbol_shadow );
3539+ if( vshadow == Qnil || vshadow == Qfalse )
3540+ {
3541+ shadow_x = 0;
3542+ shadow_y = 0;
3543+ }
3544+ else
3545+ {
3546+ VALUE vshadow_x, vshadow_y;
3547+
3548+ vshadow_x = hash_lookup( voption, symbol_shadow_x );
3549+ shadow_x = vshadow_x == Qnil ? NUM2INT( Font_getSize( argv[3] ) ) / 24 + 1 : NUM2INT(vshadow_x);
3550+
3551+ vshadow_y = hash_lookup( voption, symbol_shadow_y );
3552+ shadow_y = vshadow_y == Qnil ? NUM2INT( Font_getSize( argv[3] ) ) / 24 + 1 : NUM2INT(vshadow_y);
3553+ }
3554+
3555+ fontsize = NUM2INT( Font_getSize( argv[3] ) );
3556+ vimage = Image_allocate( cImage );
3557+ {
3558+ VALUE arr[2] = {INT2FIX(NUM2INT( Font_getWidth( argv[3], argv[2] ) ) + fontsize / 2 + edge_width * 2 + shadow_x), INT2FIX(fontsize + edge_width * 2 + shadow_y)};
3559+ Image_initialize( 2, arr, vimage );
3560+ }
3561+
3562+ /* Imageに描画 */
3563+ {
3564+ VALUE arr[5] = {INT2FIX(0), INT2FIX(0), argv[2], argv[3], voption};
3565+ Image_drawFontEx( 5, arr, vimage );
3566+ }
3567+
3568+ /* RenderTarget_drawEx呼び出し */
3569+ {
3570+ VALUE arr[4] = {argv[0], argv[1], vimage, voption};
3571+ RenderTarget_drawEx( 4, arr, obj );
3572+ }
3573+
3574+ rb_ary_push( rt->array, vimage );
3575+
3576+ return obj;
3577+}
3578+
3579+
3580+static void RenderTarget_drawMorph_func( struct DXRubyPicture_drawMorph *picture )
3581+{
3582+ TLVERTX *VertexDataTbl;
3583+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, picture->value );
3584+ float width = image->width;
3585+ float height = image->height;
3586+ float x1 = picture->x1;
3587+ float y1 = picture->y1;
3588+ float x2 = picture->x2;
3589+ float y2 = picture->y2;
3590+ float x3 = picture->x3;
3591+ float y3 = picture->y3;
3592+ float x4 = picture->x4;
3593+ float y4 = picture->y4;
3594+ float tu1;
3595+ float tu2;
3596+ float tv1;
3597+ float tv2;
3598+ int count_x, count_y;
3599+
3600+
3601+ DXRUBY_CHECK_DISPOSE( image, texture );
3602+ tu1 = image->x / image->texture->width;
3603+ tu2 = (image->x + width) / image->texture->width;
3604+ tv1 = image->y / image->texture->height;
3605+ tv2 = (image->y + height) / image->texture->height;
3606+
3607+ VertexDataTbl = alloca( sizeof(TLVERTX) * picture->dividex * picture->dividey * 6 );
3608+
3609+ for( count_y = 0; count_y < picture->dividey; count_y++ )
3610+ {
3611+ for( count_x = 0; count_x < picture->dividex; count_x++ )
3612+ {
3613+ int cur = (count_x + picture->dividex * count_y) * 6;
3614+ float wx1 = (float)count_x / (float)picture->dividex;
3615+ float wy1 = (float)count_y / (float)picture->dividey;
3616+ float wx2 = (float)(count_x+1) / (float)picture->dividex;
3617+ float wy2 = (float)(count_y+1) / (float)picture->dividey;
3618+
3619+ float tx1 = (x2 - x1) * wx1 + x1;
3620+ float ty1 = (y2 - y1) * wy1 + y1;
3621+ float bx1 = (x3 - x4) * wx1 + x4;
3622+ float by1 = (y3 - y4) * wy1 + y4;
3623+ float lx1 = (x4 - x1) * wx1 + x1;
3624+ float ly1 = (y4 - y1) * wy1 + y1;
3625+ float rx1 = (x3 - x2) * wx1 + x2;
3626+ float ry1 = (y3 - y2) * wy1 + y2;
3627+ float tx2 = (x2 - x1) * wx2 + x1;
3628+ float ty2 = (y2 - y1) * wy2 + y1;
3629+ float bx2 = (x3 - x4) * wx2 + x4;
3630+ float by2 = (y3 - y4) * wy2 + y4;
3631+ float lx2 = (x4 - x1) * wx2 + x1;
3632+ float ly2 = (y4 - y1) * wy2 + y1;
3633+ float rx2 = (x3 - x2) * wx2 + x2;
3634+ float ry2 = (y3 - y2) * wy2 + y2;
3635+
3636+ /* 頂点1 */
3637+ VertexDataTbl[cur+0].x = (bx1 - tx1) * wy1 + tx1 - 0.5f;
3638+ VertexDataTbl[cur+0].y = (ry1 - ly1) * wx1 + ly1 - 0.5f;
3639+ /* 頂点2 */
3640+ VertexDataTbl[cur+1].x = VertexDataTbl[cur+3].x = (bx2 - tx2) * wy1 + tx2 - 0.5f;
3641+ VertexDataTbl[cur+1].y = VertexDataTbl[cur+3].y = (ry1 - ly1) * wx2 + ly1 - 0.5f;
3642+ /* 頂点3 */
3643+ VertexDataTbl[cur+4].x = (bx2 - tx2) * wy2 + tx2 - 0.5f;
3644+ VertexDataTbl[cur+4].y = (ry2 - ly2) * wx2 + ly2 - 0.5f;
3645+ /* 頂点4 */
3646+ VertexDataTbl[cur+2].x = VertexDataTbl[cur+5].x = (bx1 - tx1) * wy2 + tx1 - 0.5f;
3647+ VertexDataTbl[cur+2].y = VertexDataTbl[cur+5].y = (ry2 - ly2) * wx1 + ly2 - 0.5f;
3648+ /* 頂点色 */
3649+ VertexDataTbl[cur+0].color = VertexDataTbl[cur+1].color =
3650+ VertexDataTbl[cur+2].color = VertexDataTbl[cur+3].color =
3651+ VertexDataTbl[cur+4].color = VertexDataTbl[cur+5].color = D3DCOLOR_ARGB(picture->alpha,picture->r,picture->g,picture->b);
3652+ /* Z座標 */
3653+ VertexDataTbl[cur+0].z = VertexDataTbl[cur+1].z =
3654+ VertexDataTbl[cur+2].z = VertexDataTbl[cur+3].z =
3655+ VertexDataTbl[cur+4].z = VertexDataTbl[cur+5].z = picture->z;
3656+ /* テクスチャ座標 */
3657+ VertexDataTbl[cur+0].tu = VertexDataTbl[cur+5].tu = VertexDataTbl[cur+2].tu = tu1 + ((tu2 - tu1) / picture->dividex) * count_x;
3658+ VertexDataTbl[cur+0].tv = VertexDataTbl[cur+1].tv = VertexDataTbl[cur+3].tv = tv1 + ((tv2 - tv1) / picture->dividey) * count_y;
3659+ VertexDataTbl[cur+1].tu = VertexDataTbl[cur+3].tu = VertexDataTbl[cur+4].tu = tu1 + ((tu2 - tu1) / picture->dividex) * (count_x+1);
3660+ VertexDataTbl[cur+4].tv = VertexDataTbl[cur+5].tv = VertexDataTbl[cur+2].tv = tv1 + ((tv2 - tv1) / picture->dividey) * (count_y+1);
3661+ }
3662+ }
3663+
3664+ if( picture->colorflag == 1 )
3665+ {
3666+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
3667+ }
3668+
3669+ /* テクスチャをセット */
3670+ g_pD3DDevice->lpVtbl->SetTexture(g_pD3DDevice, 0, (IDirect3DBaseTexture9*)image->texture->pD3DTexture);
3671+
3672+ /* デバイスに使用する頂点フォーマットをセット */
3673+ g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
3674+
3675+ /* 描画 */
3676+ g_pD3DDevice->lpVtbl->DrawPrimitiveUP(g_pD3DDevice, D3DPT_TRIANGLELIST, picture->dividex * picture->dividey * 2, VertexDataTbl, sizeof(TLVERTX));
3677+
3678+ if( picture->colorflag == 1 )
3679+ {
3680+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
3681+ }
3682+}
3683+
3684+/*--------------------------------------------------------------------
3685+ 描画設定(4点指定)
3686+ ---------------------------------------------------------------------*/
3687+static VALUE RenderTarget_drawMorph( int argc, VALUE *argv, VALUE obj )
3688+{
3689+ struct DXRubyImage *image;
3690+ struct DXRubyPicture_drawMorph *picture;
3691+ float z;
3692+ VALUE voption;
3693+ VALUE vz, vdividex, vdividey, valpha, vblend, vcolor;
3694+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3695+ DXRUBY_CHECK_DISPOSE( rt, surface );
3696+
3697+ if( argc < 9 ) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, 9);
3698+
3699+ if( argc < 10 || argv[9] == Qnil )
3700+ {
3701+ voption = rb_hash_new();
3702+ }
3703+ else
3704+ {
3705+ Check_Type( argv[9], T_HASH );
3706+ voption = argv[9];
3707+ }
3708+
3709+ vblend = hash_lookup( voption, symbol_blend );
3710+ valpha = hash_lookup( voption, symbol_alpha );
3711+ vdividex = hash_lookup( voption, symbol_dividex );
3712+ vdividey = hash_lookup( voption, symbol_dividey );
3713+ vz = hash_lookup( voption, symbol_z );
3714+ vcolor = hash_lookup( voption, symbol_color );
3715+
3716+ /* 引数のイメージオブジェクトから中身を取り出す */
3717+ DXRUBY_CHECK_IMAGE( argv[8] );
3718+ image = DXRUBY_GET_STRUCT( Image, argv[8] );
3719+ DXRUBY_CHECK_DISPOSE( image, texture );
3720+
3721+ picture = (struct DXRubyPicture_drawMorph *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawMorph ) );
3722+
3723+ /* DXRubyPictureオブジェクト設定 */
3724+ picture->func = RenderTarget_drawMorph_func;
3725+ picture->x1 = NUM2FLOAT( argv[0] );
3726+ picture->y1 = NUM2FLOAT( argv[1] );
3727+ picture->x2 = NUM2FLOAT( argv[2] );
3728+ picture->y2 = NUM2FLOAT( argv[3] );
3729+ picture->x3 = NUM2FLOAT( argv[4] );
3730+ picture->y3 = NUM2FLOAT( argv[5] );
3731+ picture->x4 = NUM2FLOAT( argv[6] );
3732+ picture->y4 = NUM2FLOAT( argv[7] );
3733+ picture->value = argv[8];
3734+ picture->dividex = vdividex == Qnil ? 1 : NUM2INT( vdividex );
3735+ picture->dividey = vdividey == Qnil ? 1 : NUM2INT( vdividey );
3736+ picture->alpha = valpha == Qnil ? 0xff : NUM2INT( valpha );
3737+ picture->blendflag = (vblend == Qnil ? 0 :
3738+ (vblend == symbol_add ? 4 :
3739+ (vblend == symbol_none ? 1 :
3740+ (vblend == symbol_add2 ? 5 :
3741+ (vblend == symbol_sub ? 6 :
3742+ (vblend == symbol_sub2 ? 7 : 0))))));
3743+
3744+ if( picture->dividex <= 0 || picture->dividey <= 0 )
3745+ {
3746+ rb_raise( eDXRubyError, "分割数に0以下は指定できません");
3747+ }
3748+
3749+ if( vcolor != Qnil )
3750+ {
3751+ Check_Type( vcolor, T_ARRAY );
3752+ if( RARRAY_LEN( vcolor ) < 4 )
3753+ {
3754+ picture->r = NUM2INT( rb_ary_entry(vcolor, 0) );
3755+ picture->g = NUM2INT( rb_ary_entry(vcolor, 1) );
3756+ picture->b = NUM2INT( rb_ary_entry(vcolor, 2) );
3757+ }
3758+ else
3759+ {
3760+ picture->alpha = NUM2INT( rb_ary_entry(vcolor, 0) ) * picture->alpha / 255;
3761+ picture->r = NUM2INT( rb_ary_entry(vcolor, 1) );
3762+ picture->g = NUM2INT( rb_ary_entry(vcolor, 2) );
3763+ picture->b = NUM2INT( rb_ary_entry(vcolor, 3) );
3764+ }
3765+ picture->colorflag = 1;
3766+ }
3767+ else
3768+ {
3769+ picture->r = picture->g = picture->b = 255;
3770+ picture->colorflag = 0;
3771+ }
3772+
3773+
3774+ /* リストデータに追加 */
3775+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
3776+ rt->PictureList[rt->PictureCount].z = vz == Qnil ? 0.0f : NUM2FLOAT( vz );
3777+ picture->z = vz == Qnil ? 0.0f : NUM2FLOAT( vz );
3778+ rt->PictureCount++;
3779+
3780+ return obj;
3781+}
3782+
3783+
3784+int get_array_flatten_len( VALUE ary, VALUE hash )
3785+{
3786+ int i;
3787+ int count = 0;
3788+
3789+ VALUE *p = RARRAY_PTR(ary);
3790+
3791+ rb_hash_aset( hash, INT2NUM(ary), Qtrue );
3792+
3793+ for( i = 0; i < RARRAY_LEN(ary); i++ )
3794+ {
3795+ if( TYPE(*(p + i)) == T_ARRAY )
3796+ {
3797+ if( hash_lookup( hash, INT2NUM(*(p + i))) == Qnil )
3798+ {
3799+ count += get_array_flatten_len( *(p + i), hash );
3800+ }
3801+ }
3802+ else
3803+ {
3804+ count++;
3805+ }
3806+ }
3807+ rb_hash_delete( hash, INT2NUM(ary) );
3808+ return count;
3809+}
3810+
3811+int set_array_flatten( VALUE *pd, VALUE s, VALUE hash )
3812+{
3813+ int i;
3814+ int count = 0;
3815+
3816+ VALUE *ps = RARRAY_PTR(s);
3817+
3818+ rb_hash_aset( hash, INT2NUM(s), Qtrue );
3819+
3820+ for( i = 0; i < RARRAY_LEN(s); i++ )
3821+ {
3822+ if( TYPE(*(ps + i)) == T_ARRAY )
3823+ {
3824+ if( hash_lookup( hash, INT2NUM(*(ps + i))) == Qnil )
3825+ {
3826+ count += set_array_flatten( pd + count, *(ps + i), hash );
3827+ }
3828+ }
3829+ else
3830+ {
3831+ *(pd + count) = *(ps + i);
3832+ count++;
3833+ }
3834+ }
3835+ rb_hash_delete( hash, INT2NUM(s) );
3836+ return count;
3837+}
3838+
3839+void RenderTarget_drawTile_func( struct DXRubyPicture_drawTile *picture )
3840+{
3841+ TLVERTX VertexDataTbl[6];
3842+ struct DXRubyImage *image;
3843+ VALUE vmap = RARRAY_PTR(picture->value)[0];
3844+ VALUE vmapdata = RARRAY_PTR(picture->value)[1];
3845+ int width, height;
3846+ VALUE *mapdata, *arr1, *arr2;
3847+ int i, j;
3848+ float x, y;
3849+ int startx_mod_width;
3850+ int startt_mod_height;
3851+ int image_count;
3852+
3853+ if( RARRAY_LEN( vmap ) == 0 )
3854+ {
3855+ return;
3856+ }
3857+ if( RARRAY_LEN( vmapdata ) == 0 )
3858+ {
3859+ return;
3860+ }
3861+
3862+ /* Array#flattenぽいもの実装 */
3863+ image_count = get_array_flatten_len( vmapdata, rb_hash_new() );
3864+ mapdata = alloca( image_count * sizeof(VALUE) );
3865+ set_array_flatten( mapdata, vmapdata, rb_hash_new() );
3866+
3867+ /* 幅と高さ取得 */
3868+ width = NUM2INT( rb_funcall(*mapdata, rb_intern("width"), 0) );
3869+ height = NUM2INT( rb_funcall(*mapdata, rb_intern("height"), 0) );
3870+
3871+ arr1 = RARRAY_PTR( vmap );
3872+
3873+ startx_mod_width = picture->startx % width;
3874+ startt_mod_height = picture->starty % height;
3875+
3876+ /* イメージ配列が全部イメージかどうかをチェックしとく */
3877+ for( i = 0; i < image_count; i++ )
3878+ {
3879+ struct DXRubyImage *image;
3880+ if( TYPE( mapdata[i] ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( mapdata[i] ));
3881+ image = (struct DXRubyImage *)DATA_PTR( mapdata[i] );
3882+ if( RDATA( mapdata[i] )->dfree != (RUBY_DATA_FUNC)Image_release )
3883+ {
3884+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( mapdata[i] ));
3885+ }
3886+ DXRUBY_CHECK_DISPOSE( image, texture );
3887+ }
3888+
3889+ y = picture->basey - (startt_mod_height < 0 ? height + startt_mod_height : startt_mod_height) - 0.5f;
3890+ /* 描画 */
3891+ for( i = startt_mod_height < 0 ? -1 : 0; i < picture->sizey + (startt_mod_height <= 0 ? 0 : 1); i++ )
3892+ {
3893+ int my;
3894+
3895+ if( i + picture->starty / height < 0 )
3896+ {
3897+ my = (((i + picture->starty / height) % RARRAY_LEN( vmap )) + RARRAY_LEN( vmap )) % RARRAY_LEN( vmap );
3898+ }
3899+ else
3900+ {
3901+ my = (i + picture->starty / height) % RARRAY_LEN( vmap );
3902+ }
3903+ Check_Type(arr1[my], T_ARRAY);
3904+
3905+ if( RARRAY_LEN( arr1[my] ) == 0 )
3906+ {
3907+ continue;
3908+ }
3909+
3910+ arr2 = RARRAY_PTR( arr1[my] );
3911+
3912+ x = picture->basex - (startx_mod_width < 0 ? width + startx_mod_width : startx_mod_width) - 0.5f;
3913+
3914+ for( j = startx_mod_width < 0 ? -1 : 0; j < picture->sizex + (startx_mod_width <= 0 ? 0 : 1); j++ )
3915+ {
3916+ int mx;
3917+ int index;
3918+ int len = RARRAY_LEN( arr1[my] );
3919+
3920+ if( j + picture->startx / width < 0 )
3921+ {
3922+ mx = (((j + picture->startx / width) % len) + len) % len;
3923+ }
3924+ else
3925+ {
3926+ mx = (j + picture->startx / width) % len;
3927+ }
3928+
3929+ if( arr2[mx] != Qnil )
3930+ {
3931+ index = NUM2INT( arr2[mx] );
3932+
3933+ if( index >= image_count ) rb_raise(eDXRubyError, "マップチップ番号がイメージ配列の範囲を超えています - Window_drawTile");
3934+
3935+ /* イメージオブジェクトから中身を取り出す */
3936+ image = (struct DXRubyImage *)DATA_PTR( mapdata[index] );
3937+
3938+ VertexDataTbl[0].x = VertexDataTbl[2].x = VertexDataTbl[5].x = x;
3939+ VertexDataTbl[0].y = VertexDataTbl[1].y = VertexDataTbl[3].y = y;
3940+ VertexDataTbl[1].x = VertexDataTbl[3].x = VertexDataTbl[4].x = x + width;
3941+ VertexDataTbl[4].y = VertexDataTbl[2].y = VertexDataTbl[5].y = y + height;
3942+ /* 頂点色 */
3943+ VertexDataTbl[0].color = VertexDataTbl[1].color =
3944+ VertexDataTbl[2].color = VertexDataTbl[3].color =
3945+ VertexDataTbl[4].color = VertexDataTbl[5].color = D3DCOLOR_ARGB(255,255,255,255);
3946+ /* Z座標 */
3947+ VertexDataTbl[0].z = VertexDataTbl[1].z =
3948+ VertexDataTbl[2].z = VertexDataTbl[3].z =
3949+ VertexDataTbl[4].z = VertexDataTbl[5].z = picture->z;
3950+ /* テクスチャ座標 */
3951+ VertexDataTbl[0].tu = VertexDataTbl[5].tu = VertexDataTbl[2].tu = image->x / image->texture->width;
3952+ VertexDataTbl[0].tv = VertexDataTbl[1].tv = VertexDataTbl[3].tv = image->y / image->texture->height;
3953+ VertexDataTbl[1].tu = VertexDataTbl[3].tu = VertexDataTbl[4].tu = (image->x + width) / image->texture->width;
3954+ VertexDataTbl[4].tv = VertexDataTbl[5].tv = VertexDataTbl[2].tv = (image->y + height) / image->texture->height;
3955+
3956+ /* テクスチャをセット */
3957+ g_pD3DDevice->lpVtbl->SetTexture(g_pD3DDevice, 0, (IDirect3DBaseTexture9*)image->texture->pD3DTexture);
3958+
3959+ /* デバイスに使用する頂点フォーマットをセット */
3960+ g_pD3DDevice->lpVtbl->SetFVF(g_pD3DDevice, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
3961+
3962+ /* 描画 */
3963+ g_pD3DDevice->lpVtbl->DrawPrimitiveUP(g_pD3DDevice, D3DPT_TRIANGLELIST, 2, VertexDataTbl, sizeof(TLVERTX));
3964+ }
3965+
3966+ x = x + width;
3967+ }
3968+ y = y + height;
3969+ }
3970+}
3971+
3972+/*--------------------------------------------------------------------
3973+ マップ描画
3974+ ---------------------------------------------------------------------*/
3975+static VALUE RenderTarget_drawTile( int argc, VALUE *argv, VALUE obj )
3976+{
3977+ VALUE vstartx, vstarty, vz;
3978+ VALUE *mapdata;
3979+ VALUE vbasex, vbasey, vmap, vmapdata, vsizex, vsizey;
3980+ volatile VALUE temp;
3981+ struct DXRubyPicture_drawTile *picture;
3982+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, obj );
3983+ DXRUBY_CHECK_DISPOSE( rt, surface );
3984+
3985+ rb_scan_args( argc, argv, "81", &vbasex, &vbasey, &vmap, &vmapdata, &vstartx, &vstarty, &vsizex, &vsizey, &vz );
3986+
3987+ Check_Type(vmap, T_ARRAY);
3988+ Check_Type(vmapdata, T_ARRAY);
3989+
3990+ picture = (struct DXRubyPicture_drawTile *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawTile ) );
3991+
3992+ /* DXRubyPictureオブジェクト設定 */
3993+ picture->func = RenderTarget_drawTile_func;
3994+ picture->basex = NUM2INT( vbasex );
3995+ picture->basey = NUM2INT( vbasey );
3996+ picture->sizex = NUM2INT( vsizex );
3997+ picture->sizey = NUM2INT( vsizey );
3998+ picture->startx = NUM2INT( vstartx );
3999+ picture->starty = NUM2INT( vstarty );
4000+ temp = rb_ary_new3( 2, vmap, vmapdata );
4001+ picture->value = temp;
4002+ picture->alpha = 0xff;
4003+ picture->blendflag = 0;
4004+
4005+ /* リストデータに追加 */
4006+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4007+ picture->z = rt->PictureList[rt->PictureCount].z = vz == Qnil ? 0.0f : NUM2FLOAT( vz );
4008+ rt->PictureCount++;
4009+
4010+ return obj;
4011+}
4012+
4013+
4014+/*--------------------------------------------------------------------
4015+ (内部関数)画面更新
4016+ ---------------------------------------------------------------------*/
4017+static VALUE RenderTarget_update( VALUE self )
4018+{
4019+ HRESULT hr;
4020+ int x_2d, width_2d;
4021+ int y_2d, height_2d;
4022+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self ); /* 出力先 */
4023+ int i;
4024+
4025+ DXRUBY_CHECK_DISPOSE( rt, surface );
4026+
4027+ /* シーンのクリア */
4028+ {
4029+ D3DVIEWPORT9 vp;
4030+ vp.X = x_2d = 0;
4031+ vp.Y = y_2d = 0;
4032+ if( rt->texture == NULL )
4033+ {
4034+ vp.Width = width_2d = g_D3DPP.BackBufferWidth;
4035+ vp.Height = height_2d = g_D3DPP.BackBufferHeight;
4036+ }
4037+ else
4038+ {
4039+ vp.Width = width_2d = rt->texture->width;
4040+ vp.Height = height_2d = rt->texture->height;
4041+ }
4042+ vp.MinZ = 0.0f;
4043+ vp.MaxZ = 1.0f;
4044+ g_pD3DDevice->lpVtbl->SetRenderTarget( g_pD3DDevice, 0, rt->surface );
4045+ g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
4046+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
4047+ D3DCOLOR_ARGB( rt->a, rt->r, rt->g, rt->b ), 1.0f, 0 );
4048+ }
4049+
4050+ /* シーンの描画開始 */
4051+ if( SUCCEEDED( g_pD3DDevice->lpVtbl->BeginScene( g_pD3DDevice ) ) )
4052+ {
4053+ i = 0;
4054+
4055+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ZENABLE,D3DZB_FALSE );
4056+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ZWRITEENABLE, FALSE );
4057+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_LIGHTING, FALSE);
4058+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_FOGENABLE, FALSE );
4059+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
4060+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRGBWRITEENABLE, FALSE );
4061+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_VERTEXBLEND, FALSE );
4062+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_WRAP0, 0 );
4063+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_CULLMODE, D3DCULL_NONE);
4064+
4065+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
4066+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
4067+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
4068+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
4069+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
4070+ g_pD3DDevice->lpVtbl->SetTextureStageState( g_pD3DDevice, 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
4071+
4072+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_ALPHABLENDENABLE, TRUE );
4073+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
4074+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
4075+
4076+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SEPARATEALPHABLENDENABLE, TRUE );
4077+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4078+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4079+
4080+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_FOGENABLE, FALSE );
4081+
4082+ /* 拡大縮小フィルタ設定 */
4083+ g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MINFILTER,
4084+ rt->minfilter);
4085+ g_pD3DDevice->lpVtbl->SetSamplerState(g_pD3DDevice, 0, D3DSAMP_MAGFILTER,
4086+ rt->magfilter);
4087+
4088+ if( rt->PictureCount > 0 )
4089+ {
4090+ D3DMATRIX matrix, matrix_t;
4091+ int oldflag = 0;
4092+
4093+ RenderTarget_SortPictureList( rt );
4094+
4095+ /* 2D描画 */
4096+ D3DXMatrixScaling ( &matrix, 1, -1, 1 );
4097+ D3DXMatrixTranslation( &matrix_t, (float)-(width_2d)/2.0f, (float)(height_2d)/2.0f, 0 );
4098+ D3DXMatrixMultiply( &matrix, &matrix, &matrix_t );
4099+ g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_VIEW, &matrix );
4100+ matrix._11 = 2.0f / width_2d;
4101+ matrix._12 = matrix._13 = matrix._14 = 0;
4102+ matrix._22 = 2.0f / height_2d;
4103+ matrix._21 = matrix._23 = matrix._24 = 0;
4104+ matrix._31 = matrix._32 = 0;matrix._33 = 0; matrix._34 = 0;
4105+ matrix._41 = matrix._42 = 0;matrix._43 = 1; matrix._44 = 1;
4106+ g_pD3DDevice->lpVtbl->SetTransform( g_pD3DDevice, D3DTS_PROJECTION, &matrix );
4107+
4108+ for( i = 0; i < rt->PictureCount; i++ )
4109+ {
4110+ struct DXRubyPicture_draw *temp = (struct DXRubyPicture_draw *)rt->PictureList[i].picture;
4111+
4112+ if( temp->blendflag != oldflag )
4113+ {
4114+ switch( temp->blendflag )
4115+ {
4116+ case 0: /* 半透明合成 */
4117+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
4118+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
4119+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4120+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4121+ break;
4122+ case 1: /* 単純上書き */
4123+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE );
4124+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ZERO );
4125+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4126+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO );
4127+ break;
4128+ case 4: /* 加算合成1の設定 */
4129+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
4130+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ONE );
4131+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4132+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4133+ break;
4134+ case 5: /* 加算合成2の設定 */
4135+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE );
4136+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
4137+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4138+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4139+ break;
4140+ case 6: /* 減算合成1の設定 */
4141+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ZERO );
4142+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
4143+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4144+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4145+ break;
4146+ case 7: /* 減算合成2の設定 */
4147+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ZERO );
4148+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR );
4149+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
4150+ g_pD3DDevice->lpVtbl->SetRenderState( g_pD3DDevice, D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
4151+ break;
4152+ }
4153+ }
4154+
4155+ oldflag = temp->blendflag;
4156+ temp->func( temp );
4157+ }
4158+ }
4159+
4160+ /* シーンの描画終了 */
4161+ g_pD3DDevice->lpVtbl->EndScene( g_pD3DDevice );
4162+ }
4163+
4164+ rt->PictureCount = 0;
4165+ rt->PictureSize = 0;
4166+ rt->PictureDecideCount = 0;
4167+ rt->PictureDecideSize = 0;
4168+
4169+ for( i = 0; i < RARRAY_LEN(rt->array); i++ )
4170+ {
4171+ Image_dispose( RARRAY_PTR(rt->array)[i] );
4172+ }
4173+ rb_ary_clear( rt->array );
4174+
4175+ return self;
4176+}
4177+
4178+
4179+/*--------------------------------------------------------------------
4180+ 縮小フィルタ取得
4181+ ---------------------------------------------------------------------*/
4182+static VALUE RenderTarget_getMinFilter( VALUE self )
4183+{
4184+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4185+ DXRUBY_CHECK_DISPOSE( rt, surface );
4186+ return INT2FIX( rt->minfilter );
4187+}
4188+
4189+
4190+/*--------------------------------------------------------------------
4191+ 縮小フィルタ設定
4192+ ---------------------------------------------------------------------*/
4193+static VALUE RenderTarget_setMinFilter( VALUE self, VALUE minfilter )
4194+{
4195+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4196+ DXRUBY_CHECK_DISPOSE( rt, surface );
4197+ rt->minfilter = FIX2INT( minfilter );
4198+ return minfilter;
4199+}
4200+
4201+
4202+/*--------------------------------------------------------------------
4203+ 拡大フィルタ取得
4204+ ---------------------------------------------------------------------*/
4205+static VALUE RenderTarget_getMagFilter( VALUE self )
4206+{
4207+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4208+ DXRUBY_CHECK_DISPOSE( rt, surface );
4209+ return INT2FIX( rt->minfilter );
4210+}
4211+
4212+
4213+/*--------------------------------------------------------------------
4214+ 拡大フィルタ設定
4215+ ---------------------------------------------------------------------*/
4216+static VALUE RenderTarget_setMagFilter( VALUE self, VALUE magfilter )
4217+{
4218+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4219+ DXRUBY_CHECK_DISPOSE( rt, surface );
4220+ rt->magfilter = FIX2INT( magfilter );
4221+ return magfilter;
4222+}
4223+
4224+
4225+/*--------------------------------------------------------------------
4226+ 描画予約確定
4227+ ---------------------------------------------------------------------*/
4228+static VALUE RenderTarget_decide( VALUE self )
4229+{
4230+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4231+ DXRUBY_CHECK_DISPOSE( rt, surface );
4232+ rt->PictureDecideCount = rt->PictureCount;
4233+ rt->PictureDecideSize = rt->PictureSize;
4234+ return self;
4235+}
4236+
4237+
4238+/*--------------------------------------------------------------------
4239+ 描画予約破棄
4240+ ---------------------------------------------------------------------*/
4241+static VALUE RenderTarget_discard( VALUE self )
4242+{
4243+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, self );
4244+ DXRUBY_CHECK_DISPOSE( rt, surface );
4245+ rt->PictureCount = rt->PictureDecideCount;
4246+ rt->PictureSize = rt->PictureDecideSize;
4247+ return self;
4248+}
4249+
4250+
4251+
4252+/*
4253+***************************************************************
4254+*
4255+* Global functions
4256+*
4257+***************************************************************/
4258+
4259+void Init_dxruby()
4260+{
4261+ HRESULT hr;
4262+ int i, j;
4263+
4264+ hr = CoInitialize(NULL);
4265+
4266+ if( FAILED( hr ) )
4267+ {
4268+ rb_raise( eDXRubyError, "COMの初期化に失敗しました - CoInitialize" );
4269+ }
4270+
4271+#ifdef HAVE_RB_ENC_STR_NEW
4272+ /* システムのエンコード取得 */
4273+ strcpy( sys_encode, "CP" );
4274+ itoa( GetACP(), sys_encode+2, 10 );
4275+#endif
4276+
4277+ /* インスタンスハンドル取得 */
4278+ g_hInstance = (HINSTANCE)GetModuleHandle( NULL );
4279+
4280+ /* DXRubyモジュール登録 */
4281+ mDXRuby = rb_define_module( "DXRuby" );
4282+
4283+ /* Windowモジュール登録 */
4284+ mWindow = rb_define_module_under( mDXRuby, "Window" );
4285+
4286+ /* Windowモジュールにメソッド登録 */
4287+ rb_define_singleton_method( mWindow, "loop" , Window_loop , 0 );
4288+ rb_define_singleton_method( mWindow, "draw" , Window_draw , -1 );
4289+ rb_define_singleton_method( mWindow, "draw_scale", Window_drawScale , -1 );
4290+ rb_define_singleton_method( mWindow, "drawScale", Window_drawScale , -1 );
4291+ rb_define_singleton_method( mWindow, "draw_rot" , Window_drawRot , -1 );
4292+ rb_define_singleton_method( mWindow, "drawRot" , Window_drawRot , -1 );
4293+ rb_define_singleton_method( mWindow, "draw_alpha", Window_drawAlpha , -1 );
4294+ rb_define_singleton_method( mWindow, "drawAlpha", Window_drawAlpha , -1 );
4295+ rb_define_singleton_method( mWindow, "draw_add" , Window_drawAdd , -1 );
4296+ rb_define_singleton_method( mWindow, "drawAdd" , Window_drawAdd , -1 );
4297+ rb_define_singleton_method( mWindow, "draw_sub" , Window_drawSub , -1 );
4298+ rb_define_singleton_method( mWindow, "drawSub" , Window_drawSub , -1 );
4299+ rb_define_singleton_method( mWindow, "draw_ex" , Window_drawEx , -1 );
4300+ rb_define_singleton_method( mWindow, "drawEx" , Window_drawEx , -1 );
4301+ rb_define_singleton_method( mWindow, "draw_font", Window_drawFont , -1 );
4302+ rb_define_singleton_method( mWindow, "drawFont" , Window_drawFont , -1 );
4303+ rb_define_singleton_method( mWindow, "draw_font_ex", Window_drawFontEx , -1 );
4304+ rb_define_singleton_method( mWindow, "drawFontEx" , Window_drawFontEx , -1 );
4305+ rb_define_singleton_method( mWindow, "draw_tile", Window_drawTile , -1 );
4306+ rb_define_singleton_method( mWindow, "drawTile" , Window_drawTile , -1 );
4307+ rb_define_singleton_method( mWindow, "draw_morph", Window_drawMorph , -1 );
4308+ rb_define_singleton_method( mWindow, "drawMorph" , Window_drawMorph , -1 );
4309+ rb_define_singleton_method( mWindow, "x" , Window_x , 0 );
4310+ rb_define_singleton_method( mWindow, "x=" , Window_setx , 1 );
4311+ rb_define_singleton_method( mWindow, "y" , Window_y , 0 );
4312+ rb_define_singleton_method( mWindow, "y=" , Window_sety , 1 );
4313+ rb_define_singleton_method( mWindow, "width" , Window_width , 0 );
4314+ rb_define_singleton_method( mWindow, "width=" , Window_setwidth , 1 );
4315+ rb_define_singleton_method( mWindow, "height" , Window_height , 0 );
4316+ rb_define_singleton_method( mWindow, "height=" , Window_setheight , 1 );
4317+ rb_define_singleton_method( mWindow, "caption" , Window_getCaption , 0 );
4318+ rb_define_singleton_method( mWindow, "caption=" , Window_setCaption , 1 );
4319+ rb_define_singleton_method( mWindow, "scale" , Window_getScale , 0 );
4320+ rb_define_singleton_method( mWindow, "scale=" , Window_setScale , 1 );
4321+ rb_define_singleton_method( mWindow, "windowed?", Window_getwindowed, 0 );
4322+ rb_define_singleton_method( mWindow, "windowed=", Window_setwindowed, 1 );
4323+ rb_define_singleton_method( mWindow, "real_fps" , Window_getrealfps , 0 );
4324+ rb_define_singleton_method( mWindow, "fps" , Window_getfps , 0 );
4325+ rb_define_singleton_method( mWindow, "fps=" , Window_setfps , 1 );
4326+ rb_define_singleton_method( mWindow, "frameskip?" , Window_getframeskip, 0 );
4327+ rb_define_singleton_method( mWindow, "frameskip=" , Window_setframeskip, 1 );
4328+ rb_define_singleton_method( mWindow, "bgcolor" , Window_get_bgcolor , 0 );
4329+ rb_define_singleton_method( mWindow, "bgcolor=" , Window_set_bgcolor , 1 );
4330+ rb_define_singleton_method( mWindow, "min_filter" , Window_getMinFilter , 0 );
4331+ rb_define_singleton_method( mWindow, "minFilter" , Window_getMinFilter , 0 );
4332+ rb_define_singleton_method( mWindow, "min_filter=" , Window_setMinFilter , 1 );
4333+ rb_define_singleton_method( mWindow, "minFilter=" , Window_setMinFilter , 1 );
4334+ rb_define_singleton_method( mWindow, "mag_filter" , Window_getMagFilter , 0 );
4335+ rb_define_singleton_method( mWindow, "magFilter" , Window_getMagFilter , 0 );
4336+ rb_define_singleton_method( mWindow, "mag_filter=" , Window_setMagFilter , 1 );
4337+ rb_define_singleton_method( mWindow, "magFilter=" , Window_setMagFilter , 1 );
4338+ rb_define_singleton_method( mWindow, "get_load" , Window_getload, 0 );
4339+ rb_define_singleton_method( mWindow, "getLoad" , Window_getload, 0 );
4340+ rb_define_singleton_method( mWindow, "open_filename", Window_openDialog, 2 );
4341+ rb_define_singleton_method( mWindow, "openFilename" , Window_openDialog, 2 );
4342+ rb_define_singleton_method( mWindow, "save_filename", Window_saveDialog, 2 );
4343+ rb_define_singleton_method( mWindow, "saveFilename" , Window_saveDialog, 2 );
4344+ rb_define_singleton_method( mWindow, "get_screen_shot", Window_getScreenShot, -1 );
4345+ rb_define_singleton_method( mWindow, "getScreenShot", Window_getScreenShot, -1 );
4346+ rb_define_singleton_method( mWindow, "create" , Window_create , 0 );
4347+ rb_define_singleton_method( mWindow, "update" , Window_update , 0 );
4348+ rb_define_singleton_method( mWindow, "sync" , Window_sync , 0 );
4349+ rb_define_singleton_method( mWindow, "hWnd" , Window_gethWnd, 0 );
4350+ rb_define_singleton_method( mWindow, "load_icon" , Window_loadIcon, 1 );
4351+ rb_define_singleton_method( mWindow, "loadIcon" , Window_loadIcon, 1 );
4352+// rb_define_singleton_method( mWindow, "playMovie" , Window_playMovie, 1 );
4353+ rb_define_singleton_method( mWindow, "resize" , Window_resize , 2 );
4354+ rb_define_singleton_method( mWindow, "active?" , Window_get_active, 0 );
4355+ rb_define_singleton_method( mWindow, "getScreenModes", Window_getScreenModes, 0 );
4356+ rb_define_singleton_method( mWindow, "get_screen_modes", Window_getScreenModes, 0 );
4357+ rb_define_singleton_method( mWindow, "decide" , Window_decide , 0 );
4358+ rb_define_singleton_method( mWindow, "discard" , Window_discard , 0 );
4359+
4360+// rb_define_singleton_method( mWindow, "draw_shader", Window_drawShader, -1 );
4361+// rb_define_singleton_method( mWindow, "drawShader" , Window_drawShader, -1 );
4362+
4363+
4364+// /* Shaderクラス定義 */
4365+// cShader = rb_define_class_under( mDXRuby, "Shader", rb_cObject );
4366+
4367+// /* Shaderクラスにメソッド登録*/
4368+// rb_define_private_method( cShader, "initialize", Shader_initialize, 2 );
4369+// rb_define_method( cShader, "technique" , Shader_getTechnique , 0 );
4370+// rb_define_method( cShader, "technique=" , Shader_setTechnique , 1 );
4371+
4372+// /* Shaderオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
4373+// rb_define_alloc_func( cShader, Shader_allocate );
4374+
4375+
4376+// /* ShaderCoreクラス定義 */
4377+// cShaderCore = rb_define_class_under( cShader, "Core", rb_cObject );
4378+
4379+// /* ShaderCoreクラスにメソッド登録*/
4380+// rb_define_private_method( cShaderCore, "initialize", ShaderCore_initialize, 2 );
4381+// rb_define_method( cShaderCore, "dispose" , ShaderCore_dispose, 0 );
4382+// rb_define_method( cShaderCore, "disposed?" , ShaderCore_check_disposed, 0 );
4383+// rb_define_method( cShaderCore, "param" , ShaderCore_getParam , 0 );
4384+
4385+// /* ShaderCoreオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
4386+// rb_define_alloc_func( cShaderCore, ShaderCore_allocate );
4387+
4388+
4389+ /* RenderTargetクラス定義 */
4390+ cRenderTarget = rb_define_class_under( mDXRuby, "RenderTarget", rb_cObject );
4391+
4392+ /* RenderTargetクラスにメソッド登録*/
4393+ rb_define_private_method( cRenderTarget, "initialize", RenderTarget_initialize, -1 );
4394+ rb_define_method( cRenderTarget, "dispose" , RenderTarget_dispose , 0 );
4395+ rb_define_method( cRenderTarget, "disposed?" , RenderTarget_check_disposed, 0 );
4396+ rb_define_method( cRenderTarget, "width" , RenderTarget_getWidth , 0 );
4397+ rb_define_method( cRenderTarget, "height" , RenderTarget_getHeight , 0 );
4398+ rb_define_method( cRenderTarget, "to_image" , RenderTarget_to_image , 0 );
4399+ rb_define_method( cRenderTarget, "toImage" , RenderTarget_to_image , 0 );
4400+
4401+ rb_define_method( cRenderTarget, "draw" , RenderTarget_draw , -1 );
4402+ rb_define_method( cRenderTarget, "draw_scale", RenderTarget_drawScale , -1 );
4403+ rb_define_method( cRenderTarget, "drawScale", RenderTarget_drawScale , -1 );
4404+ rb_define_method( cRenderTarget, "draw_rot" , RenderTarget_drawRot , -1 );
4405+ rb_define_method( cRenderTarget, "drawRot" , RenderTarget_drawRot , -1 );
4406+ rb_define_method( cRenderTarget, "draw_alpha", RenderTarget_drawAlpha , -1 );
4407+ rb_define_method( cRenderTarget, "drawAlpha", RenderTarget_drawAlpha , -1 );
4408+ rb_define_method( cRenderTarget, "draw_add" , RenderTarget_drawAdd , -1 );
4409+ rb_define_method( cRenderTarget, "drawAdd" , RenderTarget_drawAdd , -1 );
4410+ rb_define_method( cRenderTarget, "draw_sub" , RenderTarget_drawSub , -1 );
4411+ rb_define_method( cRenderTarget, "drawSub" , RenderTarget_drawSub , -1 );
4412+ rb_define_method( cRenderTarget, "draw_ex" , RenderTarget_drawEx , -1 );
4413+ rb_define_method( cRenderTarget, "drawEx" , RenderTarget_drawEx , -1 );
4414+ rb_define_method( cRenderTarget, "draw_font", RenderTarget_drawFont , -1 );
4415+ rb_define_method( cRenderTarget, "drawFont" , RenderTarget_drawFont , -1 );
4416+ rb_define_method( cRenderTarget, "draw_font_ex", RenderTarget_drawFontEx , -1 );
4417+ rb_define_method( cRenderTarget, "drawFontEx" , RenderTarget_drawFontEx , -1 );
4418+ rb_define_method( cRenderTarget, "draw_tile", RenderTarget_drawTile , -1 );
4419+ rb_define_method( cRenderTarget, "drawTile" , RenderTarget_drawTile , -1 );
4420+ rb_define_method( cRenderTarget, "draw_morph", RenderTarget_drawMorph , -1 );
4421+ rb_define_method( cRenderTarget, "drawMorph" , RenderTarget_drawMorph , -1 );
4422+ rb_define_method( cRenderTarget, "update" , RenderTarget_update , 0 );
4423+ rb_define_method( cRenderTarget, "bgcolor" , RenderTarget_get_bgcolor , 0 );
4424+ rb_define_method( cRenderTarget, "bgcolor=" , RenderTarget_set_bgcolor , 1 );
4425+ rb_define_method( cRenderTarget, "min_filter" , RenderTarget_getMinFilter , 0 );
4426+ rb_define_method( cRenderTarget, "minFilter" , RenderTarget_getMinFilter , 0 );
4427+ rb_define_method( cRenderTarget, "min_filter=" , RenderTarget_setMinFilter , 1 );
4428+ rb_define_method( cRenderTarget, "minFilter=" , RenderTarget_setMinFilter , 1 );
4429+ rb_define_method( cRenderTarget, "mag_filter" , RenderTarget_getMagFilter , 0 );
4430+ rb_define_method( cRenderTarget, "magFilter" , RenderTarget_getMagFilter , 0 );
4431+ rb_define_method( cRenderTarget, "mag_filter=" , RenderTarget_setMagFilter , 1 );
4432+ rb_define_method( cRenderTarget, "magFilter=" , RenderTarget_setMagFilter , 1 );
4433+ rb_define_method( cRenderTarget, "decide" , RenderTarget_decide , 0 );
4434+ rb_define_method( cRenderTarget, "discard" , RenderTarget_discard , 0 );
4435+
4436+// rb_define_method( cRenderTarget, "draw_shader", RenderTarget_drawShader, -1 );
4437+// rb_define_method( cRenderTarget, "drawShader" , RenderTarget_drawShader, -1 );
4438+
4439+ /* RenderTargetオブジェクトを生成した時にinitializeの前に呼ばれるメモリ割り当て関数登録 */
4440+ rb_define_alloc_func( cRenderTarget, RenderTarget_allocate );
4441+
4442+
4443+ rb_define_const( mDXRuby, "FORMAT_JPEG" , INT2FIX(FORMAT_JPEG));
4444+ rb_define_const( mDXRuby, "FORMAT_JPG" , INT2FIX(FORMAT_JPG) );
4445+ rb_define_const( mDXRuby, "FORMAT_PNG" , INT2FIX(FORMAT_PNG) );
4446+ rb_define_const( mDXRuby, "FORMAT_BMP" , INT2FIX(FORMAT_BMP) );
4447+ rb_define_const( mDXRuby, "FORMAT_DDS" , INT2FIX(FORMAT_DDS) );
4448+
4449+ rb_define_const( mDXRuby, "TEXF_POINT" , INT2FIX(D3DTEXF_POINT) );
4450+ rb_define_const( mDXRuby, "TEXF_LINEAR" , INT2FIX(D3DTEXF_LINEAR) );
4451+ rb_define_const( mDXRuby, "TEXF_GAUSSIANQUAD", INT2FIX(D3DTEXF_GAUSSIANQUAD) );
4452+
4453+ /* 例外定義 */
4454+ eDXRubyError = rb_define_class_under( mDXRuby, "DXRubyError", rb_eRuntimeError );
4455+
4456+ /* 定数登録 */
4457+ rb_define_const( mDXRuby, "VERSION", rb_str_new2( DXRUBY_VERSION ) );
4458+
4459+ {
4460+ VALUE temp;
4461+ temp = rb_eval_string( "$dxruby_no_include" );
4462+ if( temp == Qfalse || temp == Qnil )
4463+ {
4464+ rb_include_module( rb_cObject, mDXRuby );
4465+ }
4466+ }
4467+
4468+ /* シンボル定義 */
4469+ symbol_blend = ID2SYM(rb_intern("blend"));
4470+ symbol_angle = ID2SYM(rb_intern("angle"));
4471+ symbol_alpha = ID2SYM(rb_intern("alpha"));
4472+ symbol_scalex = ID2SYM(rb_intern("scalex"));
4473+ symbol_scaley = ID2SYM(rb_intern("scaley"));
4474+ symbol_centerx = ID2SYM(rb_intern("centerx"));
4475+ symbol_centery = ID2SYM(rb_intern("centery"));
4476+ symbol_z = ID2SYM(rb_intern("z"));
4477+ symbol_color = ID2SYM(rb_intern("color"));
4478+ symbol_add = ID2SYM(rb_intern("add"));
4479+ symbol_add2 = ID2SYM(rb_intern("add2"));
4480+ symbol_sub = ID2SYM(rb_intern("sub"));
4481+ symbol_sub2 = ID2SYM(rb_intern("sub2"));
4482+ symbol_none = ID2SYM(rb_intern("none"));
4483+ symbol_dividex = ID2SYM(rb_intern("dividex"));
4484+ symbol_dividey = ID2SYM(rb_intern("dividey"));
4485+ symbol_edge = ID2SYM(rb_intern("edge"));
4486+ symbol_edge_color = ID2SYM(rb_intern("edge_color"));
4487+ symbol_edge_width = ID2SYM(rb_intern("edge_width"));
4488+ symbol_edge_level = ID2SYM(rb_intern("edge_level"));
4489+ symbol_shadow = ID2SYM(rb_intern("shadow"));
4490+ symbol_shadow_color = ID2SYM(rb_intern("shadow_color"));
4491+ symbol_shadow_x = ID2SYM(rb_intern("shadow_x"));
4492+ symbol_shadow_y = ID2SYM(rb_intern("shadow_y"));
4493+ symbol_shadow_edge = ID2SYM(rb_intern("shadow_edge"));
4494+// symbol_shader = ID2SYM(rb_intern("shader"));
4495+ symbol_int = ID2SYM(rb_intern("int"));
4496+ symbol_float = ID2SYM(rb_intern("float"));
4497+ symbol_texture = ID2SYM(rb_intern("texture"));
4498+ symbol_technique = ID2SYM(rb_intern("technique"));
4499+ symbol_discard = ID2SYM(rb_intern("discard"));
4500+
4501+ /* 終了時に実行する関数 */
4502+ rb_set_end_proc( Window_shutdown, Qnil );
4503+
4504+ /* ロストリスト */
4505+ g_RenderTargetList.pointer = malloc( sizeof(void*) * 16 );
4506+ g_RenderTargetList.count = 0;
4507+ g_RenderTargetList.allocate_size = 16;
4508+// g_ShaderCoreList.pointer = malloc( sizeof(void*) * 16 );
4509+// g_ShaderCoreList.count = 0;
4510+// g_ShaderCoreList.allocate_size = 16;
4511+
4512+ g_WindowInfo.x = CW_USEDEFAULT;
4513+ g_WindowInfo.y = CW_USEDEFAULT;
4514+ g_WindowInfo.width = 640;
4515+ g_WindowInfo.height = 480;
4516+ g_WindowInfo.windowed = Qtrue;
4517+ g_WindowInfo.created = Qfalse;
4518+ g_WindowInfo.scale = 1;
4519+ g_WindowInfo.enablemouse = Qtrue;
4520+ g_WindowInfo.mousewheelpos = 0;
4521+ g_WindowInfo.fps = 60;
4522+ g_WindowInfo.frameskip = Qfalse;
4523+ g_WindowInfo.hIcon = 0;
4524+ g_WindowInfo.userloop = 0;
4525+ g_WindowInfo.requestclose = 0;
4526+ g_WindowInfo.render_target = RenderTarget_allocate( cRenderTarget );
4527+ g_WindowInfo.active = 0;
4528+
4529+ g_iRefAll++;
4530+
4531+ /* 大域変数に設定 */
4532+ rb_global_variable( &g_WindowInfo.render_target );
4533+
4534+ /* BG色の初期化 */
4535+ Window_set_bgcolor( mWindow, rb_ary_new3( 3, INT2FIX( 0 ), INT2FIX( 0 ), INT2FIX( 0 ) ) );
4536+
4537+ /* ウィンドウ作成(この時点では非表示) */
4538+ InitWindow();
4539+
4540+ /* DirectX Graphicsの初期化 */
4541+ InitDXGraphics();
4542+
4543+ Init_dxruby_Input();
4544+ Init_dxruby_Sound();
4545+ Init_dxruby_Font();
4546+ Init_dxruby_Image();
4547+// Init_dxruby_Sprite();
4548+}
4549+
4550+/*--------------------------------------------------------------------
4551+ (内部関数)ウィンドウの生成
4552+ ---------------------------------------------------------------------*/
4553+static void InitWindow( void )
4554+{
4555+ WNDCLASSEX wcex;
4556+ RECT rect;
4557+
4558+ /* ウインドウ・クラスの登録 */
4559+ wcex.cbSize = sizeof( WNDCLASSEX );
4560+ wcex.style = CS_HREDRAW | CS_VREDRAW;
4561+ wcex.lpfnWndProc = (WNDPROC)MainWndProc;
4562+ wcex.cbClsExtra = 0;
4563+ wcex.cbWndExtra = 0;
4564+ wcex.hInstance = g_hInstance;
4565+ wcex.hIcon = NULL;
4566+ wcex.hIconSm = NULL;
4567+ wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
4568+ wcex.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
4569+ wcex.lpszMenuName = NULL;
4570+ wcex.lpszClassName = "DXRuby";
4571+
4572+ if( !RegisterClassEx( &wcex ) )
4573+ {
4574+ rb_raise( eDXRubyError, "ウィンドウの初期化に失敗しました - RegusterClassEx" );
4575+ }
4576+
4577+ /* メイン・ウインドウ作成(ウインドウ・モード用) */
4578+ rect.top = 0;
4579+ rect.left = 0;
4580+ rect.right = g_WindowInfo.width;
4581+ rect.bottom = g_WindowInfo.height;
4582+
4583+ AdjustWindowRect( &rect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE );
4584+
4585+ rect.right = rect.right - rect.left;
4586+ rect.bottom = rect.bottom - rect.top;
4587+ rect.left = 0;
4588+ rect.top = 0;
4589+
4590+ g_hWnd = CreateWindow( TEXT("DXRuby"), TEXT("DXRuby Application"),
4591+ WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
4592+ CW_USEDEFAULT, CW_USEDEFAULT,
4593+ rect.right - rect.left, rect.bottom - rect.top,
4594+ NULL, NULL, g_hInstance, NULL );
4595+ if( g_hWnd == NULL )
4596+ {
4597+ rb_raise( eDXRubyError, "ウィンドウの初期化に失敗しました - CreateWindow" );
4598+ }
4599+
4600+ GetWindowRect( g_hWnd, &rect );
4601+ g_WindowInfo.x = rect.left;
4602+ g_WindowInfo.y = rect.top;
4603+
4604+ WINNLSEnableIME( g_hWnd, FALSE );
4605+}
4606+
4607+
4608+/*--------------------------------------------------------------------
4609+ (内部関数)DirectX Graphics初期化
4610+ ---------------------------------------------------------------------*/
4611+static void InitDXGraphics( void )
4612+{
4613+ D3DVIEWPORT9 vp;
4614+ HRESULT hr;
4615+
4616+ /* Direct3Dオブジェクトの作成 */
4617+ g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
4618+
4619+ if( g_pD3D == NULL )
4620+ {
4621+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - Direct3DCreate9" );
4622+ }
4623+
4624+ /* D3DDeviceオブジェクトの作成(ウインドウ・モード) */
4625+ ZeroMemory( &g_D3DPP, sizeof( g_D3DPP ) );
4626+
4627+ g_D3DPP.BackBufferWidth = 0;
4628+ g_D3DPP.BackBufferHeight = 0;
4629+ g_D3DPP.BackBufferFormat = D3DFMT_UNKNOWN;
4630+ g_D3DPP.BackBufferCount = 1;
4631+ g_D3DPP.MultiSampleType = D3DMULTISAMPLE_NONE;
4632+ g_D3DPP.MultiSampleQuality = 0;
4633+ g_D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
4634+ g_D3DPP.hDeviceWindow = g_hWnd;
4635+ g_D3DPP.Windowed = TRUE;
4636+ g_D3DPP.EnableAutoDepthStencil = TRUE;
4637+ g_D3DPP.AutoDepthStencilFormat = D3DFMT_D24S8;
4638+ g_D3DPP.Flags = 0;
4639+ g_D3DPP.FullScreen_RefreshRateInHz = 0;
4640+ g_D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
4641+
4642+ hr = g_pD3D->lpVtbl->CreateDevice( g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
4643+ D3DCREATE_MIXED_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice );
4644+
4645+ if( FAILED( hr ) )
4646+ {
4647+ hr = g_pD3D->lpVtbl->CreateDevice( g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
4648+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_D3DPP, &g_pD3DDevice );
4649+
4650+ if( FAILED( hr ) )
4651+ {
4652+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - CreateDevice" );
4653+ }
4654+ }
4655+
4656+ /* ビューポートの設定 */
4657+ vp.X = 0;
4658+ vp.Y = 0;
4659+ vp.Width = g_D3DPP.BackBufferWidth;
4660+ vp.Height = g_D3DPP.BackBufferHeight;
4661+ vp.MinZ = 0.0f;
4662+ vp.MaxZ = 1.0f;
4663+
4664+ hr = g_pD3DDevice->lpVtbl->SetViewport( g_pD3DDevice, &vp );
4665+
4666+ if( FAILED( hr ) )
4667+ {
4668+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - SetViewport" );
4669+ }
4670+
4671+ g_pD3DDevice->lpVtbl->Clear( g_pD3DDevice, 0, NULL, D3DCLEAR_TARGET,
4672+ D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
4673+
4674+ /* D3DXSpriteオブジェクト作成 */
4675+ hr = D3DXCreateSprite( g_pD3DDevice, &g_pD3DXSprite );
4676+
4677+ if( FAILED( hr ) )
4678+ {
4679+ rb_raise( eDXRubyError, "DirectX Graphicsの初期化に失敗しました - CreateSprite" );
4680+ }
4681+}
4682+
4683+
4684+/*--------------------------------------------------------------------
4685+ (内部関数)フレーム調整初期化
4686+ ---------------------------------------------------------------------*/
4687+static void InitSync( void )
4688+{
4689+ timeBeginPeriod( 1 );
4690+
4691+ /* パフォーマンスカウンタの秒間カウント値取得 */
4692+ if( QueryPerformanceFrequency( (LARGE_INTEGER *)&g_OneSecondCount ) )
4693+ {
4694+ /* パフォーマンスカウンタがある場合 */
4695+ g_isPerformanceCounter = 1;
4696+ QueryPerformanceCounter( (LARGE_INTEGER *)&g_OldTime );
4697+ }
4698+ else
4699+ {
4700+ /* パフォーマンスカウンタが無い場合 */
4701+ g_isPerformanceCounter = 0;
4702+ g_OneSecondCount = 1000;
4703+ g_OldTime = timeGetTime();
4704+ }
4705+}
4706+
4707+
4708+/* Ruby1.8の古いほう対応 */
4709+VALUE hash_lookup(VALUE hash, VALUE key)
4710+{
4711+ VALUE val;
4712+
4713+ if (!RHASH_TBL(hash) || !st_lookup(RHASH_TBL(hash), key, &val)) {
4714+ return Qnil;
4715+ }
4716+ return val;
4717+}
4718+
4719+/***********************
4720+ * 外部インターフェース
4721+ ***********************/
4722+
4723+/*--------------------------------------------------------------------
4724+ 描画設定(通常描画)
4725+ ---------------------------------------------------------------------*/
4726+void DXRuby_draw( int x, int y, VALUE vimage, float z )
4727+{
4728+ struct DXRubyImage *image;
4729+ struct DXRubyPicture_draw *picture;
4730+ struct DXRubyRenderTarget *rt;
4731+
4732+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4733+
4734+ /* 引数のイメージオブジェクトから中身を取り出す */
4735+ DXRUBY_CHECK_IMAGE( vimage );
4736+ image = DXRUBY_GET_STRUCT( Image, vimage );
4737+ DXRUBY_CHECK_DISPOSE( image, texture );
4738+
4739+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
4740+
4741+ /* DXRubyPictureオブジェクト設定 */
4742+ picture->func = RenderTarget_draw_func;
4743+ picture->x = x;
4744+ picture->y = y;
4745+ picture->value = vimage;
4746+ picture->alpha = 0xff;
4747+ picture->blendflag = 0;
4748+
4749+ /* リストデータに追加 */
4750+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4751+ rt->PictureList[rt->PictureCount].z = z;
4752+ picture->z = z;
4753+ rt->PictureCount++;
4754+
4755+ return;
4756+}
4757+
4758+
4759+/*--------------------------------------------------------------------
4760+ 描画設定(拡大縮小描画) フラグは0にするとcenter無視
4761+ ---------------------------------------------------------------------*/
4762+void DXRuby_drawScale( int x, int y, VALUE vimage, float scalex, float scaley, float centerx, float centery, float z, int flag )
4763+{
4764+ struct DXRubyImage *image;
4765+ struct DXRubyPicture_drawEx *picture;
4766+ struct DXRubyRenderTarget *rt;
4767+
4768+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4769+
4770+ /* 引数のイメージオブジェクトから中身を取り出す */
4771+ DXRUBY_CHECK_IMAGE( vimage );
4772+ image = DXRUBY_GET_STRUCT( Image, vimage );
4773+ DXRUBY_CHECK_DISPOSE( image, texture );
4774+
4775+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
4776+
4777+ /* DXRubyPictureオブジェクト設定 */
4778+ picture->func = RenderTarget_drawEx_func;
4779+ picture->x = x;
4780+ picture->y = y;
4781+ picture->value = vimage;
4782+ picture->alpha = 0xff;
4783+ picture->blendflag = 0;
4784+ picture->angle = 0.0f;
4785+ picture->scalex = scalex;
4786+ picture->scaley = scaley;
4787+ picture->centerx = flag ? centerx : image->width / 2;
4788+ picture->centery = flag ? centery : image->height / 2;
4789+
4790+ /* リストデータに追加 */
4791+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4792+ rt->PictureList[rt->PictureCount].z = z;
4793+ picture->z = z;
4794+ rt->PictureCount++;
4795+
4796+ return;
4797+}
4798+
4799+
4800+/*--------------------------------------------------------------------
4801+ 描画設定(回転描画) フラグは0にするとcenter無視
4802+ ---------------------------------------------------------------------*/
4803+void DXRuby_drawRot( int x, int y, VALUE vimage, float angle, int centerx, int centery, int z, int flag)
4804+{
4805+ struct DXRubyImage *image;
4806+ struct DXRubyPicture_drawEx *picture;
4807+ struct DXRubyRenderTarget *rt;
4808+
4809+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4810+
4811+ /* 引数のイメージオブジェクトから中身を取り出す */
4812+ DXRUBY_CHECK_IMAGE( vimage );
4813+ image = DXRUBY_GET_STRUCT( Image, vimage );
4814+ DXRUBY_CHECK_DISPOSE( image, texture );
4815+
4816+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
4817+
4818+ /* DXRubyPictureオブジェクト設定 */
4819+ picture->func = RenderTarget_drawEx_func;
4820+ picture->x = x;
4821+ picture->y = y;
4822+ picture->value = vimage;
4823+ picture->alpha = 0xff;
4824+ picture->blendflag = 0;
4825+ picture->angle = angle;
4826+ picture->scalex = 1.0f;
4827+ picture->scaley = 1.0f;
4828+ picture->centerx = flag ? centerx : image->width / 2;
4829+ picture->centery = flag ? centery : image->height / 2;
4830+
4831+ /* リストデータに追加 */
4832+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4833+ rt->PictureList[rt->PictureCount].z = z;
4834+ picture->z = z;
4835+ rt->PictureCount++;
4836+
4837+ return;
4838+}
4839+
4840+
4841+/*--------------------------------------------------------------------
4842+ 描画設定(半透明描画)
4843+ ---------------------------------------------------------------------*/
4844+void DXRuby_drawAlpha( int x, int y, VALUE vimage, int alpha, int z )
4845+{
4846+ struct DXRubyImage *image;
4847+ struct DXRubyPicture_draw *picture;
4848+ struct DXRubyRenderTarget *rt;
4849+
4850+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4851+
4852+ /* 引数のイメージオブジェクトから中身を取り出す */
4853+ DXRUBY_CHECK_IMAGE( vimage );
4854+ image = DXRUBY_GET_STRUCT( Image, vimage );
4855+ DXRUBY_CHECK_DISPOSE( image, texture );
4856+
4857+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
4858+
4859+ /* DXRubyPictureオブジェクト設定 */
4860+ picture->func = RenderTarget_draw_func;
4861+ picture->x = x;
4862+ picture->y = y;
4863+ picture->value = vimage;
4864+ picture->alpha = alpha;
4865+ picture->blendflag = 0;
4866+
4867+ /* リストデータに追加 */
4868+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4869+ rt->PictureList[rt->PictureCount].z = z;
4870+ picture->z = z;
4871+ rt->PictureCount++;
4872+
4873+ return;
4874+}
4875+
4876+
4877+/*--------------------------------------------------------------------
4878+ 描画設定(加算合成描画)
4879+ ---------------------------------------------------------------------*/
4880+void DXRuby_drawAdd( int x, int y, VALUE vimage, int z )
4881+{
4882+ struct DXRubyImage *image;
4883+ struct DXRubyPicture_draw *picture;
4884+ struct DXRubyRenderTarget *rt;
4885+
4886+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4887+
4888+ /* 引数のイメージオブジェクトから中身を取り出す */
4889+ DXRUBY_CHECK_IMAGE( vimage );
4890+ image = DXRUBY_GET_STRUCT( Image, vimage );
4891+ DXRUBY_CHECK_DISPOSE( image, texture );
4892+
4893+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
4894+
4895+ /* DXRubyPictureオブジェクト設定 */
4896+ picture->func = RenderTarget_draw_func;
4897+ picture->x = x;
4898+ picture->y = y;
4899+ picture->value = vimage;
4900+ picture->alpha = 0xff;
4901+ picture->blendflag = 4;
4902+
4903+ /* リストデータに追加 */
4904+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4905+ rt->PictureList[rt->PictureCount].z = z;
4906+ picture->z = z;
4907+ rt->PictureCount++;
4908+
4909+ return;
4910+}
4911+
4912+
4913+/*--------------------------------------------------------------------
4914+ 描画設定(減算合成描画)
4915+ ---------------------------------------------------------------------*/
4916+void DXRuby_drawSub( int x, int y, VALUE vimage, int z )
4917+{
4918+ struct DXRubyImage *image;
4919+ struct DXRubyPicture_draw *picture;
4920+ struct DXRubyRenderTarget *rt;
4921+
4922+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4923+
4924+ /* 引数のイメージオブジェクトから中身を取り出す */
4925+ DXRUBY_CHECK_IMAGE( vimage );
4926+ image = DXRUBY_GET_STRUCT( Image, vimage );
4927+ DXRUBY_CHECK_DISPOSE( image, texture );
4928+
4929+ picture = (struct DXRubyPicture_draw *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_draw ) );
4930+
4931+ /* DXRubyPictureオブジェクト設定 */
4932+ picture->func = RenderTarget_draw_func;
4933+ picture->x = x;
4934+ picture->y = y;
4935+ picture->value = vimage;
4936+ picture->alpha = 0xff;
4937+ picture->blendflag = 6;
4938+
4939+ /* リストデータに追加 */
4940+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4941+ rt->PictureList[rt->PictureCount].z = z;
4942+ picture->z = z;
4943+ rt->PictureCount++;
4944+
4945+ return;
4946+}
4947+
4948+
4949+/*--------------------------------------------------------------------
4950+ 描画設定(フルオプション)
4951+ ---------------------------------------------------------------------*/
4952+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 )
4953+{
4954+ struct DXRubyImage *image;
4955+ struct DXRubyRenderTarget *rt;
4956+ struct DXRubyPicture_drawEx *picture;
4957+
4958+ rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
4959+
4960+ /* 引数のイメージオブジェクトから中身を取り出す */
4961+ DXRUBY_CHECK_IMAGE( vimage );
4962+ image = DXRUBY_GET_STRUCT( Image, vimage );
4963+ DXRUBY_CHECK_DISPOSE( image, texture );
4964+
4965+ picture = (struct DXRubyPicture_drawEx *)RenderTarget_AllocPictureList( rt, sizeof( struct DXRubyPicture_drawEx ) );
4966+
4967+ /* DXRubyPictureオブジェクト設定 */
4968+ picture->func = RenderTarget_drawEx_func;
4969+ picture->x = x;
4970+ picture->y = y;
4971+ picture->value = vimage;
4972+ picture->alpha = alpha;
4973+ picture->blendflag = blend;
4974+ picture->angle = angle;
4975+ picture->scalex = scalex;
4976+ picture->scaley = scaley;
4977+ picture->centerx = flag ? centerx : image->width / 2;
4978+ picture->centery = flag ? centery : image->height / 2;
4979+
4980+ /* リストデータに追加 */
4981+ rt->PictureList[rt->PictureCount].picture = (struct DXRubyPicture *)picture;
4982+ rt->PictureList[rt->PictureCount].z = z;
4983+ picture->z = z;
4984+ rt->PictureCount++;
4985+
4986+ return;
4987+}
4988+
4989+
4990+/*--------------------------------------------------------------------
4991+ イメージのロック
4992+ ---------------------------------------------------------------------*/
4993+void *DXRuby_lock( VALUE vimage, char **address, int *pitch, int *width, int *height )
4994+{
4995+ struct DXRubyImage *image;
4996+ D3DLOCKED_RECT texrect;
4997+ RECT rect;
4998+
4999+ /* 引数のイメージオブジェクトから中身を取り出す */
5000+ if( TYPE( vimage ) != T_DATA ) rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
5001+ image = (struct DXRubyImage *)DATA_PTR( vimage );
5002+ if( RDATA( vimage )->dfree != (RUBY_DATA_FUNC)Image_release )
5003+ {
5004+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image)", rb_obj_classname( vimage ));
5005+ }
5006+
5007+ rect.left = (long)image->x;
5008+ rect.top = (long)image->y;
5009+ rect.right = (long)(image->x + image->width);
5010+ rect.bottom = (long)(image->y + image->height);
5011+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
5012+
5013+ // *((int*)((char *)texrect.pBits + x * 4 + y * texrect.Pitch)) = col;
5014+
5015+ *address = (char *)texrect.pBits;
5016+ *pitch = texrect.Pitch;
5017+ *width = (int)image->width;
5018+ *height = (int)image->height;
5019+
5020+ return image->texture->pD3DTexture;
5021+}
5022+
5023+
5024+/*--------------------------------------------------------------------
5025+ イメージのアンロック
5026+ ---------------------------------------------------------------------*/
5027+void DXRuby_unlock( void *texture )
5028+{
5029+ ((LPDIRECT3DTEXTURE9)texture)->lpVtbl->UnlockRect( (LPDIRECT3DTEXTURE9)texture, 0 );
5030+}
5031+
--- tags/1.2.2/dxruby.h (nonexistent)
+++ tags/1.2.2/dxruby.h (revision 276)
@@ -0,0 +1,260 @@
1+#include <stdlib.h>
2+#include <mmsystem.h>
3+#include <tchar.h>
4+#include <d3dx9.h>
5+#include <memory.h>
6+#include <math.h>
7+#include <d3d9types.h>
8+#include <WINNLS32.H>
9+
10+/* Ruby1.8の古いほう対応 */
11+#ifndef RSTRING_PTR
12+# define RSTRING_PTR(s) (RSTRING(s)->ptr)
13+#endif
14+#ifndef RSTRING_LEN
15+# define RSTRING_LEN(s) (RSTRING(s)->len)
16+#endif
17+
18+#ifndef RARRAY_PTR
19+# define RARRAY_PTR(s) (RARRAY(s)->ptr)
20+#endif
21+#ifndef RARRAY_LEN
22+# define RARRAY_LEN(s) (RARRAY(s)->len)
23+#endif
24+
25+#define RELEASE( x ) if( x ) { if(FAILED(x->lpVtbl->Release( x )))rb_raise(eDXRubyError,"release error"); x = NULL; }
26+#define DXRUBY_CHECK_TYPE( a, b ) \
27+ {if( TYPE( b ) != T_DATA || RDATA( b )->dfree != (RUBY_DATA_FUNC)a##_release )\
28+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::"#a")", rb_obj_classname( b ));}
29+#define DXRUBY_CHECK_IMAGE( a ) \
30+ {if( TYPE( a ) != T_DATA || (RDATA( a )->dfree != (RUBY_DATA_FUNC)Image_release && RDATA( a )->dfree != (RUBY_DATA_FUNC)RenderTarget_release) )\
31+ rb_raise(rb_eTypeError, "wrong argument type %s (expected DXRuby::Image or DXRuby::RenderTarget)", rb_obj_classname( a ));}
32+#define DXRUBY_GET_STRUCT( c, v ) ((struct DXRuby##c *)DATA_PTR( v ))
33+#define DXRUBY_CHECK_DISPOSE( a, b ) {if( a->b == NULL ) { rb_raise( eDXRubyError, "disposed object" );}}
34+#define NUM2FLOAT( x ) ((float)( FIXNUM_P(x) ? FIX2INT(x) : NUM2DBL(x) ))
35+
36+#define FORMAT_JPEG D3DXIFF_JPG
37+#define FORMAT_JPG D3DXIFF_JPG
38+#define FORMAT_PNG D3DXIFF_PNG
39+#define FORMAT_BMP D3DXIFF_BMP
40+#define FORMAT_DDS D3DXIFF_DDS
41+
42+struct DXRubyWindowInfo {
43+ int x; /* x座標 */
44+ int y; /* y座標 */
45+ int width; /* 幅 */
46+ int height; /* 高さ */
47+ int windowed; /* ウィンドウモード時にQtrue */
48+ int created; /* ウィンドウを作成したらQtrue */
49+ float scale; /* ウィンドウのサイズ倍率 */
50+ int RefreshRate; /* リフレッシュレート */
51+ int enablemouse; /* マウスを表示するかどうか */
52+ int mousewheelpos; /* マウスホイールの位置 */
53+ int fps; /* fps */
54+ int fpscheck; /* 現在のfps */
55+ int frameskip; /* コマ落ち制御フラグ */
56+ HANDLE hIcon; /* ウィンドウアイコンハンドル */
57+ int userloop; /* 自前ループされてたら1、Window.loopされたら2*/
58+ int requestclose; /* ウィンドウが閉じられたら1 */
59+ VALUE render_target; /* スクリーンレンダーターゲット */
60+ int active; /* ゲーム調整用 */
61+};
62+
63+/* ピクチャ配列 */
64+static struct DXRubyPictureList {
65+ float z; /* ピクチャのZ座標 */
66+ struct DXRubyPicture *picture; /* ピクチャ構造体へのポインタ */
67+};
68+
69+
70+/* RenderTargetオブジェクトの中身 */
71+struct DXRubyRenderTarget {
72+ struct DXRubyTexture *texture;
73+ float x; /* x始点位置 */
74+ float y; /* y始点位置 */
75+ float width; /* イメージの幅 */
76+ float height;/* イメージの高さ ここまでImageと共通*/
77+ IDirect3DSurface9 *surface;
78+
79+ int PictureCount; /* ピクチャの登録数 */
80+ int PictureAllocateCount; /* ピクチャ登録のメモリ確保数 */
81+ int PictureSize; /* ピクチャデータの使用済みサイズ */
82+ int PictureAllocateSize; /* ピクチャデータのメモリ確保サイズ */
83+ char *PictureStruct;
84+
85+ struct DXRubyPictureList *PictureList;
86+
87+ int minfilter; /* 縮小フィルタ */
88+ int magfilter; /* 拡大フィルタ */
89+
90+ int a; /* 背景クリア色 α成分 */
91+ int r; /* 背景クリア色 赤成分 */
92+ int g; /* 背景クリア色 緑成分 */
93+ int b; /* 背景クリア色 青成分 */
94+
95+ VALUE array; /* drawFontExによる自動生成Imageの置き場所 */
96+
97+ int PictureDecideCount; /* ピクチャの登録確定数 */
98+ int PictureDecideSize; /* ピクチャデータの登録確定サイズ */
99+
100+};
101+
102+struct DXRubyPicture_draw {
103+ void (*func)(void*);
104+ VALUE value;
105+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
106+ unsigned char alpha; /* アルファ(透明)値 */
107+ char reserve1; /* 予約3 */
108+ char reserve2; /* 予約4 */
109+ int x;
110+ int y;
111+ float z;
112+};
113+
114+struct DXRubyPicture_drawEx {
115+ void (*func)(void*);
116+ VALUE value;
117+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
118+ unsigned char alpha; /* アルファ(透明)値 */
119+ char reserve1; /* 予約3 */
120+ char reserve2; /* 予約4 */
121+ int x;
122+ int y;
123+ float z;
124+ float scalex;
125+ float scaley;
126+ float centerx;
127+ float centery;
128+ float angle;
129+};
130+
131+struct DXRubyPicture_drawFont {
132+ void (*func)(void*);
133+ VALUE value;
134+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
135+ unsigned char alpha; /* アルファ(透明)値 */
136+ char reserve1; /* 予約3 */
137+ char reserve2; /* 予約4 */
138+ int x;
139+ int y;
140+ int z;
141+ float scalex;
142+ float scaley;
143+ float centerx;
144+ float centery;
145+ float angle;
146+ int color; /* フォントの色 */
147+ char str[0]; /* 文字列オブジェクト */
148+};
149+
150+struct DXRubyPicture_drawMorph {
151+ void (*func)(void*);
152+ VALUE value;
153+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
154+ unsigned char alpha; /* アルファ(透明)値 */
155+ char reserve1; /* 予約3 */
156+ char reserve2; /* 予約4 */
157+ float x1;
158+ float y1;
159+ float x2;
160+ float y2;
161+ float x3;
162+ float y3;
163+ float x4;
164+ float y4;
165+ float z;
166+ int dividex;
167+ int dividey;
168+ char colorflag, r, g, b;
169+};
170+
171+struct DXRubyPicture_drawTile {
172+ void (*func)(void*);
173+ VALUE value;
174+ unsigned char blendflag; /* 半透明(000)、加算合成1(100)、加算合成2(101)、減算合成1(110)、減算合成2(111)のフラグ */
175+ unsigned char alpha; /* アルファ(透明)値 */
176+ char reserve1; /* 予約3 */
177+ char reserve2; /* 予約4 */
178+ int basex;
179+ int basey;
180+ int sizex;
181+ int sizey;
182+ int startx;
183+ int starty;
184+ float z;
185+};
186+
187+/* ShaderCore */
188+struct DXRubyShaderCore {
189+ LPD3DXEFFECT pD3DXEffect;
190+ VALUE vtype; /* 引数名と型のセット */
191+};
192+
193+/* Shader */
194+struct DXRubyShader {
195+ VALUE vcore;
196+ VALUE vparam; /* 引数名と中身のセット*/
197+ VALUE vname;
198+};
199+
200+
201+#ifdef DXRUBY_EXTERN
202+extern HINSTANCE g_hInstance; /* アプリケーションインスタンス */
203+extern HANDLE g_hWnd; /* ウィンドウハンドル */
204+extern int g_iRefAll; /* インターフェースの参照カウント */
205+
206+extern LPDIRECT3D9 g_pD3D; /* Direct3Dインターフェイス */
207+extern LPDIRECT3DDEVICE9 g_pD3DDevice; /* Direct3DDeviceインターフェイス */
208+extern D3DPRESENT_PARAMETERS g_D3DPP; /* D3DDeviceの設定 */
209+
210+extern struct DXRubyWindowInfo g_WindowInfo;
211+extern char sys_encode[256];
212+
213+extern VALUE mDXRuby; /* DXRubyモジュール */
214+extern VALUE eDXRubyError; /* 例外 */
215+
216+/* シンボル */
217+extern VALUE symbol_blend;
218+extern VALUE symbol_angle;
219+extern VALUE symbol_alpha;
220+extern VALUE symbol_scalex;
221+extern VALUE symbol_scaley;
222+extern VALUE symbol_centerx;
223+extern VALUE symbol_centery;
224+extern VALUE symbol_z;
225+extern VALUE symbol_color;
226+extern VALUE symbol_add;
227+extern VALUE symbol_add2;
228+extern VALUE symbol_sub;
229+extern VALUE symbol_sub2;
230+extern VALUE symbol_none;
231+extern VALUE symbol_dividex;
232+extern VALUE symbol_dividey;
233+extern VALUE symbol_edge;
234+extern VALUE symbol_edge_color;
235+extern VALUE symbol_edge_width;
236+extern VALUE symbol_edge_level;
237+extern VALUE symbol_shadow;
238+extern VALUE symbol_shadow_color;
239+extern VALUE symbol_shadow_x;
240+extern VALUE symbol_shadow_y;
241+extern VALUE symbol_shadow_edge;
242+extern VALUE symbol_shader;
243+extern VALUE symbol_int;
244+extern VALUE symbol_float;
245+extern VALUE symbol_texture;
246+extern VALUE symbol_technique;
247+extern VALUE symbol_discard;
248+
249+#endif
250+
251+void *RenderTarget_AllocPictureList( struct DXRubyRenderTarget *rt, int size );
252+void RenderTarget_draw_func( struct DXRubyPicture_draw *picture );
253+void RenderTarget_drawShader_func( struct DXRubyPicture_draw *picture );
254+void RenderTarget_drawEx_func( struct DXRubyPicture_drawEx *picture );
255+void RenderTarget_release( struct DXRubyRenderTarget* rt );
256+void ShaderCore_release( struct DXRubyShaderCore *core );
257+void Shader_release( struct DXRubyShader *shader );
258+
259+VALUE hash_lookup(VALUE hash, VALUE key);
260+
--- tags/1.2.2/image.c (nonexistent)
+++ tags/1.2.2/image.c (revision 276)
@@ -0,0 +1,2453 @@
1+#define WINVER 0x0500 /* バージョン定義 Windows2000以上 */
2+#define _WIN32_WINNT WINVER
3+
4+#include "ruby.h"
5+#ifndef RUBY_ST_H
6+#include "st.h"
7+#endif
8+
9+#define DXRUBY_EXTERN 1
10+#include "dxruby.h"
11+#include "image.h"
12+#include "font.h"
13+
14+VALUE cImage; /* イメージクラス */
15+
16+/* 色 */
17+struct DXRubyColor {
18+ unsigned char blue;
19+ unsigned char green;
20+ unsigned char red;
21+ unsigned char alpha;
22+};
23+
24+
25+/*--------------------------------------------------------------------
26+ Textureロード
27+ ---------------------------------------------------------------------*/
28+static struct DXRubyTexture *Image_textureload( char *filename, D3DXIMAGE_INFO *psrcinfo)
29+{
30+ HRESULT hr;
31+ struct DXRubyTexture *texture;
32+
33+ /* テクスチャメモリ取得 */
34+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
35+
36+ if( texture == NULL )
37+ {
38+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_textureload" );
39+ }
40+
41+ /* ファイルを読み込んでテクスチャオブジェクトを作成する */
42+ hr = D3DXCreateTextureFromFileEx( g_pD3DDevice, filename,psrcinfo->Width, psrcinfo->Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
43+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
44+ 0, 0, &texture->pD3DTexture);
45+
46+ if( FAILED( hr ) )
47+ {
48+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", filename );
49+ }
50+
51+ return texture;
52+}
53+
54+
55+/*--------------------------------------------------------------------
56+ イメージオブジェクトのdup/clone
57+ ---------------------------------------------------------------------*/
58+VALUE Image_initialize_copy( VALUE self, VALUE obj )
59+{
60+ struct DXRubyImage *srcimage;
61+ struct DXRubyImage *dstimage;
62+ struct DXRubyTexture *texture;
63+ D3DLOCKED_RECT srctrect;
64+ D3DLOCKED_RECT dsttrect;
65+ int i, j;
66+ RECT srcrect;
67+ RECT dstrect;
68+ HRESULT hr;
69+ D3DSURFACE_DESC desc;
70+ int *psrc;
71+ int *pdst;
72+
73+ if( TYPE(obj) != T_DATA || RDATA(obj)->dfree != Image_release )
74+ {
75+ rb_raise( eDXRubyError, "wrong argument type" );
76+ }
77+
78+ Data_Get_Struct( self, struct DXRubyImage, dstimage );
79+// DXRUBY_CHECK_DISPOSE( dstimage, texture );
80+ Data_Get_Struct( obj, struct DXRubyImage, srcimage );
81+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
82+
83+ g_iRefAll++;
84+
85+ /* テクスチャメモリ取得 */
86+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
87+ if( texture == NULL )
88+ {
89+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_dup" );
90+ }
91+
92+ /* テクスチャオブジェクトを作成する */
93+ hr = D3DXCreateTexture( g_pD3DDevice, srcimage->width, srcimage->height,
94+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
95+ &texture->pD3DTexture);
96+ if( FAILED( hr ) )
97+ {
98+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_dup" );
99+ }
100+
101+ texture->refcount = 1;
102+
103+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
104+ texture->width = desc.Width;
105+ texture->height = desc.Height;
106+
107+ dstimage->texture = texture;
108+ dstimage->x = 0;
109+ dstimage->y = 0;
110+ dstimage->width = srcimage->width;
111+ dstimage->height =srcimage-> height;
112+
113+ /* イメージコピー */
114+ dstrect.left = 0;
115+ dstrect.top = 0;
116+ dstrect.right = srcimage->width;
117+ dstrect.bottom = srcimage->height;
118+ srcrect.left = srcimage->x;
119+ srcrect.top = srcimage->y;
120+ srcrect.right = srcimage->x + srcimage->width;
121+ srcrect.bottom = srcimage->y + srcimage->height;
122+
123+ dstimage->texture->pD3DTexture->lpVtbl->LockRect( dstimage->texture->pD3DTexture, 0, &dsttrect, &dstrect, 0 );
124+ srcimage->texture->pD3DTexture->lpVtbl->LockRect( srcimage->texture->pD3DTexture, 0, &srctrect, &srcrect, D3DLOCK_READONLY );
125+
126+ for( i = 0; i < srcimage->height; i++)
127+ {
128+ psrc = (int*)((char *)srctrect.pBits + i * srctrect.Pitch);
129+ pdst = (int*)((char *)dsttrect.pBits + i * dsttrect.Pitch);
130+ for( j = 0; j < srcimage->width; j++)
131+ {
132+ *(pdst++) = *(psrc++);
133+ }
134+ }
135+
136+ dstimage->texture->pD3DTexture->lpVtbl->UnlockRect( dstimage->texture->pD3DTexture, 0 );
137+ srcimage->texture->pD3DTexture->lpVtbl->UnlockRect( srcimage->texture->pD3DTexture, 0 );
138+
139+ return self;
140+}
141+
142+
143+/*********************************************************************
144+ * Imageクラス
145+ *
146+ * 描画用の画像を保持するクラス。
147+ * ファイル名を渡してloadすると読み込まれ、Window::drawに渡して描画する。
148+ *********************************************************************/
149+
150+/*--------------------------------------------------------------------
151+ 参照されなくなったときにGCから呼ばれる関数
152+ ---------------------------------------------------------------------*/
153+static void Image_free( struct DXRubyImage *image )
154+{
155+ /* テクスチャオブジェクトの開放 */
156+ image->texture->refcount--;
157+ if( image->texture->refcount == 0 )
158+ {
159+ RELEASE( image->texture->pD3DTexture );
160+ free( image->texture );
161+ image->texture = NULL;
162+ }
163+}
164+
165+void Image_release( struct DXRubyImage *image )
166+{
167+ if( image->texture )
168+ {
169+ Image_free( image );
170+ }
171+ free( image );
172+ image = NULL;
173+
174+ g_iRefAll--;
175+ if( g_iRefAll == 0 )
176+ {
177+ CoUninitialize();
178+ }
179+}
180+
181+/*--------------------------------------------------------------------
182+ Imageクラスのdispose。
183+ ---------------------------------------------------------------------*/
184+VALUE Image_dispose( VALUE self )
185+{
186+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, self );
187+ DXRUBY_CHECK_DISPOSE( image, texture );
188+ Image_free( image );
189+ return self;
190+}
191+
192+
193+/*--------------------------------------------------------------------
194+ Imageクラスのdisposed?。
195+ ---------------------------------------------------------------------*/
196+static VALUE Image_check_disposed( VALUE self )
197+{
198+ if( DXRUBY_GET_STRUCT( Image, self )->texture == NULL )
199+ {
200+ return Qtrue;
201+ }
202+
203+ return Qfalse;
204+}
205+
206+/*--------------------------------------------------------------------
207+ Imageクラスのdelayed_dispose。
208+ ---------------------------------------------------------------------*/
209+static VALUE Image_delayed_dispose( VALUE self )
210+{
211+ struct DXRubyRenderTarget *rt = DXRUBY_GET_STRUCT( RenderTarget, g_WindowInfo.render_target );
212+ struct DXRubyImage *image = DXRUBY_GET_STRUCT( Image, self );
213+ DXRUBY_CHECK_DISPOSE( image, texture );
214+
215+ rb_ary_push( rt->array, self );
216+
217+ return self;
218+}
219+
220+
221+/*--------------------------------------------------------------------
222+ Imageクラスのallocate。メモリを確保する為にinitialize前に呼ばれる。
223+ ---------------------------------------------------------------------*/
224+VALUE Image_allocate( VALUE klass )
225+{
226+ VALUE obj;
227+ struct DXRubyImage *image;
228+
229+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
230+ image = malloc(sizeof(struct DXRubyImage));
231+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_allocate" );
232+ obj = Data_Wrap_Struct(klass, 0, Image_release, image);
233+
234+ /* とりあえずテクスチャオブジェクトはNULLにしておく */
235+ image->texture = NULL;
236+
237+ return obj;
238+}
239+
240+
241+/*--------------------------------------------------------------------
242+ イメージのデータ設定(内部処理用box描画)
243+ ---------------------------------------------------------------------*/
244+static void fill( int x1, int y1, int x2, int y2, int col, struct DXRubyImage *image )
245+{
246+ D3DLOCKED_RECT texrect;
247+ int x, y;
248+ RECT rect;
249+ int *p;
250+
251+ rect.left = x1 + image->x;
252+ rect.top = y1 + image->y;
253+ rect.right = x2 + image->x + 1;
254+ rect.bottom = y2 + image->y + 1;
255+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
256+ for( y = 0; y <= y2 - y1; y++ )
257+ {
258+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
259+ for( x = 0; x <= x2 - x1; x++ )
260+ {
261+ *(p++) = col;
262+ }
263+ }
264+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
265+ return;
266+}
267+
268+
269+/*--------------------------------------------------------------------
270+ 配列から色取得
271+ ---------------------------------------------------------------------*/
272+static int array2color( VALUE color )
273+{
274+ int col;
275+
276+ Check_Type(color, T_ARRAY);
277+
278+ if( RARRAY_LEN( color ) == 3 )
279+ {
280+ col = D3DCOLOR_ARGB(255, NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)), NUM2INT(rb_ary_entry(color, 2)));
281+ }
282+ else
283+ {
284+ col = D3DCOLOR_ARGB(NUM2INT(rb_ary_entry(color, 0)), NUM2INT(rb_ary_entry(color, 1)),
285+ NUM2INT(rb_ary_entry(color, 2)), NUM2INT(rb_ary_entry(color, 3)));
286+ }
287+ return col;
288+}
289+
290+
291+/*--------------------------------------------------------------------
292+ ImageクラスのInitialize
293+ ---------------------------------------------------------------------*/
294+VALUE Image_initialize( int argc, VALUE *argv, VALUE obj )
295+{
296+ struct DXRubyImage *image;
297+ struct DXRubyTexture *texture;
298+ HRESULT hr;
299+ D3DSURFACE_DESC desc;
300+ VALUE vwidth, vheight, vary;
301+ int col = 0, width, height;
302+
303+ g_iRefAll++;
304+
305+ rb_scan_args( argc, argv, "21", &vwidth, &vheight, &vary );
306+
307+ width = NUM2INT( vwidth );
308+ height = NUM2INT( vheight );
309+
310+ if( width <= 0 || height <= 0 )
311+ {
312+ rb_raise( eDXRubyError, "Imageオブジェクトの作成に失敗しました - Image_initialize" );
313+ }
314+
315+ if( vary != Qnil )
316+ {
317+ Check_Type( vary, T_ARRAY );
318+ col = array2color( vary );
319+ }
320+
321+ /* テクスチャメモリ取得 */
322+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
323+
324+ if( texture == NULL )
325+ {
326+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_initialize" );
327+ }
328+
329+ /* テクスチャオブジェクトを作成する */
330+ hr = D3DXCreateTexture( g_pD3DDevice, width, height,
331+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
332+ &texture->pD3DTexture);
333+
334+ if( FAILED( hr ) )
335+ {
336+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_initialize" );
337+ }
338+
339+ texture->refcount = 1;
340+
341+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
342+ texture->width = desc.Width;
343+ texture->height = desc.Height;
344+
345+ /* Imageオブジェクト設定 */
346+ Data_Get_Struct( obj, struct DXRubyImage, image );
347+
348+ image->texture = texture;
349+ image->x = 0;
350+ image->y = 0;
351+ image->width = width;
352+ image->height = height;
353+
354+ fill( 0, 0, width - 1, height - 1, col, image );
355+
356+ return obj;
357+}
358+
359+
360+/*--------------------------------------------------------------------
361+ Imageクラスのload
362+ ---------------------------------------------------------------------*/
363+static VALUE Image_load( int argc, VALUE *argv, VALUE klass )
364+{
365+ struct DXRubyImage *image;
366+ struct DXRubyTexture *texture;
367+ D3DXIMAGE_INFO srcinfo;
368+ D3DSURFACE_DESC desc;
369+ HRESULT hr;
370+ VALUE vfilename, vx, vy, vwidth, vheight, obj, vsjisstr;
371+ int x, y, width, height;
372+
373+ /* デバイスオブジェクトの初期化チェック */
374+ if( g_pD3DDevice == NULL )
375+ {
376+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
377+ }
378+
379+ rb_scan_args( argc, argv, "14", &vfilename, &vx, &vy, &vwidth, &vheight );
380+
381+ Check_Type(vfilename, T_STRING);
382+
383+ /* ファイル情報取得 */
384+#ifdef HAVE_RB_ENC_STR_NEW
385+ if( rb_enc_get_index( vfilename ) != 0 )
386+ {
387+ vsjisstr = rb_funcall( vfilename, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
388+ }
389+ else
390+ {
391+ vsjisstr = vfilename;
392+ }
393+#else
394+ vsjisstr = vfilename;
395+#endif
396+
397+ hr = D3DXGetImageInfoFromFile( RSTRING_PTR( vsjisstr ), &srcinfo );
398+
399+ if( FAILED( hr ) )
400+ {
401+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", RSTRING_PTR( vsjisstr ) );
402+ }
403+
404+ if( vx == Qnil )
405+ {
406+ x = 0;
407+ y = 0;
408+ width = srcinfo.Width;
409+ height = srcinfo.Height;
410+ }
411+ else
412+ {
413+ x = NUM2INT( vx );
414+ y = vy == Qnil ? 0 : NUM2INT( vy );
415+ if( x < 0 || x >= srcinfo.Width || y < 0 || y >= srcinfo.Height )
416+ {
417+ rb_raise( eDXRubyError, "画像の原点位置が異常値です(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_load", x, y, srcinfo.Width, srcinfo.Height );
418+ }
419+ width = vwidth == Qnil ? srcinfo.Width - x : NUM2INT( vwidth );
420+ height = vheight == Qnil ? srcinfo.Height - y : NUM2INT( vheight );
421+ if( srcinfo.Width - x < width || x + width > srcinfo.Width || srcinfo.Height - y < height || y + height > srcinfo.Height ||
422+ width < 0 || height < 0 )
423+ {
424+ rb_raise( eDXRubyError, "画像のサイズが異常値です - Image_load" );
425+ }
426+ }
427+
428+ /* テクスチャロード */
429+ texture = Image_textureload( RSTRING_PTR( vsjisstr ), &srcinfo );
430+ texture->refcount = 1;
431+
432+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
433+ texture->width = desc.Width;
434+ texture->height = desc.Height;
435+
436+ /* Imageオブジェクト設定 */
437+ image = malloc(sizeof(struct DXRubyImage));
438+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_load" );
439+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
440+
441+ image->texture = texture;
442+ image->x = x;
443+ image->y = y;
444+ image->width = width;
445+ image->height = height;
446+
447+ g_iRefAll++;
448+
449+ return obj;
450+}
451+
452+
453+/*--------------------------------------------------------------------
454+ ImageクラスのloadFromFileInMemory
455+ ---------------------------------------------------------------------*/
456+static VALUE Image_loadFromFileInMemory( VALUE klass, VALUE vstr )
457+{
458+ struct DXRubyImage *image;
459+ struct DXRubyTexture *texture;
460+ D3DXIMAGE_INFO srcinfo;
461+ D3DSURFACE_DESC desc;
462+ HRESULT hr;
463+ VALUE obj;
464+ int size, x, y, width, height;
465+
466+ /* デバイスオブジェクトの初期化チェック */
467+ if( g_pD3DDevice == NULL )
468+ {
469+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
470+ }
471+
472+ Check_Type(vstr, T_STRING);
473+
474+ /* ファイル情報取得 */
475+ size = RSTRING_LEN( vstr );
476+
477+ hr = D3DXGetImageInfoFromFileInMemory( RSTRING_PTR( vstr ), size, &srcinfo );
478+
479+ if( FAILED( hr ) )
480+ {
481+ rb_raise( eDXRubyError, "イメージデータの読み込みに失敗しました - Image_loadFromFileInMemory" );
482+ }
483+
484+ /* テクスチャメモリ取得 */
485+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
486+
487+ if( texture == NULL )
488+ {
489+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_loadFromFileInMemory" );
490+ }
491+
492+ /* ファイルを読み込んでテクスチャオブジェクトを作成する */
493+ hr = D3DXCreateTextureFromFileInMemoryEx( g_pD3DDevice, RSTRING_PTR( vstr ), size, srcinfo.Width, srcinfo.Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
494+ D3DX_DEFAULT, D3DX_DEFAULT, 0,
495+ 0, 0, &texture->pD3DTexture);
496+
497+ if( FAILED( hr ) )
498+ {
499+ rb_raise( eDXRubyError, "イメージデータの読み込みに失敗しました - Image_loadFromFileInMemory" );
500+ }
501+
502+ texture->refcount = 1;
503+
504+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
505+ texture->width = desc.Width;
506+ texture->height = desc.Height;
507+
508+ /* Imageオブジェクト設定 */
509+ image = malloc(sizeof(struct DXRubyImage));
510+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_loadFromFileInMemory" );
511+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
512+
513+ image->texture = texture;
514+ image->x = 0;
515+ image->y = 0;
516+ image->width = srcinfo.Width;
517+ image->height = srcinfo.Height;
518+
519+ g_iRefAll++;
520+
521+ return obj;
522+}
523+
524+
525+/*--------------------------------------------------------------------
526+ Imageオブジェクトの分割作成
527+ ---------------------------------------------------------------------*/
528+static VALUE Image_loadToArray( VALUE klass, VALUE vfilename, VALUE vx, VALUE vy )
529+{
530+ struct DXRubyImage *image;
531+ struct DXRubyTexture *texture;
532+ int i, j, x, y;
533+ VALUE obj;
534+ VALUE varray, vsjisstr;
535+ D3DXIMAGE_INFO srcinfo;
536+ D3DSURFACE_DESC desc;
537+ HRESULT hr;
538+
539+ Check_Type(vfilename, T_STRING);
540+ x = NUM2INT( vx );
541+ y = NUM2INT( vy );
542+
543+ if( x <= 0 || y <= 0 ) rb_raise( eDXRubyError, "画像の数指定が異常値です(x=%d,y=%d) - Image_loadToArray", x, y );
544+
545+ /* ファイル情報取得 */
546+#ifdef HAVE_RB_ENC_STR_NEW
547+ if( rb_enc_get_index( vfilename ) != 0 )
548+ {
549+ vsjisstr = rb_funcall( vfilename, rb_intern( "encode" ), 1, rb_str_new2( sys_encode ) );
550+ }
551+ else
552+ {
553+ vsjisstr = vfilename;
554+ }
555+#else
556+ vsjisstr = vfilename;
557+#endif
558+ hr = D3DXGetImageInfoFromFile( RSTRING_PTR( vsjisstr ), &srcinfo );
559+
560+ if( FAILED( hr ) )
561+ {
562+ rb_raise( eDXRubyError, "ファイルの読み込みに失敗しました - %s", RSTRING_PTR( vsjisstr ) );
563+ }
564+
565+ /* テクスチャロード */
566+ texture = Image_textureload( RSTRING_PTR( vsjisstr ), &srcinfo );
567+ texture->refcount = x * y;
568+
569+ texture->pD3DTexture->lpVtbl->GetLevelDesc(texture->pD3DTexture, 0, &desc );
570+ texture->width = desc.Width;
571+ texture->height = desc.Height;
572+
573+ /* Ruby配列作成 */
574+ varray = rb_ary_new();
575+
576+ for( i = 0; i < y; i++ )
577+ {
578+ for( j = 0; j < x; j++ )
579+ {
580+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
581+ image = malloc(sizeof(struct DXRubyImage));
582+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_loadToArray" );
583+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
584+
585+ image->texture = texture;
586+ image->x = j * srcinfo.Width / x;
587+ image->y = i * srcinfo.Height / y;
588+ image->width = srcinfo.Width / x;
589+ image->height = srcinfo.Height / y;
590+
591+ rb_ary_push(varray, obj);
592+ g_iRefAll++;
593+ }
594+ }
595+
596+ return varray;
597+}
598+
599+
600+/*--------------------------------------------------------------------
601+ 配列からイメージを作る
602+ ---------------------------------------------------------------------*/
603+static VALUE Image_createFromArray( VALUE klass, VALUE vwidth, VALUE vheight, VALUE array )
604+{
605+ struct DXRubyImage *image;
606+ struct DXRubyTexture *texture;
607+ HRESULT hr;
608+ int i, j, x, y;
609+ D3DLOCKED_RECT LockedRect;
610+ VALUE obj;
611+ int width, height;
612+ D3DSURFACE_DESC desc;
613+
614+ /* デバイスオブジェクトの初期化チェック */
615+ if( g_pD3DDevice == NULL )
616+ {
617+ rb_raise( eDXRubyError, "DirectX Graphicsが初期化されていません" );
618+ }
619+
620+ width = NUM2INT( vwidth );
621+ height = NUM2INT( vheight );
622+ Check_Type(array, T_ARRAY);
623+
624+ if( width <= 0 || height <= 0 ) rb_raise( eDXRubyError, "画像のサイズ指定が異常値です(width=%d,height=%d) - Image_loadToArray", width, height );
625+
626+ /* テクスチャメモリ取得 */
627+ texture = (struct DXRubyTexture *)malloc( sizeof( struct DXRubyTexture ) );
628+ if( texture == NULL )
629+ {
630+ rb_raise( eDXRubyError, "画像用メモリの取得に失敗しました - Image_textureload" );
631+ }
632+
633+ /* テクスチャサイズ割り出し */
634+ for( x = 1; x < width; x = x * 2 );
635+ for( y = 1; y < height; y = y * 2 );
636+
637+ /* テクスチャオブジェクトを作成する */
638+ hr = D3DXCreateTexture( g_pD3DDevice, x, y,
639+ 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
640+ &texture->pD3DTexture);
641+ if( FAILED( hr ) )
642+ {
643+ rb_raise( eDXRubyError, "テクスチャの作成に失敗しました - Image_initialize" );
644+ }
645+
646+ /* テクスチャロック */
647+ hr = texture->pD3DTexture->lpVtbl->LockRect( texture->pD3DTexture, 0, &LockedRect, NULL, 0 );
648+ if( FAILED( hr ) )
649+ {
650+ rb_raise( eDXRubyError, "サーフェイスのロックに失敗しました - LockRect" );
651+ }
652+
653+ /* 書き込み */
654+ for( i = 0; i < height; i++ )
655+ {
656+ for( j = 0; j < width * 4; j += 4 )
657+ {
658+ int a1 = NUM2INT(rb_ary_entry(array, j + i * width * 4));
659+ int a2 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 1));
660+ int a3 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 2));
661+ int a4 = NUM2INT(rb_ary_entry(array, j + i * width * 4 + 3));
662+ *((int*)((char *)LockedRect.pBits + j + i * LockedRect.Pitch)) = D3DCOLOR_ARGB(a1, a2, a3, a4);
663+ }
664+ }
665+
666+ /* テクスチャアンロック */
667+ texture->pD3DTexture->lpVtbl->UnlockRect( texture->pD3DTexture, 0 );
668+
669+ texture->refcount = 1;
670+ texture->pD3DTexture->lpVtbl->GetLevelDesc( texture->pD3DTexture, 0, &desc );
671+ texture->width = desc.Width;
672+ texture->height = desc.Height;
673+
674+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
675+ image = malloc(sizeof(struct DXRubyImage));
676+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_createFromArray" );
677+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
678+
679+ image->texture = texture;
680+ image->x = 0;
681+ image->y = 0;
682+ image->width = width;
683+ image->height = height;
684+
685+ g_iRefAll++;
686+
687+ return obj;
688+}
689+
690+
691+/*--------------------------------------------------------------------
692+ Imageオブジェクトのslice
693+ ---------------------------------------------------------------------*/
694+static VALUE Image_slice_instance( int argc, VALUE *argv, VALUE vsrcimage )
695+{
696+ struct DXRubyImage *srcimage;
697+ struct DXRubyImage *image;
698+ struct DXRubyTexture *texture;
699+ D3DXIMAGE_INFO srcinfo;
700+ HRESULT hr;
701+ VALUE vx, vy, vwidth, vheight, obj;
702+ int x, y, width, height;
703+
704+ rb_scan_args( argc, argv, "04", &vx, &vy, &vwidth, &vheight );
705+
706+ Data_Get_Struct( vsrcimage, struct DXRubyImage, srcimage );
707+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
708+
709+ if( vx == Qnil )
710+ {
711+ x = 0;
712+ y = 0;
713+ width = srcimage->width;
714+ height = srcimage->height;
715+ }
716+ else
717+ {
718+ x = NUM2INT( vx );
719+ y = vy == Qnil ? 0 : NUM2INT( vy );
720+ if( x < 0 || x >= srcimage->width || y < 0 || y >= srcimage->height )
721+ {
722+ rb_raise( eDXRubyError, "画像の原点位置が異常値です(x=%d,y=%d, tex_width=%d,tex_height=%d) - Image_slice", x, y, srcimage->width, srcimage->height );
723+ }
724+ width = vwidth == Qnil ? srcimage->width - x : NUM2INT( vwidth );
725+ height = vheight == Qnil ? srcimage->height - y : NUM2INT( vheight );
726+ if( srcimage->width - x < width || x + width > srcimage->width || srcimage->height - y < height || y + height > srcimage->height ||
727+ width < 0 || height < 0 )
728+ {
729+ rb_raise( eDXRubyError, "画像のサイズが異常値です - Image_slice" );
730+ }
731+ }
732+
733+ /* テクスチャロード */
734+ texture = srcimage->texture;
735+ texture->refcount += 1;
736+
737+ /* Imageオブジェクト設定 */
738+ image = malloc(sizeof(struct DXRubyImage));
739+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_slice" );
740+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
741+
742+ image->texture = texture;
743+ image->x = x + srcimage->x;
744+ image->y = y + srcimage->y;
745+ image->width = width;
746+ image->height = height;
747+
748+ g_iRefAll++;
749+
750+ /* Imageのコピー */
751+ return Image_initialize_copy( Image_allocate( cImage ), obj );
752+}
753+
754+
755+/*--------------------------------------------------------------------
756+ ImgaeオブジェクトのsliceToArray
757+ ---------------------------------------------------------------------*/
758+static VALUE Image_sliceToArray( VALUE self, VALUE vx, VALUE vy )
759+{
760+ struct DXRubyImage *srcimage;
761+ struct DXRubyTexture *texture;
762+ HRESULT hr;
763+ int x, y, i, j;
764+ VALUE array, obj;
765+
766+ x = NUM2INT( vx );
767+ y = NUM2INT( vy );
768+
769+ if( x <= 0 || y <= 0 ) rb_raise( eDXRubyError, "画像の数指定が異常値です(x=%d,y=%d) - Image_sliceToArray", x, y );
770+
771+ /* 元Imageのチェック */
772+ Data_Get_Struct( self, struct DXRubyImage, srcimage );
773+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
774+
775+ /* 元Imageのコピー */
776+ obj = Image_initialize_copy( Image_allocate( cImage ), self );
777+
778+ /* コピーしたImageからslice */
779+ Data_Get_Struct( obj, struct DXRubyImage, srcimage );
780+ DXRUBY_CHECK_DISPOSE( srcimage, texture );
781+
782+ texture = srcimage->texture;
783+ texture->refcount += x * y;
784+
785+ /* Ruby配列作成 */
786+ array = rb_ary_new();
787+
788+ for( i = 0; i < y; i++ )
789+ {
790+ for( j = 0; j < x; j++ )
791+ {
792+ /* DXRubyImageのメモリ取得&Imageオブジェクト生成 */
793+ struct DXRubyImage *image = malloc(sizeof(struct DXRubyImage));
794+ if( image == NULL ) rb_raise( eDXRubyError, "メモリの取得に失敗しました - Image_sliceToArray" );
795+ obj = Data_Wrap_Struct(cImage, 0, Image_release, image);
796+
797+ image->texture = texture;
798+ image->x = srcimage->x + j * srcimage->width / x;
799+ image->y = srcimage->y + i * srcimage->height / y;
800+ image->width = srcimage->width / x;
801+ image->height = srcimage->height / y;
802+
803+ rb_ary_push( array, obj );
804+ g_iRefAll++;
805+ }
806+ }
807+
808+ return array;
809+}
810+
811+
812+/*--------------------------------------------------------------------
813+ イメージのデータ取得
814+ ---------------------------------------------------------------------*/
815+static VALUE Image_getPixel( VALUE obj, VALUE vx, VALUE vy )
816+{
817+ struct DXRubyImage *image;
818+ VALUE ary[4];
819+ struct DXRubyColor a;
820+ D3DLOCKED_RECT texrect;
821+ int x, y;
822+ RECT rect;
823+
824+ x = NUM2INT( vx );
825+ y = NUM2INT( vy );
826+
827+ Data_Get_Struct( obj, struct DXRubyImage, image );
828+ DXRUBY_CHECK_DISPOSE( image, texture );
829+
830+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
831+ {
832+ ary[0] = ary[1] = ary[2] = ary[3] = INT2FIX( 0 );
833+ return rb_ary_new4( 4, ary );
834+ }
835+
836+ rect.left = x + image->x;
837+ rect.top = y + image->y;
838+ rect.right = x + image->x + 1;
839+ rect.bottom = y + image->y + 1;
840+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
841+
842+ a = *(struct DXRubyColor *)texrect.pBits;
843+
844+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
845+
846+ ary[0] = INT2FIX( a.alpha );
847+ ary[1] = INT2FIX( a.red );
848+ ary[2] = INT2FIX( a.green );
849+ ary[3] = INT2FIX( a.blue );
850+
851+ return rb_ary_new4( 4, ary );
852+}
853+
854+
855+/*--------------------------------------------------------------------
856+ イメージのデータ設定
857+ ---------------------------------------------------------------------*/
858+static VALUE Image_setPixel( VALUE obj, VALUE vx, VALUE vy, VALUE color )
859+{
860+ struct DXRubyImage *image;
861+ int a1, a2, a3, a4;
862+ D3DLOCKED_RECT texrect;
863+ int x, y;
864+ RECT rect;
865+
866+ x = NUM2INT( vx );
867+ y = NUM2INT( vy );
868+ Check_Type(color, T_ARRAY);
869+
870+ Data_Get_Struct( obj, struct DXRubyImage, image );
871+ DXRUBY_CHECK_DISPOSE( image, texture );
872+
873+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
874+ {
875+ return obj;
876+ }
877+
878+ rect.left = x + image->x;
879+ rect.top = y + image->y;
880+ rect.right = x + image->x + 1;
881+ rect.bottom = y + image->y + 1;
882+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
883+
884+ *((int*)((char *)texrect.pBits)) = array2color( color );
885+
886+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
887+
888+ return obj;
889+}
890+
891+
892+/*--------------------------------------------------------------------
893+ イメージの色比較
894+ ---------------------------------------------------------------------*/
895+static VALUE Image_compare( VALUE obj, VALUE vx, VALUE vy, VALUE color )
896+{
897+ struct DXRubyImage *image;
898+ DWORD a;
899+ D3DLOCKED_RECT texrect;
900+ int x, y, col;
901+ int a1, a2, a3, a4;
902+ RECT rect;
903+
904+ x = NUM2INT( vx );
905+ y = NUM2INT( vy );
906+ Check_Type(color, T_ARRAY);
907+
908+ Data_Get_Struct( obj, struct DXRubyImage, image );
909+ DXRUBY_CHECK_DISPOSE( image, texture );
910+
911+ if( x < 0 || x >= image->width || y < 0 || y >= image->height )
912+ {
913+ return INT2FIX( 0 );
914+ }
915+
916+ col = array2color( color );
917+
918+ rect.left = x + image->x;
919+ rect.top = y + image->y;
920+ rect.right = x + image->x + 1;
921+ rect.bottom = y + image->y + 1;
922+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, D3DLOCK_READONLY );
923+
924+ a = *(LPDWORD)texrect.pBits;
925+
926+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
927+
928+ if( RARRAY_LEN( color ) == 3 )
929+ {
930+
931+ if( (a & 0x00ffffff) == ((DWORD)col & 0x00ffffff) )
932+ {
933+ return Qtrue;
934+ }
935+ else
936+ {
937+ return Qfalse;
938+ }
939+ }
940+ else
941+ {
942+ if( a == (DWORD)col )
943+ {
944+ return Qtrue;
945+ }
946+ else
947+ {
948+ return Qfalse;
949+ }
950+ }
951+}
952+
953+
954+/*--------------------------------------------------------------------
955+ イメージのデータ設定(box描画塗りつぶさない)
956+ ---------------------------------------------------------------------*/
957+static VALUE Image_box( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
958+{
959+ struct DXRubyImage *image;
960+ D3DLOCKED_RECT texrect;
961+ int x, y, x1, y1, x2, y2;
962+ int col;
963+ RECT rect;
964+
965+ Data_Get_Struct( obj, struct DXRubyImage, image );
966+ DXRUBY_CHECK_DISPOSE( image, texture );
967+
968+ x1 = NUM2INT( vx1 );
969+ y1 = NUM2INT( vy1 );
970+ x2 = NUM2INT( vx2 );
971+ y2 = NUM2INT( vy2 );
972+
973+ /* 左上から右下の指定に修正 */
974+ if( x1 > x2 )
975+ {
976+ x = x2;
977+ x2 = x1;
978+ x1 = x;
979+ }
980+ if( y1 > y2 )
981+ {
982+ y = y2;
983+ y2 = y1;
984+ y1 = y;
985+ }
986+
987+ /* 範囲外の指定は無視 */
988+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
989+ {
990+ return obj;
991+ }
992+
993+ /* クリップ */
994+ if( x1 < 0 )
995+ {
996+ x1 = 0;
997+ }
998+ if( x2 > image->width - 1 )
999+ {
1000+ x2 = image->width - 1;
1001+ }
1002+ if( y1 < 0 )
1003+ {
1004+ y1 = 0;
1005+ }
1006+ if( y2 > image->height - 1 )
1007+ {
1008+ y2 = image->height - 1;
1009+ }
1010+
1011+ Check_Type(color, T_ARRAY);
1012+ col = array2color( color );
1013+
1014+ rect.left = x1 + image->x;
1015+ rect.top = y1 + image->y;
1016+ rect.right = x2 + image->x + 1;
1017+ rect.bottom = y2 + image->y + 1;
1018+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1019+ for( y = 0; y <= y2 - y1; y++ )
1020+ {
1021+ *((int*)((char *)texrect.pBits + y * texrect.Pitch)) = col;
1022+ *((int*)((char *)texrect.pBits + (x2 - x1)* 4 + y * texrect.Pitch)) = col;
1023+ }
1024+ for( x = 0; x <= x2 - x1; x++ )
1025+ {
1026+ *((int*)((char *)texrect.pBits + x * 4)) = col;
1027+ *((int*)((char *)texrect.pBits + x * 4 + (y2 - y1) * texrect.Pitch)) = col;
1028+ }
1029+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1030+
1031+ return obj;
1032+}
1033+
1034+
1035+/*--------------------------------------------------------------------
1036+ イメージのデータ設定(box描画塗りつぶす)
1037+ ---------------------------------------------------------------------*/
1038+static VALUE Image_boxFill( VALUE obj, VALUE vx1, VALUE vy1, VALUE vx2, VALUE vy2, VALUE color )
1039+{
1040+ struct DXRubyImage *image;
1041+ int x, y, x1, y1, x2, y2;
1042+ int col;
1043+
1044+ Data_Get_Struct( obj, struct DXRubyImage, image );
1045+ DXRUBY_CHECK_DISPOSE( image, texture );
1046+
1047+ x1 = NUM2INT( vx1 );
1048+ y1 = NUM2INT( vy1 );
1049+ x2 = NUM2INT( vx2 );
1050+ y2 = NUM2INT( vy2 );
1051+
1052+ /* 左上から右下の指定に修正 */
1053+ if( x1 > x2 )
1054+ {
1055+ x = x2;
1056+ x2 = x1;
1057+ x1 = x;
1058+ }
1059+ if( y1 > y2 )
1060+ {
1061+ y = y2;
1062+ y2 = y1;
1063+ y1 = y;
1064+ }
1065+
1066+ /* 範囲外の指定は無視 */
1067+ if( x1 > image->width - 1 || x2 < 0 || y1 > image->height - 1 || y2 < 0)
1068+ {
1069+ return obj;
1070+ }
1071+
1072+ /* クリップ */
1073+ if( x1 < 0 )
1074+ {
1075+ x1 = 0;
1076+ }
1077+ if( x2 > image->width - 1 )
1078+ {
1079+ x2 = image->width - 1;
1080+ }
1081+ if( y1 < 0 )
1082+ {
1083+ y1 = 0;
1084+ }
1085+ if( y2 > image->height - 1 )
1086+ {
1087+ y2 = image->height - 1;
1088+ }
1089+
1090+ Check_Type(color, T_ARRAY);
1091+ col = array2color( color );
1092+
1093+ fill( x1, y1, x2, y2, col, image );
1094+
1095+ return obj;
1096+}
1097+
1098+
1099+/*--------------------------------------------------------------------
1100+ イメージのデータ設定(全部塗りつぶす)
1101+ ---------------------------------------------------------------------*/
1102+static VALUE Image_fill( VALUE obj, VALUE color )
1103+{
1104+ struct DXRubyImage *image;
1105+ int col;
1106+
1107+ Data_Get_Struct( obj, struct DXRubyImage, image );
1108+ DXRUBY_CHECK_DISPOSE( image, texture );
1109+
1110+ Check_Type(color, T_ARRAY);
1111+ col = array2color( color );
1112+
1113+ fill( 0, 0, image->width-1, image->height-1, col, image );
1114+
1115+ return obj;
1116+}
1117+
1118+
1119+/*--------------------------------------------------------------------
1120+ イメージのカラーキー設定。実体は指定色を透明に。
1121+ ---------------------------------------------------------------------*/
1122+static VALUE Image_setColorKey( VALUE obj, VALUE color )
1123+{
1124+ struct DXRubyImage *image;
1125+ int col;
1126+ D3DLOCKED_RECT texrect;
1127+ int x, y;
1128+ RECT rect;
1129+ int *p;
1130+
1131+ Data_Get_Struct( obj, struct DXRubyImage, image );
1132+ DXRUBY_CHECK_DISPOSE( image, texture );
1133+
1134+ Check_Type(color, T_ARRAY);
1135+ col = array2color( color ) & 0x00ffffff;
1136+
1137+ rect.left = image->x;
1138+ rect.top = image->y;
1139+ rect.right = image->x + image->width;
1140+ rect.bottom = image->y + image->height;
1141+ image->texture->pD3DTexture->lpVtbl->LockRect( image->texture->pD3DTexture, 0, &texrect, &rect, 0 );
1142+ for( y = 0; y < image->height; y++ )
1143+ {
1144+ p = (int*)((char *)texrect.pBits + y * texrect.Pitch);
1145+ for( x = 0; x < image->width; x++ )
1146+ {
1147+ if( (*p & 0x00ffffff) == col )
1148+ {
1149+ *p = col;
1150+ }
1151+ p++;
1152+ }
1153+ }
1154+ image->texture->pD3DTexture->lpVtbl->UnlockRect( image->texture->pD3DTexture, 0 );
1155+
1156+ return obj;
1157+}
1158+
1159+
1160+/*--------------------------------------------------------------------
1161+ イメージのデータ設定(circle用のline描画)
1162+ ---------------------------------------------------------------------*/
1163+static void Image_circle_line( int x1, int x2, int y, RECT *rect, int col, D3DLOCKED_RECT *texrect )
1164+{
1165+ int x;
1166+ int *p;
1167+
1168+ if( y < 0 || y >= rect->bottom - rect->top )
1169+ {
1170+ return;
1171+ }
1172+
1173+ /* クリップ */
1174+ if( x1 < 0 )
1175+ {
1176+ x1 = 0;
1177+ }
1178+ if( x2 > rect->right - rect->left - 1 )
1179+ {
1180+ x2 = rect->r