OSDN Git Service

74d55926be870c6550e894b51e01f09bb896e756
[winaudioj/stedx.git] / sf_windows.h
1 #pragma once
2 /*
3   ==============================================================================
4
5    This file is part of the Shooting3
6    Copyright 2005-7 by Satoshi Fujiwara.
7
8    Shooting3 can be redistributed and/or modified under the terms of the
9    GNU General Public License, as published by the Free Software Foundation;
10    either version 2 of the License, or (at your option) any later version.
11
12    S.F.Tracker is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with S.F.Tracker; if not, visit www.gnu.org/licenses or write to the
19    Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
20    Boston, MA 02111-1307 USA
21
22   ==============================================================================
23 */
24 // Windows Header Files:
25 #include "exception.h"
26 #include "xbyak.h"
27 //#include "input.h"
28
29 _COM_SMARTPTR_TYPEDEF(ID2D1Factory,__uuidof(ID2D1Factory));
30 _COM_SMARTPTR_TYPEDEF(IWICImagingFactory, __uuidof(IWICImagingFactory));
31 _COM_SMARTPTR_TYPEDEF(IDWriteFactory , __uuidof(IDWriteFactory));
32 _COM_SMARTPTR_TYPEDEF(IDWriteGdiInterop , __uuidof(IDWriteGdiInterop));
33 _COM_SMARTPTR_TYPEDEF(IDWriteFontFace , __uuidof(IDWriteFontFace));
34 _COM_SMARTPTR_TYPEDEF(IDWriteFont , __uuidof(IDWriteFont));
35 _COM_SMARTPTR_TYPEDEF(IDWriteFontFamily , __uuidof(IDWriteFontFamily));
36 _COM_SMARTPTR_TYPEDEF(IDWriteFontCollection , __uuidof(IDWriteFontCollection));
37 _COM_SMARTPTR_TYPEDEF(IDWriteLocalizedStrings , __uuidof(IDWriteLocalizedStrings));
38 _COM_SMARTPTR_TYPEDEF(ID2D1HwndRenderTarget , __uuidof(ID2D1HwndRenderTarget));
39 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapRenderTarget , __uuidof(ID2D1BitmapRenderTarget));
40 _COM_SMARTPTR_TYPEDEF(ID2D1GdiInteropRenderTarget , __uuidof(ID2D1GdiInteropRenderTarget));
41 _COM_SMARTPTR_TYPEDEF(IDWriteTextFormat, __uuidof(IDWriteTextFormat));
42 _COM_SMARTPTR_TYPEDEF(IDWriteTextLayout, __uuidof(IDWriteTextLayout));
43 _COM_SMARTPTR_TYPEDEF(ID2D1PathGeometry , __uuidof(ID2D1PathGeometry));
44 _COM_SMARTPTR_TYPEDEF(ID2D1LinearGradientBrush , __uuidof(ID2D1LinearGradientBrush));
45 _COM_SMARTPTR_TYPEDEF(ID2D1GradientStopCollection , __uuidof(ID2D1GradientStopCollection));
46 _COM_SMARTPTR_TYPEDEF(ID2D1SolidColorBrush , __uuidof(ID2D1SolidColorBrush));
47 _COM_SMARTPTR_TYPEDEF(ID2D1BitmapBrush , __uuidof(ID2D1BitmapBrush));
48 _COM_SMARTPTR_TYPEDEF(ID2D1Bitmap , __uuidof(ID2D1Bitmap));
49 _COM_SMARTPTR_TYPEDEF(IWICBitmapDecoder,__uuidof(IWICBitmapDecoder));
50 _COM_SMARTPTR_TYPEDEF(IWICBitmapFrameDecode,__uuidof(IWICBitmapFrameDecode));
51 _COM_SMARTPTR_TYPEDEF(IWICStream,__uuidof(IWICStream));
52 _COM_SMARTPTR_TYPEDEF(IWICFormatConverter,__uuidof(IWICFormatConverter));
53 _COM_SMARTPTR_TYPEDEF(IWICBitmapScaler,__uuidof(IWICBitmapScaler));
54
55 template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
56 {
57   if(ptr)
58   {
59     ptr.Release();
60   }
61 };
62
63
64
65 namespace sf{
66
67 ID2D1BitmapPtr load_bitmap_from_file(
68     ID2D1HwndRenderTargetPtr render_target,
69     IWICImagingFactoryPtr wic_factory,
70         std::wstring uri,
71         boost::uint32_t destination_width = 0,
72         boost::uint32_t destination_height = 0
73     );
74
75 /** WNDCLASSEXラッパクラス */
76 struct window_class_ex
77 {
78         window_class_ex(
79                 const wchar_t*  menu_name ,
80                 const std::wstring&  class_name ,
81                 HINSTANCE   hInstance = NULL,
82                 WNDPROC     lpfnWndProc = ::DefWindowProcW,
83                 boost::uint32_t        style = CS_HREDRAW | CS_VREDRAW,
84                 boost::int32_t     cbClsExtra  = 0,
85                 HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
86                 HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
87                 HBRUSH      hbrBackground = NULL,
88                 HICON       hIconSm = NULL
89                 ) : is_register_(false)
90         {
91
92                 if(::GetClassInfoExW(hInstance,class_name.c_str(),&wndclass_) == 0)
93                 {
94                         if(::GetLastError() == ERROR_CLASS_DOES_NOT_EXIST)
95                         { 
96                                 ::ZeroMemory(&wndclass_,sizeof(wndclass_));
97                                 wndclass_.lpszMenuName = (LPCWSTR)menu_name;
98                                 wndclass_.lpszClassName = class_name.c_str();
99                                 wndclass_.cbSize = sizeof(::WNDCLASSEXW);
100                                 wndclass_.cbWndExtra = sizeof(LONG_PTR);
101                                 wndclass_.hInstance = hInstance;
102                                 wndclass_.lpfnWndProc = lpfnWndProc;
103                                 wndclass_.style = style;
104                                 wndclass_.cbClsExtra = cbClsExtra;
105                                 wndclass_.hIcon = hIcon;
106                                 wndclass_.hCursor = hCursor;
107                                 wndclass_.hbrBackground = hbrBackground;
108                                 wndclass_.hIconSm = hIconSm;
109                                 atom_ = ::RegisterClassExW(&wndclass_) ;
110                                 BOOST_ASSERT(atom_ != 0);
111                                 is_register_ = true;
112                         } else {
113                                 throw win32_error_exception();
114                         }
115                 } else {
116                         is_register_ = false;
117                 }
118         };
119         
120         ~window_class_ex()
121         {
122                 if(is_register_){
123                         ::UnregisterClassW(wndclass_.lpszClassName,wndclass_.hInstance);
124                 }
125         }
126
127 private:
128         bool is_register_;
129         ATOM atom_;
130         ::WNDCLASSEXW wndclass_;
131 };
132
133
134
135 struct get_dc {
136         get_dc(HWND hwnd) : hwnd_(hwnd),hdc_(GetDC(hwnd)) {}
137         HDC get(){return hdc_;}
138         ~get_dc(){::ReleaseDC(hwnd_,hdc_);}
139 private:
140         HDC hdc_;
141         HWND hwnd_;
142 };
143
144 struct compatible_dc {
145         compatible_dc(HDC hdc) : hdc_(::CreateCompatibleDC(hdc)){}; 
146         ~compatible_dc(){::DeleteDC(hdc_);};
147         HDC get() { return hdc_;};
148 private:
149         HDC hdc_;
150 };
151
152 struct ref_dc {
153         ref_dc(HDC& hdc) : hdc_(hdc) {};
154         ~ref_dc(){};
155         HDC get() { return hdc_;};
156 private:
157         HDC& hdc_;
158 };
159
160 struct d2_dc {
161         d2_dc(ID2D1GdiInteropRenderTargetPtr& ptr,D2D1_DC_INITIALIZE_MODE mode) :hdc_(0),ptr_(ptr)
162   {
163     hr_ = ptr->GetDC(mode,&hdc_);
164   };
165         ~d2_dc(){ptr_->ReleaseDC(NULL);};
166         HDC get() { return hdc_;};
167 private:
168   HRESULT hr_;
169         HDC hdc_;
170   ID2D1GdiInteropRenderTargetPtr& ptr_;
171 };
172
173 template <typename Holder>
174 struct device_context
175 {
176         explicit device_context(Holder* holder) : holder_(holder){};
177         ~device_context() {}
178         operator HDC(){return holder_->get();}
179 private:
180         boost::scoped_ptr<Holder> holder_;
181 };
182
183 typedef device_context<d2_dc> d2_dc_type;
184
185 struct paint_struct 
186 {
187         paint_struct(HWND hwnd) : hwnd_(hwnd)
188         {
189                 ::BeginPaint(hwnd,&paintstruct_);
190         }
191         ~paint_struct() {::EndPaint(hwnd_,&paintstruct_);}
192         PAINTSTRUCT* operator->(){return &paintstruct_;}
193 private:
194         HWND hwnd_;
195         PAINTSTRUCT paintstruct_;
196 };
197
198 template <typename T>
199 struct begin_draw
200 {
201         begin_draw(T& render_target) : render_target_(render_target) ,is_end_(false) {render_target->BeginDraw();}
202         HRESULT end_draw() 
203         {
204                 HRESULT hr = S_OK;
205                 if(!is_end_) { 
206                         hr = render_target_->EndDraw();
207                         is_end_ = true;
208                 }
209
210                 return hr;
211         };
212         ~begin_draw(){ if(!is_end_) { render_target_->EndDraw();}}
213 private:
214         T& render_target_;
215         bool is_end_;
216 };
217
218 struct mouse
219 {
220         mouse() : x_(0.0f),y_(0.0f),left_button_(false),middle_button_(false),right_button_(false){}
221 private:
222         float x_,y_;
223         bool left_button_,middle_button_,right_button_;
224 };
225
226 /** window ベースクラス */
227 struct base_window 
228 {
229         typedef boost::signals2::signal<LRESULT (HWND,boost::uint32_t,WPARAM, LPARAM) > on_message_type;
230         on_message_type on_message;
231         typedef boost::signals2::signal<void ()> on_render_type;
232         on_render_type on_render;
233         operator HWND();
234 protected:
235         base_window(
236                 const std::wstring& title,
237                 const std::wstring& name,bool fit_to_display,
238                 float width,float height);
239         ~base_window();
240         void register_class (
241                 wchar_t* menu_name,
242                 boost::uint32_t style, 
243                 boost::int32_t     cbClsExtra  = 0,
244                 HICON       hIcon = ::LoadIcon(NULL,IDI_APPLICATION),
245                 HCURSOR     hCursor = ::LoadCursor(NULL, IDC_ARROW),
246                 HBRUSH      hbrBackground = NULL,
247                 HICON       hIconSm = NULL
248         );              
249
250         /** デフォルト設定 */
251         void register_class();
252         void create_window();
253         void update();
254         void show(boost::uint32_t show_flag);
255         virtual void discard_device();
256         virtual void create_device();
257         virtual void create_device_independent_resources();
258         //ID2D1FactoryPtr factory();
259         //ID2D1HwndRenderTargetPtr render_target();
260         //IDWriteFactoryPtr write_factory();
261
262         virtual LRESULT window_proc(HWND hwnd,boost::uint32_t message, WPARAM wParam, LPARAM lParam);
263 protected:
264         static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
265         {
266                 base_window* ptr = reinterpret_cast<base_window*>(hwnd);
267                 hwnd = ptr->hwnd_;
268                 return ptr->window_proc(hwnd,message,wParam,lParam);
269         };
270
271         struct hwnd_this_thunk : public Xbyak::CodeGenerator {
272                 hwnd_this_thunk(base_window* impl,WNDPROC proc)
273                 {
274                         push(eax);
275                         mov(eax,ptr[esp + 8]);
276                         mov(ptr[&(impl->hwnd_)],eax);
277                         mov(eax,(DWORD)impl);
278                         mov(ptr[esp + 8],eax);
279                         pop(eax);
280                         jmp(proc);
281                 }
282         };
283
284         //ID3D11DevicePtr                               d3d_device_;
285         //D3D_DRIVER_TYPE                       driver_type_;
286         //D3D_FEATURE_LEVEL             feature_level_;
287         //IDXGISwapChainPtr                     swap_chain_;
288         //ID3D11DeviceContextPtr        device_context_;
289         //ID3D11RenderTargetViewPtr             render_target_view_;
290         //ID3DX11EffectPtr                              effect_;
291         //ID3DX11EffectTechnique*               technique_;
292         //ID3D11InputLayoutPtr          vertex_layout_;
293         //ID3D11BufferPtr                               vertex_buffer_;
294         //ID3D11BufferPtr             index_buffer_;
295         //ID3D11ShaderResourceViewPtr         texture_rv_;
296         //ID3D11ShaderResourceViewPtr                   sprite_tex_;
297         //ID3DX11EffectMatrixVariable*       world_variable_;
298         //ID3DX11EffectMatrixVariable*         view_variable_;
299         //ID3DX11EffectMatrixVariable*         projection_variable_;
300         //ID3DX11EffectVectorVariable*         mesh_color_variable_;
301         //ID3DX11EffectShaderResourceVariable* diffuse_variable_;
302         //D3DXMATRIX                          world_;
303         //D3DXMATRIX                          view_;
304         //D3DXMATRIX                          projection_;
305         //D3DXVECTOR4                         mesh_color_;
306         //ID3DX10SpritePtr                                      sprite_;
307         //D3DX10_SPRITE                                         sprite_buffer_[1];
308         //ID3D11BlendStatePtr                                   sprite_blend_state_;
309
310         HWND hwnd_;
311         ID2D1FactoryPtr factory_;
312 //      ID2D1DCRenderTargetPtr render_target_;
313         ID2D1HwndRenderTargetPtr render_target_;
314         IDWriteFactoryPtr write_factory_;
315         IWICImagingFactoryPtr wic_imaging_factory_;
316         //ID2D1BitmapPtr bitmap_;
317         hwnd_this_thunk thunk_;
318         std::wstring title_;
319         std::wstring name_;
320         float width_,height_;
321         bool fit_to_display_;
322         boost::shared_ptr<sf::window_class_ex> wnd_class_;
323         WNDPROC thunk_proc_;
324 //      boost::shared_ptr<input> input_;
325 };
326
327 //struct toplevel_window;
328 //typedef boost::shared_ptr<toplevel_window> toplevel_window_ptr;
329 //
330 ///** toplevel_window を生成する関数 */
331 //toplevel_window_ptr create_toplevel_window (
332 //  const std::wstring& menu_name,
333 //  const std::wstring& name,
334 //  const boost::uint32_t show_flag = SW_SHOWNORMAL,
335 //  bool fit_to_display = false,
336 //  float width = 640,
337 //  float height = 480
338 //);
339 //
340 //
341 //
342 ///** toplevel ウィンドウクラス */
343 ///* このクラスは、create_toplevel_window 関数からのみ生成可能 */
344 //struct toplevel_window : public base_window
345 //{
346 //  friend   toplevel_window_ptr create_toplevel_window
347 //  (
348 //        const std::wstring& menu_name,
349 //        const std::wstring& name,
350 //        const boost::uint32_t show_flag,
351 //        bool fit_to_display ,
352 //        float width ,
353 //        float height
354 //  );
355 //      void main_loop();
356 //protected:
357 //      void render();
358 //      toplevel_window(const std::wstring& menu_name,const std::wstring& name,bool fit_to_display,float width = 640,float height = 480) : base_window(menu_name,name,fit_to_display,width,height) 
359 //      {
360 //              on_render.connect(boost::bind(&toplevel_window::render,this));
361 //      };
362 //      LRESULT toplevel_window::window_proc(HWND hwnd,boost::uint32_t message, WPARAM wParam, LPARAM lParam);
363 //};
364
365 struct av_mm_thread_characteristics
366 {
367         av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
368         {
369                 handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
370         }
371
372         bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
373
374         ~av_mm_thread_characteristics()
375         {
376                 ::AvRevertMmThreadCharacteristics(handle_);
377         }
378
379 private:
380         std::wstring task_name_;
381         boost::uint32_t task_index_;
382         HANDLE handle_;
383 };
384
385 struct widget
386 {
387         void draw();
388         float x_,y_;
389 };
390
391 typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
392 typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
393
394 }