reverted useless threaded buffering code
[picodrive.git] / platform / win32 / GenaDrive / Direct.cpp
... / ...
CommitLineData
1#include "app.h"\r
2\r
3#ifdef USE_D3D\r
4// d3d\r
5static IDirect3D8 *Direct3D=NULL;\r
6IDirect3DDevice8 *Device=NULL;\r
7IDirect3DSurface8 *DirectBack=NULL; // Back Buffer\r
8\r
9static IDirect3DVertexBuffer8 *VertexBuffer=NULL;\r
10\r
11struct CustomVertex\r
12{\r
13 float x,y,z; // Vertex cordinates\r
14 unsigned int colour;\r
15 float u,v; // Texture coordinates\r
16};\r
17#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)\r
18\r
19static CustomVertex VertexList[4];\r
20#endif\r
21\r
22// ddraw\r
23#include <ddraw.h>\r
24\r
25LPDIRECTDRAW7 m_pDD = NULL;\r
26LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer = NULL;\r
27LPDIRECTDRAWSURFACE7 m_pddsBackBuffer = NULL;\r
28\r
29// quick and dirty stuff..\r
30static void DirectExitDDraw()\r
31{\r
32 RELEASE(m_pddsBackBuffer);\r
33 RELEASE(m_pddsFrontBuffer);\r
34 RELEASE(m_pDD);\r
35}\r
36\r
37static int DirectDrawInit()\r
38{\r
39 HRESULT ret;\r
40 LPDIRECTDRAWCLIPPER pcClipper = NULL;\r
41 DDSURFACEDESC2 ddsd;\r
42\r
43 ret = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);\r
44 if (ret) { LOGFAIL(); return 1; }\r
45\r
46 // Set cooperative level\r
47 ret = m_pDD->SetCooperativeLevel( FrameWnd, DDSCL_NORMAL );\r
48 if (ret) { LOGFAIL(); goto fail; }\r
49\r
50 // Create the primary surface\r
51 ZeroMemory( &ddsd, sizeof( ddsd ) );\r
52 ddsd.dwSize = sizeof( ddsd );\r
53 ddsd.dwFlags = DDSD_CAPS;\r
54 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;\r
55\r
56 ret = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL );\r
57 if (ret) { LOGFAIL(); goto fail; }\r
58\r
59 // Create the backbuffer surface\r
60 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;\r
61 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;\r
62 ddsd.dwWidth = EmuWidth;\r
63 ddsd.dwHeight = EmuHeight;\r
64\r
65 ret = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL );\r
66 if (ret) { LOGFAIL(); goto fail; }\r
67\r
68 // clipper\r
69 ret = m_pDD->CreateClipper( 0, &pcClipper, NULL );\r
70 if (ret) { LOGFAIL(); goto fail; }\r
71\r
72 ret = pcClipper->SetHWnd( 0, FrameWnd );\r
73 if (ret) { LOGFAIL(); goto fail; }\r
74\r
75 ret = m_pddsFrontBuffer->SetClipper( pcClipper );\r
76 if (ret) { LOGFAIL(); goto fail; }\r
77\r
78 RELEASE(pcClipper);\r
79 return 0;\r
80\r
81fail:\r
82 RELEASE(pcClipper);\r
83 DirectExitDDraw();\r
84 return 1;\r
85}\r
86\r
87static int DirectScreenDDraw()\r
88{\r
89 DDSURFACEDESC2 sd;\r
90 unsigned short *ps=EmuScreen;\r
91 int ret, x, y;\r
92\r
93 memset(&sd, 0, sizeof(sd));\r
94 sd.dwSize = sizeof(sd);\r
95 ret = m_pddsBackBuffer->Lock(NULL, &sd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);\r
96 if (ret) { LOGFAIL(); return 1; }\r
97\r
98 //dprintf2("w: %i h: %i pi: %i pf: %i\n", sd.dwWidth, sd.dwHeight, sd.lPitch, sd.ddpfPixelFormat.dwRGBBitCount);\r
99\r
100 if (sd.ddpfPixelFormat.dwRGBBitCount == 32)\r
101 {\r
102 int *dst = (int *)sd.lpSurface;\r
103 for (y = 0; y < EmuHeight; y++)\r
104 {\r
105 for (x = 0; x < EmuWidth; x++)\r
106 {\r
107 int s = *ps++;\r
108 dst[x] = ((s&0xf800)<<8) | ((s&0x07e0)<<5) | ((s&0x001f)<<3);\r
109 }\r
110 dst = (int *)((char *)dst + sd.lPitch);\r
111 }\r
112 }\r
113 else if (sd.ddpfPixelFormat.dwRGBBitCount == 24) /* wine uses this for me */\r
114 {\r
115 void *dst = sd.lpSurface;\r
116 for (y = 0; y < EmuHeight; y++)\r
117 {\r
118 unsigned char *dst1 = (unsigned char *) dst;\r
119 for (x = 0; x < EmuWidth; x++, dst1 += 3)\r
120 {\r
121 int s = *ps++;\r
122 dst1[2] = (s&0xf800)>>8; dst1[1] = (s&0x07e0)>>3; dst1[0] = s<<3; // BGR\r
123 }\r
124 dst = (void *)((char *)dst + sd.lPitch);\r
125 }\r
126 }\r
127 else if (sd.ddpfPixelFormat.dwRGBBitCount == 16)\r
128 {\r
129 unsigned short *dst = (unsigned short *)sd.lpSurface;\r
130 for (y = 0; y < EmuHeight; y++)\r
131 {\r
132 memcpy(dst, ps, EmuWidth*2);\r
133 ps += EmuWidth;\r
134 dst = (unsigned short *)((char *)dst + sd.lPitch);\r
135 }\r
136 }\r
137 else\r
138 {\r
139 LOGFAIL();\r
140 }\r
141\r
142 ret = m_pddsBackBuffer->Unlock(NULL);\r
143 if (ret) { LOGFAIL(); return 1; }\r
144 return 0;\r
145}\r
146\r
147static int DirectClearDDraw(unsigned int colour)\r
148{\r
149 int ret;\r
150 DDBLTFX ddbltfx;\r
151 ZeroMemory( &ddbltfx, sizeof(ddbltfx) );\r
152 ddbltfx.dwSize = sizeof(ddbltfx);\r
153 ddbltfx.dwFillColor = colour;\r
154\r
155 if (m_pddsBackBuffer != NULL)\r
156 ret = m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );\r
157 if (ret) { LOGFAIL(); return 1; }\r
158 return 0;\r
159}\r
160\r
161static int DirectPresentDDraw()\r
162{\r
163 int ret = m_pddsFrontBuffer->Blt(&FrameRectMy, m_pddsBackBuffer, &EmuScreenRect, DDBLT_WAIT, NULL);\r
164 if (ret) { LOGFAIL(); return 1; }\r
165 return 0;\r
166}\r
167\r
168\r
169/* D3D */\r
170\r
171int DirectInit()\r
172{\r
173#if USE_D3D\r
174 D3DPRESENT_PARAMETERS d3dpp;\r
175 D3DDISPLAYMODE mode;\r
176 int i,u,ret=0;\r
177\r
178 memset(&d3dpp,0,sizeof(d3dpp));\r
179 memset(&mode,0,sizeof(mode));\r
180\r
181 Direct3D=Direct3DCreate8(D3D_SDK_VERSION); if (Direct3D==NULL) return 1;\r
182\r
183 // Set up the structure used to create the D3D device:\r
184 d3dpp.BackBufferWidth =MainWidth;\r
185 d3dpp.BackBufferHeight=MainHeight;\r
186 d3dpp.BackBufferCount =1;\r
187 d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;\r
188 d3dpp.MultiSampleType =D3DMULTISAMPLE_NONE;\r
189\r
190#ifdef _XBOX\r
191 d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8;\r
192 d3dpp.FullScreen_RefreshRateInHz=60;\r
193#else\r
194 Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&mode);\r
195 d3dpp.BackBufferFormat=mode.Format;\r
196 d3dpp.Windowed=1;\r
197 d3dpp.hDeviceWindow=FrameWnd;\r
198#endif\r
199\r
200 // Try to create a device with hardware vertex processing:\r
201 for (i=0;i<3;i++)\r
202 {\r
203 int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING;\r
204\r
205 // Try software vertex processing:\r
206 if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING;\r
207 if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING;\r
208\r
209 Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,FrameWnd,\r
210 behave|D3DCREATE_MULTITHREADED,&d3dpp,&Device);\r
211 if (Device) break;\r
212 }\r
213\r
214 if (Device==NULL)\r
215 {\r
216#if 0\r
217 // try ref\r
218 Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,FrameWnd,\r
219 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,&d3dpp,&Device);\r
220 if (Device==NULL) goto fail0;\r
221 HMODULE test = LoadLibrary("d3d8d.dll");\r
222 if (test != NULL) FreeLibrary(test);\r
223 else {\r
224 error("Sorry, but this program requires Direct3D with hardware acceleration.\n\n"\r
225 "You can try using Direct3D software emulation, but you have to install "\r
226 "DirectX SDK for it to work\n(it seems to be missing now).");\r
227 goto fail1;\r
228 }\r
229#else\r
230 goto fail1;\r
231#endif\r
232 }\r
233\r
234 Device->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&DirectBack);\r
235 if (DirectBack==NULL) goto fail1;\r
236\r
237 Device->CreateVertexBuffer(sizeof(VertexList),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&VertexBuffer);\r
238 if (VertexBuffer==NULL) goto fail2;\r
239\r
240 ret=TexScreenInit(); if (ret) goto fail3;\r
241\r
242 //FontInit();\r
243\r
244 Device->SetRenderState(D3DRS_LIGHTING,0); // Turn off lighting\r
245\r
246 // Set up texture modes:\r
247 Device->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);\r
248 Device->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);\r
249\r
250 return 0;\r
251\r
252fail3:\r
253 RELEASE(VertexBuffer)\r
254fail2:\r
255 RELEASE(DirectBack)\r
256fail1:\r
257 RELEASE(Device)\r
258fail0:\r
259 RELEASE(Direct3D)\r
260\r
261 // error("Failed to use Direct3D, trying DirectDraw..");\r
262#endif\r
263 // try DirectDraw\r
264 return DirectDrawInit();\r
265}\r
266\r
267void DirectExit()\r
268{\r
269#ifdef USE_D3D\r
270 TexScreenExit();\r
271\r
272 // d3d\r
273 RELEASE(VertexBuffer)\r
274 RELEASE(DirectBack)\r
275 RELEASE(Device)\r
276 RELEASE(Direct3D)\r
277#endif\r
278 DirectExitDDraw();\r
279}\r
280\r
281int DirectClear(unsigned int colour)\r
282{\r
283#ifdef USE_D3D\r
284 if (Device != NULL) {\r
285 Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0);\r
286 return 0;\r
287 }\r
288#endif\r
289\r
290 return DirectClearDDraw(colour);\r
291}\r
292\r
293int DirectPresent()\r
294{\r
295#ifdef USE_D3D\r
296 if (Device != NULL) {\r
297 Device->Present(NULL,NULL,NULL,NULL);\r
298 return 0;\r
299 }\r
300#endif\r
301\r
302 return DirectPresentDDraw();\r
303}\r
304\r
305#ifdef USE_D3D\r
306static int MakeVertexList()\r
307{\r
308 struct CustomVertex *vert=NULL,*pv=NULL;\r
309 float dist=0.0f;\r
310 float scalex=0.0f,scaley=0.0f;\r
311 unsigned int colour=0xffffff;\r
312 float right=0.0f,bottom=0.0f;\r
313\r
314 if (LoopMode!=8) colour=0x102040;\r
315\r
316 dist=10.0f; scalex=dist*1.3333f; scaley=dist;\r
317\r
318 scalex*=640.0f/(float)MainWidth;\r
319 scaley*=448.0f/(float)MainHeight;\r
320\r
321 vert=VertexList;\r
322\r
323 // Put the vertices for the corners of the screen:\r
324 pv=vert;\r
325 pv->z=dist;\r
326 pv->x=-scalex; pv->y=scaley;\r
327 pv->colour=colour; pv++;\r
328\r
329 *pv=vert[0]; pv->x= scalex; pv->y= scaley; pv++;\r
330 *pv=vert[0]; pv->x=-scalex; pv->y=-scaley; pv++;\r
331 *pv=vert[0]; pv->x= scalex; pv->y=-scaley; pv++;\r
332\r
333 // Find where the screen images ends on the texture\r
334 right =(float)EmuWidth /(float)TexWidth;\r
335 bottom=(float)EmuHeight/(float)TexHeight;\r
336\r
337 // Write texture coordinates:\r
338 pv=vert;\r
339 pv->u=0.0f; pv->v=0.00f; pv++;\r
340 pv->u=right; pv->v=0.00f; pv++;\r
341 pv->u=0.0f; pv->v=bottom; pv++;\r
342 pv->u=right; pv->v=bottom; pv++;\r
343\r
344 return 0;\r
345}\r
346\r
347static int SetupMatrices()\r
348{\r
349 D3DXVECTOR3 eye ( 0.0f, 0.0f, 0.0f );\r
350 D3DXVECTOR3 look( 0.0f, 0.0f, 0.0f );\r
351 D3DXVECTOR3 up ( 0.0f, 1.0f, 0.0f );\r
352 D3DXMATRIX mat;\r
353 float nudgex=0.0f,nudgey=0.0f;\r
354\r
355 memset(&mat,0,sizeof(mat));\r
356\r
357 mat.m[0][0]=mat.m[1][1]=mat.m[2][2]=mat.m[3][3]=1.0f;\r
358 Device->SetTransform(D3DTS_WORLD,&mat);\r
359\r
360 look.x=(float)Inp.axis[2]/2457.6f;\r
361 look.y=(float)Inp.axis[3]/2457.6f;\r
362 look.z=10.0f;\r
363\r
364 // Nudge pixels to the centre of each screen pixel:\r
365 nudgex=13.3333f/(float)(MainWidth <<1);\r
366 nudgey=10.0000f/(float)(MainHeight<<1);\r
367 eye.x +=nudgex; eye.y +=nudgey;\r
368 look.x+=nudgex; look.y+=nudgey;\r
369\r
370 D3DXMatrixLookAtLH(&mat,&eye,&look,&up);\r
371 Device->SetTransform(D3DTS_VIEW,&mat);\r
372\r
373 D3DXMatrixPerspectiveFovLH(&mat, 0.5f*PI, 1.3333f, 0.2f, 1000.0f);\r
374 Device->SetTransform(D3DTS_PROJECTION,&mat);\r
375 return 0;\r
376}\r
377\r
378int DirectScreen()\r
379{\r
380 unsigned char *lock=NULL;\r
381 int ret;\r
382\r
383 if (Device == NULL)\r
384 return DirectScreenDDraw();\r
385\r
386 // Copy the screen to the screen texture:\r
387#ifdef _XBOX\r
388 TexScreenSwizzle();\r
389#else\r
390 ret=TexScreenLinear();\r
391 if (ret) dprintf2("TexScreenLinear failed\n");\r
392#endif\r
393\r
394 SetupMatrices();\r
395\r
396 MakeVertexList();\r
397\r
398 // Copy vertices in:\r
399 VertexBuffer->Lock(0,sizeof(VertexList),&lock,0);\r
400 if (lock==NULL) { dprintf2("VertexBuffer->Lock failed\n"); return 1; }\r
401 memcpy(lock,VertexList,sizeof(VertexList));\r
402 VertexBuffer->Unlock();\r
403\r
404 Device->BeginScene();\r
405 Device->SetTexture(0,TexScreen);\r
406 Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex));\r
407 Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);\r
408 Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);\r
409 Device->EndScene();\r
410\r
411 return 0;\r
412}\r
413#else\r
414int DirectScreen()\r
415{\r
416 return DirectScreenDDraw();\r
417}\r
418#endif\r
419\r