experimental ddraw code
[picodrive.git] / platform / win32 / GenaDrive / Direct.cpp
CommitLineData
cc68a136 1\r
2#include "app.h"\r
3\r
7c9e6899 4// d3d\r
cc68a136 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\r
7c9e6899 21// ddraw\r
22#include <ddraw.h>\r
23\r
24LPDIRECTDRAW7 m_pDD;\r
25LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer;\r
26LPDIRECTDRAWSURFACE7 m_pddsBackBuffer;\r
27\r
28// quick and dirty stuff..\r
29static int DirectDrawInit()\r
30{\r
31 HRESULT ret;\r
32\r
33 ret = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL);\r
34 if (ret) { LOGFAIL(); return 1; }\r
35\r
36 // Set cooperative level\r
37 ret = m_pDD->SetCooperativeLevel( FrameWnd, DDSCL_NORMAL );\r
38 if (ret) { LOGFAIL(); return 1; }\r
39\r
40 // Create the primary surface\r
41 DDSURFACEDESC2 ddsd;\r
42 ZeroMemory( &ddsd, sizeof( ddsd ) );\r
43 ddsd.dwSize = sizeof( ddsd );\r
44 ddsd.dwFlags = DDSD_CAPS;\r
45 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;\r
46\r
47 ret = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL );\r
48 if (ret) { LOGFAIL(); return 1; }\r
49\r
50 // Create the backbuffer surface\r
51 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; \r
52 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;\r
53 ddsd.dwWidth = 320;\r
54 ddsd.dwHeight = 240;\r
55\r
56 ret = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL );\r
57 if (ret) { LOGFAIL(); return 1; }\r
58\r
59 // clipper\r
60 LPDIRECTDRAWCLIPPER pcClipper = NULL;\r
61 ret = m_pDD->CreateClipper( 0, &pcClipper, NULL );\r
62 if (ret) { LOGFAIL(); return 1; }\r
63\r
64 ret = pcClipper->SetHWnd( 0, FrameWnd );\r
65 if (ret) { LOGFAIL(); return 1; }\r
66\r
67 ret = m_pddsFrontBuffer->SetClipper( pcClipper );\r
68 if (ret) { LOGFAIL(); return 1; }\r
69\r
70 RELEASE(pcClipper);\r
71\r
72#if 0\r
73 DDSURFACEDESC2 sd;\r
74 memset(&sd, 0, sizeof(sd));\r
75 sd.dwSize = sizeof(sd);\r
76 ret = m_pddsBackBuffer->Lock(NULL, &sd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);\r
77 if (ret) { LOGFAIL(); return 1; }\r
78\r
79 memset(sd.lpSurface, 0xcc, 200*200);\r
80\r
81 ret = m_pddsBackBuffer->Unlock(NULL);\r
82 if (ret) { LOGFAIL(); return 1; }\r
83#else\r
84 DDBLTFX ddbltfx;\r
85 ZeroMemory( &ddbltfx, sizeof(ddbltfx) );\r
86 ddbltfx.dwSize = sizeof(ddbltfx);\r
87 ddbltfx.dwFillColor = 0xff00;\r
88\r
89 ret = m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );\r
90#endif\r
91\r
92 ret = m_pddsFrontBuffer->Blt(NULL, m_pddsBackBuffer, NULL, DDBLT_WAIT, NULL);\r
93 if (ret) { LOGFAIL(); return 1; }\r
94Sleep(2000);\r
95/* Sleep(500);\r
96 ret = m_pddsFrontBuffer->Blt(NULL, m_pddsBackBuffer, NULL, DDBLT_WAIT, NULL);\r
97 if (ret) { LOGFAIL(); return 1; }\r
98 Sleep(500);\r
99 ret = m_pddsFrontBuffer->Blt(NULL, m_pddsBackBuffer, NULL, DDBLT_WAIT, NULL);\r
100 if (ret) { LOGFAIL(); return 1; }\r
101*/\r
102 return 0;\r
103}\r
104\r
105\r
cc68a136 106int DirectInit()\r
107{\r
108 D3DPRESENT_PARAMETERS d3dpp; \r
109 D3DDISPLAYMODE mode;\r
8831ef19 110 int i,u,ret=0;\r
cc68a136 111\r
112 memset(&d3dpp,0,sizeof(d3dpp));\r
113 memset(&mode,0,sizeof(mode));\r
114\r
115 Direct3D=Direct3DCreate8(D3D_SDK_VERSION); if (Direct3D==NULL) return 1;\r
116\r
117 // Set up the structure used to create the D3D device:\r
118 d3dpp.BackBufferWidth =MainWidth;\r
119 d3dpp.BackBufferHeight=MainHeight;\r
120 d3dpp.BackBufferCount =1;\r
121 d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;\r
122\r
123#ifdef _XBOX\r
124 d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8;\r
125 d3dpp.FullScreen_RefreshRateInHz=60;\r
126#else\r
127 Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&mode);\r
128 d3dpp.BackBufferFormat=mode.Format;\r
129 d3dpp.Windowed=1;\r
130#endif\r
131\r
132 // Try to create a device with hardware vertex processing:\r
7c9e6899 133 for (i=0;i<3;i++)\r
cc68a136 134 {\r
7c9e6899 135 int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING;\r
cc68a136 136\r
7c9e6899 137 // Try software vertex processing:\r
138 if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING;\r
139 if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING;\r
cc68a136 140\r
7c9e6899 141 Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,FrameWnd,\r
142 behave|D3DCREATE_MULTITHREADED,&d3dpp,&Device);\r
cc68a136 143 if (Device) break;\r
144 }\r
145\r
7c9e6899 146 if (Device==NULL)\r
147 {\r
148#if 0\r
149 // try ref\r
150 Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,FrameWnd,\r
151 D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,&d3dpp,&Device);\r
152 if (Device==NULL) goto fail0;\r
153 HMODULE test = LoadLibrary("d3d8d.dll");\r
154 if (test != NULL) FreeLibrary(test);\r
155 else {\r
156 error("Sorry, but this program requires Direct3D with hardware acceleration.\n\n"\r
157 "You can try using Direct3D software emulation, but you have to install "\r
158 "DirectX SDK for it to work\n(it seems to be missing now).");\r
159 goto fail1;\r
160 }\r
161#else\r
162 goto fail1;\r
163#endif\r
164 }\r
cc68a136 165\r
166 Device->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&DirectBack);\r
7c9e6899 167 if (DirectBack==NULL) goto fail1;\r
cc68a136 168\r
169 Device->CreateVertexBuffer(sizeof(VertexList),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&VertexBuffer);\r
7c9e6899 170 if (VertexBuffer==NULL) goto fail2;\r
cc68a136 171\r
7c9e6899 172 ret=TexScreenInit(); if (ret) goto fail3;\r
cc68a136 173\r
4b2b67eb 174 //FontInit();\r
cc68a136 175\r
176 Device->SetRenderState(D3DRS_LIGHTING,0); // Turn off lighting\r
177\r
178 // Set up texture modes:\r
179 Device->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);\r
180 Device->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);\r
7c9e6899 181\r
cc68a136 182 return 0;\r
7c9e6899 183\r
184fail3:\r
185 RELEASE(VertexBuffer)\r
186fail2:\r
187 RELEASE(DirectBack)\r
188fail1:\r
189 RELEASE(Device)\r
190fail0:\r
191 RELEASE(Direct3D)\r
192\r
193 // error("Failed to use Direct3D, trying DirectDraw..");\r
194\r
195 // try DirectDraw\r
196 return DirectDrawInit();\r
cc68a136 197}\r
198\r
199void DirectExit()\r
200{\r
4b2b67eb 201 //FontExit();\r
7c9e6899 202 TexScreenExit();\r
cc68a136 203\r
204 RELEASE(VertexBuffer)\r
205 RELEASE(DirectBack)\r
206 RELEASE(Device)\r
207 RELEASE(Direct3D)\r
208}\r
209\r
210\r
211static int MakeVertexList()\r
212{\r
213 struct CustomVertex *vert=NULL,*pv=NULL;\r
214 float dist=0.0f;\r
215 float scalex=0.0f,scaley=0.0f;\r
216 unsigned int colour=0xffffff;\r
217 float right=0.0f,bottom=0.0f;\r
218\r
219 if (LoopMode!=8) colour=0x102040;\r
220\r
221 dist=10.0f; scalex=dist*1.3333f; scaley=dist;\r
222\r
223 scalex*=640.0f/(float)MainWidth;\r
224 scaley*=448.0f/(float)MainHeight;\r
225\r
226 vert=VertexList;\r
227\r
228 // Put the vertices for the corners of the screen:\r
229 pv=vert;\r
230 pv->z=dist;\r
231 pv->x=-scalex; pv->y=scaley;\r
232 pv->colour=colour; pv++;\r
233\r
234 *pv=vert[0]; pv->x= scalex; pv->y= scaley; pv++;\r
235 *pv=vert[0]; pv->x=-scalex; pv->y=-scaley; pv++;\r
236 *pv=vert[0]; pv->x= scalex; pv->y=-scaley; pv++;\r
237\r
238 // Find where the screen images ends on the texture\r
239 right =(float)EmuWidth /(float)TexWidth;\r
240 bottom=(float)EmuHeight/(float)TexHeight;\r
241\r
242 // Write texture coordinates:\r
243 pv=vert;\r
244 pv->u=0.0f; pv->v=0.00f; pv++;\r
245 pv->u=right; pv->v=0.00f; pv++;\r
246 pv->u=0.0f; pv->v=bottom; pv++;\r
247 pv->u=right; pv->v=bottom; pv++;\r
248\r
249 return 0;\r
250}\r
251\r
252int DirectClear(unsigned int colour)\r
253{\r
254 Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0);\r
255 return 0;\r
256}\r
257\r
258int DirectPresent()\r
259{\r
260 Device->Present(NULL,NULL,NULL,NULL);\r
261 return 0;\r
262}\r
263\r
264static int SetupMatrices()\r
265{\r
266 D3DXVECTOR3 eye ( 0.0f, 0.0f, 0.0f );\r
267 D3DXVECTOR3 look( 0.0f, 0.0f, 0.0f );\r
268 D3DXVECTOR3 up ( 0.0f, 1.0f, 0.0f );\r
269 D3DXMATRIX mat;\r
270 float nudgex=0.0f,nudgey=0.0f;\r
271\r
272 memset(&mat,0,sizeof(mat));\r
273 \r
274 mat.m[0][0]=mat.m[1][1]=mat.m[2][2]=mat.m[3][3]=1.0f;\r
275 Device->SetTransform(D3DTS_WORLD,&mat);\r
276\r
277 look.x=(float)Inp.axis[2]/2457.6f;\r
278 look.y=(float)Inp.axis[3]/2457.6f;\r
279 look.z=10.0f;\r
280\r
281 // Nudge pixels to the centre of each screen pixel:\r
282 nudgex=13.3333f/(float)(MainWidth <<1);\r
283 nudgey=10.0000f/(float)(MainHeight<<1);\r
284 eye.x +=nudgex; eye.y +=nudgey;\r
285 look.x+=nudgex; look.y+=nudgey;\r
286\r
287 D3DXMatrixLookAtLH(&mat,&eye,&look,&up);\r
288 Device->SetTransform(D3DTS_VIEW,&mat);\r
289\r
290 D3DXMatrixPerspectiveFovLH(&mat, 0.5f*PI, 1.3333f, 0.2f, 1000.0f);\r
291 Device->SetTransform(D3DTS_PROJECTION,&mat);\r
292 return 0;\r
293}\r
294\r
295int DirectScreen()\r
296{\r
297 unsigned char *lock=NULL;\r
8831ef19 298 int ret;\r
cc68a136 299\r
300 // Copy the screen to the screen texture:\r
301#ifdef _XBOX\r
302 TexScreenSwizzle();\r
303#else\r
8831ef19 304 ret=TexScreenLinear();\r
305 if (ret) dprintf2("TexScreenLinear failed\n");\r
cc68a136 306#endif\r
307\r
308 SetupMatrices();\r
309\r
310 MakeVertexList();\r
311\r
312 // Copy vertices in:\r
8831ef19 313 VertexBuffer->Lock(0,sizeof(VertexList),&lock,0);\r
314 if (lock==NULL) { dprintf2("VertexBuffer->Lock failed\n"); return 1; }\r
cc68a136 315 memcpy(lock,VertexList,sizeof(VertexList));\r
316 VertexBuffer->Unlock();\r
317\r
7c9e6899 318 ret=Device->BeginScene();\r
319 if (ret) dprintf2("BeginScene failed\n");\r
8831ef19 320 ret=Device->SetTexture(0,TexScreen);\r
321 if (ret) dprintf2("SetTexture failed\n");\r
322 ret=Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex));\r
323 if (ret) dprintf2("SetStreamSource failed\n");\r
324 ret=Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);\r
325 if (ret) dprintf2("SetVertexShader failed\n");\r
326 ret=Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);\r
327 if (ret) dprintf2("DrawPrimitive failed\n");\r
7c9e6899 328 ret=Device->EndScene();\r
329 if (ret) dprintf2("EndScene failed\n");\r
8831ef19 330\r
cc68a136 331 return 0;\r
332}\r