bugfixes, new scaling, double ym upd at 940
[picodrive.git] / platform / win32 / GenaDrive / Direct.cpp
CommitLineData
cc68a136 1\r
2#include "app.h"\r
3\r
4static IDirect3D8 *Direct3D=NULL;\r
5IDirect3DDevice8 *Device=NULL;\r
6IDirect3DSurface8 *DirectBack=NULL; // Back Buffer\r
7\r
8static IDirect3DVertexBuffer8 *VertexBuffer=NULL;\r
9\r
10struct 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
18static CustomVertex VertexList[4];\r
19\r
20int 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
88void 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
100static 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
141int 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
147int DirectPresent()\r
148{\r
149 Device->Present(NULL,NULL,NULL,NULL);\r
150 return 0;\r
151}\r
152\r
153static 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
184int 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