tweaking win32 port
[picodrive.git] / platform / win32 / GenaDrive / Direct.cpp
1 \r
2 #include "app.h"\r
3 \r
4 static IDirect3D8 *Direct3D=NULL;\r
5 IDirect3DDevice8 *Device=NULL;\r
6 IDirect3DSurface8 *DirectBack=NULL; // Back Buffer\r
7 \r
8 static IDirect3DVertexBuffer8 *VertexBuffer=NULL;\r
9 \r
10 struct CustomVertex\r
11 {\r
12   float x,y,z; // Vertex cordinates\r
13   unsigned int colour;\r
14   float u,v; // Texture coordinates\r
15 };\r
16 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)\r
17 \r
18 static CustomVertex VertexList[4];\r
19 \r
20 int DirectInit()\r
21 {\r
22   D3DPRESENT_PARAMETERS d3dpp; \r
23   D3DDISPLAYMODE mode;\r
24   D3DDEVTYPE dt = D3DDEVTYPE_HAL;\r
25   int i,u,ret=0;\r
26 \r
27   memset(&d3dpp,0,sizeof(d3dpp));\r
28   memset(&mode,0,sizeof(mode));\r
29 \r
30   Direct3D=Direct3DCreate8(D3D_SDK_VERSION); if (Direct3D==NULL) return 1;\r
31 \r
32   // Set up the structure used to create the D3D device:\r
33   d3dpp.BackBufferWidth =MainWidth;\r
34   d3dpp.BackBufferHeight=MainHeight;\r
35   d3dpp.BackBufferCount =1;\r
36   d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;\r
37 \r
38 #ifdef _XBOX\r
39   d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8;\r
40   d3dpp.FullScreen_RefreshRateInHz=60;\r
41 #else\r
42   Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&mode);\r
43   d3dpp.BackBufferFormat=mode.Format;\r
44   d3dpp.Windowed=1;\r
45 #endif\r
46 \r
47   // Try to create a device with hardware vertex processing:\r
48   for (u=0;u<2;u++)\r
49   {\r
50     for (i=0;i<4;i++)\r
51     {\r
52       int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING;\r
53 \r
54       // Try software vertex processing:\r
55       if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING;\r
56       if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING;\r
57 \r
58       Direct3D->CreateDevice(D3DADAPTER_DEFAULT,dt,FrameWnd,behave,&d3dpp,&Device);\r
59       if (Device) break;\r
60     }\r
61     if (Device) break;\r
62     dt = D3DDEVTYPE_REF;\r
63   }\r
64 \r
65   if (Device==NULL) return 1;\r
66 \r
67   Device->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&DirectBack);\r
68   if (DirectBack==NULL) return 1;\r
69 \r
70   Device->CreateVertexBuffer(sizeof(VertexList),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&VertexBuffer);\r
71   if (VertexBuffer==NULL) return 1;\r
72 \r
73   ret=TexScreenInit(); if (ret) return 1;\r
74 \r
75   //FontInit();\r
76 \r
77   Device->SetRenderState(D3DRS_LIGHTING,0); // Turn off lighting\r
78 \r
79   // Set up texture modes:\r
80   Device->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP);\r
81   Device->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP);\r
82   return 0;\r
83 }\r
84 \r
85 void DirectExit()\r
86 {\r
87   //FontExit();\r
88   //TexScreenExit();\r
89 \r
90   RELEASE(VertexBuffer)\r
91   RELEASE(DirectBack)\r
92   RELEASE(Device)\r
93   RELEASE(Direct3D)\r
94 }\r
95 \r
96 \r
97 static int MakeVertexList()\r
98 {\r
99   struct CustomVertex *vert=NULL,*pv=NULL;\r
100   float dist=0.0f;\r
101   float scalex=0.0f,scaley=0.0f;\r
102   unsigned int colour=0xffffff;\r
103   float right=0.0f,bottom=0.0f;\r
104 \r
105   if (LoopMode!=8) colour=0x102040;\r
106 \r
107   dist=10.0f; scalex=dist*1.3333f; scaley=dist;\r
108 \r
109   scalex*=640.0f/(float)MainWidth;\r
110   scaley*=448.0f/(float)MainHeight;\r
111 \r
112   vert=VertexList;\r
113 \r
114   // Put the vertices for the corners of the screen:\r
115   pv=vert;\r
116   pv->z=dist;\r
117   pv->x=-scalex; pv->y=scaley;\r
118   pv->colour=colour; pv++;\r
119 \r
120   *pv=vert[0]; pv->x= scalex; pv->y= scaley; pv++;\r
121   *pv=vert[0]; pv->x=-scalex; pv->y=-scaley; pv++;\r
122   *pv=vert[0]; pv->x= scalex; pv->y=-scaley; pv++;\r
123 \r
124   // Find where the screen images ends on the texture\r
125   right =(float)EmuWidth /(float)TexWidth;\r
126   bottom=(float)EmuHeight/(float)TexHeight;\r
127 \r
128   // Write texture coordinates:\r
129   pv=vert;\r
130   pv->u=0.0f;  pv->v=0.00f;  pv++;\r
131   pv->u=right; pv->v=0.00f;  pv++;\r
132   pv->u=0.0f;  pv->v=bottom; pv++;\r
133   pv->u=right; pv->v=bottom; pv++;\r
134 \r
135   return 0;\r
136 }\r
137 \r
138 int DirectClear(unsigned int colour)\r
139 {\r
140   Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0);\r
141   return 0;\r
142 }\r
143 \r
144 int DirectPresent()\r
145 {\r
146   Device->Present(NULL,NULL,NULL,NULL);\r
147   return 0;\r
148 }\r
149 \r
150 static int SetupMatrices()\r
151 {\r
152   D3DXVECTOR3 eye ( 0.0f, 0.0f, 0.0f );\r
153   D3DXVECTOR3 look( 0.0f, 0.0f, 0.0f );\r
154   D3DXVECTOR3 up  ( 0.0f, 1.0f, 0.0f );\r
155   D3DXMATRIX mat;\r
156   float nudgex=0.0f,nudgey=0.0f;\r
157 \r
158   memset(&mat,0,sizeof(mat));\r
159   \r
160   mat.m[0][0]=mat.m[1][1]=mat.m[2][2]=mat.m[3][3]=1.0f;\r
161   Device->SetTransform(D3DTS_WORLD,&mat);\r
162 \r
163   look.x=(float)Inp.axis[2]/2457.6f;\r
164   look.y=(float)Inp.axis[3]/2457.6f;\r
165   look.z=10.0f;\r
166 \r
167   // Nudge pixels to the centre of each screen pixel:\r
168   nudgex=13.3333f/(float)(MainWidth <<1);\r
169   nudgey=10.0000f/(float)(MainHeight<<1);\r
170   eye.x +=nudgex; eye.y +=nudgey;\r
171   look.x+=nudgex; look.y+=nudgey;\r
172 \r
173   D3DXMatrixLookAtLH(&mat,&eye,&look,&up);\r
174   Device->SetTransform(D3DTS_VIEW,&mat);\r
175 \r
176   D3DXMatrixPerspectiveFovLH(&mat, 0.5f*PI, 1.3333f, 0.2f, 1000.0f);\r
177   Device->SetTransform(D3DTS_PROJECTION,&mat);\r
178   return 0;\r
179 }\r
180 \r
181 int DirectScreen()\r
182 {\r
183   unsigned char *lock=NULL;\r
184   int ret;\r
185 \r
186   // Copy the screen to the screen texture:\r
187 #ifdef _XBOX\r
188   TexScreenSwizzle();\r
189 #else\r
190   ret=TexScreenLinear();\r
191   if (ret) dprintf2("TexScreenLinear failed\n");\r
192 #endif\r
193 \r
194   SetupMatrices();\r
195 \r
196   MakeVertexList();\r
197 \r
198   // Copy vertices in:\r
199   VertexBuffer->Lock(0,sizeof(VertexList),&lock,0);\r
200   if (lock==NULL) { dprintf2("VertexBuffer->Lock failed\n"); return 1; }\r
201   memcpy(lock,VertexList,sizeof(VertexList));\r
202   VertexBuffer->Unlock();\r
203 \r
204   ret=Device->SetTexture(0,TexScreen);\r
205   if (ret) dprintf2("SetTexture failed\n");\r
206   ret=Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex));\r
207   if (ret) dprintf2("SetStreamSource failed\n");\r
208   ret=Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);\r
209   if (ret) dprintf2("SetVertexShader failed\n");\r
210   ret=Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);\r
211   if (ret) dprintf2("DrawPrimitive failed\n");\r
212 \r
213   return 0;\r
214 }\r