]> icculus.org git repositories - btb/d2x.git/blob - arch/win32/scene.cpp
more header cleanup
[btb/d2x.git] / arch / win32 / scene.cpp
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 "gr.h"
246 #include "..\main\inferno.h"
247 #include "..\3d\globvars.h"
248 #include "3d.h"
249 }
250
251 #undef __BOGUS1
252 #undef __BOGUS2
253
254 LPDIRECT3DDEVICE3 g_pd3dDevice;
255
256 HRESULT App_StartFrame( LPDIRECT3DDEVICE3 pd3dDevice, LPDIRECT3DVIEWPORT3 pvViewport, D3DRECT* prcViewRect )
257 {
258         g_pd3dDevice = pd3dDevice;
259
260         HRESULT hResult;
261
262         hResult = pvViewport->Clear2 (1UL, prcViewRect, D3DCLEAR_TARGET, 0, 1.0f, 0);
263
264     // Begin the scene 
265     hResult = pd3dDevice->BeginScene();
266
267         ASSERT (g_stkWorlds.size () == 1);
268
269         return hResult;
270 }
271
272 HRESULT App_EndFrame (void)
273 {
274         HRESULT hResult;
275         
276         hResult = g_pd3dDevice->EndScene ();
277
278         ASSERT (g_stkWorlds.size () == 1);
279
280         return hResult;
281 }
282
283 extern "C" RGBQUAD w32lastrgb[256];
284
285 extern "C" void Win32_DoSetPalette (PALETTEENTRY *rgpe)
286 {
287         g_setTextures.SetPaletteEntries (rgpe);
288         for (int i = 0; i < 256; i++) {
289                 w32lastrgb[i].rgbBlue = rgpe[i].peBlue;
290                 w32lastrgb[i].rgbGreen = rgpe[i].peGreen;
291                 w32lastrgb[i].rgbRed = rgpe[i].peRed;
292         }
293 }
294
295 extern "C" void Win32_DoGetPalette (PALETTEENTRY *rgpe)
296 {
297         g_setTextures.GetPaletteEntries (rgpe);
298 }
299
300 extern "C" int Win32_PaletteStepUp (int r, int g, int b)
301 {
302         if (g_setTextures.HasPalette ())
303         {
304                 g_fPSURed = g_fPSUGreen = g_fPSUBlue = 0.0f;
305                 return FALSE;
306         }
307         else
308         {
309                 g_fPSURed = (float) r / 32.0f;
310                 g_fPSUGreen = (float) g / 32.0f;
311                 g_fPSUBlue = (float) b / 32.0f;
312                 return TRUE;
313         }
314 }
315
316 D3DVECTOR g_vecRight, g_vecUp;
317
318 extern "C" void Win32_set_view_matrix ()
319 {
320         vms_vector *pPos = &View_position;
321         vms_matrix *pOrient = &View_matrix;
322
323         D3DVECTOR vecView;
324         vecView.x = (D3DVALUE) f2fl (pPos->x) / 10;
325         vecView.y = (D3DVALUE) f2fl (pPos->y) / 10;
326         vecView.z = (D3DVALUE) f2fl (pPos->z) / 10;
327
328         D3DMATRIX matView;
329         D3DVECTOR vecDir;
330         matView(0, 0) = g_vecRight.x = (D3DVALUE) f2fl (pOrient->rvec.x) / 10;
331         matView(1, 0) = g_vecRight.y = (D3DVALUE) f2fl (pOrient->rvec.y) / 10;
332         matView(2, 0) = g_vecRight.z = (D3DVALUE) f2fl (pOrient->rvec.z) / 10;
333
334         matView(0, 1) = g_vecUp.x = (D3DVALUE) f2fl (pOrient->uvec.x) / 10;
335         matView(1, 1) = g_vecUp.y = (D3DVALUE) f2fl (pOrient->uvec.y) / 10;
336         matView(2, 1) = g_vecUp.z = (D3DVALUE) f2fl (pOrient->uvec.z) / 10;
337
338         matView(0, 2) = vecDir.x = (D3DVALUE) f2fl (pOrient->fvec.x) / 10;
339         matView(1, 2) = vecDir.y = (D3DVALUE) f2fl (pOrient->fvec.y) / 10;
340         matView(2, 2) = vecDir.z = (D3DVALUE) f2fl (pOrient->fvec.z) / 10;
341
342         matView(3, 0) = -DotProduct (g_vecRight, vecView);
343         matView(3, 1) = -DotProduct (g_vecUp, vecView);
344         matView(3, 2) = -DotProduct (vecDir, vecView);
345
346         matView(0, 3) = matView(1, 3) = matView(2, 3) = 0.0f;
347         matView(3, 3) = 1.0f;
348
349     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
350 }
351
352 HRESULT SetTexture (CTexture *pTexture)
353 {
354         HRESULT hResult = S_OK;
355         LPDIRECT3DTEXTURE2 pd3dt;
356         BOOL bTransparent;
357
358         if (pTexture != NULL)
359         {
360                 pd3dt = pTexture->GetTexture ();
361                 bTransparent = pTexture->IsTransparent ();
362         }
363         else
364         {
365                 pd3dt = NULL;
366                 bTransparent = FALSE;
367         }
368
369         if (pd3dt != g_pd3dtLast)
370         {
371                 g_pd3dtLast = pd3dt;
372
373                 hResult = g_pd3dDevice->SetTexture (0, pd3dt);
374                 ASSERT (SUCCEEDED (hResult));
375         }
376
377         if (bTransparent != g_bTransparentLast)
378         {
379                 g_bTransparentLast = bTransparent;
380
381                 hResult = g_pd3dDevice->SetRenderState (D3DRENDERSTATE_COLORKEYENABLE, bTransparent);
382                 ASSERT (SUCCEEDED (hResult));
383         }
384         return hResult;
385 }
386
387 extern "C" bool g3_draw_tmap (int cPoints, g3s_point **rgpPoints, g3s_uvl *rgpUvls, grs_bitmap *pbm)
388 {
389         ASSERT (cPoints <= sizeof (g_rgVerts) / sizeof (g_rgVerts[0]));
390
391         for (ULONG iPoint = 0; iPoint < cPoints; iPoint ++)
392         {
393                 D3DLVERTEX *pvert = &g_rgVerts [iPoint];
394                 const g3s_point *pPoint = rgpPoints [iPoint];
395                 const g3s_uvl *pUvl = &rgpUvls [iPoint];
396                 double dCol = f2fl (pUvl->l);
397                 double dColR = min (1, max (0, dCol + g_fPSURed));
398                 double dColG = min (1, max (0, dCol + g_fPSUGreen));
399                 double dColB = min (1, max (0, dCol + g_fPSUBlue));
400
401                 pvert->x = (D3DVALUE) f2fl (pPoint->p3_orig.x) / 10;
402                 pvert->y = (D3DVALUE) f2fl (pPoint->p3_orig.y) / 10;
403                 pvert->z = (D3DVALUE) f2fl (pPoint->p3_orig.z) / 10;
404                 pvert->tu = (D3DVALUE) f2fl (pUvl->u);
405                 pvert->tv = (D3DVALUE) f2fl (pUvl->v);
406                 pvert->color = D3DRGBA (dColR, dColG, dColB, 0);
407                 pvert->specular = 0;
408         }
409
410         HRESULT hResult;
411         hResult = SetTexture ((CTexture *) pbm->pvSurface);
412         ASSERT (SUCCEEDED (hResult));
413
414         hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, g_rgVerts, cPoints, D3DDP_WAIT);
415         ASSERT (SUCCEEDED (hResult));
416
417         return hResult == S_OK;
418 }
419
420 extern "C" bool g3_draw_poly (int cPoints, g3s_point **rgpPoints)
421 {
422         ASSERT (cPoints <= sizeof (g_rgVerts) / sizeof (g_rgVerts[0]));
423         PALETTEENTRY pe = g_setTextures.ReadPalette (grd_curcanv->cv_color);
424         BYTE bR = pe.peRed;
425         BYTE bG = pe.peGreen;
426         BYTE bB = pe.peBlue;
427         double dColR = min (1, max (0, (float) bR / 256 + g_fPSURed));
428         double dColG = min (1, max (0, (float) bG / 256 + g_fPSUGreen));
429         double dColB = min (1, max (0, (float) bB / 256 + g_fPSUBlue));
430
431         for (ULONG iPoint = 0; iPoint < cPoints; iPoint ++)
432         {
433                 D3DLVERTEX *pvert = &g_rgVerts [iPoint];
434                 const g3s_point *pPoint = rgpPoints [iPoint];
435
436                 pvert->x = (D3DVALUE) f2fl (pPoint->p3_orig.x) / 10;
437                 pvert->y = (D3DVALUE) f2fl (pPoint->p3_orig.y) / 10;
438                 pvert->z = (D3DVALUE) f2fl (pPoint->p3_orig.z) / 10;
439                 pvert->tu = 0;
440                 pvert->tv = 0;
441                 pvert->color = D3DRGBA (dColR, dColG, dColB, 0);
442                 pvert->specular = 0;
443         }
444
445         HRESULT hResult;
446         hResult = SetTexture (NULL);
447         ASSERT (SUCCEEDED (hResult));
448
449         hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, g_rgVerts, cPoints, D3DDP_WAIT);
450         ASSERT (SUCCEEDED (hResult));
451
452         return S_OK;
453 }
454
455
456
457 extern "C" bool g3_draw_bitmap (vms_vector *pos, fix width, fix height,grs_bitmap *pbm)
458 {
459         ULONG cPoints = 4;
460
461         D3DVECTOR vecRight = g_vecRight * f2fl (width);
462         D3DVECTOR vecUp = g_vecUp * f2fl (height);
463         D3DVECTOR vecPos (
464                 (D3DVALUE) f2fl (pos->x) / 10,
465                 (D3DVALUE) f2fl (pos->y) / 10,
466                 (D3DVALUE) f2fl (pos->z) / 10);
467
468         double dCol = 0.5;
469         double dColR = min (1, max (0, dCol + g_fPSURed));
470         double dColG = min (1, max (0, dCol + g_fPSUGreen));
471         double dColB = min (1, max (0, dCol + g_fPSUBlue));
472         D3DCOLOR col = D3DRGBA (dColR, dColG, dColB, 0);
473
474         D3DVALUE flAdjX, flAdjY;
475         CTexture *pTexture = (CTexture *) pbm->pvSurface;
476         pTexture->GetBitmapAdj (&flAdjX, &flAdjY);
477
478         D3DLVERTEX rgVerts [4] =
479         {
480                 D3DLVERTEX (vecPos - vecRight - vecUp, col, 0, 0,      flAdjY),
481                 D3DLVERTEX (vecPos - vecRight + vecUp, col, 0, 0,      0),
482                 D3DLVERTEX (vecPos + vecRight + vecUp, col, 0, flAdjX, 0),
483                 D3DLVERTEX (vecPos + vecRight - vecUp, col, 0, flAdjX, flAdjY),
484         };
485
486         HRESULT hResult;
487         hResult = SetTexture (pTexture);
488         ASSERT (SUCCEEDED (hResult));
489
490         hResult = g_pd3dDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, D3DFVF_LVERTEX, rgVerts, cPoints, D3DDP_WAIT);
491         ASSERT (SUCCEEDED (hResult));
492
493         return S_OK;
494 }
495
496 extern "C" void BlitToPrimary(HDC hSrcDC)
497 {
498         RECT rectDest;
499         rectDest.left   = 0;
500         rectDest.top    = 0;
501         rectDest.right  = g_pFramework->m_dwRenderWidth;
502         rectDest.bottom = g_pFramework->m_dwRenderHeight;
503
504         if (g_bWindowed)
505         {
506                 rectDest.left   += g_pFramework->m_rcScreenRect.left;
507                 rectDest.right  += g_pFramework->m_rcScreenRect.left;
508                 rectDest.top    += g_pFramework->m_rcScreenRect.top;
509                 rectDest.bottom += g_pFramework->m_rcScreenRect.top;
510         }
511
512         HDC hDstDC;
513         if (g_pFramework->GetFrontBuffer()->GetDC(&hDstDC) == DD_OK)
514         {
515                 StretchBlt(hDstDC, rectDest.left, rectDest.top, 
516                         rectDest.right - rectDest.left, rectDest.bottom - rectDest.top,
517                         hSrcDC, 0, 0, 320, 200, SRCCOPY);
518                 g_pFramework->GetFrontBuffer()->ReleaseDC(hDstDC);
519         }
520         return;
521 }
522
523 extern "C" void BlitToPrimaryRect(HDC hSrcDC, int x, int y, int w, int h, 
524         unsigned char *dst)
525 {
526         RECT rectDest;
527         int destWidth = g_pFramework->m_dwRenderWidth;
528         int destHeight = g_pFramework->m_dwRenderHeight;
529
530         rectDest.left   = (x * destWidth) / 320;
531         rectDest.top    = (y * destHeight) / 200;
532         rectDest.right  = ((x + w) * destWidth) / 320;
533         rectDest.bottom = ((y + h) * destHeight) / 200;
534
535         if (g_bWindowed && (int)dst == BM_D3D_DISPLAY)
536         {
537                 rectDest.left   += g_pFramework->m_rcScreenRect.left;
538                 rectDest.right  += g_pFramework->m_rcScreenRect.left;
539                 rectDest.top    += g_pFramework->m_rcScreenRect.top;
540                 rectDest.bottom += g_pFramework->m_rcScreenRect.top;
541         }
542
543         HDC hDstDC;
544         IDirectDrawSurface4 *pddsDest = ((int)dst == BM_D3D_DISPLAY) ?
545                 g_pFramework->GetFrontBuffer() :
546                 g_pFramework->GetRenderSurface();
547         if (pddsDest->GetDC(&hDstDC) == DD_OK)
548         {
549                 StretchBlt(hDstDC, rectDest.left, rectDest.top, 
550                         rectDest.right - rectDest.left, rectDest.bottom - rectDest.top,
551                         hSrcDC, x, y, w, h, SRCCOPY);
552                 pddsDest->ReleaseDC(hDstDC);
553         }
554         return;
555 }
556
557 HRESULT Blit (
558         RECT &rectDest,
559         LPDIRECTDRAWSURFACE4 pddsSrc,
560         RECT &rectSrc,
561         DWORD dwFlags,
562         DDBLTFX *pddbltfx,
563         BOOL bPrimary)
564 {
565         rectDest.left   = rectDest.left * g_pFramework->m_dwRenderWidth / 320;
566         rectDest.top    = rectDest.top  * g_pFramework->m_dwRenderHeight / 200;
567         rectDest.right  = (rectDest.right  + 1) * g_pFramework->m_dwRenderWidth  / 320;
568         rectDest.bottom = (rectDest.bottom + 1) * g_pFramework->m_dwRenderHeight / 200;
569
570         if (g_bWindowed && bPrimary)
571         {
572                 rectDest.left   += g_pFramework->m_rcScreenRect.left;
573                 rectDest.right  += g_pFramework->m_rcScreenRect.left;
574                 rectDest.top    += g_pFramework->m_rcScreenRect.top;
575                 rectDest.bottom += g_pFramework->m_rcScreenRect.top;
576         }
577
578         IDirectDrawSurface4 *pddsDest;
579         if (bPrimary)
580         {
581                 pddsDest = g_pFramework->GetFrontBuffer ();
582         }
583         else
584         {
585                 pddsDest = g_pFramework->GetRenderSurface();
586         }
587
588         return pddsDest->Blt (
589                 &rectDest,
590                 pddsSrc,
591                 &rectSrc,
592                 dwFlags,
593                 pddbltfx);
594 }
595
596 static void findmask6(int in_mask, int *shift, int *bits6)
597 {
598         int i;
599
600         if (!in_mask) {
601                 *shift = 0;
602                 *bits6 = 6;
603                 return;
604         }
605         i = 0;
606         while (!(in_mask & 1))
607         {
608                 in_mask >>= 1;
609                 i++;
610         }
611         *shift = i;
612         i = 0;
613         while (in_mask & 1)
614         {
615                 in_mask >>= 1;
616                 i++;
617         }
618         *bits6 = 6 - i;
619 }
620
621 void Win32_SetupColor(void)
622 {
623         DDPIXELFORMAT pf; 
624         pf.dwSize = sizeof(pf);
625         g_pFramework->GetFrontBuffer ()->GetPixelFormat(&pf);
626         g_TrueColor = pf.dwRGBBitCount == 24 || pf.dwRGBBitCount == 32;
627         if (!g_TrueColor)
628         {
629                 findmask6(pf.dwRBitMask, &g_RShift, &g_RBits6);
630                 findmask6(pf.dwGBitMask, &g_GShift, &g_GBits6);
631                 findmask6(pf.dwBBitMask, &g_BShift, &g_BBits6);
632         }
633 }
634
635 extern "C" void Win32_Rect (
636         int left, int top, int right, int bot,
637         int iSurf,
638         int iCol)
639 {
640         RECT rectDest = {left, top, right, bot};
641
642         DDBLTFX ddbltfx;
643         ddbltfx.dwSize = sizeof (ddbltfx);
644
645         #if 0   
646         if (g_setTextures.HasPalette ())
647         {
648                 ddbltfx.dwFillColor = iCol;
649         }
650         else
651         {
652                 PALETTEENTRY pe = g_setTextures.ReadPalette (iCol);
653                 ddbltfx.dwFillColor = *(DWORD*) &pe;
654         }
655         #else
656         unsigned char *p = gr_current_pal + iCol * 3;
657         if (g_TrueColor)
658                 ddbltfx.dwFillColor = (255 << 24) | (p[0] << 18) | 
659                         (p[1] << 10) | (p[2] << 2);
660         else
661                 ddbltfx.dwFillColor = (p[0] >> g_RBits6) << g_RShift |
662                         (p[1] >> g_GBits6) << g_GShift |
663                         (p[2] >> g_BBits6) << g_BShift;
664         #endif
665
666         HRESULT hr = Blit (
667                 rectDest,
668                 NULL,
669                 rectDest,
670                 DDBLT_WAIT | DDBLT_COLORFILL,
671                 &ddbltfx,
672                 iSurf == BM_D3D_DISPLAY);
673 }
674
675
676 extern "C" void Win32_BlitLinearToDirectX (
677         int w, int h,
678         int dx, int dy,
679         int sx, int sy,
680         void *pvSurface,
681         int iSurf,
682         BOOL bTransparent)
683 {
684         CTexture *pTexture = (CTexture *) pvSurface;
685
686         if (pTexture == NULL)
687         {
688                 return;
689         }
690
691         if (!(w <= pTexture->m_ulWidthSource && h <= pTexture->m_ulHeightSource))
692         {
693                 ASSERT (FALSE);
694         }
695
696         if (pTexture->isDirtyMemory ())
697         {
698                 pTexture->CleanMemory ();
699         }
700
701         RECT rectDest = {dx, dy, dx + w, dy + h};
702         RECT rectSrc = {0, 0, w, h};
703
704         HRESULT hr = Blit (
705                 rectDest,
706                 pTexture->GetSurface (),
707                 rectSrc,
708                 DDBLT_WAIT,
709                 NULL,
710                 iSurf == BM_D3D_DISPLAY);
711 }
712
713 extern "C" void Win32_start_instance_matrix (vms_vector *pPos, vms_matrix *pOrient)
714 {
715         D3DMATRIX matOrientInv;
716         if (pOrient != NULL)
717         {
718                 D3DMATRIX matOrient;
719
720                 matOrient(0, 0) = (D3DVALUE) f2fl (pOrient->rvec.x);
721                 matOrient(1, 0) = (D3DVALUE) f2fl (pOrient->rvec.y);
722                 matOrient(2, 0) = (D3DVALUE) f2fl (pOrient->rvec.z);
723                 matOrient(3, 0) = 0;
724                 matOrient(0, 1) = (D3DVALUE) f2fl (pOrient->uvec.x);
725                 matOrient(1, 1) = (D3DVALUE) f2fl (pOrient->uvec.y);
726                 matOrient(2, 1) = (D3DVALUE) f2fl (pOrient->uvec.z);
727                 matOrient(3, 1) = 0;
728                 matOrient(0, 2) = (D3DVALUE) f2fl (pOrient->fvec.x);
729                 matOrient(1, 2) = (D3DVALUE) f2fl (pOrient->fvec.y);
730                 matOrient(2, 2) = (D3DVALUE) f2fl (pOrient->fvec.z);
731                 matOrient(3, 2) = 0;
732                 matOrient(0, 3) = 0;
733                 matOrient(1, 3) = 0;
734                 matOrient(2, 3) = 0;
735                 matOrient(3, 3) = 1;
736
737                 D3DMath_MatrixInvert (matOrientInv, matOrient);
738         }
739         else
740         {
741                 D3DUtil_SetIdentityMatrix (matOrientInv);
742         }
743
744         D3DMATRIX matTranslate;
745         D3DUtil_SetTranslateMatrix (
746                 matTranslate,
747                 (D3DVALUE) f2fl (pPos->x) / 10,
748                 (D3DVALUE) f2fl (pPos->y) / 10,
749                 (D3DVALUE) f2fl (pPos->z) / 10);
750
751         D3DMATRIX matTmp;
752         D3DMath_MatrixMultiply (matTmp, g_stkWorlds.top (), matTranslate);
753         D3DMATRIX matWorld;
754         D3DMath_MatrixMultiply (matWorld, matTmp, matOrientInv);
755
756         g_stkWorlds.push (matWorld);
757
758     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
759 }
760
761 extern "C" void Win32_done_instance (void)
762 {
763         g_stkWorlds.pop ();
764
765         D3DMATRIX matWorld = g_stkWorlds.top ();
766     g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
767 }
768
769
770 extern "C" void Win32_SetTextureBits (grs_bitmap *bm, unsigned char *data, int bRle)
771 {
772         CTexture *pTexture = (CTexture *) bm->pvSurface;
773         if (pTexture != NULL)
774         {
775                 pTexture->SetBitmapData (data, bRle);
776                 pTexture->SetTransparent (bm->bm_flags & BM_FLAG_TRANSPARENT);
777         }
778 }
779
780 extern "C" void Win32_CreateTexture (grs_bitmap *bm)
781 {
782         bm->pvSurface = (void *) g_setTextures.CreateTexture (
783                 bm->bm_data,
784                 bm->bm_w,
785                 bm->bm_h,
786                 bm->bm_rowsize);
787 }
788
789 extern "C" void Win32_FreeTexture (grs_bitmap *bm)
790 {
791         CTexture *pTexture = (CTexture *) bm->pvSurface;
792         if (pTexture != NULL)
793         {
794                 g_setTextures.FreeTexture (pTexture);
795                 bm->pvSurface = NULL;
796         }
797 }
798
799 extern "C" void Win32_SetTransparent (void *pvTexture, BOOL bTransparent)
800 {
801         CTexture *pTexture = (CTexture *) pvTexture;
802         if (pTexture != NULL)
803         {
804                 pTexture->SetTransparent (bTransparent);
805         }
806 }
807