source: trunk/src/ddraw/OS2DDRAW.CPP@ 587

Last change on this file since 587 was 587, checked in by hugh, 26 years ago

Implemented new colorconversion routine and fixed bug in fastblt function.
Changed the palettehandling code

File size: 53.5 KB
Line 
1#include <memory.h>
2
3#define INITGUID
4#include "os2ddraw.h"
5#include "os2clipper.h"
6#include "os2palette.h"
7#include "os2surface.h"
8#define _OS2WIN_H
9#define FAR
10#include "misc.h"
11#include <string.h>
12#include <winreg.h>
13#include <winuser.h>
14#include <winerror.h>
15#include <builtin.h>
16#include "cio2.h"
17
18// include with the videomodes we support
19// better would be to get these modes from the card
20// But for now we use standard VESA 2.0 modes with 70Hz
21#include "os2ddrawmodes.h"
22#include "os2DDWindow.h"
23#include "os2palset.h"
24
25#define KEY_DIRECT2 "\\Software\\Win32OS2\\Direct2"
26#define KEY_DIRECT2DRAW "\\Software\\Win32OS2\\Direct2\\Draw"
27
28FOURCC SupportedFourCCs[] = {FOURCC_SCRN,FOURCC_LUT8,FOURCC_R565,FOURCC_RGB3,FOURCC_RGB4};
29//******************************************************************************
30//******************************************************************************
31OS2IDirectDraw::OS2IDirectDraw(GUID *lpGUID) :
32 Referenced(0), lastError(DD_OK),
33 pFrameBuffer(NULL), hwndClient(0), screenwidth(640),
34 screenheight(480), screenbpp(8),PrimaryExists(FALSE),pPrimSurf(NULL)
35
36{
37 HKEY hkDirectDraw2;
38 DWORD dwVSize, dwVType;
39 ULONG rc;
40
41 // Setup table for 3d devices
42 Vtbl3D.AddRef = D3DAddRef;
43 Vtbl3D.Release = D3DRelease;
44 Vtbl3D.QueryInterface = D3DQueryInterface;
45 Vtbl3D.Initialize = D3DInitialize;
46 Vtbl3D.EnumDevices = D3DEnumDevices;
47 Vtbl3D.CreateLight = D3DCreateLight;
48 Vtbl3D.CreateMaterial = D3DCreateMaterial;
49 Vtbl3D.CreateViewport = D3DCreateViewport;
50 Vtbl3D.FindDevice = D3DFindDevice;
51
52 // old V2 Interface
53 Vtbl.AddRef = DrawAddRef;
54 Vtbl.Release = DrawRelease;
55 Vtbl.QueryInterface = DrawQueryInterface;
56 Vtbl.Compact = DrawCompact;
57 Vtbl.CreateClipper = DrawCreateClipper;
58 Vtbl.CreatePalette = DrawCreatePalette;
59 Vtbl.CreateSurface = DrawCreateSurface;
60 Vtbl.DuplicateSurface = DrawDuplicateSurface;
61 Vtbl.EnumDisplayModes = DrawEnumDisplayModes;
62 Vtbl.EnumSurfaces = DrawEnumSurfaces;
63 Vtbl.FlipToGDISurface = DrawFlipToGDISurface;
64 Vtbl.GetCaps = DrawGetCaps;
65 Vtbl.GetDisplayMode = DrawGetDisplayMode;
66 Vtbl.GetFourCCCodes = DrawGetFourCCCodes;
67 Vtbl.GetGDISurface = DrawGetGDISurface;
68 Vtbl.GetMonitorFrequency = DrawGetMonitorFrequency;
69 Vtbl.GetScanLine = DrawGetScanLine;
70 Vtbl.GetVerticalBlankStatus = DrawGetVerticalBlankStatus;
71 Vtbl.Initialize = DrawInitialize;
72 Vtbl.RestoreDisplayMode = DrawRestoreDisplayMode;
73 Vtbl.SetCooperativeLevel = DrawSetCooperativeLevel;
74 if(lpGUID && *lpGUID == IID_IDirectDraw2)
75 *(ULONG *)&Vtbl.SetDisplayMode = (ULONG)DrawSetDisplayMode2;
76 else
77 *(ULONG *)&Vtbl.SetDisplayMode = (ULONG)DrawSetDisplayMode;
78 Vtbl.WaitForVerticalBlank = DrawWaitForVerticalBlank;
79 Vtbl.GetAvailableVidMem = DrawGetAvailableVidMem;
80
81 // New V4 interface
82 Vtbl4.AddRef = DrawAddRef; // todo change to a DrawAddRef4 as handling this has changed
83 Vtbl4.Release = DrawRelease; // see above
84 Vtbl4.QueryInterface = DrawQueryInterface;
85 Vtbl4.Compact = DrawCompact;
86 Vtbl4.CreateClipper = DrawCreateClipper;
87 Vtbl4.CreateSurface = DrawCreateSurface4;//
88 Vtbl4.DuplicateSurface = DrawDuplicateSurface4;//
89 Vtbl4.EnumDisplayModes = DrawEnumDisplayModes4;//
90 Vtbl4.EnumSurfaces = DrawEnumSurfaces4; //
91 Vtbl4.FlipToGDISurface = DrawFlipToGDISurface;
92 Vtbl4.GetCaps = DrawGetCaps;
93 Vtbl4.GetDisplayMode = DrawGetDisplayMode4;//
94 Vtbl4.GetFourCCCodes = DrawGetFourCCCodes;
95 Vtbl4.GetGDISurface = DrawGetGDISurface4;//
96 Vtbl4.GetMonitorFrequency = DrawGetMonitorFrequency;
97 Vtbl4.GetScanLine = DrawGetScanLine;
98 Vtbl4.GetVerticalBlankStatus = DrawGetVerticalBlankStatus;
99 Vtbl4.Initialize = DrawInitialize;
100 Vtbl4.RestoreDisplayMode = DrawRestoreDisplayMode;
101 Vtbl4.SetCooperativeLevel = DrawSetCooperativeLevel;
102 Vtbl4.SetDisplayMode = DrawSetDisplayMode2;
103 Vtbl4.WaitForVerticalBlank = DrawWaitForVerticalBlank;
104 Vtbl4.GetAvailableVidMem = DrawGetAvailableVidMem4;
105 Vtbl4.GetSurfaceFromDC = DrawGetSurfaceFromDC;
106 Vtbl4.RestoreAllSurfaces = DrawRestoreAllSurfaces;
107 Vtbl4.TestCooperativeLevel = DrawTestCooperativeLevel;
108 Vtbl4.GetDeviceIdentifier = DrawGetDeviceIdentifier;
109
110 if(lpGUID && *lpGUID == IID_IDirect3D)
111 {
112 WriteLog("D3D Interface\n");
113
114 lpVtbl = (IDirectDraw4Vtbl *)&Vtbl3D;
115 }
116 else
117 {
118 if(lpGUID && *lpGUID == IID_IDirectDraw4)
119 {
120 WriteLog("V4 Interface\n");
121 lpVtbl = &Vtbl4;
122 }
123 else
124 {
125 WriteLog("<V4 Interface\n");
126 lpVtbl = (IDirectDraw4Vtbl *) &Vtbl;
127 }
128 }
129
130 rc = DiveOpen( &hDive,
131 FALSE,
132 &pFrameBuffer);
133 if(rc)
134 {
135 WriteLog("ERROR: DiveOpen returned %d\n", rc);
136 lastError = DDERR_GENERIC;
137 hDive = NULL;
138 }
139 else
140 {
141 WriteLog("DiveOpen OK\n");
142 }
143 memset( &dCaps,
144 0,
145 sizeof(DIVE_CAPS) );
146 dCaps.ulStructLen = sizeof(DIVE_CAPS);
147
148 rc = DiveQueryCaps( &dCaps,
149 DIVE_BUFFER_SCREEN);
150
151
152 // Shall we run in FS mode ?
153 if(ERROR_SUCCESS==RegOpenKeyA(HKEY_LOCAL_MACHINE,KEY_DIRECT2DRAW,&hkDirectDraw2))
154 {
155 dwVSize = 4;
156 dwVType = REG_DWORD;
157 if(ERROR_SUCCESS!=RegQueryValueExA(hkDirectDraw2,"Fullscreen",NULL,&dwVType,(LPBYTE)&bScale,&dwVSize))
158 bScale = FALSE;
159 }
160 else
161 bScale = FALSE;
162}
163//******************************************************************************
164//******************************************************************************
165OS2IDirectDraw::~OS2IDirectDraw()
166{
167 dprintf(("OS2IDirectDraw::~OS2IDirectDraw()\n"));
168 if(hDive)
169 DiveClose(hDive);
170 if(hDiveColorConv)
171 DiveClose(hDiveColorConv);
172
173 // Safty call in case the program did set the pal to all black
174 // so if the destructor gets called we might be able change this back
175 OS2ResetPhysPalette();
176}
177//******************************************************************************
178//******************************************************************************
179FOURCC OS2IDirectDraw::GetScreenFourCC()
180{
181 return SupportedFourCCs[screenbpp>>3];
182}
183//******************************************************************************
184//******************************************************************************
185HRESULT __stdcall DrawQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
186{
187 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
188 #ifdef DEBUG
189 WriteLog("OS2IDirectDraw::QueryInterface\n");
190 #endif
191
192 *ppvObj = NULL;
193
194 if(!IsEqualGUID(riid, CLSID_DirectDraw) &&
195 !IsEqualGUID(riid, IID_IDirectDraw) &&
196 !IsEqualGUID(riid, IID_IDirectDraw2) &&
197 !IsEqualGUID(riid, IID_IDirectDraw4))
198//&& !IsEqualGUID(riid, IID_IUnknown))
199 return E_NOINTERFACE;
200
201 // ToDo Better way of returning differnent intterfaces for same class
202
203 if(IsEqualGUID(riid, IID_IDirectDraw4))
204 {
205 WriteLog("IID_IDirectDraw4 Interface\n");
206 me->lpVtbl = &me->Vtbl4;
207 }
208 else
209 {
210 WriteLog("No IID_IDirectDraw4 Interface\n");
211 me->lpVtbl = (IDirectDraw4Vtbl *) &me->Vtbl;
212 }
213 *ppvObj = This;
214 DrawAddRef(This);
215
216 return(DD_OK);
217}
218//******************************************************************************
219//******************************************************************************
220ULONG __stdcall DrawAddRef(THIS This)
221{
222 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
223
224 #ifdef DEBUG
225 WriteLog("OS2IDirectDraw::AddRef %d\n", me->Referenced+1);
226 #endif
227
228 return ++me->Referenced;
229}
230//******************************************************************************
231//******************************************************************************
232ULONG __stdcall DrawRelease(THIS This)
233{
234 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
235 ULONG rc;
236
237 #ifdef DEBUG
238 WriteLog("OS2IDirectDraw::Release %d\n", me->Referenced-1);
239 WriteLog("OS2IDirectDraw::%X \n", me);
240 #endif
241
242 if(me->Referenced)
243 {
244
245 me->Referenced--;
246 if(me->Referenced == 0)
247 {
248 delete(me);
249 rc = 0;
250 }
251 else
252 rc = me->Referenced;
253 }
254 else
255 rc = 0;
256
257 return rc;
258}
259//******************************************************************************
260//******************************************************************************
261HRESULT __stdcall DrawCompact(THIS)
262{
263 #ifdef DEBUG
264 WriteLog("Compact\n");
265 #endif
266
267 return(DD_OK);
268}
269//******************************************************************************
270//******************************************************************************
271HRESULT __stdcall DrawCreateClipper(THIS This, DWORD, LPDIRECTDRAWCLIPPER FAR *lplpDD, IUnknown FAR * )
272{
273 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
274 OS2IDirectDrawClipper *newclip;
275 HRESULT rc;
276
277 newclip = new OS2IDirectDrawClipper(me);
278
279 #ifdef DEBUG
280 WriteLog("CreateClipper\n");
281 #endif
282
283 if(newclip == NULL)
284 {
285 rc = DDERR_OUTOFMEMORY;
286 }
287 else
288 {
289 newclip->Vtbl.AddRef((IDirectDrawClipper *)newclip);
290 rc = newclip->GetLastError();
291 if(rc != DD_OK)
292 {
293 *lplpDD = NULL;
294 delete newclip;
295 }
296 else
297 *lplpDD = (IDirectDrawClipper *)newclip;
298 }
299
300 return(rc);
301}
302//******************************************************************************
303//******************************************************************************
304HRESULT __stdcall DrawCreatePalette(THIS This, DWORD dwFlags,
305 LPPALETTEENTRY lpColorTable,
306 LPDIRECTDRAWPALETTE FAR *lplpDD,
307 IUnknown FAR *pUnkOuter)
308{
309 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
310 OS2IDirectDrawPalette *newpal;
311 HRESULT rc = DD_OK;
312 int palsize = 0;
313
314 if(dwFlags & DDPCAPS_8BITENTRIES)
315 {
316 // We Don't support Indexed palettes...
317
318 rc = DDERR_INVALIDPARAMS;
319 }
320
321 if(dwFlags & DDPCAPS_2BIT)
322 palsize = 4;
323 if(dwFlags & DDPCAPS_4BIT)
324 palsize = 16;
325 if(dwFlags & DDPCAPS_8BIT)
326 palsize = 256;
327 if(dwFlags & DDPCAPS_ALLOW256)
328 palsize = 256;
329
330 if(palsize == 0)
331 rc = DDERR_INVALIDPARAMS;
332
333 if(DD_OK == rc)
334 {
335 #ifdef DEBUG
336 WriteLog("CreatePalette with %d colors\n", palsize);
337 #endif
338
339 newpal = new OS2IDirectDrawPalette((VOID*)me, palsize, lpColorTable, dwFlags);
340
341 if(newpal == NULL)
342 {
343 rc = DDERR_OUTOFMEMORY;
344 }
345 else
346 {
347 newpal->Vtbl.AddRef((IDirectDrawPalette *)newpal);
348 rc = newpal->GetLastError();
349
350 if(DD_OK != rc)
351 {
352 *lplpDD = NULL;
353 delete newpal;
354 }
355 else
356 *lplpDD = (IDirectDrawPalette *)newpal;
357 }
358 }
359
360 return(rc);
361}
362//******************************************************************************
363//******************************************************************************
364HRESULT __stdcall DrawCreateSurface(THIS This, LPDDSURFACEDESC lpDDSurfaceDesc,
365 LPDIRECTDRAWSURFACE FAR *lplpDD,
366 IUnknown FAR *pUnkOuter)
367{
368 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
369 OS2IDirectDrawSurface *newsurf;
370 HRESULT rc;
371
372 #ifdef DEBUG
373 WriteLog("CreateSurface\n");
374 WriteLog("dwSize %d\n", lpDDSurfaceDesc->dwSize);
375 WriteLog("dwFlags %X\n", lpDDSurfaceDesc->dwFlags);
376 WriteLog("dwHeight %d\n", lpDDSurfaceDesc->dwHeight);
377 WriteLog("dwWidth %d\n", lpDDSurfaceDesc->dwWidth);
378 WriteLog("lPitch %d\n", lpDDSurfaceDesc->lPitch);
379 WriteLog("dwBackBufferCount %d\n", lpDDSurfaceDesc->dwBackBufferCount);
380 WriteLog("dwMipMapCount %d\n", lpDDSurfaceDesc->dwMipMapCount);
381 WriteLog("dwAlphaBitDepth %d\n", lpDDSurfaceDesc->dwAlphaBitDepth);
382 WriteLog("ddsCaps.dwCaps %X\n", lpDDSurfaceDesc->ddsCaps.dwCaps);
383 #endif
384
385 newsurf = new OS2IDirectDrawSurface(me, (LPDDSURFACEDESC2)lpDDSurfaceDesc);
386 if(newsurf == NULL)
387 {
388 rc = DDERR_OUTOFMEMORY;
389 }
390 else
391 {
392 newsurf->Vtbl.AddRef((IDirectDrawSurface *)newsurf);
393 rc = newsurf->GetLastError();
394 if(rc != DD_OK)
395 {
396 WriteLog("Error createing Surface\n\n");
397 *lplpDD = NULL;
398 delete newsurf;
399 }
400 else
401 *lplpDD = (IDirectDrawSurface *)newsurf;
402
403 WriteLog("New Surface created at %08X\n\n", newsurf);
404 }
405
406 return(rc);
407}
408//******************************************************************************
409//******************************************************************************
410HRESULT __stdcall DrawCreateSurface4(THIS This, LPDDSURFACEDESC2 lpDDSurfaceDesc2,
411 LPDIRECTDRAWSURFACE4 FAR *lplpDD,
412 IUnknown FAR *pUnkOuter)
413{
414 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
415 OS2IDirectDrawSurface *newsurf;
416 HRESULT rc;
417
418 #ifdef DEBUG
419 WriteLog("CreateSurface4\n");
420 WriteLog("dwSize %d\n", lpDDSurfaceDesc2->dwSize);
421 WriteLog("dwHeight %d\n", lpDDSurfaceDesc2->dwHeight);
422 WriteLog("dwWidth %d\n", lpDDSurfaceDesc2->dwWidth);
423 WriteLog("lPitch %d\n", lpDDSurfaceDesc2->lPitch);
424 WriteLog("dwBackBufferCount %d\n", lpDDSurfaceDesc2->dwBackBufferCount);
425 WriteLog("dwMipMapCount %d\n", lpDDSurfaceDesc2->dwMipMapCount);
426 WriteLog("dwAlphaBitDepth %d\n", lpDDSurfaceDesc2->dwAlphaBitDepth);
427 WriteLog("ddsCaps.dwCaps %X\n", lpDDSurfaceDesc2->ddsCaps.dwCaps);
428 #endif
429
430 newsurf = new OS2IDirectDrawSurface(me, lpDDSurfaceDesc2);
431
432 if(newsurf == NULL)
433 {
434 rc =DDERR_OUTOFMEMORY;
435 }
436 else
437 {
438 newsurf->Vtbl.AddRef((IDirectDrawSurface *)newsurf);
439 rc = newsurf->GetLastError();
440 if(rc != DD_OK)
441 {
442 WriteLog("Error createing Surface\n\n");
443 *lplpDD = NULL;
444
445 delete newsurf;
446 }
447 else
448 *lplpDD = (IDirectDrawSurface4 *)newsurf;
449
450 WriteLog("New Surface created at %08X\n\n", newsurf);
451 }
452
453 return(rc);
454}
455//******************************************************************************
456//******************************************************************************
457HRESULT __stdcall DrawDuplicateSurface(THIS, LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * )
458{
459 #ifdef DEBUG
460 WriteLog("DuplicateSurface NIY\n");
461 #endif
462 return(DD_OK);
463}
464//******************************************************************************
465//******************************************************************************
466HRESULT __stdcall DrawDuplicateSurface4(THIS, LPDIRECTDRAWSURFACE4, LPDIRECTDRAWSURFACE4 FAR * )
467{
468 #ifdef DEBUG
469 WriteLog("DuplicateSurface4 NIY\n");
470 #endif
471
472 return(DD_OK);
473}
474//******************************************************************************
475//******************************************************************************
476HRESULT __stdcall DrawEnumDisplayModes(THIS This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc,
477 LPVOID lpContext, LPDDENUMMODESCALLBACK lpDDEnumModesCallback)
478{
479 int iMode = 0;
480 DDSURFACEDESC DDSurfAct;
481 BOOL fCallAgain;
482 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
483
484 #ifdef DEBUG
485 WriteLog("EnumDisplayModes\n");
486 #endif
487
488 // Check for Pointer to callback function
489 if (NULL == lpDDEnumModesCallback)
490 {
491 #ifdef DEBUG
492 WriteLog("EnumDisplayModes : Error NO EnumFunction passed in\n");
493 #endif
494
495 return(DDERR_GENERIC);
496 }
497
498
499 // Setting up the surface
500 // During enum we report resolution and bitdepth, maybe we should
501 // also report back : Caps and Pitch
502 memset(&DDSurfAct,0,sizeof(DDSURFACEDESC));
503 DDSurfAct.dwSize = sizeof(DDSURFACEDESC);
504 DDSurfAct.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ;
505 // Only report the bitdepth hope this is ok this way, we must set the BitMask fields
506
507 DDSurfAct.ddpfPixelFormat.dwSize = sizeof (DDPIXELFORMAT);
508 DDSurfAct.ddpfPixelFormat.dwFlags = DDPF_RGB;
509 // Check if we use DIVE or Voodoo
510 if(me->lpVtbl != (IDirectDraw4Vtbl *) &(me->Vtbl3D))
511 {
512 // DIVE modes
513
514 // Enumerate all modes ?
515 if (NULL==lpDDSurfaceDesc)
516 {
517 // Check if we shall report 320x200 mode
518
519 if(dwFlags && DDEDM_STANDARDVGAMODES)
520 {
521 DDSurfAct.dwHeight = ModesDive[0].iYRes;
522 DDSurfAct.dwWidth = ModesDive[0].iXRes;
523 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[0].iBits;
524 if(!lpDDEnumModesCallback(&DDSurfAct,lpContext))
525 {
526 return (DD_OK);
527 }
528 }
529 // Don't know the flag for Mode X so we skip reporting it
530
531 // Now report all our modes
532 iMode = 2;
533 fCallAgain = TRUE;
534 do
535 {
536 // if the mode fits in the current resolution report it
537 // Change this if we support Fullscreen later !!!
538 if(ModesDive[iMode].iXRes < me->dCaps.ulHorizontalResolution)
539 {
540 DDSurfAct.dwHeight = ModesDive[iMode].iYRes;
541 DDSurfAct.dwWidth = ModesDive[iMode].iXRes;
542 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[iMode].iBits;
543 switch(ModesDive[iMode].iBits)
544 {
545 case 16:
546 // VESA uses 565 encoding in 16 bit modes
547 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
548 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000007E0;
549 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
550 break;
551 case 24:
552 // VESA uses per default RGB4
553 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
554 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
555 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
556 break;
557 default:
558 break;
559 }
560 fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
561 }
562 iMode++;
563 }
564 while((ModesDive[iMode].iBits <= me->dCaps.ulDepth) &&
565 (iMode < NUM_MODES_DIVE) && (TRUE==fCallAgain));
566 }
567 else
568 {
569 // No, so filter modes with lpDDSurfaceDesc
570
571 // Return Error if the program want to use other than the 3 supported values
572 // for filtering
573
574 if (lpDDSurfaceDesc->dwFlags & !(DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT))
575 return(DDERR_INVALIDPARAMS);
576
577 iMode = 0;
578 if( (dwFlags && DDEDM_STANDARDVGAMODES) &&
579 (
580 (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
581 (ModesDive[iMode].iXRes==lpDDSurfaceDesc->dwWidth)
582 )||(!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
583 (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
584 (ModesDive[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
585 (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
586 (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
587 (ModesDive[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
588 (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
589 )
590 )
591 {
592 DDSurfAct.dwHeight = ModesDive[0].iYRes;
593 DDSurfAct.dwWidth = ModesDive[0].iXRes;
594 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[0].iBits;
595 if(!lpDDEnumModesCallback(&DDSurfAct,lpContext))
596 {
597 return (DD_OK);
598 }
599 }
600 // Don't know the flag for Mode X so we skip reporting it
601
602 // Now report all our modes
603 iMode = 2;
604 fCallAgain = TRUE;
605 do
606 {
607 // if the mode fits in the current resolution and the filter applies report it
608 // Change this if we support Fullscreen later !!!
609 if( (ModesDive[iMode].iXRes < me->dCaps.ulHorizontalResolution)&&
610 (
611 (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
612 (ModesDive[iMode].iXRes==lpDDSurfaceDesc->dwWidth))||
613 (!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
614 (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
615 (ModesDive[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
616 (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
617 (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
618 (ModesDive[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
619 (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
620 )
621 )
622 {
623 DDSurfAct.dwHeight = ModesDive[iMode].iYRes;
624 DDSurfAct.dwWidth = ModesDive[iMode].iXRes;
625 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesDive[iMode].iBits;
626
627 fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
628 }
629 iMode++;
630 }
631 while((ModesDive[iMode].iBits <= me->dCaps.ulDepth) &&
632 (iMode < NUM_MODES_DIVE) && (TRUE==fCallAgain));
633
634 }
635 }
636 else
637 {
638
639 // VOODOO modes
640
641 // Enumerate all modes ?
642 if (NULL==lpDDSurfaceDesc)
643 {
644
645 // report all our modes
646 iMode = 0;
647 fCallAgain = TRUE;
648 do
649 {
650 DDSurfAct.dwHeight = ModesVoodoo[iMode].iYRes;
651 DDSurfAct.dwWidth = ModesVoodoo[iMode].iXRes;
652 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesVoodoo[iMode].iBits;
653
654 fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
655 iMode++;
656 }
657 while((iMode < NUM_MODES_VOODOO) && (TRUE==fCallAgain));
658 }
659 else
660 {
661 // No, so filter modes with lpDDSurfaceDesc
662
663 // Return Error if the program want to use other than the 3 supported values
664 // for filtering
665
666 if (lpDDSurfaceDesc->dwFlags & !(DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT))
667 {
668 return(DDERR_INVALIDPARAMS);
669 }
670
671 iMode = 2;
672 fCallAgain = TRUE;
673 do
674 {
675 // if the mode fits the filter applies report it
676 if(
677 (((lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)&&
678 (ModesVoodoo[iMode].iXRes==lpDDSurfaceDesc->dwWidth))||
679 (!(lpDDSurfaceDesc->dwFlags & DDSD_WIDTH)))&&
680 (((lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)&&
681 (ModesVoodoo[iMode].iYRes==lpDDSurfaceDesc->dwHeight))||
682 (!(lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT)))&&
683 (((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
684 (ModesVoodoo[iMode].iBits==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount))||
685 (!(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)))
686 )
687 {
688 DDSurfAct.dwHeight = ModesVoodoo[iMode].iYRes;
689 DDSurfAct.dwWidth = ModesVoodoo[iMode].iXRes;
690 DDSurfAct.ddpfPixelFormat.dwRGBBitCount = ModesVoodoo[iMode].iBits;
691
692 fCallAgain = lpDDEnumModesCallback(&DDSurfAct,lpContext);
693 }
694 iMode++;
695 }
696 while((iMode < NUM_MODES_VOODOO) && (TRUE==fCallAgain));
697
698 }
699
700 }
701
702
703
704 return(DD_OK);
705}
706//******************************************************************************
707//******************************************************************************
708HRESULT __stdcall DrawEnumDisplayModes4(THIS This, DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc2,
709 LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpDDEnumModesCallback2)
710{
711 int iMode = 0;
712 DDSURFACEDESC DDSurfAct;
713 BOOL fCallAgain;
714 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
715
716 #ifdef DEBUG
717 WriteLog("EnumDisplayModes4 NIY\n");
718 #endif
719 return(DD_OK);
720}
721//******************************************************************************
722//******************************************************************************
723HRESULT __stdcall DrawEnumSurfaces(THIS, DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK )
724{
725 #ifdef DEBUG
726 WriteLog("EnumSurfaces NIY\n");
727 #endif
728
729 return(DD_OK);
730}
731//******************************************************************************
732//******************************************************************************
733HRESULT __stdcall DrawEnumSurfaces4(THIS, DWORD, LPDDSURFACEDESC2, LPVOID,LPDDENUMSURFACESCALLBACK2 )
734{
735 #ifdef DEBUG
736 WriteLog("EnumSurfaces4 NIY\n");
737 #endif
738
739 return(DD_OK);
740}
741//******************************************************************************
742//******************************************************************************
743HRESULT __stdcall DrawFlipToGDISurface(THIS)
744{
745 #ifdef DEBUG
746 WriteLog("FlipToGDISurface NIY\n");
747 #endif
748
749 return(DD_OK);
750}
751//******************************************************************************
752//******************************************************************************
753HRESULT __stdcall DrawGetCaps(THIS, LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps)
754{
755 #ifdef DEBUG
756 WriteLog("DDGetCaps of ");
757 #endif
758
759 if( (NULL==lpDDDriverCaps) && (NULL==lpDDHELCaps) )
760 return(DDERR_INVALIDPARAMS);
761
762 if(NULL!=lpDDDriverCaps)
763 {
764 // Caller want Driver Caps
765
766 WriteLog("Driver\n");
767
768 if(sizeof(DDCAPS)!=lpDDDriverCaps->dwSize)
769 {
770 WriteLog("Size Not Set\n");
771 return(DDERR_INVALIDPARAMS);
772 }
773 // Clear structure so we only have to set the supported flags
774
775
776 memset(lpDDDriverCaps,0,sizeof(DDCAPS));
777
778
779 // Reset the size
780 lpDDDriverCaps->dwSize = sizeof(DDCAPS);
781
782 // Now report the CAPs back which we support
783 lpDDDriverCaps->dwCaps = DDCAPS_BLT | // We do blitting
784 DDCAPS_BLTCOLORFILL | // We do colorfills
785 DDCAPS_COLORKEY | // We support Colorkeying
786 DDCAPS_COLORKEYHWASSIST | // But we (may) use the CPU
787 DDCAPS_GDI | // Maybe check if we are on Voodoo ?
788 DDCAPS_PALETTEVSYNC; // Got VSync
789
790 lpDDDriverCaps->dwCaps2 = DDCAPS2_CERTIFIED | // Who cares so say yes
791 DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
792 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
793 DDCAPS2_NONLOCALVIDMEM | // All surfaces are in memory
794 DDCAPS2_WIDESURFACES; // Any size you want!
795
796 lpDDDriverCaps->dwCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
797
798// lpDDDriverCaps->dwFXCaps = DDFXCAPS_BLTMIRRORUPDOWN; // DIVE supports this, do we also ?
799 // Maybe later add stretching support?
800
801 lpDDDriverCaps->dwPalCaps = DDPCAPS_8BIT | // Only 8 Bits pals
802 DDPCAPS_ALLOW256 | // But all 256 colors
803 DDPCAPS_VSYNC | // Vsync yet
804 DDPCAPS_PRIMARYSURFACE; //
805 lpDDDriverCaps->dwVidMemTotal = 2048*1024; // total video memory
806 lpDDDriverCaps->dwVidMemFree = 2048*1024; // total free video memory
807 lpDDDriverCaps->dwNumFourCCCodes; // number of supported FOURCC codes
808 lpDDDriverCaps->dwRops[DD_ROP_SPACE]; // supported raster ops
809 lpDDDriverCaps->dwSVBCaps = DDCAPS_BLT | // We do blitting
810 DDCAPS_BLTCOLORFILL | // We do colorfills
811 DDCAPS_COLORKEY | // We support Colorkeying
812 DDCAPS_COLORKEYHWASSIST;
813 lpDDDriverCaps->dwSVBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
814 lpDDDriverCaps->dwSVBFXCaps; // .
815 lpDDDriverCaps->dwSVBRops[DD_ROP_SPACE]; // .
816 lpDDDriverCaps->dwVSBCaps = DDCAPS_BLT | // We do blitting
817 DDCAPS_BLTCOLORFILL | // We do colorfills
818 DDCAPS_COLORKEY | // We support Colorkeying
819 DDCAPS_COLORKEYHWASSIST;
820 lpDDDriverCaps->dwVSBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
821 lpDDDriverCaps->dwVSBFXCaps; // .
822 lpDDDriverCaps->dwVSBRops[DD_ROP_SPACE]; // .
823 lpDDDriverCaps->dwSSBCaps = DDCAPS_BLT | // We do blitting
824 DDCAPS_BLTCOLORFILL | // We do colorfills
825 DDCAPS_COLORKEY | // We support Colorkeying
826 DDCAPS_COLORKEYHWASSIST;
827 lpDDDriverCaps->dwSSBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
828 lpDDDriverCaps->dwSSBFXCaps; // .
829 lpDDDriverCaps->dwSSBRops[DD_ROP_SPACE]; // .
830 lpDDDriverCaps->dwSVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
831 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
832 DDCAPS2_WIDESURFACES; // Any size you want!
833 lpDDDriverCaps->dwNLVBCaps = DDCAPS_BLT | // We do blitting
834 DDCAPS_BLTCOLORFILL | // We do colorfills
835 DDCAPS_COLORKEY | // We support Colorkeying
836 DDCAPS_COLORKEYHWASSIST;
837 lpDDDriverCaps->dwNLVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
838 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
839 DDCAPS2_WIDESURFACES; // Any size you want!
840 lpDDDriverCaps->dwNLVBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
841 lpDDDriverCaps->dwNLVBFXCaps; // .
842 lpDDDriverCaps->dwNLVBRops[DD_ROP_SPACE];// .
843 DDSCAPS2 ddsCaps; // general surface caps
844
845 }
846
847 if(NULL!=lpDDHELCaps)
848 {
849 // Caller wants HEL Caps
850 WriteLog(" HEL\n");
851
852 if(sizeof(DDCAPS)!=lpDDHELCaps->dwSize)
853 {
854 WriteLog("Size Not Set\n");
855 return(DDERR_INVALIDPARAMS);
856 }
857 // Clear structure so we only have to set the supported flags
858
859
860 memset(lpDDHELCaps,0,sizeof(DDCAPS));
861
862
863 // Reset the size
864 lpDDHELCaps->dwSize = sizeof(DDCAPS);
865
866 // Now report the CAPs back which we support
867 lpDDHELCaps->dwCaps = DDCAPS_BLT | // We do blitting
868 DDCAPS_BLTCOLORFILL | // We do colorfills
869 DDCAPS_COLORKEY | // We support Colorkeying
870 DDCAPS_COLORKEYHWASSIST | // But we (may) use the CPU
871 DDCAPS_GDI | // Maybe check if we are on Voodoo ?
872 DDCAPS_PALETTEVSYNC; // Got VSync
873
874 lpDDHELCaps->dwCaps2 = DDCAPS2_CERTIFIED | // Who cares so say yes
875 DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
876 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
877 DDCAPS2_NONLOCALVIDMEM | // All surfaces are in memory
878 DDCAPS2_WIDESURFACES; // Any size you want!
879
880 lpDDHELCaps->dwCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
881
882// lpDDDriverCaps->dwFXCaps = DDFXCAPS_BLTMIRRORUPDOWN; // DIVE supports this, do we also ?
883 // Maybe later add stretching support?
884
885 lpDDHELCaps->dwPalCaps = DDPCAPS_8BIT | // Only 8 Bits pals
886 DDPCAPS_ALLOW256 | // But all 256 colors
887 DDPCAPS_VSYNC | // Vsync yet
888 DDPCAPS_PRIMARYSURFACE; //
889 lpDDHELCaps->dwVidMemTotal = 2048*1024; // total video memory
890 lpDDHELCaps->dwVidMemFree = 2048*1024; // total free video memory
891 lpDDHELCaps->dwNumFourCCCodes; // number of supported FOURCC codes
892 lpDDHELCaps->dwRops[DD_ROP_SPACE]; // supported raster ops
893 lpDDHELCaps->dwSVBCaps = DDCAPS_BLT | // We do blitting
894 DDCAPS_BLTCOLORFILL | // We do colorfills
895 DDCAPS_COLORKEY | // We support Colorkeying
896 DDCAPS_COLORKEYHWASSIST;
897 lpDDHELCaps->dwSVBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
898 lpDDHELCaps->dwSVBFXCaps; // .
899 lpDDHELCaps->dwSVBRops[DD_ROP_SPACE]; // .
900 lpDDHELCaps->dwVSBCaps = DDCAPS_BLT | // We do blitting
901 DDCAPS_BLTCOLORFILL | // We do colorfills
902 DDCAPS_COLORKEY | // We support Colorkeying
903 DDCAPS_COLORKEYHWASSIST;
904 lpDDHELCaps->dwVSBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
905 lpDDHELCaps->dwVSBFXCaps; // .
906 lpDDHELCaps->dwVSBRops[DD_ROP_SPACE]; // .
907 lpDDHELCaps->dwSSBCaps = DDCAPS_BLT | // We do blitting
908 DDCAPS_BLTCOLORFILL | // We do colorfills
909 DDCAPS_COLORKEY | // We support Colorkeying
910 DDCAPS_COLORKEYHWASSIST;
911 lpDDHELCaps->dwSSBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
912 lpDDHELCaps->dwSSBFXCaps; // .
913 lpDDHELCaps->dwSSBRops[DD_ROP_SPACE]; // .
914 lpDDHELCaps->dwSVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
915 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
916 DDCAPS2_WIDESURFACES; // Any size you want!
917 lpDDHELCaps->dwNLVBCaps = DDCAPS_BLT | // We do blitting
918 DDCAPS_BLTCOLORFILL | // We do colorfills
919 DDCAPS_COLORKEY | // We support Colorkeying
920 DDCAPS_COLORKEYHWASSIST;
921 lpDDHELCaps->dwNLVBCaps2 = DDCAPS2_CANRENDERWINDOWED | // Better check for Voodoo ?!
922 DDCAPS2_COPYFOURCC | // yepp memcpy will do this
923 DDCAPS2_WIDESURFACES; // Any size you want!
924 lpDDHELCaps->dwNLVBCKeyCaps = DDCKEYCAPS_SRCBLT; // Only source transparent blitting
925 lpDDHELCaps->dwNLVBFXCaps; // .
926 lpDDHELCaps->dwNLVBRops[DD_ROP_SPACE];// .
927
928 }
929
930 return(DD_OK);
931}
932//******************************************************************************
933//******************************************************************************
934HRESULT __stdcall DrawGetDisplayMode(THIS This, LPDDSURFACEDESC lpDDSurfaceDesc)
935{
936 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
937 #ifdef DEBUG
938 WriteLog("GetDisplayMode\n");
939 #endif
940
941 // Check Parameter
942 if(NULL==lpDDSurfaceDesc)
943 return(DDERR_INVALIDPARAMS);
944
945 if(sizeof(DDSURFACEDESC)!=lpDDSurfaceDesc->dwSize)
946 return(DDERR_INVALIDPARAMS);
947
948 // We report back the DIVE caps. maybe we should set up a local DDSURFACEDESC
949 // for the object so we can change the values when we switch modes (or say so)
950 // as a program may use this function to check the values after a mode change
951 // An other reason to to so is Voodoo supports maybe more functions
952
953 // Tell what we report
954 lpDDSurfaceDesc->dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
955 lpDDSurfaceDesc->dwHeight = me->dCaps.ulHorizontalResolution;
956 lpDDSurfaceDesc->dwWidth = me->dCaps.ulVerticalResolution;
957 // Set the PixelFormat
958 lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
959
960 lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC = me->dCaps.fccColorEncoding;
961 lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = me->dCaps.ulDepth;
962 lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask = 0; // No Alpha support
963 switch(me->dCaps.ulDepth)
964 {
965 case 4:
966 // Assume that no one will run OS/2 PM with less then 16 colors and try
967 // to start a DirectX program ;)
968 lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4;
969 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0;
970 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0;
971 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0;
972 break;
973 case 8:
974 lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8 |
975 DDPF_FOURCC;
976 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0;
977 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0;
978 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0;
979 break;
980 case 15:
981 case 16:
982 lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 16; // No sure about 15Bit modes
983 lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
984 if (FOURCC_R555 == me->dCaps.fccColorEncoding)
985 {
986 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00007C00;
987 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000003E0;
988 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
989 }
990 else
991 {
992 if(FOURCC_R565 == me->dCaps.fccColorEncoding)
993 {
994 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
995 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000007E0;
996 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000001F;
997 }
998 else
999 {
1000 // R664
1001 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x0000F800;
1002 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x000003F0;
1003 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000000F;
1004 }
1005 }
1006 break;
1007 case 24:
1008 lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
1009 if(FOURCC_RGB3 == me->dCaps.fccColorEncoding)
1010 {
1011 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
1012 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1013 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
1014 }
1015 else
1016 {
1017 // BGR3
1018 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x000000FF;
1019 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1020 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
1021 }
1022 break;
1023 case 32:
1024 lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
1025 if(FOURCC_RGB4 == me->dCaps.fccColorEncoding)
1026 {
1027 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
1028 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1029 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x000000FF;
1030 }
1031 else
1032 {
1033 // BGR4
1034 lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0x000000FF;
1035 lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1036 lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
1037 }
1038 break;
1039 default:
1040 #ifdef DEBUG
1041 WriteLog("Unsupported mode\n");
1042 #endif
1043 return(DDERR_UNSUPPORTEDMODE);
1044 }
1045
1046 return(DD_OK);
1047}
1048//******************************************************************************
1049//******************************************************************************
1050HRESULT __stdcall DrawGetDisplayMode4(THIS This, LPDDSURFACEDESC2 lpDDSurfaceDesc2)
1051{
1052 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
1053 #ifdef DEBUG
1054 WriteLog("GetDisplayMode\n");
1055 #endif
1056
1057 // Check Parameter
1058 if(NULL==lpDDSurfaceDesc2)
1059 return(DDERR_INVALIDPARAMS);
1060
1061 if(sizeof(DDSURFACEDESC)!=lpDDSurfaceDesc2->dwSize)
1062 return(DDERR_INVALIDPARAMS);
1063
1064 // We report back the DIVE caps. maybe we should set up a local DDSURFACEDESC
1065 // for the object so we can change the values when we switch modes (or say so)
1066 // as a program may use this function to check the values after a mode change
1067 // An other reason to to so is Voodoo supports maybe more functions
1068
1069 // Tell what we report
1070 lpDDSurfaceDesc2->dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
1071 lpDDSurfaceDesc2->dwHeight = me->dCaps.ulHorizontalResolution;
1072 lpDDSurfaceDesc2->dwWidth = me->dCaps.ulVerticalResolution;
1073 // Set the PixelFormat
1074 lpDDSurfaceDesc2->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
1075
1076 lpDDSurfaceDesc2->ddpfPixelFormat.dwFourCC = me->dCaps.fccColorEncoding;
1077 lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBBitCount = me->dCaps.ulDepth;
1078 lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBAlphaBitMask = 0; // No Alpha support
1079 switch(me->dCaps.ulDepth)
1080 {
1081 case 4:
1082 // Assume that no one will run OS/2 PM with less then 16 colors and try
1083 // to start a DirectX program ;)
1084 lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4;
1085 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0;
1086 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0;
1087 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0;
1088 break;
1089 case 8:
1090 lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8 |
1091 DDPF_FOURCC;
1092 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0;
1093 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0;
1094 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0;
1095 break;
1096 case 15:
1097 case 16:
1098 lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBBitCount = 16; // No sure about 15Bit modes
1099 lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
1100 if (FOURCC_R555 == me->dCaps.ulDepth)
1101 {
1102 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00007C00;
1103 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000003E0;
1104 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000001F;
1105 }
1106 else
1107 {
1108 if(FOURCC_R565 == me->dCaps.fccColorEncoding)
1109 {
1110 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x0000F800;
1111 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000007E0;
1112 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000001F;
1113 }
1114 else
1115 {
1116 // R664
1117 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x0000F800;
1118 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x000003F0;
1119 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x0000000F;
1120 }
1121 }
1122 break;
1123 case 24:
1124 lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
1125 if(FOURCC_RGB3 == me->dCaps.fccColorEncoding)
1126 {
1127 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
1128 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1129 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x000000FF;
1130 }
1131 else
1132 {
1133 // BGR3
1134 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x000000FF;
1135 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1136 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
1137 }
1138 break;
1139 case 32:
1140 lpDDSurfaceDesc2->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_FOURCC;
1141 if(FOURCC_RGB4 == me->dCaps.fccColorEncoding)
1142 {
1143 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x00FF0000;
1144 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1145 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x000000FF;
1146 }
1147 else
1148 {
1149 // BGR4
1150 lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask = 0x000000FF;
1151 lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask = 0x0000FF00;
1152 lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x00FF0000;
1153 }
1154 break;
1155 default:
1156 #ifdef DEBUG
1157 WriteLog("Unsupported mode\n");
1158 #endif
1159 return(DDERR_UNSUPPORTEDMODE);
1160 }
1161
1162 return(DD_OK);
1163}
1164//******************************************************************************
1165//******************************************************************************
1166HRESULT __stdcall DrawGetFourCCCodes(THIS, LPDWORD lpNumCodes, LPDWORD lpCodes)
1167{
1168 DWORD dwFCC[3] = {FOURCC_LUT8,FOURCC_R565,FOURCC_RGB3};
1169 #ifdef DEBUG
1170 WriteLog("GetFourCCCodes\n");
1171 #endif
1172
1173 if(NULL==lpNumCodes)
1174 return(DDERR_INVALIDPARAMS);
1175
1176 if(NULL==lpCodes)
1177 {
1178 *lpNumCodes = 3; // LUT8, R565, RGB3 are the FourCC we support for now
1179 }
1180 else
1181 {
1182 for(int i=0;(i<3)&&(i<*lpNumCodes);i++)
1183 {
1184 *lpCodes = dwFCC[i];
1185 lpCodes +=4;
1186 }
1187 if(*lpNumCodes < 3)
1188 *lpNumCodes = 3;
1189 }
1190 return(DD_OK);
1191}
1192//******************************************************************************
1193//******************************************************************************
1194HRESULT __stdcall DrawGetGDISurface(THIS, LPDIRECTDRAWSURFACE FAR *)
1195{
1196 #ifdef DEBUG
1197 WriteLog("GetGDISurface NYI\n");
1198 #endif
1199
1200 return(DD_OK);
1201}
1202//******************************************************************************
1203//******************************************************************************
1204HRESULT __stdcall DrawGetGDISurface4(THIS, LPDIRECTDRAWSURFACE4 FAR *)
1205{
1206 #ifdef DEBUG
1207 WriteLog("GetGDISurface NYI\n");
1208 #endif
1209
1210 return(DD_OK);
1211}
1212//******************************************************************************
1213//******************************************************************************
1214HRESULT __stdcall DrawGetMonitorFrequency(THIS This, LPDWORD lpdwFreq)
1215{
1216 ULONG ulTime1, ulTime2;
1217 DWORD dwFlags = DDWAITVB_BLOCKBEGIN;
1218 #ifdef DEBUG
1219 WriteLog("GetMonitorFrequency\n");
1220 #endif
1221 if(NULL==lpdwFreq)
1222 return(DDERR_INVALIDPARAMS);
1223
1224
1225
1226 if(DD_OK==DrawWaitForVerticalBlank(This, dwFlags, 0))
1227 {
1228 ulTime1 = GetTickCount();
1229 // Timer has an accuracy of 4 ms so call it al least 4 times
1230 DrawWaitForVerticalBlank(This, dwFlags, 0);
1231 DrawWaitForVerticalBlank(This, dwFlags, 0);
1232 DrawWaitForVerticalBlank(This, dwFlags, 0);
1233 DrawWaitForVerticalBlank(This, dwFlags, 0);
1234 ulTime2 = GetTickCount();
1235 ulTime2 -= ulTime1;
1236 if(ulTime2) // paranoid check to avoid DIV0
1237 *lpdwFreq = 4000 / ulTime2;
1238 else
1239 *lpdwFreq = 70;
1240 }
1241 else
1242 {
1243 // Assume 70 Hz maybe better return DDERR_UNSUPPORTED if this function isn't mandatory
1244 *lpdwFreq = 70;
1245 }
1246
1247
1248
1249 return(DD_OK);
1250}
1251//******************************************************************************
1252//******************************************************************************
1253HRESULT __stdcall DrawGetScanLine(THIS, LPDWORD lpdwLine)
1254{
1255 BOOL bVertBlank;
1256 #ifdef DEBUG
1257 WriteLog("GetScanLine\n");
1258 #endif
1259 // ToDO find a way to get this position, so for now simply return DDERR_UNSUPPORTED
1260 // as we indicated in DDCAPS we don't support this.
1261
1262 return(DDERR_UNSUPPORTED);
1263
1264 //the following code could be used if we implement this
1265 /*
1266 if(NULL==lpdwLine)
1267 return(DDERR_INVALIDPARAMS);
1268 DrawGetVertcalBlackStatus(This,&bVertBlank);
1269 if(bVertBlank)
1270 return (DDERR_VERTICALBLANKINPROGRESS);
1271 *lpdwLine = GetLine(); // GetLine would be the function which gets us the line
1272 return(DD_OK);
1273 */
1274}
1275//******************************************************************************
1276//******************************************************************************
1277HRESULT __stdcall DrawGetVerticalBlankStatus(THIS , LPBOOL lpbIsInVB)
1278{
1279 int rc;
1280 #ifdef DEBUG
1281 WriteLog("GetVerticalBlankStatus\n");
1282 #endif
1283 if(NULL==lpbIsInVB)
1284 return(DDERR_INVALIDPARAMS);
1285
1286
1287 rc = io_init1();
1288
1289
1290 if(0==rc) // try to get IOPL for the thread
1291 {
1292 *lpbIsInVB = (c_inb1(0x3da)&0x08)!=0;
1293
1294 io_exit1(); // reset IOPL
1295
1296 return(DD_OK);
1297 }
1298
1299 return(DDERR_UNSUPPORTED);
1300}
1301//******************************************************************************
1302//******************************************************************************
1303HRESULT __stdcall DrawInitialize(THIS, GUID FAR *)
1304{
1305 #ifdef DEBUG
1306 WriteLog("Initialize\n");
1307 #endif
1308
1309 return(DD_OK);
1310}
1311//******************************************************************************
1312//******************************************************************************
1313HRESULT __stdcall DrawRestoreDisplayMode(THIS)
1314{
1315 #ifdef DEBUG
1316 WriteLog("RestoreDisplayMod\n");
1317 #endif
1318
1319 return(DD_OK);
1320}
1321//******************************************************************************
1322//******************************************************************************
1323HRESULT __stdcall DrawSetCooperativeLevel(THIS This, HWND hwndClient, DWORD dwFlags)
1324{
1325 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
1326
1327 #ifdef DEBUG
1328 WriteLog("SetCooperativeLevel: hwnd %X, Flags %X\n", hwndClient, dwFlags);
1329 #endif
1330
1331 me->hwndClient = hwndClient;
1332 #if 0
1333 OS2DDSubclassWindow(hwndClient);
1334 #endif
1335 return(DD_OK);
1336}
1337//******************************************************************************
1338//Backwards compatibility, what's that??
1339//******************************************************************************
1340HRESULT __stdcall DrawSetDisplayMode2(THIS This, DWORD dwWidth, DWORD dwHeight,
1341 DWORD dwBPP, DWORD dwRefreshRate,
1342 DWORD dwFlags)
1343{
1344 ULONG rc;
1345 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
1346
1347 #ifdef DEBUG
1348 WriteLog("SetDisplayMode2 to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP);
1349 #endif
1350
1351 me->screenwidth = dwWidth;
1352 me->screenheight = dwHeight;
1353 me->screenbpp = dwBPP;
1354 if(me->screenbpp!=me->dCaps.ulDepth)
1355 {
1356 rc = DiveOpen( &me->hDiveColorConv,
1357 FALSE,
1358 0);
1359 WriteLog("Screen in different mode than requested, open addional DIVE instance(rc=%X)\n\n",rc);
1360
1361 }
1362// _interrupt(3);
1363 return(DD_OK);
1364}
1365//******************************************************************************
1366//******************************************************************************
1367HRESULT __stdcall DrawSetDisplayMode(THIS This, DWORD dwWidth, DWORD dwHeight,
1368 DWORD dwBPP)
1369{
1370 ULONG rc;
1371 OS2IDirectDraw *me = (OS2IDirectDraw *)This;
1372
1373#ifdef DEBUG
1374 WriteLog("SetDisplayMode to %dx%d with %d bits colors\n", dwWidth, dwHeight, dwBPP);
1375#endif
1376 me->screenwidth = dwWidth;
1377 me->screenheight = dwHeight;
1378 me->screenbpp = dwBPP;
1379 if(me->screenbpp!=me->dCaps.ulDepth)
1380 {
1381 rc = DiveOpen( &me->hDiveColorConv,
1382 FALSE,
1383 0);
1384 WriteLog("Screen in different mode than requested, open addional DIVE instance(rc=%X)\n\n",rc);
1385
1386 }
1387// _interrupt(3);
1388 return(DD_OK);
1389}
1390//******************************************************************************
1391//******************************************************************************
1392HRESULT __stdcall DrawWaitForVerticalBlank(THIS, DWORD dwFlags, HANDLE hEvent)
1393{
1394 HRESULT rc;
1395 int rci;
1396
1397 #ifdef DEBUG
1398 WriteLog("WaitForVerticalBlank\n");
1399 #endif
1400
1401 if(DDWAITVB_BLOCKBEGINEVENT == dwFlags) // This parameter isn't support in DX
1402 return (DDERR_UNSUPPORTED);
1403
1404
1405 rci = io_init1();
1406
1407
1408 if(rci) // try to get IOPL for the thread
1409 return (DDERR_UNSUPPORTED); // we failed so return error that we don't support this
1410
1411 // AT this point we should have IOPL so lets use it!
1412
1413 rc = DDERR_INVALIDPARAMS; // set returnvalue to fail
1414
1415 if(DDWAITVB_BLOCKBEGIN == dwFlags)
1416 {
1417 while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of vert. retrace if one is running
1418 while ((c_inb1(0x3da)&0x08)==0); // Wait for new start of retrace
1419 rc = DD_OK;
1420 }
1421
1422 if(DDWAITVB_BLOCKEND == dwFlags)
1423 {
1424 rc = DD_OK;
1425 if((c_inb1(0x3da)&0x08)!=0) // Are we in a vert. retrace
1426 {
1427 while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of retrace
1428 }
1429 else
1430 {
1431 while ((c_inb1(0x3da)&0x08)==0); // Wait for new start of retrace
1432 while ((c_inb1(0x3da)&0x08)!=0); // Wait for end of vert. retrace
1433 }
1434
1435 }
1436
1437
1438 io_exit1();
1439
1440
1441 return (rc);
1442
1443}
1444//******************************************************************************
1445//*** Added in the v2 interface ***
1446//******************************************************************************
1447HRESULT __stdcall DrawGetAvailableVidMem(THIS, LPDDSCAPS lpDDSCaps,
1448 LPDWORD lpdwTotal, LPDWORD lpdwFree)
1449{
1450 #ifdef DEBUG
1451 WriteLog("GetAvailableVidMem\n");
1452 #endif
1453
1454 // Check parameters
1455 if(NULL==lpDDSCaps)
1456 return(DDERR_INVALIDPARAMS);
1457
1458 if((NULL==lpdwTotal)&&(NULL==lpdwFree))
1459 return(DDERR_INVALIDPARAMS);
1460
1461 if(NULL!=lpdwTotal)
1462 *lpdwTotal = 2048 *1024;
1463
1464 if(NULL!=lpdwFree)
1465 *lpdwFree = 2048 *1024;
1466
1467 return(DD_OK);
1468}
1469//******************************************************************************
1470//
1471//******************************************************************************
1472HRESULT __stdcall DrawGetAvailableVidMem4(THIS, LPDDSCAPS2 lpDDSCaps2,
1473 LPDWORD lpdwTotal, LPDWORD lpdwFree)
1474{
1475 #ifdef DEBUG
1476 WriteLog("GetAvailableVidMem\n");
1477 #endif
1478
1479 // Check parameters
1480 if(NULL==lpDDSCaps2)
1481 return(DDERR_INVALIDPARAMS);
1482
1483 if((NULL==lpdwTotal)&&(NULL==lpdwFree))
1484 return(DDERR_INVALIDPARAMS);
1485
1486 if(NULL!=lpdwTotal)
1487 *lpdwTotal = 2048 *1024;
1488
1489 if(NULL!=lpdwFree)
1490 *lpdwFree = 2048 *1024;
1491
1492 return(DD_OK);
1493}
1494//******************************************************************************
1495//*** Added in the v4 interface ***
1496//******************************************************************************
1497HRESULT __stdcall DrawGetSurfaceFromDC(THIS, HDC hdc, LPDIRECTDRAWSURFACE4 *)
1498{
1499 #ifdef DEBUG
1500 WriteLog("GetSurfaceFromDC NYI\n");
1501 #endif
1502
1503 return(DD_OK);
1504}
1505//******************************************************************************
1506//******************************************************************************
1507HRESULT __stdcall DrawRestoreAllSurfaces(THIS)
1508{
1509 #ifdef DEBUG
1510 WriteLog("RestoreAllSurfaces\n");
1511 #endif
1512
1513 return(DD_OK);
1514}
1515//******************************************************************************
1516//******************************************************************************
1517HRESULT __stdcall DrawTestCooperativeLevel(THIS)
1518{
1519 #ifdef DEBUG
1520 WriteLog("TestCooperativeLevel\n");
1521 #endif
1522
1523 return(DD_OK);
1524}
1525//******************************************************************************
1526//******************************************************************************
1527HRESULT __stdcall DrawGetDeviceIdentifier( THIS, LPDDDEVICEIDENTIFIER lpdddi,
1528 DWORD dwFlags)
1529{
1530 #ifdef DEBUG
1531 WriteLog("GetDeviceIdentifier Flags = %d\n",dwFlags);
1532 #endif
1533 if(NULL==lpdddi)
1534 return DDERR_INVALIDPARAMS;
1535
1536
1537
1538 memset( lpdddi,
1539 0,
1540 sizeof(DDDEVICEIDENTIFIER));
1541 // ToDo: Cretae a GUID and put some better data inside
1542 strcpy( lpdddi->szDriver,
1543 "OS/2 DIVE Driver");
1544 strcpy( lpdddi->szDescription,
1545 "ODIN DD Emulation Driver");
1546
1547
1548
1549 return(DD_OK);
1550}
1551//******************************************************************************
1552//******************************************************************************
1553VOID OS2IDirectDraw::SwitchDisplay(HWND hwnd)
1554{
1555 DWORD dwVType, dwVSize;
1556 HKEY hkDirectDraw2;
1557
1558
1559
1560 if (bScale)
1561 {
1562 if (ERROR_SUCCESS==RegOpenKeyA(HKEY_LOCAL_MACHINE,KEY_DIRECT2DRAW,&hkDirectDraw2))
1563 {
1564 dwVSize = 4;
1565 dwVType = REG_DWORD;
1566 if (ERROR_SUCCESS!=RegQueryValueExA( hkDirectDraw2, "Fullscreen", NULL, &dwVType,
1567 (LPBYTE)&bScale, &dwVSize))
1568 bScale = FALSE;
1569 }
1570 else
1571 bScale = FALSE;
1572 }
1573
1574
1575}
1576//******************************************************************************
1577//******************************************************************************
1578
Note: See TracBrowser for help on using the repository browser.