1 //-----------------------------------------------------------------------------
2 // File: VBuffer.cpp
3 //
4 // Desc: Example code showing how to use DirectX 6 vertex buffers.
5 //
6 //       Note: This code uses the D3D Framework helper library.
7 //
8 //
9 // Copyright (c) 1997-1998 Microsoft Corporation. All rights reserved.
10 //-----------------------------------------------------------------------------
11 
12 #include "pch.h"
13 #include "scene.h"
14 #include <stack>
15 
16 #include "D3DTextr.h"
17 #include "D3DUtil.h"
18 #include "D3DMath.h"
19 #include "D3DFrame.h"
20 
21 #include "texture.h"
22 
23 extern CD3DFramework* g_pFramework;
24 extern BOOL           g_bWindowed;
25 
26 extern "C" {
27 #include "d3dhelp.h"
28 }
29 
30 //-----------------------------------------------------------------------------
31 // Declare the application globals for use in WinMain.cpp
32 //-----------------------------------------------------------------------------
33 void   Win32_SetupColor(void);
34 BOOL   g_TrueColor;
35 int    g_RShift, g_GShift, g_BShift;
36 int    g_RBits6, g_GBits6, g_BBits6;
37 
38 TCHAR* g_strAppTitle       = TEXT( "Direct3D Descent" );
39 BOOL   g_bAppUseZBuffer    = FALSE;
40 BOOL   g_bAppUseBackBuffer = TRUE;
41 
42 LPDIRECT3DTEXTURE2 g_pd3dtLast;
43 BOOL g_bTransparentLast;
44 
45 std::stack <D3DMATRIX> g_stkWorlds;
46 
47 float g_fPSURed = 0.0f;
48 float g_fPSUGreen = 0.0f;
49 float g_fPSUBlue = 0.0f;
50 
51 D3DLVERTEX g_rgVerts [16];
52 
53 CTextureSet g_setTextures;
54 
55 //-----------------------------------------------------------------------------
56 // Defines, constants, and global variables
57 //-----------------------------------------------------------------------------
58 
59 
60 //-----------------------------------------------------------------------------
61 // Function prototypes and global (or static) variables
62 //-----------------------------------------------------------------------------
63 HRESULT App_InitDeviceObjects( LPDIRECT3DDEVICE3, LPDIRECT3DVIEWPORT3 );
64 VOID    App_DeleteDeviceObjects( LPDIRECT3DDEVICE3, LPDIRECT3DVIEWPORT3 );
65 
66 
67 
68 
69 //-----------------------------------------------------------------------------
70 // Name: App_OneTimeSceneInit()
71 // Desc: Called during initial app startup, this function performs all the
72 //       permanent initialization.
73 //-----------------------------------------------------------------------------
App_OneTimeSceneInit(HWND hWnd)74 HRESULT App_OneTimeSceneInit( HWND hWnd )
75 {
76     // Create some textures
77     return S_OK;
78 }
79 
80 
81 //-----------------------------------------------------------------------------
82 // Name: App_InitDeviceObjects()
83 // Desc: Initialize scene objects.
84 //-----------------------------------------------------------------------------
App_InitDeviceObjects(LPDIRECT3DDEVICE3 pd3dDevice,LPDIRECT3DVIEWPORT3 pvViewport)85 HRESULT App_InitDeviceObjects( LPDIRECT3DDEVICE3 pd3dDevice,
86                                LPDIRECT3DVIEWPORT3 pvViewport )
87 {
88     // Check parameters
89     if( NULL==pd3dDevice || NULL==pvViewport )
90         return E_INVALIDARG;
91 
92 
93 	D3DVIEWPORT2 vdData;
94     ZeroMemory( &vdData, sizeof(D3DVIEWPORT2) );
95     vdData.dwSize		= sizeof(vdData);
96 	vdData.dwX			= 0;
97 	vdData.dwY			= 0;
98     vdData.dwWidth		= g_pFramework->m_dwRenderWidth;
99     vdData.dwHeight		= 147 * g_pFramework->m_dwRenderHeight / 200;
100     vdData.dvMaxZ		= 1.0f;
101 
102     vdData.dvClipX		= -1.0f;
103     vdData.dvClipY		= (FLOAT) g_pFramework->m_dwRenderHeight / (FLOAT) g_pFramework->m_dwRenderWidth;
104     vdData.dvClipWidth	= 2.0f;
105     vdData.dvClipHeight	= 2.0f * vdData.dvClipY;
106     vdData.dvMinZ		= 0.0f;
107     vdData.dvMaxZ		= 1.0f;
108 
109     // Set the parameters to the new viewport
110     if (FAILED (pvViewport->SetViewport2 (&vdData)))
111     {
112         DEBUG_MSG( TEXT("Error: Couldn't set the viewport data") );
113         return D3DFWERR_NOVIEWPORT;
114     }
115 
116 
117 	// Get a ptr to the ID3D object to create VB's, materials and/or lights.
118     // Note: the Release() call just serves to decrease the ref count.
119     LPDIRECT3D3 pD3D;
120     if( FAILED( pd3dDevice->GetDirect3D( &pD3D ) ) )
121         return E_FAIL;
122     pD3D->Release();
123 
124 	// Get the device's caps bits
125 	D3DDEVICEDESC ddHwDesc, ddSwDesc;
126 	D3DUtil_InitDeviceDesc( ddHwDesc );
127 	D3DUtil_InitDeviceDesc( ddSwDesc );
128 	if( FAILED( pd3dDevice->GetCaps( &ddHwDesc, &ddSwDesc ) ) )
129 		return E_FAIL;
130 
131 	D3DMATRIX matProj;
132 	float fAspect = 1.0f;
133     D3DUtil_SetProjectionMatrix( matProj, g_PI/3, fAspect, 0.01f, 1000.0f );
134     pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );
135 
136     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
137     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
138 	//pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );
139 	//pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
140 
141 	pd3dDevice->SetRenderState (D3DRENDERSTATE_SPECULARENABLE, FALSE);
142 	pd3dDevice->SetRenderState (D3DRENDERSTATE_DITHERENABLE, TRUE);
143 	pd3dDevice->SetRenderState (D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE);
144 	pd3dDevice->SetRenderState (D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID);
145 	pd3dDevice->SetRenderState (D3DRENDERSTATE_ZENABLE, 0);
146 	pd3dDevice->SetRenderState (D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
147 	pd3dDevice->SetRenderState (D3DRENDERSTATE_COLORKEYENABLE, FALSE);
148 
149 	D3DMATRIX matID;
150 	D3DUtil_SetIdentityMatrix (matID);
151 
152 	while (!g_stkWorlds.empty ())
153 		g_stkWorlds.pop ();
154 
155 	g_stkWorlds.push (matID);
156     pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matID );
157 
158 	g_setTextures.Initialize ();
159 
160 	g_bTransparentLast = FALSE;
161 	g_pd3dtLast = NULL;
162 
163 	Win32_SetupColor();
164 
165     return S_OK;
166 }
167 
168 
169 
170 
171 //-----------------------------------------------------------------------------
172 // Name: App_FinalCleanup()
173 // Desc: Called before the app exits, this function gives the app the chance
174 //       to cleanup after itself.
175 //-----------------------------------------------------------------------------
App_FinalCleanup(LPDIRECT3DDEVICE3 pd3dDevice,LPDIRECT3DVIEWPORT3 pvViewport)176 HRESULT App_FinalCleanup( LPDIRECT3DDEVICE3 pd3dDevice,
177                           LPDIRECT3DVIEWPORT3 pvViewport)
178 {
179     App_DeleteDeviceObjects( pd3dDevice, pvViewport );
180 
181 	return S_OK;
182 }
183 
184 
185 
186 
187 //-----------------------------------------------------------------------------
188 // Name: App_DeleteDeviceObjects()
189 // Desc: Called when the app is exitting, or the device is being changed,
190 //       this function deletes any device dependant objects.
191 //-----------------------------------------------------------------------------
App_DeleteDeviceObjects(LPDIRECT3DDEVICE3 pd3dDevice,LPDIRECT3DVIEWPORT3 pvViewport)192 VOID App_DeleteDeviceObjects( LPDIRECT3DDEVICE3 pd3dDevice,
193                               LPDIRECT3DVIEWPORT3 pvViewport)
194 {
195     D3DTextr_InvalidateAllTextures();
196 
197 	g_setTextures.Uninitialize ();
198 
199 	Win32_InvalidatePages();
200 
201 	Win32_SetupColor();
202 }
203 
204 
205 
206 
207 //----------------------------------------------------------------------------
208 // Name: App_RestoreSurfaces
209 // Desc: Restores any previously lost surfaces. Must do this for all surfaces
210 //       (including textures) that the app created.
211 //----------------------------------------------------------------------------
App_RestoreSurfaces()212 HRESULT App_RestoreSurfaces()
213 {
214 	return S_OK;
215 }
216 
217 
218 
219 
220 //-----------------------------------------------------------------------------
221 // Name: App_ConfirmDevice()
222 // Desc: Called during device intialization, this code checks the device
223 //       for some minimum set of capabilities
224 //-----------------------------------------------------------------------------
App_ConfirmDevice(DDCAPS * pddDriverCaps,D3DDEVICEDESC * pd3dDeviceDesc)225 HRESULT App_ConfirmDevice( DDCAPS* pddDriverCaps,
226 						   D3DDEVICEDESC* pd3dDeviceDesc )
227 {
228 	// Don't allow 3d Devices that don't support textures(Matrox Millenium)
229 	if (!pd3dDeviceDesc->dwMaxTextureWidth)
230 		return DDERR_INVALIDOBJECT;
231 
232     return S_OK;
233 
234 }
235 
236 
237 
238 
239 #define byte __BOGUS1
240 #define bool __BOGUS2
241 
242 extern "C"
243 {
244 #include "types.h"
245 #include "grdef.h"
246 #include "..\main\segment.h"
247 #include "..\main\segpoint.h"
248 #include "..\main\object.h"
249 #include "..\3d\globvars.h"
250 #include "3d.h"
251 #include "palette.h"
252 }
253 
254 #undef __BOGUS1
255 #undef __BOGUS2
256 
257 LPDIRECT3DDEVICE3 g_pd3dDevice;
258 
App_StartFrame(LPDIRECT3DDEVICE3 pd3dDevice,LPDIRECT3DVIEWPORT3 pvViewport,D3DRECT * prcViewRect)259 HRESULT App_StartFrame( LPDIRECT3DDEVICE3 pd3dDevice, LPDIRECT3DVIEWPORT3 pvViewport, D3DRECT* prcViewRect )
260 {
261 	g_pd3dDevice = pd3dDevice;
262 
263 	HRESULT hResult;
264 
265 	hResult = pvViewport->Clear2 (1UL, prcViewRect, D3DCLEAR_TARGET, 0, 1.0f, 0);
266 
267     // Begin the scene
268     hResult = pd3dDevice->BeginScene();
269 
270 	ASSERT (g_stkWorlds.size () == 1);
271 
272 	return hResult;
273 }
274 
App_EndFrame(void)275 HRESULT App_EndFrame (void)
276 {
277 	HRESULT hResult;
278 
279 	hResult = g_pd3dDevice->EndScene ();
280 
281 	ASSERT (g_stkWorlds.size () == 1);
282 
283 	return hResult;
284 }
285 
286 extern "C" RGBQUAD w32lastrgb[256];
287 
Win32_DoSetPalette(PALETTEENTRY * rgpe)288 extern "C" void Win32_DoSetPalette (PALETTEENTRY *rgpe)
289 {
290 	g_setTextures.SetPaletteEntries (rgpe);
291 	for (int i = 0; i < 256; i++) {
292 		w32lastrgb[i].rgbBlue = rgpe[i].peBlue;
293 		w32lastrgb[i].rgbGreen = rgpe[i].peGreen;
294 		w32lastrgb[i].rgbRed = rgpe[i].peRed;
295 	}
296 }
297 
Win32_DoGetPalette(PALETTEENTRY * rgpe)298 extern "C" void Win32_DoGetPalette (PALETTEENTRY *rgpe)
299 {
300 	g_setTextures.GetPaletteEntries (rgpe);
301 }
302 
Win32_PaletteStepUp(int r,int g,int b)303 extern "C" int Win32_PaletteStepUp (int r, int g, int b)
304 {
305 	if (g_setTextures.HasPalette ())
306 	{
307 		g_fPSURed = g_fPSUGreen = g_fPSUBlue = 0.0f;
308 		return FALSE;
309 	}
310 	else
311 	{
312 		g_fPSURed = (float) r / 32.0f;
313 		g_fPSUGreen = (float) g / 32.0f;
314 		g_fPSUBlue = (float) b / 32.0f;
315 		return TRUE;
316 	}
317 }
318 
319 D3DVECTOR g_vecRight, g_vecUp;
320 
Win32_set_view_matrix()321 extern "C" void Win32_set_view_matrix ()
322 {
323 	vms_vector *pPos = &View_position;
324 	vms_matrix *pOrient = &View_matrix;
325 
326 	D3DVECTOR vecView;
327 	vecView.x = (D3DVALUE) f2fl (pPos->x) / 10;
328 	vecView.y = (D3DVALUE) f2fl (pPos->y) / 10;
329 	vecView.z = (D3DVALUE) f2fl (pPos->z) / 10;
330 
331 	D3DMATRIX matView;
332 	D3DVECTOR vecDir;
333 	matView(0, 0) = g_vecRight.x = (D3DVALUE) f2fl (pOrient->rvec.x) / 10;
334 	matView(1, 0) = g_vecRight.y = (D3DVALUE) f2fl (pOrient->rvec.y) / 10;
335 	matView(2, 0) = g_vecRight.z = (D3DVALUE) f2fl (pOrient->rvec.z) / 10;
336 
337 	matView(0, 1) = g_vecUp.x = (D3DVALUE) f2fl (pOrient->uvec.x) / 10;
338 	matView(1, 1) = g_vecUp.y = (D3DVALUE) f2fl (pOrient->uvec.y) / 10;
339 	matView(2, 1) = g_vecUp.z = (D3DVALUE) f2fl (pOrient->uvec.z) / 10;
340 
341 	matView(0, 2) = vecDir.x = (D3DVALUE) f2fl (pOrient->fvec.x) / 10;
342 	matView(1, 2) = vecDir.y = (D3DVALUE) f2fl (pOrient->fvec.y) / 10;
343 	matView(2, 2) = vecDir.z = (D3DVALUE) f2fl (pOrient->fvec.z) / 10;
344 
345 	matView(3, 0) = -DotProduct (g_vecRight, vecView);
346 	matView(3, 1) = -DotProduct (g_vecUp, vecView);
347 	matView(3, 2) = -DotProduct (vecDir, vecView);
348 
349 	matView(0, 3) = matView(1, 3) = matView(2, 3) = 0.0f;
350 	matView(3, 3) = 1.0f;
351 
352     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
353 }
354 
SetTexture(CTexture * pTexture)355 HRESULT SetTexture (CTexture *pTexture)
356 {
357 	HRESULT hResult = S_OK;
358 	LPDIRECT3DTEXTURE2 pd3dt;
359 	BOOL bTransparent;
360 
361 	if (pTexture != NULL)
362 	{
363 		pd3dt = pTexture->GetTexture ();
364 		bTransparent = pTexture->IsTransparent ();
365 	}
366 	else
367 	{
368 		pd3dt = NULL;
369 		bTransparent = FALSE;
370 	}
371 
372 	if (pd3dt != g_pd3dtLast)
373 	{
374 		g_pd3dtLast = pd3dt;
375 
376 		hResult = g_pd3dDevice->SetTexture (0, pd3dt);
377 		ASSERT (SUCCEEDED (hResult));
378 	}
379 
380 	if (bTransparent != g_bTransparentLast)
381 	{
382 		g_bTransparentLast = bTransparent;
383 
384 		hResult = g_pd3dDevice->SetRenderState (D3DRENDERSTATE_COLORKEYENABLE, bTransparent);
385 		ASSERT (SUCCEEDED (hResult));
386 	}
387 	return hResult;
388 }
389 
g3_draw_tmap(int cPoints,g3s_point ** rgpPoints,g3s_uvl * rgpUvls,grs_bitmap * pbm)390 extern "C" bool g3_draw_tmap (int cPoints, g3s_point **rgpPoints, g3s_uvl *rgpUvls, grs_bitmap *pbm)
391 {
392 	ASSERT (cPoints <= sizeof (g_rgVerts) / sizeof (g_rgVerts[0]));
393 
394 	for (ULONG iPoint = 0; iPoint < cPoints; iPoint ++)
395 	{
396 		D3DLVERTEX *pvert = &g_rgVerts [iPoint];
397 		const g3s_point *pPoint = rgpPoints [iPoint];
398 		const g3s_uvl *pUvl = &rgpUvls [iPoint];
399 		double dCol = f2fl (pUvl->l);
400 		double dColR = min (1, max (0, dCol + g_fPSURed));
401 		double dColG = min (1, max (0, dCol + g_fPSUGreen));
402 		double dColB = min (1, max (0, dCol + g_fPSUBlue));
403 
404 		pvert->x = (D3DVALUE) f2fl (pPoint->p3_orig.x) / 10;
405 		pvert->y = (D3DVALUE) f2fl (pPoint->p3_orig.y) / 10;
406 		pvert->z = (D3DVALUE) f2fl (pPoint->p3_orig.z) / 10;
407 		pvert->tu = (D3DVALUE) f2fl (pUvl->u);
408 		pvert->tv = (D3DVALUE) f2fl (pUvl->v);
409 		pvert->color = D3DRGBA (dColR, dColG, dColB, 0);
410 		pvert->specular = 0;
411 	}
412 
413 	HRESULT hResult;
414 	hResult = SetTexture ((CTexture *) pbm->pvSurface);
415 	ASSERT (SUCCEEDED (hResult));
416 
417 	hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, g_rgVerts, cPoints, D3DDP_WAIT);
418 	ASSERT (SUCCEEDED (hResult));
419 
420 	return hResult == S_OK;
421 }
422 
g3_draw_poly(int cPoints,g3s_point ** rgpPoints)423 extern "C" bool g3_draw_poly (int cPoints, g3s_point **rgpPoints)
424 {
425 	ASSERT (cPoints <= sizeof (g_rgVerts) / sizeof (g_rgVerts[0]));
426 	PALETTEENTRY pe = g_setTextures.ReadPalette (grd_curcanv->cv_color);
427 	BYTE bR = pe.peRed;
428 	BYTE bG = pe.peGreen;
429 	BYTE bB = pe.peBlue;
430 	double dColR = min (1, max (0, (float) bR / 256 + g_fPSURed));
431 	double dColG = min (1, max (0, (float) bG / 256 + g_fPSUGreen));
432 	double dColB = min (1, max (0, (float) bB / 256 + g_fPSUBlue));
433 
434 	for (ULONG iPoint = 0; iPoint < cPoints; iPoint ++)
435 	{
436 		D3DLVERTEX *pvert = &g_rgVerts [iPoint];
437 		const g3s_point *pPoint = rgpPoints [iPoint];
438 
439 		pvert->x = (D3DVALUE) f2fl (pPoint->p3_orig.x) / 10;
440 		pvert->y = (D3DVALUE) f2fl (pPoint->p3_orig.y) / 10;
441 		pvert->z = (D3DVALUE) f2fl (pPoint->p3_orig.z) / 10;
442 		pvert->tu = 0;
443 		pvert->tv = 0;
444 		pvert->color = D3DRGBA (dColR, dColG, dColB, 0);
445 		pvert->specular = 0;
446 	}
447 
448 	HRESULT hResult;
449 	hResult = SetTexture (NULL);
450 	ASSERT (SUCCEEDED (hResult));
451 
452 	hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, g_rgVerts, cPoints, D3DDP_WAIT);
453 	ASSERT (SUCCEEDED (hResult));
454 
455 	return S_OK;
456 }
457 
458 
459 
g3_draw_bitmap(vms_vector * pos,fix width,fix height,grs_bitmap * pbm)460 extern "C" bool g3_draw_bitmap (vms_vector *pos, fix width, fix height,grs_bitmap *pbm)
461 {
462 	ULONG cPoints = 4;
463 
464 	D3DVECTOR vecRight = g_vecRight * f2fl (width);
465 	D3DVECTOR vecUp = g_vecUp * f2fl (height);
466 	D3DVECTOR vecPos (
467 		(D3DVALUE) f2fl (pos->x) / 10,
468 		(D3DVALUE) f2fl (pos->y) / 10,
469 		(D3DVALUE) f2fl (pos->z) / 10);
470 
471 	double dCol = 0.5;
472 	double dColR = min (1, max (0, dCol + g_fPSURed));
473 	double dColG = min (1, max (0, dCol + g_fPSUGreen));
474 	double dColB = min (1, max (0, dCol + g_fPSUBlue));
475 	D3DCOLOR col = D3DRGBA (dColR, dColG, dColB, 0);
476 
477 	D3DVALUE flAdjX, flAdjY;
478 	CTexture *pTexture = (CTexture *) pbm->pvSurface;
479 	pTexture->GetBitmapAdj (&flAdjX, &flAdjY);
480 
481 	D3DLVERTEX rgVerts [4] =
482 	{
483 		D3DLVERTEX (vecPos - vecRight - vecUp, col, 0, 0,      flAdjY),
484 		D3DLVERTEX (vecPos - vecRight + vecUp, col, 0, 0,      0),
485 		D3DLVERTEX (vecPos + vecRight + vecUp, col, 0, flAdjX, 0),
486 		D3DLVERTEX (vecPos + vecRight - vecUp, col, 0, flAdjX, flAdjY),
487 	};
488 
489 	HRESULT hResult;
490 	hResult = SetTexture (pTexture);
491 	ASSERT (SUCCEEDED (hResult));
492 
493 	hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, rgVerts, cPoints, D3DDP_WAIT);
494 	ASSERT (SUCCEEDED (hResult));
495 
496 	return S_OK;
497 }
498 
BlitToPrimary(HDC hSrcDC)499 extern "C" void BlitToPrimary(HDC hSrcDC)
500 {
501 	RECT rectDest;
502 	rectDest.left	= 0;
503 	rectDest.top	= 0;
504 	rectDest.right	= g_pFramework->m_dwRenderWidth;
505 	rectDest.bottom	= g_pFramework->m_dwRenderHeight;
506 
507 	if (g_bWindowed)
508 	{
509 		rectDest.left	+= g_pFramework->m_rcScreenRect.left;
510 		rectDest.right	+= g_pFramework->m_rcScreenRect.left;
511 		rectDest.top	+= g_pFramework->m_rcScreenRect.top;
512 		rectDest.bottom	+= g_pFramework->m_rcScreenRect.top;
513 	}
514 
515 	HDC hDstDC;
516 	if (g_pFramework->GetFrontBuffer()->GetDC(&hDstDC) == DD_OK)
517 	{
518 		StretchBlt(hDstDC, rectDest.left, rectDest.top,
519 			rectDest.right - rectDest.left,	rectDest.bottom - rectDest.top,
520 			hSrcDC, 0, 0, 320, 200, SRCCOPY);
521 		g_pFramework->GetFrontBuffer()->ReleaseDC(hDstDC);
522 	}
523 	return;
524 }
525 
BlitToPrimaryRect(HDC hSrcDC,int x,int y,int w,int h,unsigned char * dst)526 extern "C" void BlitToPrimaryRect(HDC hSrcDC, int x, int y, int w, int h,
527 	unsigned char *dst)
528 {
529 	RECT rectDest;
530 	int destWidth = g_pFramework->m_dwRenderWidth;
531 	int destHeight = g_pFramework->m_dwRenderHeight;
532 
533 	rectDest.left	= (x * destWidth) / 320;
534 	rectDest.top	= (y * destHeight) / 200;
535 	rectDest.right	= ((x + w) * destWidth) / 320;
536 	rectDest.bottom	= ((y + h) * destHeight) / 200;
537 
538 	if (g_bWindowed && (int)dst == BM_D3D_DISPLAY)
539 	{
540 		rectDest.left	+= g_pFramework->m_rcScreenRect.left;
541 		rectDest.right	+= g_pFramework->m_rcScreenRect.left;
542 		rectDest.top	+= g_pFramework->m_rcScreenRect.top;
543 		rectDest.bottom	+= g_pFramework->m_rcScreenRect.top;
544 	}
545 
546 	HDC hDstDC;
547 	IDirectDrawSurface4 *pddsDest = ((int)dst == BM_D3D_DISPLAY) ?
548 		g_pFramework->GetFrontBuffer() :
549 		g_pFramework->GetRenderSurface();
550 	if (pddsDest->GetDC(&hDstDC) == DD_OK)
551 	{
552 		StretchBlt(hDstDC, rectDest.left, rectDest.top,
553 			rectDest.right - rectDest.left,	rectDest.bottom - rectDest.top,
554 			hSrcDC, x, y, w, h, SRCCOPY);
555 		pddsDest->ReleaseDC(hDstDC);
556 	}
557 	return;
558 }
559 
Blit(RECT & rectDest,LPDIRECTDRAWSURFACE4 pddsSrc,RECT & rectSrc,DWORD dwFlags,DDBLTFX * pddbltfx,BOOL bPrimary)560 HRESULT Blit (
561 	RECT &rectDest,
562 	LPDIRECTDRAWSURFACE4 pddsSrc,
563 	RECT &rectSrc,
564 	DWORD dwFlags,
565 	DDBLTFX *pddbltfx,
566 	BOOL bPrimary)
567 {
568 	rectDest.left	= rectDest.left * g_pFramework->m_dwRenderWidth / 320;
569 	rectDest.top	= rectDest.top  * g_pFramework->m_dwRenderHeight / 200;
570 	rectDest.right	= (rectDest.right  + 1) * g_pFramework->m_dwRenderWidth  / 320;
571 	rectDest.bottom	= (rectDest.bottom + 1) * g_pFramework->m_dwRenderHeight / 200;
572 
573 	if (g_bWindowed && bPrimary)
574 	{
575 		rectDest.left	+= g_pFramework->m_rcScreenRect.left;
576 		rectDest.right	+= g_pFramework->m_rcScreenRect.left;
577 		rectDest.top	+= g_pFramework->m_rcScreenRect.top;
578 		rectDest.bottom	+= g_pFramework->m_rcScreenRect.top;
579 	}
580 
581 	IDirectDrawSurface4 *pddsDest;
582 	if (bPrimary)
583 	{
584 		pddsDest = g_pFramework->GetFrontBuffer ();
585 	}
586 	else
587 	{
588 		pddsDest = g_pFramework->GetRenderSurface();
589 	}
590 
591 	return pddsDest->Blt (
592 		&rectDest,
593 		pddsSrc,
594 		&rectSrc,
595 		dwFlags,
596 		pddbltfx);
597 }
598 
findmask6(int in_mask,int * shift,int * bits6)599 static void findmask6(int in_mask, int *shift, int *bits6)
600 {
601 	int i;
602 
603 	if (!in_mask) {
604 		*shift = 0;
605 		*bits6 = 6;
606 		return;
607 	}
608 	i = 0;
609 	while (!(in_mask & 1))
610 	{
611 		in_mask >>= 1;
612 		i++;
613 	}
614 	*shift = i;
615 	i = 0;
616 	while (in_mask & 1)
617 	{
618 		in_mask >>= 1;
619 		i++;
620 	}
621 	*bits6 = 6 - i;
622 }
623 
Win32_SetupColor(void)624 void Win32_SetupColor(void)
625 {
626 	DDPIXELFORMAT pf;
627 	pf.dwSize = sizeof(pf);
628 	g_pFramework->GetFrontBuffer ()->GetPixelFormat(&pf);
629 	g_TrueColor = pf.dwRGBBitCount == 24 || pf.dwRGBBitCount == 32;
630 	if (!g_TrueColor)
631 	{
632 		findmask6(pf.dwRBitMask, &g_RShift, &g_RBits6);
633 		findmask6(pf.dwGBitMask, &g_GShift, &g_GBits6);
634 		findmask6(pf.dwBBitMask, &g_BShift, &g_BBits6);
635 	}
636 }
637 
Win32_Rect(int left,int top,int right,int bot,int iSurf,int iCol)638 extern "C" void Win32_Rect (
639 	int left, int top, int right, int bot,
640 	int iSurf,
641 	int iCol)
642 {
643 	RECT rectDest = {left, top, right, bot};
644 
645 	DDBLTFX ddbltfx;
646 	ddbltfx.dwSize = sizeof (ddbltfx);
647 
648 	#if 0
649 	if (g_setTextures.HasPalette ())
650 	{
651 		ddbltfx.dwFillColor = iCol;
652 	}
653 	else
654 	{
655 		PALETTEENTRY pe = g_setTextures.ReadPalette (iCol);
656 		ddbltfx.dwFillColor = *(DWORD*) &pe;
657 	}
658 	#else
659 	unsigned char *p = gr_current_pal + iCol * 3;
660 	if (g_TrueColor)
661 		ddbltfx.dwFillColor = (255 << 24) | (p[0] << 18) |
662 			(p[1] << 10) | (p[2] << 2);
663 	else
664 		ddbltfx.dwFillColor = (p[0] >> g_RBits6) << g_RShift |
665 			(p[1] >> g_GBits6) << g_GShift |
666 			(p[2] >> g_BBits6) << g_BShift;
667 	#endif
668 
669 	HRESULT hr = Blit (
670 		rectDest,
671 		NULL,
672 		rectDest,
673 		DDBLT_WAIT | DDBLT_COLORFILL,
674 		&ddbltfx,
675 		iSurf == BM_D3D_DISPLAY);
676 }
677 
678 
Win32_BlitLinearToDirectX(int w,int h,int dx,int dy,int sx,int sy,void * pvSurface,int iSurf,BOOL bTransparent)679 extern "C" void Win32_BlitLinearToDirectX (
680 	int w, int h,
681 	int dx, int dy,
682 	int sx, int sy,
683 	void *pvSurface,
684 	int iSurf,
685 	BOOL bTransparent)
686 {
687 	CTexture *pTexture = (CTexture *) pvSurface;
688 
689 	if (pTexture == NULL)
690 	{
691 		return;
692 	}
693 
694 	if (!(w <= pTexture->m_ulWidthSource && h <= pTexture->m_ulHeightSource))
695 	{
696 		ASSERT (FALSE);
697 	}
698 
699 	if (pTexture->isDirtyMemory ())
700 	{
701 		pTexture->CleanMemory ();
702 	}
703 
704 	RECT rectDest = {dx, dy, dx + w, dy + h};
705 	RECT rectSrc = {0, 0, w, h};
706 
707 	HRESULT hr = Blit (
708 		rectDest,
709 		pTexture->GetSurface (),
710 		rectSrc,
711 		DDBLT_WAIT,
712 		NULL,
713 		iSurf == BM_D3D_DISPLAY);
714 }
715 
Win32_start_instance_matrix(vms_vector * pPos,vms_matrix * pOrient)716 extern "C" void Win32_start_instance_matrix (vms_vector *pPos, vms_matrix *pOrient)
717 {
718 	D3DMATRIX matOrientInv;
719 	if (pOrient != NULL)
720 	{
721 		D3DMATRIX matOrient;
722 
723 		matOrient(0, 0) = (D3DVALUE) f2fl (pOrient->rvec.x);
724 		matOrient(1, 0) = (D3DVALUE) f2fl (pOrient->rvec.y);
725 		matOrient(2, 0) = (D3DVALUE) f2fl (pOrient->rvec.z);
726 		matOrient(3, 0) = 0;
727 		matOrient(0, 1) = (D3DVALUE) f2fl (pOrient->uvec.x);
728 		matOrient(1, 1) = (D3DVALUE) f2fl (pOrient->uvec.y);
729 		matOrient(2, 1) = (D3DVALUE) f2fl (pOrient->uvec.z);
730 		matOrient(3, 1) = 0;
731 		matOrient(0, 2) = (D3DVALUE) f2fl (pOrient->fvec.x);
732 		matOrient(1, 2) = (D3DVALUE) f2fl (pOrient->fvec.y);
733 		matOrient(2, 2) = (D3DVALUE) f2fl (pOrient->fvec.z);
734 		matOrient(3, 2) = 0;
735 		matOrient(0, 3) = 0;
736 		matOrient(1, 3) = 0;
737 		matOrient(2, 3) = 0;
738 		matOrient(3, 3) = 1;
739 
740 		D3DMath_MatrixInvert (matOrientInv, matOrient);
741 	}
742 	else
743 	{
744 		D3DUtil_SetIdentityMatrix (matOrientInv);
745 	}
746 
747 	D3DMATRIX matTranslate;
748 	D3DUtil_SetTranslateMatrix (
749 		matTranslate,
750 		(D3DVALUE) f2fl (pPos->x) / 10,
751 		(D3DVALUE) f2fl (pPos->y) / 10,
752 		(D3DVALUE) f2fl (pPos->z) / 10);
753 
754 	D3DMATRIX matTmp;
755 	D3DMath_MatrixMultiply (matTmp, g_stkWorlds.top (), matTranslate);
756 	D3DMATRIX matWorld;
757 	D3DMath_MatrixMultiply (matWorld, matTmp, matOrientInv);
758 
759 	g_stkWorlds.push (matWorld);
760 
761     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
762 }
763 
Win32_done_instance(void)764 extern "C" void Win32_done_instance (void)
765 {
766 	g_stkWorlds.pop ();
767 
768 	D3DMATRIX matWorld = g_stkWorlds.top ();
769     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
770 }
771 
772 
Win32_SetTextureBits(grs_bitmap * bm,unsigned char * data,int bRle)773 extern "C" void Win32_SetTextureBits (grs_bitmap *bm, unsigned char *data, int bRle)
774 {
775 	CTexture *pTexture = (CTexture *) bm->pvSurface;
776 	if (pTexture != NULL)
777 	{
778 		pTexture->SetBitmapData (data, bRle);
779 		pTexture->SetTransparent (bm->bm_flags & BM_FLAG_TRANSPARENT);
780 	}
781 }
782 
Win32_CreateTexture(grs_bitmap * bm)783 extern "C" void Win32_CreateTexture (grs_bitmap *bm)
784 {
785 	bm->pvSurface = (void *) g_setTextures.CreateTexture (
786 		bm->bm_data,
787 		bm->bm_w,
788 		bm->bm_h,
789 		bm->bm_rowsize);
790 }
791 
Win32_FreeTexture(grs_bitmap * bm)792 extern "C" void Win32_FreeTexture (grs_bitmap *bm)
793 {
794 	CTexture *pTexture = (CTexture *) bm->pvSurface;
795 	if (pTexture != NULL)
796 	{
797 		g_setTextures.FreeTexture (pTexture);
798 		bm->pvSurface = NULL;
799 	}
800 }
801 
Win32_SetTransparent(void * pvTexture,BOOL bTransparent)802 extern "C" void Win32_SetTransparent (void *pvTexture, BOOL bTransparent)
803 {
804 	CTexture *pTexture = (CTexture *) pvTexture;
805 	if (pTexture != NULL)
806 	{
807 		pTexture->SetTransparent (bTransparent);
808 	}
809 }
810 
811