1 /*
2 Copyright (c) 2005-2020 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 // common Windows parts
18 #include "winvideo.h"
19
20 // and another headers
21 #include <cassert>
22 #include <stdio.h>
23 #include <dxsdkver.h>
24 #if _DXSDK_PRODUCT_MAJOR < 9
25 #error DXSDK Version 9 and above required.
26 #endif
27 #include <d2d1.h>
28 #include <d2d1helper.h>
29 #pragma comment(lib, "d2d1.lib")
30
31 ID2D1Factory *m_pD2DFactory;
32 ID2D1HwndRenderTarget *m_pRenderTarget;
33 ID2D1Bitmap *m_pBitmap;
34 D2D1_SIZE_U bitmapSize;
35
36 HANDLE g_hVSync;
37
38 #include <DXErr.h>
39 #pragma comment(lib, "DxErr.lib")
40
41 //! Create a dialog box and tell the user what went wrong
DisplayError(LPSTR lpstrErr,HRESULT hres)42 bool DisplayError(LPSTR lpstrErr, HRESULT hres)
43 {
44 if(hres != S_OK){
45 static bool InError = false;
46 int retval = 0;
47 if (!InError)
48 {
49 InError = true;
50 const char *message = hres?DXGetErrorString(hres):0;
51 retval = MessageBoxA(g_hAppWnd, lpstrErr, hres?message:"Error!", MB_OK|MB_ICONERROR);
52 InError = false;
53 }
54 }
55 return false;
56 }
57
DrawBitmap()58 void DrawBitmap()
59 {
60 HRESULT hr = S_OK;
61 if (m_pRenderTarget) {
62 m_pRenderTarget->BeginDraw();
63 if (m_pBitmap)
64 hr = m_pBitmap->CopyFromMemory(NULL,(BYTE*)g_pImg, 4*g_sizex);
65 DisplayError( "DrawBitmap error", hr );
66 m_pRenderTarget->DrawBitmap(m_pBitmap);
67 m_pRenderTarget->EndDraw();
68 }
69 return;
70 }
71
mouse(int k,LPARAM lParam)72 inline void mouse(int k, LPARAM lParam)
73 {
74 int x = (int)LOWORD(lParam);
75 int y = (int)HIWORD(lParam);
76 RECT rc;
77 GetClientRect(g_hAppWnd, &rc);
78 g_video->on_mouse( x*g_sizex/(rc.right - rc.left), y*g_sizey/(rc.bottom - rc.top), k );
79 }
80
81 //! Win event processing function
InternalWndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)82 LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
83 {
84 switch (iMsg)
85 {
86 case WM_MOVE:
87 // Check to make sure our window exists before we tell it to repaint.
88 // This will fail the first time (while the window is being created).
89 if (hwnd) {
90 InvalidateRect(hwnd, NULL, FALSE);
91 UpdateWindow(hwnd);
92 }
93 return 0L;
94
95 case WM_SIZE:
96 case WM_PAINT:
97 if( g_video->running && g_video->updating ) {
98 DrawBitmap();
99 Sleep(0);
100 }
101 break;
102 // Process all mouse and keyboard events
103 case WM_LBUTTONDOWN: mouse( 1, lParam ); break;
104 case WM_LBUTTONUP: mouse(-1, lParam ); break;
105 case WM_RBUTTONDOWN: mouse( 2, lParam ); break;
106 case WM_RBUTTONUP: mouse(-2, lParam ); break;
107 case WM_MBUTTONDOWN: mouse( 3, lParam ); break;
108 case WM_MBUTTONUP: mouse(-3, lParam ); break;
109 case WM_CHAR: g_video->on_key( (int)wParam); break;
110
111 // some useless stuff
112 case WM_ERASEBKGND: return 1; // keeps erase-background events from happening, reduces chop
113 case WM_DISPLAYCHANGE: return 0;
114
115 // Now, shut down the window...
116 case WM_DESTROY: PostQuitMessage(0); return 0;
117 }
118 // call user defined proc, if exists
119 return g_pUserProc? g_pUserProc(hwnd, iMsg, wParam, lParam) : DefWindowProc(hwnd, iMsg, wParam, lParam);
120 }
121
init_window(int sizex,int sizey)122 bool video::init_window(int sizex, int sizey)
123 {
124 assert(win_hInstance != 0);
125 g_sizex = sizex; g_sizey = sizey;
126 if (!WinInit(win_hInstance, win_iCmdShow, gWndClass, title, false)) {
127 DisplayError("Unable to initialize the program's window.");
128 return false;
129 }
130 ShowWindow(g_hAppWnd, SW_SHOW);
131 g_pImg = new unsigned int[sizex*sizey];
132
133 HRESULT hr = S_OK;
134
135 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
136 // Create a Direct2D render target.
137 if (SUCCEEDED(hr) && !m_pRenderTarget){
138 RECT rc;
139 GetClientRect(g_hAppWnd, &rc);
140
141 bitmapSize = D2D1::SizeU(
142 rc.right - rc.left,
143 rc.bottom - rc.top
144 );
145
146 hr = m_pD2DFactory->CreateHwndRenderTarget(
147 D2D1::RenderTargetProperties(),
148 D2D1::HwndRenderTargetProperties(g_hAppWnd, bitmapSize),
149 &m_pRenderTarget
150 );
151 if (SUCCEEDED(hr) && !m_pBitmap){
152 D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
153 DXGI_FORMAT_B8G8R8A8_UNORM,
154 D2D1_ALPHA_MODE_IGNORE
155 );
156 D2D1_BITMAP_PROPERTIES bitmapProperties;
157 bitmapProperties.pixelFormat = pixelFormat;
158 m_pRenderTarget->GetDpi( &bitmapProperties.dpiX, &bitmapProperties.dpiY );
159 m_pRenderTarget->CreateBitmap(bitmapSize,bitmapProperties,&m_pBitmap);
160 m_pRenderTarget->DrawBitmap(m_pBitmap);
161 }
162 }
163
164 running = true;
165 return true;
166 }
167
terminate()168 void video::terminate()
169 {
170 if (m_pBitmap) m_pBitmap->Release();
171 if (m_pRenderTarget) m_pRenderTarget->Release();
172 if (m_pD2DFactory) m_pD2DFactory->Release();
173 g_video = 0; running = false;
174 if(g_pImg) { delete[] g_pImg; g_pImg = 0; }
175 }
176
177 //////////// drawing area constructor & destructor /////////////
178
drawing_area(int x,int y,int sizex,int sizey)179 drawing_area::drawing_area(int x, int y, int sizex, int sizey)
180 : base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex),
181 pixel_depth(24), ptr32(g_pImg), start_x(x), start_y(y), size_x(sizex), size_y(sizey)
182 {
183 assert(x < g_sizex); assert(y < g_sizey);
184 assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);
185
186 index = base_index; // current index
187 }
188
update()189 void drawing_area::update()
190 {
191 if(g_video->updating) {
192 RECT r;
193 r.left = start_x; r.right = start_x + size_x;
194 r.top = start_y; r.bottom = start_y + size_y;
195 InvalidateRect(g_hAppWnd, &r, false);
196 }
197 }
198