remove needless sleep on linux hmiplay startup (d1x r1.6)
[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 "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
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
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
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
298 extern "C" void Win32_DoGetPalette (PALETTEENTRY *rgpe)
299 {
300         g_setTextures.GetPaletteEntries (rgpe);
301 }
302
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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