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