source: trunk/src/ddraw/surface.cpp@ 9560

Last change on this file since 9560 was 9560, checked in by sandervl, 23 years ago

Cleanup

File size: 116.3 KB
Line 
1/* $Id: surface.cpp,v 1.3 2002-12-29 14:11:02 sandervl Exp $ */
2
3/*
4 * DirectDraw Surface class implementaion
5 *
6 * Copyright 1999 Markus Montkowski
7 * Copyright 2000 Michal Necasek
8 * Copyright 1998-2001 Sander van Leeuwen
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14#define _OS2WIN_H
15#define FAR
16
17#include <odin.h>
18#include <winbase.h>
19#include <stdlib.h>
20#include <string.h>
21#include <memory.h>
22#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
23 ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
24 ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
25#include <fourcc.h>
26#define INITGUID
27#include "ddraw2d.h"
28#include "clipper.h"
29#include "palette.h"
30#include "surface.h"
31#include "surfacehlp.h"
32#include "os2util.h"
33#include "rectangle.h"
34#include <misc.h>
35#include "asmutil.h"
36#include "bltFunc.h"
37#include "colorconv.h"
38#include "fillfunc.h"
39#include <winerror.h>
40#include <os2win.h>
41#include <cpuhlp.h>
42#include "asmutil.h"
43#include "wndproc.h"
44
45#ifndef __WATCOMC__
46 #include <builtin.h>
47#endif
48
49extern IDirectDrawSurface4Vtbl DDrawSurfaceV4Table;
50extern IDirectDrawSurface3Vtbl DDrawSurfaceV3Table;
51extern IDirectDrawSurface2Vtbl DDrawSurfaceV2Table;
52
53//******************************************************************************
54//******************************************************************************
55OS2IDirectDrawSurface::OS2IDirectDrawSurface(OS2IDirectDraw *lpDirectDraw,
56 LPDDSURFACEDESC2 lpDDSurfaceDesc, BOOL Implicit, BOOL Mainchain) :
57 Referenced(0), lastError(DD_OK),
58 diveBufNr(-1), lpClipper(NULL),
59 lpPalette(NULL), lpDraw(NULL),
60 fLocked(FALSE), hdcImage(NULL),
61 hbmImage(NULL),
62 pFrameBuffer(NULL),Updated(FALSE),
63 fOverlayValid(FALSE),
64 BackBuffer(NULL),FrontBuffer(NULL),
65 pDBreal(NULL),pFBreal(NULL), hwndFullScreen(0)
66
67{
68 DWORD rc;
69 DDSURFACEDESC2 ComplexSurfaceDesc;
70 OS2IDirectDrawSurface *MipMapSurface;
71
72 memset(&sBlt, 0, sizeof(sBlt));
73
74 lpVtbl = &Vtbl2;
75 lpVtbl2 = &Vtbl2;
76 dwUnknownData = 0xDEADDEAD;
77
78 //copy DirectDraw V2, V3 & V4 tables
79 Vtbl = DDrawSurfaceV4Table;
80 Vtbl3 = DDrawSurfaceV3Table;
81 Vtbl2 = DDrawSurfaceV2Table;
82
83 lpDraw = lpDirectDraw;
84 lpDraw->Vtbl.AddRef(lpDraw);
85
86 ImplicitSurface = Implicit;
87
88 hDive = lpDirectDraw->GetDiveInstance();
89 hDiveCC = lpDirectDraw->GetCCDiveInstance();
90 surfaceType = DDSCAPS_OFFSCREENPLAIN;
91 memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC2));
92
93 dprintf(("Pixel format:"));
94 _dump_pixelformat(&lpDDSurfaceDesc->ddpfPixelFormat);
95 dprintf(("Capabilities"));
96 _dump_DDSCAPS(lpDDSurfaceDesc->ddsCaps.dwCaps);
97 _dump_DDSCAPS2(lpDDSurfaceDesc->ddsCaps.dwCaps2);
98
99 if(lpDraw->dCaps.ulDepth != 15)
100 {
101 if(lpDraw->dCaps.ulDepth >= 8)
102 dwBytesPPDive = lpDraw->dCaps.ulDepth >> 3;
103 else
104 dwBytesPPDive = 1; // not sure if this is the case
105 }
106 else
107 dwBytesPPDive = 2; // 2 bytes for 15Bit
108
109 // Setting up Cursors for handling attached Surfaces
110
111 DPA_SurfaceMipMaps = DPA_Create(8);
112 if(NULL==DPA_SurfaceMipMaps)
113 {
114 dprintf(("DDRAW: Internal : Error creating DPA for MipMaps\n"));
115 lastError = DDERR_OUTOFMEMORY ;
116 return;
117 }
118
119 DPA_SurfaceAttached = DPA_Create(8);
120 if(NULL==DPA_SurfaceAttached)
121 {
122 dprintf(("DDRAW: Internal : Error creating DPA for attached surfaces\n"));
123 lastError = DDERR_OUTOFMEMORY ;
124 return;
125 }
126
127 DPA_LockedRects = DPA_Create(8);
128 if(NULL==DPA_LockedRects)
129 {
130 dprintf(("DDRAW: Internal : Error creating DPA for Locked Rectangles\n"));
131 lastError = DDERR_OUTOFMEMORY ;
132 return;
133 }
134
135 DPA_SurfacePrivateData = DPA_Create(8);
136 if(NULL==DPA_SurfacePrivateData)
137 {
138 dprintf(("DDRAW: Internal : Error creating DPA for private surface Data\n"));
139 lastError = DDERR_OUTOFMEMORY ;
140 return;
141 }
142
143 switch(lpDraw->GetScreenBpp())
144 {
145 case 8:
146 switch(lpDraw->dCaps.ulDepth)
147 {
148 case 8:
149 BltSolid = &BltSolid8to8;
150 ColorConv = NULL;
151 ColorFill = &Fill8on8;
152 break;
153 case 16:
154 BltSolid = &BltSolid8to16;
155 ColorConv = &Conv8to16;
156 ColorFill = &Fill8on16;
157 break;
158 case 24:
159 BltSolid = &BltSolid8to24;
160 ColorConv = &Conv8to24;
161 ColorFill = &Fill8on24;
162 break;
163 case 32:
164 BltSolid = &BltSolid8to32;
165 ColorConv = &Conv8to32;
166 ColorFill = &Fill8on32;
167 break;
168 default:
169 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
170 BltSolid = NULL;
171 ColorConv = NULL;
172 ColorFill = NULL;
173 break;
174 }
175 break;
176 case 16:
177 switch(lpDraw->dCaps.ulDepth)
178 {
179 case 8:
180 BltSolid = &BltSolid16to8;
181 ColorConv = &Conv16to8;
182 ColorFill = &Fill16on8;
183 break;
184 case 16:
185 BltSolid = &BltSolid16to16;
186 ColorConv = NULL;
187 ColorFill = &Fill16on16;
188 break;
189 case 24:
190 BltSolid = &BltSolid16to24;
191 ColorConv = &Conv16to24;
192 ColorFill = &Fill16on24;
193 break;
194 case 32:
195 BltSolid = &BltSolid16to32;
196 ColorConv = &Conv16to32;
197 ColorFill = &Fill16on32;
198 break;
199 default:
200 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
201 BltSolid = NULL;
202 ColorConv = NULL;
203 ColorFill = NULL;
204 break;
205 }
206 break;
207 case 24:
208 switch(lpDraw->dCaps.ulDepth)
209 {
210 case 8:
211 BltSolid = &BltSolid24to8;
212 ColorConv = &Conv24to8;
213 ColorFill = &Fill24on8;
214 break;
215 case 16:
216 BltSolid = &BltSolid24to16;
217 ColorConv = &Conv24to16;
218 ColorFill = &Fill24on16;
219 break;
220 case 24:
221 BltSolid = &BltSolid24to24;
222 ColorConv = NULL;
223 ColorFill = &Fill24on24;
224 break;
225 case 32:
226 BltSolid = &BltSolid24to32;
227 ColorConv = &Conv24to32;
228 ColorFill = &Fill24on32;
229 break;
230 default:
231 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
232 BltSolid = NULL;
233 ColorConv = NULL;
234 ColorFill = NULL;
235 break;
236 }
237 break;
238 case 32:
239 switch(lpDraw->dCaps.ulDepth)
240 {
241 case 8:
242 BltSolid = &BltSolid32to8;
243 ColorConv = &Conv32to8;
244 ColorFill = &Fill32on8;
245 break;
246 case 16:
247 BltSolid = &BltSolid32to16;
248 ColorConv = &Conv32to16;
249 ColorFill = &Fill32on16;
250 break;
251 case 24:
252 BltSolid = &BltSolid32to24;
253 ColorConv = &Conv32to24;
254 ColorFill = &Fill32on24;
255 break;
256 case 32:
257 BltSolid = &BltSolid32to32;
258 ColorConv = NULL;
259 ColorFill = &Fill32on32;
260 break;
261 default:
262 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
263 BltSolid = NULL;
264 ColorConv = NULL;
265 ColorFill = NULL;
266 break;
267 }
268 break;
269 default:
270 dprintf(("DDRAW: Unsupported DX ColorDepth %d",lpDraw->GetScreenBpp()));
271 BltSolid = NULL;
272 ColorConv = NULL;
273 ColorFill = NULL;
274 break;
275 }
276 // hack set DDSD_CAPS if the value is other than 0
277 if( DDSurfaceDesc.ddsCaps.dwCaps)
278 DDSurfaceDesc.dwFlags |= DDSD_CAPS;
279
280 if( DDSurfaceDesc.dwFlags & DDSD_CAPS )
281 {
282#if 0
283//TODO: Docs say this is done, but does it really happen in windows?
284 // check for invalid flag combinations
285 switch(lpDDSurfaceDesc->ddsCaps.dwCaps2 & (DDSCAPS2_OPAQUE|DDSCAPS2_HINTDYNAMIC|DDSCAPS2_HINTSTATIC))
286 {
287 case 0:
288 case DDSCAPS2_OPAQUE:
289 case DDSCAPS2_HINTDYNAMIC:
290 case DDSCAPS2_HINTSTATIC:
291 break;
292
293 default:
294 dprintf(("DDRAW: Internal : illegal ddscaps2 flag combination (static/dynamic/opaque)"));
295 lastError = DDERR_INVALIDCAPS ;
296 return;
297 }
298#endif
299
300 // First check if we want to create a primary surface while the ddraw object already has one
301 surfaceType = DDSurfaceDesc.ddsCaps.dwCaps;
302
303 if( surfaceType & DDSCAPS_PRIMARYSURFACE)
304 {
305 dprintf(("DDRAW: Primary surface!\n"));
306 if( lpDraw->HasPrimarySurface())
307 {
308 dprintf(("DDRAW: Primary surface already exits!\n"));
309 lastError = DDERR_PRIMARYSURFACEALREADYEXISTS;
310 return;
311 }
312
313 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) ||
314 (DDSurfaceDesc.dwFlags & DDSD_WIDTH) ||
315 (DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT)
316 )
317 {
318 // Dx doc says passing width,height etc. for primary surface in not permitted!!
319 dprintf(("DDRAW: Invalid parameters\n\n"));
320 lastError = DDERR_INVALIDPARAMS;
321 return;
322 }
323
324 // Check if OS/2 is running in the requested colormode
325
326 diveBufNr = DIVE_BUFFER_SCREEN;
327 if( lpDraw->dCaps.ulDepth == lpDraw->GetScreenBpp() )
328 {
329 dprintf(("DDRAW: Direct Screen Access possible\n"));
330
331 // Yes so direct access to framebuffer is possible
332
333 pFrameBuffer = lpDraw->GetFrameBuffer();
334 pDiveBuffer = pFrameBuffer;
335 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
336 dwPitchFB = dwPitchDB;
337 DDSurfaceDesc.lPitch = dwPitchDB;
338 }
339 else
340 {
341 // No so we create a virtual framebuffer which the program can access
342 // and blit to the real framebuffer on Unlock to do color conversion
343
344 dprintf( ("Need Color conversion %d => %d Bit\n",
345 lpDraw->GetScreenBpp(),
346 lpDraw->dCaps.ulDepth
347 ));
348
349 dwPitchFB = (lpDraw->GetScreenWidth() * lpDraw->GetScreenBpp() +7) & ~7;
350 DDSurfaceDesc.lPitch = dwPitchFB;
351
352 // 24 byte more to enable alignment and speed up blitting
353
354 pFBreal = (char*)malloc( lpDraw->GetScreenHeight() * dwPitchFB + 24);
355 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
356
357 // DiveBuffer points to real framebuffer
358 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
359 pDiveBuffer = lpDraw->GetFrameBuffer();
360
361 }
362
363 // Update passed in and local Surface description
364
365 dprintf(("DDRAW: Setting up Surface\n"));
366 DDSurfaceDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT |
367 DDSD_PITCH | DDSD_LPSURFACE |
368 DDSD_PIXELFORMAT;
369 DDSurfaceDesc.dwHeight = lpDraw->GetScreenHeight();
370 DDSurfaceDesc.dwWidth = lpDraw->GetScreenWidth();
371 DDSurfaceDesc.lpSurface = pFrameBuffer;
372 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
373 lpDraw->SetPrimarySurface(TRUE);
374 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
375 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
376 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp();
377
378 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
379 {
380 case 4:
381 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
382 break;
383 case 8:
384 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
385 break;
386 case 16:
387 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
388 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
389 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
390 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
391 break;
392 case 24:
393 case 32:
394 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
395 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
396 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
397 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
398 break;
399 default:
400 // Remove the Pixelformat flag
401 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
402 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
403 break;
404 } // end switch
405
406 dprintf(("DDRAW: Surface set up, checking other Caps\n"));
407
408 if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
409 {
410 dprintf(("DDRAW: Complex Surface\n"));
411
412 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
413 {
414 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
415 memset( &ComplexSurfaceDesc,
416 0,
417 sizeof(DDSURFACEDESC2));
418
419 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
420 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
421 DDSD_WIDTH |
422 DDSD_HEIGHT |
423 DDSD_PIXELFORMAT;
424 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
425 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
426 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
427 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
428 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
429 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
430 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
431 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
432
433 if(DDSurfaceDesc.dwBackBufferCount>1)
434 {
435 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
436 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
437 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
438 }
439
440 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
441 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
442
443 if (BackBuffer->GetLastError()==DD_OK)
444 {
445 dprintf(("DDRAW: created backbuffer"));
446 // Our Primary Buffer is also the frontbuffer of a flipchain
447 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP;
448 BackBuffer->SetFrontBuffer(this);
449 }
450 else
451 {
452 dprintf(("DDRAW: Error creating backbuffer"));
453 }
454 }
455 else
456 {
457 dprintf(("DDRAW: Unsupported Complex Surface\n"));
458 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
459
460 lastError = DDERR_OUTOFMEMORY;
461 return;
462 } //endif Backbuffer
463 } // endif DDSCAPS_COMPLEX
464
465 width = DDSurfaceDesc.dwWidth;
466 height = DDSurfaceDesc.dwHeight;
467
468 lpDraw->pPrimSurf = this;
469
470 lastError = DD_OK;
471
472#if 0
473//NOTE: This isn't working at all (interferes with mouse messages for application
474// window)
475 //If in fullscreen mode, create transparent window covering the entire desktop
476 if(lpDraw->GetCooperativeLevel() & DDSCL_FULLSCREEN)
477 {
478 DirectDrawSurface_RegisterClass();
479 hwndFullScreen = DirectDrawSurface_CreateWindow(DDSurfaceDesc.dwWidth,
480 DDSurfaceDesc.dwHeight,
481 lpDraw->GetClientWindow());
482
483 if(hwndFullScreen == 0) {
484 DebugInt3();
485 lastError = DDERR_OUTOFMEMORY;
486 }
487 dprintf(("DDRAW: Created fullscreen transparent window %x", hwndFullScreen));
488 }
489#endif
490 return;
491 } // endif DDSCAPS_PRIMARYSURFACE
492
493 //
494 // ToDo : Do better calulation of Bitmap Size to support the compressed Bitmaps in Dx6
495 //
496
497 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) &&
498 (DDSurfaceDesc.dwFlags & DDSD_WIDTH)
499 )
500
501 {
502 DWORD dwBpp;
503 DWORD dwCaps;
504 dprintf(( " Requested Size %dx%d\n",
505 DDSurfaceDesc.dwWidth,
506 DDSurfaceDesc.dwHeight));
507
508 if(DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT) // Pixelformat passed in ?
509 {
510 dprintf(("DDRAW: Pixelformat requested :"));
511 // YES use it
512 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB)
513 {
514 dwBpp = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
515 }
516 else
517 {
518 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
519 dwBpp = 8;
520 else
521 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
522 dwBpp = 4;
523 else
524 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
525 dprintf(("DDRAW: Pixelformat FOURCC %4s", &DDSurfaceDesc.ddpfPixelFormat.dwFourCC));
526 switch(DDSurfaceDesc.ddpfPixelFormat.dwFourCC) {
527 case FOURCC_RGB3:
528 dwBpp = 24;
529 break;
530 case FOURCC_RGB4:
531 dwBpp = 32;
532 break;
533 default:
534 dprintf(("DDRAW: Unsupported FOURCC!"));
535 lastError = DDERR_UNSUPPORTEDFORMAT;
536 return;
537 }
538 }
539 }
540 }
541 else
542 {
543 dprintf(("DDRAW: Use Screen Format :"));
544 dwBpp = lpDraw->GetScreenBpp(); // No use Screenformat
545 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
546 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
547 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = dwBpp;
548 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
549 {
550 case 4:
551 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
552 break;
553 case 8:
554 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
555 break;
556 case 16:
557 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
558 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
559 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
560 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
561 break;
562 case 24:
563 case 32:
564 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
565 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
566 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
567 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
568 break;
569 default:
570 // Remove the Pixelformat flag
571 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
572 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
573 break;
574 } // end switch
575
576 }
577
578 dprintf(("DDRAW: %d Bits\n",dwBpp));
579
580 // three possible situaltions
581 // 1. User supplied pointer to surface -> use it
582 // 2. Delayed allocation of a texture -> don't alloc
583 // 3. Normal allocation
584 // After this check for complex flag.
585
586 dwCaps = DDSurfaceDesc.ddsCaps.dwCaps;
587
588 if(DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
589 {
590 // 1.
591
592 dprintf(("DDRAW: Usersupplied Surface\n"));
593
594 if(NULL==DDSurfaceDesc.lpSurface)
595 {
596 // pointer is NULL! Stupid user ;)
597 lastError = DDERR_INVALIDPARAMS;
598 return;
599 }
600
601 // User allocated the Buffer for the surface so we don't have to
602
603 Updated = TRUE; // Set Flag to indicate User supplied buffer so we don't free it
604
605 // As we allready copied the surface description we are done if the # of colors
606 // of the surface is the same then the screen
607
608 pFrameBuffer = (char*)DDSurfaceDesc.lpSurface;
609 diveBufNr = -1;
610 dwPitchFB = DDSurfaceDesc.lPitch;
611
612 if( lpDraw->dCaps.ulDepth == dwBpp )
613 {
614 // Yes No Colorconversion is needed so point to the same buffer
615 dwPitchDB = dwPitchFB;
616 pDiveBuffer = pFrameBuffer;
617 }
618 else
619 {
620 // No so we must create the Divebuffer to do the color conversion
621 // and blit to the real framebuffer on Unlock to do color conversion
622
623 dwPitchDB = (DDSurfaceDesc.dwWidth * dwBytesPPDive +7) & ~7;
624
625 // 24 byte more to enable alignment and speed up blitting
626
627 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchDB + 24);
628 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
629
630 // Not sure if that is ok but we need this for translation
631 // I hope no game uses YUV or such a crap
632
633 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = SupportedFourCCs[dwBpp>>3];
634 }
635
636 }
637 else
638 {
639
640 if(dwCaps & DDSCAPS_ALLOCONLOAD)
641 {
642 // 2.
643
644 dprintf(("DDRAW: Alloc on Load Texture?!\n"));
645
646 dwCaps &= ~DDSCAPS_ALLOCONLOAD; // remove flag
647
648 // only allow this flag for textures
649 if(!dwCaps & DDSCAPS_TEXTURE)
650 {
651 lastError = DDERR_INVALIDPARAMS;
652 return;
653 }
654
655 dwCaps &= ~DDSCAPS_TEXTURE; // remove flag
656 pFrameBuffer = NULL;
657 pDiveBuffer = NULL;
658
659 // This surface isn't allocated yet, but when the texture is loaded
660 dprintf(("DDRAW: Warning : Delayed memory allocation on request\n"));
661 DDSurfaceDesc.lpSurface = NULL;
662 }
663 else
664 {
665 // 3.
666
667 dprintf(("DDRAW: Alloc now!\n"));
668
669 DDSurfaceDesc.dwFlags = DDSurfaceDesc.dwFlags;
670
671 dwPitchFB = DDSurfaceDesc.dwWidth * (dwBpp<8?1:dwBpp/8);
672 dwPitchFB = (dwPitchFB +7) & ~7; // Align on QWords
673 DDSurfaceDesc.lPitch = dwPitchFB;
674 if(dwBpp<8)
675 {
676 dprintf(("DDRAW: 1 or 4 Bit Surface encountered may not work !"));
677 }
678
679
680 // 24 byte more to enable alignment and speed up blitting
681
682 pFBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchFB + 24);
683
684 if(NULL==pFBreal)
685 {
686 lastError = DDERR_OUTOFMEMORY;
687 return;
688 }
689
690 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
691
692 dprintf(("DDRAW: Framebuffer @ %08X QWAligned @ %08X with a Pitch of %d\n",
693 pFBreal, pFrameBuffer, dwPitchFB));
694
695 DDSurfaceDesc.lpSurface = pFrameBuffer;
696
697 if( (lpDraw->dCaps.ulDepth ) == dwBpp )
698 {
699 dprintf(("DDRAW: No CC_Buffer needed\n"));
700 // Yes => No Colorconversion is needed so point to the same buffer
701 pDiveBuffer = pFrameBuffer;
702 dwPitchDB = dwPitchFB;
703 }
704 else
705 {
706 dwPitchDB = (DDSurfaceDesc.dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7;
707 dprintf( ("DDRAW: Alloc CCBuf with malloc (%dx%d) Pitch %d ",
708 DDSurfaceDesc.dwHeight,
709 DDSurfaceDesc.dwWidth,
710 dwPitchDB));
711 // No so we must create the Divebuffer to do the colortranslation
712 // and blit to the real framebuffer on Unlock to do color conversion
713 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight *
714 dwPitchDB + 24);
715 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
716 dprintf(( " @ %08X\n", pDiveBuffer));
717
718 }
719
720// if(Mainchain)
721// {
722 diveBufNr = 0;
723 rc = DiveAllocImageBuffer( hDive,
724 &diveBufNr,
725 lpDraw->dCaps.fccColorEncoding,
726 DDSurfaceDesc.dwWidth,
727 DDSurfaceDesc.dwHeight,
728 dwPitchDB,
729 (PBYTE)pDiveBuffer);
730 dprintf(("DDRAW: DiveAllocImageBuffer %x -> %d (rc=%d)",pDiveBuffer, diveBufNr, rc));
731// }
732
733 } // end of 3rd case
734 } // End of alloc surfaces
735
736 width = DDSurfaceDesc.dwWidth;
737 height = DDSurfaceDesc.dwHeight;
738
739 if( dwCaps & DDSCAPS_COMPLEX)
740 {
741 // remove the flag
742 dwCaps &= ~DDSCAPS_COMPLEX;
743 dprintf(("DDRAW: Complex Surface\n"));
744
745 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
746 {
747 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
748
749#if 1
750 memset( &ComplexSurfaceDesc,
751 0,
752 sizeof(DDSURFACEDESC2));
753
754 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
755 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
756 DDSD_WIDTH |
757 DDSD_HEIGHT |
758 DDSD_PIXELFORMAT;
759 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
760 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
761 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
762 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
763 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
764 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
765 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
766 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
767
768 if(DDSurfaceDesc.dwBackBufferCount>1)
769 {
770 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
771 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
772 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
773 }
774
775 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
776 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
777
778 if (BackBuffer->GetLastError()==DD_OK)
779 {
780 dprintf(("DDRAW: created backbuffer"));
781 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
782 BackBuffer->SetFrontBuffer(this);
783 }
784 else
785 {
786 dprintf(("DDRAW: Error creating backbuffer"));
787 }
788#else
789 memcpy( &ComplexSurfaceDesc,
790 &DDSurfaceDesc,
791 sizeof(DDSURFACEDESC2));
792 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
793 ComplexSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; // set flip
794 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; // remove backbuffer
795
796 if(ComplexSurfaceDesc.dwBackBufferCount>1)
797 {
798 ComplexSurfaceDesc.dwBackBufferCount--;
799 }
800 else
801 {
802 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
803 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX;
804 }
805 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, Mainchain);
806 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
807
808 if (BackBuffer->GetLastError()==DD_OK)
809 {
810 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
811 BackBuffer->SetFrontBuffer(this);
812 }
813#endif
814 }
815
816 // MipMap Surfaces are handled here
817 if( (DDSurfaceDesc.dwFlags & DDSD_MIPMAPCOUNT) &&
818 (dwCaps & DDSCAPS_TEXTURE) &&
819 (dwCaps & DDSCAPS_MIPMAP) )
820 {
821 dwCaps &= ~ (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
822
823 dprintf(("DDRAW: Mipmpa # = %d\n",DDSurfaceDesc.dwMipMapCount));
824 memcpy( &ComplexSurfaceDesc,
825 &DDSurfaceDesc,
826 sizeof(DDSURFACEDESC2));
827 ComplexSurfaceDesc.dwMipMapCount = 0;
828 ComplexSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
829
830 for(int i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
831 {
832 dprintf(("DDRAW: Creating MipMap %d\n",i));
833 // Mpmaps shirnk by 2
834 ComplexSurfaceDesc.dwWidth /= 2;
835 ComplexSurfaceDesc.dwHeight /= 2;
836
837 MipMapSurface = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE);
838 MipMapSurface->Vtbl.AddRef((IDirectDrawSurface *)MipMapSurface);
839
840 DPA_InsertPtr( DPA_SurfaceMipMaps,
841 DPA_GetPtrCount(DPA_SurfaceMipMaps),
842 MipMapSurface);
843
844 if(MipMapSurface->GetLastError() != DD_OK)
845 {
846 lastError = MipMapSurface->GetLastError();
847 dprintf(("DDRAW: Attached surface creation returned error %d\n",lastError));
848 return;
849 } // Endif Errorcheck
850 } //End for(i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
851 } // End of MipMaps
852
853 #if 0
854 if(DDSurfaceDesc.dwFlags)
855 dprintf(("DDRAW: Unsupported Complex Surface\n"));
856 #endif
857 } // Endif DDSCAPS_COMPLEX
858 }
859 else
860 {
861 lastError = DDERR_INVALIDPARAMS;
862 }
863 } // Endif DDCAPS is valid
864 else
865 {
866 dprintf(("DDRAW: CAPS not valid\n"));
867 lastError = DDERR_INVALIDPARAMS;
868 }
869 dprintf(("DDRAW: Buf %X Screen Caps (%d,%d), bitcount %d\n\n", this, lpDraw->GetScreenHeight(), lpDraw->GetScreenWidth(),
870 lpDraw->dCaps.ulDepth));
871 if(DD_OK!=lastError)
872 {
873 dprintf(("DDRAW: Some Error Check Flags\n"));
874 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
875 }
876}
877//******************************************************************************
878//******************************************************************************
879HRESULT OS2IDirectDrawSurface::DoColorFill(LPRECT lpDestRect,DWORD dwFillColor)
880{
881
882 int FillWidth, FillHeight, Top, Left;
883 DWORD *pPal24;
884 WORD *pPal16;
885 dprintf(("DDRAW: ColorFill with %08X\n", dwFillColor));
886
887 if(NULL!=lpDestRect)
888 {
889 dprintf(("DDRAW: Fill only Rect(%d,%d)(%d,%d) (%d,%d)", lpDestRect->left, lpDestRect->top,
890 lpDestRect->right, lpDestRect->bottom, width, height));
891 FillWidth = RECT_WIDTH(lpDestRect);
892 FillHeight = RECT_HEIGHT(lpDestRect);
893 Top = lpDestRect->top;
894 Left = lpDestRect->left;
895 if(Top + FillHeight > height) {
896 FillHeight = height - Top;
897 dprintf(("correcting FillHeight to %d", FillHeight));
898 }
899 if(Left + FillWidth > width) {
900 FillWidth = width - Left;
901 dprintf(("correcting FillWidth to %d", FillWidth));
902 }
903 }
904 else
905 {
906 dprintf(("DDRAW: Fill all at addr "));
907 Top = 0;
908 Left = 0;
909 FillWidth = width;
910 FillHeight = height;
911 //pLine = pDiveBuffer;
912 }
913 //dprintf(("DDRAW: 0x%08X (%d/%d) at\n", pLine,FillWidth,FillHeight));
914
915 // Better safe than sorry
916 if (FillHeight <= 0)
917 return(DD_OK);
918
919 if(pDiveBuffer!=pFrameBuffer)
920 {
921 if( (NULL== lpDraw->pPrimSurf) ||
922 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
923 {
924 if(!fPalInit)
925 {
926 for(DWORD i=0;i<256;i++)
927 {
928 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
929 ((DefaultPalette[i*3+1]>>2) <<5) +
930 ((DefaultPalette[i*3]>>3) << 11);
931 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
932 ((DefaultPalette[i*3+1]>>2) <<16) +
933 ((DefaultPalette[i*3]>>3) << 24);
934 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
935 i,
936 DefaultPalette[i*3],
937 DefaultPalette[i*3+1],
938 DefaultPalette[i*3+2],
939 wDefaultPalete16[i]));
940 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
941 // (lpColorTable[i].peGreen<<16) +
942 // (lpColorTable[i].peRed<<24);
943 }
944 fPalInit = TRUE;
945 }
946 pPal16 = &wDefaultPalete16[0];
947 pPal24 = &dwDefaultPalete24[0];
948 }
949 else
950 {
951 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
952 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
953 }
954 }
955
956 if(NULL!=ColorFill) {
957 ColorFill( pDiveBuffer, pFrameBuffer, Top, Left,
958 FillWidth, FillHeight, dwPitchDB,dwPitchFB,
959 dwFillColor,(16==lpDraw->dCaps.ulDepth)?(VOID*)pPal16:(VOID*)pPal24);
960 SurfChangeUniquenessValue(this);
961 }
962 else
963 {
964 dprintf(("DDRAW: ColorFill function is NULL!!"));
965 }
966
967 return(DD_OK);
968}
969//******************************************************************************
970//******************************************************************************
971void OS2IDirectDrawSurface::ColorConversion(LPRECT lpRect)
972{
973 //char *pSrc,*pDst,*pSLine,*pDLine;
974 DWORD CCwidth,CCheight,x,y;
975 DWORD *pPal24;
976 WORD *pPal16;
977
978 if( (NULL== lpDraw->pPrimSurf) ||
979 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
980 {
981 if(!fPalInit)
982 {
983 for(DWORD i=0;i<256;i++)
984 {
985 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
986 ((DefaultPalette[i*3+1]>>2) <<5) +
987 ((DefaultPalette[i*3]>>3) << 11);
988 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
989 ((DefaultPalette[i*3+1]>>2) <<16) +
990 ((DefaultPalette[i*3]>>3) << 24);
991 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
992 i,
993 DefaultPalette[i*3],
994 DefaultPalette[i*3+1],
995 DefaultPalette[i*3+2],
996 wDefaultPalete16[i]));
997 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
998 // (lpColorTable[i].peGreen<<16) +
999 // (lpColorTable[i].peRed<<24);
1000 }
1001 fPalInit = TRUE;
1002 }
1003 pPal16 = &wDefaultPalete16[0];
1004 pPal24 = &dwDefaultPalete24[0];
1005 }
1006 else
1007 {
1008 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
1009 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
1010 }
1011
1012 if(NULL==lpRect)
1013 {
1014 //pSrc = pFrameBuffer;
1015 //pDst = pDiveBuffer;
1016 CCwidth = width;
1017 CCheight = height;
1018 x = 0;
1019 y = 0;
1020 }
1021 else
1022 {
1023 // ToDo: Check why the top/bottom values come in swaped here
1024 // for now simply reverse them with the following 3 lines
1025 y = lpRect->top;
1026 lpRect->top = lpRect->bottom;
1027 lpRect->bottom = y;
1028 // end of hack
1029 #if 0
1030 pSrc = pFrameBuffer +
1031 (lpRect->top * dwPitchFB) +
1032 (lpRect->left* (lpDraw->dCaps.ulDepth/8));
1033 pDst = pDiveBuffer +
1034 (lpRect->top * dwPitchDB) +
1035 (lpRect->left* dwBytesPPDive);
1036 #endif
1037 y = lpRect->top;
1038 x = lpRect->left;
1039 CCwidth = lpRect->right - lpRect->left;
1040 CCheight = lpRect->bottom - lpRect->top;
1041
1042 }
1043
1044// dprintf( ("H: %d W: %d\n SRC @ %08X\n DST @ %08X\n",
1045// CCheight, CCwidth, pSrc,pDst));
1046 if(NULL!=ColorConv)
1047 ColorConv( pDiveBuffer, pFrameBuffer, y, x,
1048 CCwidth, CCheight, dwPitchDB,dwPitchFB,
1049 16==lpDraw->dCaps.ulDepth?(VOID*)pPal16:(VOID*)pPal24);
1050 else
1051 {
1052 dprintf(("DDRAW: ColorConv function is NULL!!"));
1053 }
1054
1055/*
1056 pSLine = pSrc;
1057 pDLine = pDst;
1058
1059 switch(lpDraw->dCaps.ulDepth)
1060 {
1061 case 8:
1062 dprintf(("DDRAW: 8Bit target CC not implemented\n"));
1063 break;
1064 case 15:
1065 dprintf(("DDRAW: 15 Bit not implemented using 16bit might look ugly\n"));
1066 case 16:
1067 if(8==lpDraw->GetScreenBpp())
1068 {
1069 dprintf(("DDRAW: 8->16Bit CC\n"));
1070 for(y=0;CCheight;CCheight--,y++)
1071 {
1072 for(x=0;x<width;x++)
1073 {
1074 *(((WORD*)pDLine)+x) = pPal16[pSLine[x]];
1075
1076 }
1077 pSLine += dwPitchFB;
1078 pDLine += dwPitchDB;
1079 }
1080 }
1081 else
1082 {
1083 dprintf(("DDRAW: %d ->16Bit Not implemented",lpDraw->GetScreenBpp()));
1084 }
1085 break;
1086 case 24:
1087 if(8==lpDraw->GetScreenBpp())
1088 {
1089 dprintf(("DDRAW: 8->24Bit CC"));
1090 for(y=0;CCheight;CCheight--,y++)
1091 {
1092 char *pIter;
1093 for(x=0,pIter=pDLine;x<width;x++,pIter=pDLine)
1094 {
1095 *((DWORD*)pIter) = pPal24[pSLine[x]];
1096 pIter+=3;
1097 }
1098 pSLine += dwPitchFB;
1099 pDLine += dwPitchDB;
1100 }
1101 }
1102 else
1103 {
1104 dprintf(("DDRAW: %d ->24Bit Not implemented",lpDraw->GetScreenBpp()));
1105 }
1106 break;
1107 case 32:
1108 if(8==lpDraw->GetScreenBpp())
1109 {
1110 dprintf(("DDRAW: 8->32Bit CC"));
1111 for(y=0;CCheight;CCheight--,y++)
1112 {
1113 for(x=0;x<width;x++)
1114 {
1115 *(((DWORD*)pDLine)+x) = pPal24[pSLine[x]];
1116
1117 }
1118 pSLine += dwPitchFB;
1119 pDLine += dwPitchDB;
1120 }
1121 }
1122 else
1123 {
1124 dprintf(("DDRAW: %d ->32Bit Not implemented",lpDraw->GetScreenBpp()));
1125 }
1126 break;
1127 default:
1128 dprintf( ("Unexpected Screen Bitdepth %d\n",
1129 lpDraw->dCaps.ulDepth));
1130 break;
1131 }
1132*/
1133}
1134//******************************************************************************
1135//******************************************************************************
1136// Internal callbacks uses by destructor
1137INT CALLBACK DestroyRects(LPVOID lpItem, DWORD dwRes)
1138{
1139 DDRectangle *pItem = (DDRectangle*) lpItem;
1140 delete(pItem);
1141 return 1;
1142}
1143
1144INT CALLBACK ReleaseSurfaces(LPVOID lpItem, DWORD dwRes)
1145{
1146 OS2IDirectDrawSurface *pSurf;
1147 pSurf = (OS2IDirectDrawSurface *)lpItem;
1148 pSurf->Vtbl.Release(pSurf);
1149 return 1;
1150}
1151//******************************************************************************
1152//******************************************************************************
1153OS2IDirectDrawSurface::~OS2IDirectDrawSurface()
1154{
1155 if(hwndFullScreen) {
1156 DestroyWindow(hwndFullScreen);
1157 }
1158
1159 if(DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1160 {
1161 lpDraw->SetPrimarySurface(FALSE);
1162 if(lpPalette)
1163 lpPalette->RestorePhysPalette();
1164
1165 }
1166 else
1167 {
1168 if( diveBufNr != -1)
1169 {
1170 if(fLocked)
1171 DiveEndImageBufferAccess(hDive, diveBufNr);
1172 DiveFreeImageBuffer(hDive, diveBufNr);
1173
1174 }
1175
1176 fLocked = FALSE;
1177 diveBufNr = -1;
1178 }
1179 // Free Buffers if they have been allocated
1180 // DIVE Buffer
1181
1182 if(NULL!=pDBreal)
1183 free(pDBreal);
1184
1185 // FrameBuffer
1186
1187 if(NULL!=pFBreal)
1188 free(pFBreal);
1189
1190 // Clear the list of locked rectangles
1191 if (DPA_GetPtrCount(DPA_LockedRects)>0)
1192 {
1193 DPA_DestroyCallback( DPA_LockedRects,
1194 DestroyRects,
1195 0);
1196 }
1197
1198 if(lpClipper)
1199 {
1200 lpClipper->Vtbl.Release((IDirectDrawClipper*)lpClipper);
1201 lpClipper = NULL;
1202 }
1203
1204 if(lpPalette)
1205 {
1206 lpPalette->Vtbl.Release((IDirectDrawPalette*)lpPalette);
1207 lpPalette = NULL;
1208 }
1209
1210 if(hbmImage)
1211 DeleteObject(hbmImage);
1212
1213 if(hdcImage)
1214 DeleteDC(hdcImage);
1215
1216 if (NULL!=BackBuffer)
1217 BackBuffer->Vtbl.Release(BackBuffer);
1218
1219 if (DPA_GetPtrCount(DPA_SurfaceMipMaps)>0)
1220 {
1221 DPA_DestroyCallback( DPA_SurfaceMipMaps,
1222 ReleaseSurfaces,
1223 0);
1224 }
1225
1226 if (DPA_GetPtrCount(DPA_SurfaceAttached)>0)
1227 {
1228 DPA_DestroyCallback( DPA_SurfaceAttached,
1229 ReleaseSurfaces,
1230 0);
1231 }
1232
1233 lpDraw->Vtbl.Release(lpDraw);
1234}
1235
1236//******************************************************************************
1237//******************************************************************************
1238inline void OS2IDirectDrawSurface::SetFrontBuffer( OS2IDirectDrawSurface* NewFBuffer)
1239{
1240 FrontBuffer = NewFBuffer;
1241 if (NULL==NewFBuffer)
1242 {
1243
1244 dprintf(("DDRAW: Remove Frontbuffer\n"));
1245
1246 // The real Frontbuffer was removed check if I'm now the one
1247 if(NULL!=BackBuffer)
1248 {
1249 dprintf(("DDRAW: We have the a backbuffer so we're the Frontbuffer\n"));
1250 NextFlip = BackBuffer;
1251 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
1252 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1253 BackBuffer->SetFrontBuffer(this);
1254 }
1255 else
1256 {
1257 // Flipchain is destroyed
1258 dprintf(("DDRAW: No longer part of a flipchain\n"));
1259 DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);
1260 }
1261 }
1262 else
1263 {
1264 dprintf(("DDRAW: Set new Frontbuffer to 0x%08X\n",NewFBuffer));
1265 if(NULL==NewFBuffer->GetFrontBuffer())
1266 {
1267 dprintf(("DDRAW: We're the 1st backbuffer\n"));
1268 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
1269 FrontBuffer->NextFlip = this;
1270 }
1271 else
1272 {
1273 dprintf(("DDRAW: We are one of many buffers\n"));
1274 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER ;
1275 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1276 }
1277
1278 if(NULL!=BackBuffer)
1279 BackBuffer->SetFrontBuffer(this);
1280
1281 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
1282 }
1283}
1284//******************************************************************************
1285//******************************************************************************
1286HRESULT WIN32API SurfQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
1287{
1288 // ToDo: Add Interface handling for D3D Textures
1289 HRESULT rc;
1290 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1291
1292 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfQueryInterface\n"));
1293
1294 if(NULL==ppvObj)
1295 {
1296 rc = DDERR_INVALIDPARAMS;
1297 goto RetFn;
1298 }
1299
1300 rc = E_NOINTERFACE;
1301 *ppvObj = NULL;
1302
1303 if(IsEqualGUID(riid, IID_IDirectDrawSurface))
1304 {
1305 *ppvObj = &me->lpVtbl; // ToDo DO a real V1 table
1306 rc = DD_OK;
1307 goto RetFn;
1308 }
1309 if(IsEqualGUID(riid, IID_IDirectDrawSurface2))
1310 {
1311 *ppvObj = &me->lpVtbl2;
1312 rc = DD_OK;
1313 goto RetFn;
1314 }
1315 if(IsEqualGUID(riid, IID_IDirectDrawSurface3))
1316 {
1317 *ppvObj = &me->Vtbl3;
1318 rc = DD_OK;
1319 goto RetFn;
1320 }
1321 if(IsEqualGUID(riid, IID_IDirectDrawSurface4))
1322 {
1323 *ppvObj = This;
1324 rc =DD_OK;
1325 }
1326
1327 //if(IsEqualGUID(riid, IID_IUnknown)) ...
1328
1329RetFn:
1330
1331 if(DD_OK==rc)
1332 SurfAddRef(This);
1333
1334 return(rc);
1335}
1336//******************************************************************************
1337//******************************************************************************
1338ULONG WIN32API SurfAddRef(THIS This)
1339{
1340 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1341
1342 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1));
1343
1344 return ++me->Referenced;
1345}
1346//******************************************************************************
1347//******************************************************************************
1348ULONG WIN32API SurfRelease(THIS This)
1349{
1350 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1351
1352 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1));
1353 dprintf(("DDRAW: OS2IDirectDrawSurface::Surface %X\n", me));
1354 if(me->Referenced)
1355 {
1356 me->Referenced--;
1357 if(me->Referenced == 0)
1358 {
1359 delete( me);
1360 #ifndef __WATCOMC__
1361 //_interrupt(3);
1362 #endif
1363 return(0);
1364 }
1365 else
1366 return me->Referenced;
1367 }
1368 else
1369 return(0);
1370}
1371//******************************************************************************
1372//******************************************************************************
1373HRESULT WIN32API SurfAddAttachedSurface(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurface)
1374{
1375
1376 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1377 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1378}
1379//******************************************************************************
1380//******************************************************************************
1381HRESULT WIN32API SurfAddAttachedSurface3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurface)
1382{
1383
1384 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1385 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1386}
1387//******************************************************************************
1388//******************************************************************************
1389HRESULT WIN32API SurfAddAttachedSurface4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurface)
1390{
1391 OS2IDirectDrawSurface *AttachedSurface;
1392 OS2IDirectDrawSurface *BBCursor;
1393 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1394 int rc;
1395
1396 dprintf(("DDRAW: SurfAddAttachedSurface4\n"));
1397
1398 if (NULL==lpDDSurface)
1399 return DDERR_INVALIDPARAMS;
1400
1401 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
1402
1403 if(AttachedSurface->IsImplicitSurface())
1404 {
1405 dprintf(("DDRAW: Internal : Can't attach an implicitly created surface to another surface\n"));
1406 return(DDERR_CANNOTATTACHSURFACE);
1407 }
1408
1409 if(This == AttachedSurface)
1410 {
1411 dprintf(("DDRAW: Can't attach a surface to itself\n"));
1412 return(DDERR_CANNOTATTACHSURFACE);
1413 }
1414
1415 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
1416 {
1417 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1418 {
1419 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1420 {
1421 rc = DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1422 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1423 AttachedSurface);
1424
1425 if( rc>=0)
1426 {
1427 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1428 me->DDSurfaceDesc.dwMipMapCount++;
1429
1430 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1431 }
1432 else
1433 {
1434 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1435 return(DDERR_CANNOTATTACHSURFACE);
1436 }
1437 }
1438 else
1439 {
1440 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1441 return(DDERR_CANNOTATTACHSURFACE);
1442 }
1443 }
1444 else
1445 {
1446 rc = DPA_InsertPtr( me->DPA_SurfaceAttached,
1447 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1448 AttachedSurface);
1449
1450 if(rc>=0)
1451 {
1452 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1453 }
1454 else
1455 {
1456 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1457 return(DDERR_CANNOTATTACHSURFACE);
1458 }
1459 }
1460 } // endif DDSCAPS_TEXTURE
1461 else
1462 {
1463 if( (AttachedSurface->DDSurfaceDesc.dwWidth != me->DDSurfaceDesc.dwWidth)
1464 || (AttachedSurface->DDSurfaceDesc.dwHeight != me->DDSurfaceDesc.dwHeight)
1465 // || (AttachedSurface->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount !=
1466 // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
1467 )
1468 {
1469 dprintf(("DDRAW: Surfaces don't have equal dimensions\n"));
1470 return(DDERR_CANNOTATTACHSURFACE);
1471 }
1472 else
1473 {
1474 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
1475 {
1476 if( (AttachedSurface->GetFrontBuffer()!=NULL) || (AttachedSurface->BackBuffer!= NULL))
1477 {
1478 dprintf(("DDRAW: Surface already has a front/backbuffer\n"));
1479 return(DDERR_SURFACEALREADYATTACHED);
1480 }
1481
1482 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
1483 {
1484 if(NULL!=me->BackBuffer)
1485 {
1486 BBCursor = me->BackBuffer;
1487 while(NULL!=BBCursor)
1488 {
1489 BBCursor->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1490 BBCursor->DDSurfaceDesc.dwBackBufferCount++;
1491 BBCursor->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1492 BBCursor = BBCursor->BackBuffer;
1493 }
1494 BBCursor->BackBuffer = AttachedSurface;
1495 AttachedSurface->SetFrontBuffer(BBCursor);
1496 }
1497 else
1498 {
1499 me->BackBuffer = AttachedSurface;
1500 AttachedSurface->SetFrontBuffer(me);
1501 }
1502 me->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1503 me->DDSurfaceDesc.dwBackBufferCount++;
1504 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1505
1506 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1507 return (DD_OK);
1508 }
1509 else
1510 {
1511 dprintf(("DDRAW: Can't attach backbuffer to anything but a frontbuffer\n"));
1512 return(DDERR_CANNOTATTACHSURFACE);
1513 }
1514 }
1515 else
1516 {
1517 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1518 {
1519 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1520 {
1521 if( DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1522 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1523 AttachedSurface) >=0)
1524 {
1525 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1526 me->DDSurfaceDesc.dwMipMapCount++;
1527 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1528
1529 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1530 }
1531 else
1532 {
1533 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1534 return(DDERR_CANNOTATTACHSURFACE);
1535 }
1536 }
1537 else
1538 {
1539 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1540 return(DDERR_CANNOTATTACHSURFACE);
1541 }
1542 }
1543 else
1544 {
1545 if( DPA_InsertPtr( me->DPA_SurfaceAttached,
1546 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1547 AttachedSurface) >=0)
1548 {
1549 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1550 }
1551 else
1552 {
1553 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1554 return(DDERR_CANNOTATTACHSURFACE);
1555 }
1556 }
1557 }// End if not DDSCAPS_BACKBUFFER
1558 }
1559 }
1560 dprintf(("DDRAW: Surface attached\n"));
1561 return(DD_OK);
1562}
1563//******************************************************************************
1564//******************************************************************************
1565HRESULT WIN32API SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
1566{
1567 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1568 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1569
1570 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
1571}
1572//******************************************************************************
1573//******************************************************************************
1574HRESULT WIN32API SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface)
1575{
1576 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1577 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1578
1579 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
1580}
1581//******************************************************************************
1582//******************************************************************************
1583HRESULT WIN32API SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
1584{
1585
1586 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1587 OS2IDirectDrawSurface *AttachedSurface;
1588 OS2IDirectDrawSurface *SurfaceCursor;
1589 int i;
1590
1591 BOOL Found = FALSE;
1592 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
1593
1594 if((0!=dwFlags)||(NULL==lpDDSurface))
1595 return(DDERR_INVALIDPARAMS);
1596
1597 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
1598 if (AttachedSurface->IsImplicitSurface())
1599 return (DDERR_CANNOTDETACHSURFACE);
1600
1601 if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
1602 !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
1603 {
1604 // Surface seams to be a backbuffer in a flipchain search it
1605
1606 // Goto top of list
1607 if(me->FrontBuffer!=NULL)
1608 {
1609 SurfaceCursor = me->FrontBuffer;
1610 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1611 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1612 }
1613 else
1614 SurfaceCursor = me;
1615
1616 // now iterrate through the list skip first in list as we don't remove the frontbuffer
1617
1618 SurfaceCursor = SurfaceCursor->BackBuffer;
1619 while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
1620 SurfaceCursor = SurfaceCursor->BackBuffer;
1621
1622 if(SurfaceCursor!=NULL)
1623 {
1624 Found = TRUE;
1625 // remove the Surface from the list
1626 SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
1627 if(SurfaceCursor->BackBuffer!=NULL)
1628 {
1629 SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
1630
1631 }
1632 else
1633 {
1634 // we were the last buffer in the list have we been the only backbuffer?
1635 if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
1636 {
1637 // Yepp so "destroy" the flipchain
1638 SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1639 SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1640 }
1641 }
1642 // decrement the backbuffer count of all buffers in the chain in front of us
1643 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1644 {
1645 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1646 SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
1647 }
1648
1649 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
1650 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1651 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1652 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
1653 AttachedSurface->lpVtbl->Release(AttachedSurface);
1654
1655 }
1656 } //endif delete back/frontbuffers
1657
1658 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
1659 {
1660 // seams like someone wants a new frontbuffer
1661
1662 // Goto top of list
1663
1664 if(me->FrontBuffer!=NULL)
1665 {
1666 SurfaceCursor = me->FrontBuffer;
1667 while(SurfaceCursor->GetFrontBuffer()!=NULL)
1668 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
1669 }
1670 else
1671 SurfaceCursor = me;
1672
1673 if(SurfaceCursor == AttachedSurface)
1674 {
1675 Found = TRUE;
1676 SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
1677 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
1678 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1679 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
1680 AttachedSurface->lpVtbl->Release(AttachedSurface);
1681 }
1682
1683 }
1684
1685
1686 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) )
1687 {
1688 // Surface seams to be a mipmap
1689 i = 0;
1690 while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found)
1691 {
1692 if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface)
1693 {
1694 Found = TRUE;
1695 DPA_DeletePtr(me->DPA_SurfaceMipMaps,i);
1696 AttachedSurface->lpVtbl->Release(AttachedSurface);
1697 // adjust our info
1698 me->DDSurfaceDesc.dwMipMapCount-- ;
1699 if (!me->DDSurfaceDesc.dwMipMapCount)
1700 {
1701 me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
1702 }
1703 }
1704 i++;
1705 }
1706 }
1707
1708 if(!Found)
1709 {
1710 // Surface seams to be an attached one
1711 i = 0;
1712 while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found)
1713 {
1714 if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface)
1715 {
1716 Found = TRUE;
1717 DPA_DeletePtr(me->DPA_SurfaceAttached,i);
1718 AttachedSurface->lpVtbl->Release(AttachedSurface);
1719 }
1720 i++;
1721 }
1722 }
1723
1724
1725 return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
1726}
1727//******************************************************************************
1728//******************************************************************************
1729HRESULT WIN32API SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
1730{
1731 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1732 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
1733
1734 return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
1735}
1736//******************************************************************************
1737//******************************************************************************
1738HRESULT WIN32API SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
1739{
1740 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1741 OS2IDirectDrawSurface *EnumSurface;
1742 DDSURFACEDESC2 EnumDesc;
1743 int i,count;
1744 HRESULT rc;
1745
1746 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
1747 if (NULL==lpCallBack)
1748 return (DDERR_INVALIDPARAMS);
1749
1750 rc = DDENUMRET_OK;
1751
1752
1753 if(me->BackBuffer != NULL)
1754 {
1755 memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
1756 rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
1757 }
1758
1759 count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps);
1760
1761 if(count>0)
1762 {
1763 i=0;
1764 while( (DDENUMRET_OK == rc) && i<count )
1765 {
1766 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
1767 memcpy( &EnumDesc,
1768 &(EnumSurface->DDSurfaceDesc),
1769 sizeof(DDSURFACEDESC2));
1770 // Calling back into WIN32 app so we had to reset FS
1771 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
1772 i++;
1773 }
1774 }
1775
1776 count = DPA_GetPtrCount(me->DPA_SurfaceAttached);
1777
1778 if(count>0)
1779 {
1780 i=0;
1781 while( (DDENUMRET_OK == rc) && i<count )
1782 {
1783 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
1784 memcpy( &EnumDesc,
1785 &(EnumSurface->DDSurfaceDesc),
1786 sizeof(DDSURFACEDESC2));
1787 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
1788 i++;
1789 }
1790 }
1791
1792 return(DD_OK);
1793}
1794//******************************************************************************
1795//******************************************************************************
1796HRESULT WIN32API SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
1797{
1798 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1799
1800 dprintf(("DDRAW: SurfFlip\n"));
1801
1802 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
1803}
1804//******************************************************************************
1805//******************************************************************************
1806HRESULT WIN32API SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags)
1807{
1808 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1809
1810 dprintf(("DDRAW: SurfFlip\n"));
1811
1812 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
1813}
1814//******************************************************************************
1815//******************************************************************************
1816HRESULT WIN32API SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
1817{
1818 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1819 OS2IDirectDrawSurface *FlipSurface;
1820 OS2IDirectDrawSurface *FlipCursor;
1821 LPVOID Data;
1822 char *pcrFB,*pcFB,*pcrDB,*pcDB;
1823
1824 dprintf(("DDRAW: SurfFlip4\n"));
1825
1826 if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
1827 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
1828 )
1829 {
1830 dprintf(("DDRAW: Flip called on none Frontbuffer/Flip surface\n Flags:\n"));
1831 _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
1832 dprintf(("DDRAW: \n"));
1833 return(DDERR_NOTFLIPPABLE);
1834 }
1835
1836 if(NULL!=lpDDSurf)
1837 {
1838 dprintf(("DDRAW: Check if Surface is in Flipchain!\n"));
1839
1840 // We got an override surface check if it is in the flipchain
1841 FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
1842 FlipCursor = me->BackBuffer;
1843 while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
1844 {
1845 FlipCursor = FlipCursor->BackBuffer;
1846 }
1847
1848 if(FlipCursor!=FlipSurface)
1849 {
1850 dprintf(("DDRAW: Surface not in Flipchain!\n"));
1851
1852 return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
1853 }
1854 }
1855 else
1856 {
1857 FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
1858 dprintf(("DDRAW: Next Surface @ 0x%08X\n",FlipSurface));
1859 }
1860
1861 if((me->fLocked)||(FlipSurface->fLocked))
1862 {
1863 dprintf(("DDRAW: Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked));
1864
1865 return(DDERR_SURFACEBUSY);
1866 }
1867
1868 if (-1 != me->diveBufNr)
1869 {
1870 //dprintf(("DDRAW: DIVE Flipchain DiveBuffer #%d",FlipSurface->diveBufNr));
1871
1872 // we got some DIVE surfaces
1873 // On Dive Buffers More then Double buffering won't get any perf. gain
1874 // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
1875 // Doulebuffering should work best.
1876
1877 //rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
1878 //dprintf(("DDRAW: DiveBlitImage rc = 0x%08X\n"));
1879 SurfBltFast4( me,
1880 0,
1881 0,
1882 (LPDIRECTDRAWSURFACE4)FlipSurface,
1883 NULL,
1884 DDBLTFAST_NOCOLORKEY);
1885
1886 if(NULL==lpDDSurf)
1887 {
1888 // advance in the flipchain if no valid override surface was passed in
1889 // if we reached the end of the flipchain The Frontbuffer is the next to flip to
1890 me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
1891 }
1892 }
1893 else
1894 {
1895 dprintf(("DDRAW: Memory Flipchain"));
1896 // Memory Flipchain
1897 //
1898 // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
1899 //
1900 // We only change the memory pointer to the buffers no need to copy all the data
1901 // So the NextFlip is here allways the Backbuffer so we won't advance this
1902 //
1903 // Sample (triple buffering) : Before Flip After Flip
1904 // Buffer: FB BB TB FB BB TB
1905 // Memory: 11 22 33 22 33 11
1906 //
1907
1908 Data = me->DDSurfaceDesc.lpSurface;
1909 pcrFB = me->pFBreal;
1910 pcFB = me->pFrameBuffer;
1911 pcrDB = me->pDBreal;
1912 pcDB = me->pDiveBuffer;
1913 me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
1914 me->pFBreal = FlipSurface->pFBreal;
1915 me->pFrameBuffer = FlipSurface->pFrameBuffer;
1916 me->pDBreal = FlipSurface->pDBreal;
1917 me->pDiveBuffer = FlipSurface->pDiveBuffer;
1918
1919 if (NULL==lpDDSurf)
1920 {
1921 while (NULL!=FlipSurface->BackBuffer)
1922 {
1923 FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
1924 FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal;
1925 FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer;
1926 FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal;
1927 FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer;
1928 FlipSurface = FlipSurface->BackBuffer;
1929 }
1930 }
1931 FlipSurface->DDSurfaceDesc.lpSurface = Data;
1932 FlipSurface->pFBreal = pcrFB;
1933 FlipSurface->pFrameBuffer = pcFB;
1934 FlipSurface->pDBreal = pcrDB;
1935 FlipSurface->pDiveBuffer = pcDB;
1936 }
1937
1938 return DD_OK;
1939}
1940
1941//******************************************************************************
1942//******************************************************************************
1943HRESULT WIN32API SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
1944 LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
1945{
1946 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1947 dprintf(("DDRAW: SurfGetAttachedSurface\n"));
1948
1949 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
1950}
1951//******************************************************************************
1952//******************************************************************************
1953HRESULT WIN32API SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps,
1954 LPDIRECTDRAWSURFACE3 FAR * lpDDSurf)
1955{
1956 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1957 dprintf(("DDRAW: SurfGetAttachedSurface3\n"));
1958
1959 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
1960}
1961//******************************************************************************
1962//******************************************************************************
1963HRESULT WIN32API SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
1964 LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
1965{
1966 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1967 OS2IDirectDrawSurface *EnumSurface = NULL;
1968 OS2IDirectDrawSurface *AttachedSurface = NULL;
1969 HRESULT rc;
1970 int i;
1971
1972 dprintf(("DDRAW: SurfGetAttachedSurface4\n>Requested Caps: "));
1973 _dump_DDSCAPS(lpDDCaps->dwCaps);
1974 dprintf(("DDRAW: \n"));
1975
1976 if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
1977 {
1978 dprintf(("DDRAW: Invalid params\n\n"));
1979 return (DDERR_INVALIDPARAMS);
1980 }
1981
1982
1983 rc = DD_OK;
1984
1985 if( (me->BackBuffer!=NULL) &&
1986 (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
1987 {
1988 dprintf(("DDRAW: Return Backbuffer\n"));
1989 AttachedSurface = me->BackBuffer;
1990 }
1991
1992 if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0)
1993 {
1994 i=0;
1995 while( i<DPA_GetPtrCount(me->DPA_SurfaceMipMaps) )
1996 {
1997 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
1998 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
1999 {
2000 if(NULL==AttachedSurface)
2001 AttachedSurface = EnumSurface;
2002 else
2003 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
2004 // but function must fail if more then one surface fits
2005
2006 }
2007 i++;
2008 }
2009 }
2010
2011 if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0)
2012 {
2013 i=0;
2014 while( i<DPA_GetPtrCount(me->DPA_SurfaceAttached) )
2015 {
2016 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
2017 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
2018 {
2019 if(NULL==AttachedSurface)
2020 AttachedSurface = EnumSurface;
2021 else
2022 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
2023 // but function must fail if more then one surface fits
2024
2025 }
2026 i++;
2027 }
2028 }
2029
2030 if( (DD_OK==rc) &&
2031 (NULL!=AttachedSurface) )
2032 {
2033 *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
2034 // not sure but as we returned an reference rains usage count
2035 AttachedSurface->lpVtbl->AddRef(AttachedSurface);
2036 }
2037 else
2038 {
2039 *lpDDSurf = NULL;
2040 rc = DDERR_NOTFOUND;
2041 }
2042
2043
2044 return rc;
2045}
2046//******************************************************************************
2047//******************************************************************************
2048HRESULT WIN32API SurfGetBltStatus(THIS This, DWORD)
2049{
2050 dprintf(("DDRAW: SurfGetBltStatus\n"));
2051
2052 return(DD_OK);
2053}
2054//******************************************************************************
2055//******************************************************************************
2056HRESULT WIN32API SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
2057{
2058 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2059
2060 dprintf(("DDRAW: SurfGetCaps\n"));
2061
2062 if(NULL==lpDDCaps)
2063 return(DDERR_INVALIDPARAMS);
2064
2065 lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
2066 _dump_DDSCAPS(lpDDCaps->dwCaps);
2067 return(DD_OK);
2068}
2069//******************************************************************************
2070//******************************************************************************
2071HRESULT WIN32API SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
2072{
2073 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2074 dprintf(("DDRAW: SurfGetCaps4\n"));
2075
2076 if(NULL==lpDDCaps)
2077 return(DDERR_INVALIDPARAMS);
2078
2079 memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
2080 _dump_DDSCAPS(lpDDCaps->dwCaps);
2081 _dump_DDSCAPS2(lpDDCaps->dwCaps2);
2082
2083 return(DD_OK);
2084}
2085//******************************************************************************
2086//******************************************************************************
2087HRESULT WIN32API SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
2088{
2089 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2090
2091 dprintf(("DDRAW: SurfGetClipper\n"));
2092
2093 if(me->lpClipper)
2094 {
2095 *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
2096 return(DD_OK);
2097 }
2098 else
2099 return(DDERR_NOCLIPPERATTACHED);
2100}
2101//******************************************************************************
2102//******************************************************************************
2103HRESULT WIN32API SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
2104{
2105 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2106 dprintf(("DDRAW: SurfGetColorKey\n"));
2107
2108 if ((0==dwFlags) || (NULL==lpDDColKey))
2109 return (DDERR_INVALIDPARAMS);
2110
2111 // as we report only src colorkey in the caps return error on all others flags
2112 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
2113 return(DDERR_UNSUPPORTED);
2114
2115 if(me->DDSurfaceDesc.dwFlags & dwFlags)
2116 {
2117 if(DDCKEY_SRCBLT & dwFlags)
2118 {
2119 memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
2120 }
2121 else
2122 return (DDERR_INVALIDPARAMS); // some other flags where set => error
2123 }
2124 else
2125 return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
2126
2127 return (DD_OK);
2128}
2129//******************************************************************************
2130//******************************************************************************
2131HRESULT WIN32API SurfGetDC(THIS This, HDC FAR *hdc)
2132{
2133 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2134 DDSURFACEDESC2 LockedSurfaceDesc;
2135 HRESULT rc;
2136 BITMAP bmpSurface;
2137 struct
2138 {
2139 BITMAPINFOHEADER bmiHead;
2140 RGBQUAD bmiCols[256];
2141 } BitmapInfo;
2142
2143 dprintf(("DDRAW: SurfGetDC\n"));
2144
2145 if (hdc == NULL)
2146 return(DDERR_INVALIDPARAMS);
2147
2148 LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2149
2150 if(DD_OK != me->Vtbl.Lock(me,NULL,&LockedSurfaceDesc,0,0))
2151 {
2152 return(DDERR_DCALREADYCREATED);
2153 }
2154
2155 rc = DD_OK;
2156
2157 if(me->hdcImage == NULL)
2158 {
2159 // Create a Device context
2160 me->hdcImage = CreateCompatibleDC(NULL);
2161 if(me->hdcImage == NULL)
2162 {
2163 dprintf(("DDRAW: Can't create compatible DC!\n"));
2164 me->Vtbl.Unlock(me,NULL);
2165 rc = DDERR_GENERIC;
2166 }
2167 }
2168
2169 if( (DD_OK==rc) && (me->hbmImage == NULL) )
2170 {
2171 OS2IDirectDrawPalette *ddpal = NULL;
2172
2173 dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n",
2174 LockedSurfaceDesc.dwWidth,
2175 LockedSurfaceDesc.dwHeight,
2176 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount
2177 ));
2178 memset(&BitmapInfo, 0, sizeof(BitmapInfo));
2179 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2180 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
2181 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
2182 BitmapInfo.bmiHead.biPlanes = 1;
2183 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2184
2185 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2186 {
2187 case 1:
2188 case 4:
2189 dprintf(("DDRAW: 1/4 Bit Not yet supported\n"));
2190 break;
2191 case 8:
2192 BitmapInfo.bmiHead.biCompression = BI_RGB;
2193 if (me->lpPalette != NULL)
2194 ddpal = me->lpPalette;
2195 if ((me->FrontBuffer != NULL) && (me->FrontBuffer->lpPalette != NULL))
2196 ddpal = me->FrontBuffer->lpPalette;
2197 if (ddpal != NULL) {
2198 ddpal->Vtbl.GetEntries((IDirectDrawPalette*)ddpal,
2199 0, 0, 256, (PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2200 }
2201 else {
2202 dprintf(("DDRAW: Using default palette\n"));
2203 for (DWORD i = 0; i < 256; i++) {
2204 BitmapInfo.bmiCols[i].rgbBlue = DefaultPalette[i*3+2];
2205 BitmapInfo.bmiCols[i].rgbGreen = DefaultPalette[i*3+1];
2206 BitmapInfo.bmiCols[i].rgbRed = DefaultPalette[i*3];
2207 BitmapInfo.bmiCols[i].rgbReserved = 0;
2208 }
2209 }
2210 me->hbmImage = CreateDIBitmap( me->hdcImage,
2211 &BitmapInfo.bmiHead,
2212 CBM_INIT,
2213 LockedSurfaceDesc.lpSurface,
2214 (PBITMAPINFO)&BitmapInfo,
2215 DIB_RGB_COLORS);
2216 break;
2217
2218 case 16:
2219 case 24:
2220 case 32:
2221 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2222 BitmapInfo.bmiHead.biClrUsed = 3;
2223 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2224 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2225 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2226 me->hbmImage = CreateDIBitmap( me->hdcImage,
2227 &BitmapInfo.bmiHead,
2228 CBM_INIT,
2229 LockedSurfaceDesc.lpSurface,
2230 (PBITMAPINFO)&BitmapInfo,
2231 DIB_RGB_COLORS );
2232 break;
2233
2234 default:
2235 dprintf( ("Unexpected BitCount %d \n",
2236 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2237 me->hbmImage=NULL;
2238 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2239
2240 if(me->hbmImage == NULL)
2241 {
2242 dprintf(("DDRAW: Can't create bitmap!\n"));
2243 DeleteDC(me->hdcImage);
2244 me->hdcImage = NULL;
2245 me->Vtbl.Unlock(me,NULL);
2246 rc = DDERR_GENERIC;
2247 }
2248 }
2249 else
2250 {
2251 if( (DD_OK==rc) && (me->dwLastDCUnique != me->dwUniqueValue) )
2252 {
2253 dprintf(("DDRAW: The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n"));
2254
2255 memset(&BitmapInfo,0, sizeof(BitmapInfo));
2256 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2257 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
2258 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
2259 BitmapInfo.bmiHead.biPlanes = 1;
2260 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2261
2262 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2263 {
2264 case 1:
2265 case 4:
2266 case 8:
2267 BitmapInfo.bmiHead.biCompression = BI_RGB;
2268 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2269 SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
2270 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2271 break;
2272 case 16:
2273 case 32:
2274 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2275 BitmapInfo.bmiHead.biClrUsed = 3;
2276 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2277 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2278 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2279 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2280 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2281 break;
2282 case 24:
2283 BitmapInfo.bmiHead.biCompression = BI_RGB;
2284 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2285 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2286 break;
2287 default:
2288 dprintf(("DDRAW: Unexpected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2289 break;
2290 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2291
2292 }
2293 }
2294
2295 // Allways select the bitmap into the DC! No matter if the old or a new one
2296
2297 if (DD_OK==rc)
2298 {
2299 if ((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
2300 {
2301 dprintf(("DDRAW: Can't select bitmap into DC!\n"));
2302 DeleteDC(me->hdcImage);
2303 me->hdcImage = NULL;
2304 DeleteObject(me->hbmImage);
2305 me->hbmImage = NULL;
2306 me->Vtbl.Unlock(me,NULL);
2307 rc = DDERR_GENERIC;
2308 }
2309 else
2310 {
2311 *hdc = me->hdcImage;
2312 }
2313 }
2314
2315 return rc;
2316}
2317//******************************************************************************
2318//******************************************************************************
2319HRESULT WIN32API SurfGetFlipStatus(THIS This, DWORD dwFlags)
2320{
2321 dprintf(("DDRAW: SurfGetFlipStatus\n"));
2322
2323 if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
2324 return DDERR_INVALIDPARAMS;
2325
2326 return(DD_OK);
2327}
2328//******************************************************************************
2329//******************************************************************************
2330HRESULT WIN32API SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
2331{
2332 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2333
2334 dprintf(("DDRAW: SurfGetPalette\n"));
2335
2336 if(me->lpPalette)
2337 {
2338 *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
2339 return(DD_OK);
2340 }
2341 else
2342 return(DDERR_NOPALETTEATTACHED);
2343}
2344//******************************************************************************
2345//******************************************************************************
2346HRESULT WIN32API SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
2347{
2348 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2349
2350 dprintf(("DDRAW: SurfGetPixelFormat %x %x", This, lpPixelFormat));
2351
2352 if(NULL==lpPixelFormat)
2353 return DDERR_INVALIDPARAMS;
2354
2355 _dump_pixelformat(&me->DDSurfaceDesc.ddpfPixelFormat);
2356
2357 memcpy( (char*)lpPixelFormat,
2358 (char*)&(me->DDSurfaceDesc.ddpfPixelFormat),
2359 sizeof(DDPIXELFORMAT));
2360
2361 return(DD_OK);
2362}
2363//******************************************************************************
2364//******************************************************************************
2365HRESULT WIN32API SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
2366{
2367 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2368
2369 dprintf(("DDRAW: SurfGetSurfaceDesc\n"));
2370
2371 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
2372 return(DDERR_INVALIDPARAMS);
2373
2374 memcpy( (char *)lpSurface,
2375 (char *)&me->DDSurfaceDesc,
2376 sizeof(DDSURFACEDESC));
2377
2378 return(DD_OK);
2379}
2380//******************************************************************************
2381//******************************************************************************
2382HRESULT WIN32API SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
2383{
2384 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2385
2386 dprintf(("DDRAW: SurfGetSurfaceDesc4\n"));
2387
2388 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
2389 return(DDERR_INVALIDPARAMS);
2390
2391 memcpy( (char *)lpSurface,
2392 (char *)&me->DDSurfaceDesc,
2393 sizeof(DDSURFACEDESC2));
2394
2395 return(DD_OK);
2396}
2397//******************************************************************************
2398//******************************************************************************
2399HRESULT WIN32API SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
2400{
2401 dprintf(("DDRAW: SurfInitialize\n"));
2402
2403 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
2404}
2405//******************************************************************************
2406//******************************************************************************
2407HRESULT WIN32API SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
2408{
2409 dprintf(("DDRAW: SurfInitialize\n"));
2410
2411 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
2412}
2413//******************************************************************************
2414//******************************************************************************
2415HRESULT WIN32API SurfIsLost(THIS)
2416{
2417 // We don't loose any surface ;)
2418 // But we might shoud check for primary and/or Dive Buffers as I don't know
2419 // if they are preserved if switching to a FS DOS/OS2 session
2420 //
2421 dprintf(("DDRAW: SurfIsLost\n"));
2422
2423 return(DD_OK);
2424}
2425//******************************************************************************
2426//******************************************************************************
2427HRESULT WIN32API SurfLock( THIS This,
2428 LPRECT lpRect,
2429 LPDDSURFACEDESC lpSurfaceDesc,
2430 DWORD dwFlags,
2431 HANDLE hEvent)
2432{
2433 DDSURFACEDESC2 SurfaceDesc4;
2434 HRESULT rc;
2435
2436 dprintf(("DDRAW: SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent));
2437
2438 if((NULL==lpSurfaceDesc)|| ((dwFlags & DDLOCK_EVENT) && NULL != hEvent)) {
2439 dprintf(("Invalid parameters"));
2440 return DDERR_INVALIDPARAMS;
2441 }
2442
2443 if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC) && lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC2)) {
2444 dprintf(("Invalid parameters"));
2445 return DDERR_INVALIDPARAMS;
2446 }
2447
2448 SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
2449
2450 rc = SurfLock4( This,
2451 lpRect,
2452 &SurfaceDesc4,
2453 dwFlags,
2454 hEvent);
2455 if (DD_OK==rc)
2456 {
2457 memcpy( (char*)lpSurfaceDesc,
2458 (char*)&SurfaceDesc4,
2459 lpSurfaceDesc->dwSize );
2460 }
2461
2462 return(rc);
2463}
2464//******************************************************************************
2465//******************************************************************************
2466HRESULT WIN32API SurfLock4( THIS This,
2467 LPRECT lpRect,
2468 LPDDSURFACEDESC2 lpSurfaceDesc,
2469 DWORD dwFlags,
2470 HANDLE hEvent)
2471{
2472
2473 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2474 int i;
2475
2476 BOOL Found;
2477 DDRectangle *pIRectCurrent,*pIRectNew;
2478 HRESULT rc;
2479
2480 dprintf( ("SurfLock4 %08X %08X %08X %d %d\n",
2481 me,
2482 (int)lpRect,
2483 (int)lpSurfaceDesc,
2484 dwFlags,
2485 hEvent) );
2486
2487 if( (NULL==lpSurfaceDesc) ||
2488 (NULL!=hEvent)
2489 )
2490 {
2491 dprintf(("DDERR_INVALIDPARAMS"));
2492 return DDERR_INVALIDPARAMS;
2493 }
2494
2495 if (NULL!=lpRect)
2496 pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
2497 else
2498 pIRectNew = new DDRectangle( 0, 0, me->width, me->height);
2499
2500 // ToDo : the lockchecking should be done in a critcal seq.
2501 dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n",
2502 pIRectNew->Left(),
2503 pIRectNew->Top(),
2504 pIRectNew->Right(),
2505 pIRectNew->Bottom()));
2506
2507 rc = DD_OK;
2508
2509 if(me->fLocked)
2510 {
2511 if (NULL==lpRect)
2512 {
2513 // If anything is locked we can't lock the complete surface
2514 dprintf(("DDRAW: Surface has locked Rectangles and we want to completely lock it\n"));
2515 Found = TRUE;
2516 }
2517 else
2518 {
2519 // If the new Rectangle intersects with any of the already locked rectangles it can't
2520 // be locked so check for this
2521
2522 dprintf(("DDRAW: Surface has locked Rectangles, check if they overlap\n"));
2523
2524 i=0;
2525 Found = FALSE;
2526
2527 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2528 {
2529 pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
2530 dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n",
2531 pIRectCurrent->Top(),
2532 pIRectCurrent->Left(),
2533 pIRectCurrent->Bottom(),
2534 pIRectCurrent->Right() ));
2535 Found = pIRectCurrent->intersects(*pIRectNew);
2536 i++;
2537 }
2538
2539 }
2540
2541 if (Found)
2542 {
2543 delete pIRectNew;
2544 dprintf(("DDRAW: SurfLock4: Surface already locked\n\n"));
2545 rc = DDERR_SURFACEBUSY;
2546 }
2547
2548 }
2549
2550 if(DD_OK == rc)
2551 {
2552 memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
2553
2554 if(lpRect != NULL)
2555 {
2556 lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer +
2557 (lpRect->top * me->dwPitchFB) +
2558 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
2559 dprintf(("DDRAW: SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left));
2560 }
2561 else
2562 {
2563 dprintf(("DDRAW: SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface));
2564 }
2565 // Add the rectangle to the list of locked rectangles
2566
2567 pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
2568
2569 DPA_InsertPtr( me->DPA_LockedRects,
2570 DPA_GetPtrCount(me->DPA_LockedRects),
2571 pIRectNew);
2572
2573#if 0
2574 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2575 {
2576 OS2RECTL rectOS2;
2577
2578 rectOS2.xLeft = pIRectNew->Left();
2579 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectNew->Bottom();
2580 rectOS2.xRight = pIRectNew->Right();
2581 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectNew->Top();
2582 dprintf(("DiveAcquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
2583 int ret = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectOS2);
2584 if(ret) {
2585 dprintf(("ERROR: DiveAcquireFrameBuffer failed with %d", ret));
2586 }
2587 }
2588#endif
2589 me->fLocked = TRUE;
2590
2591 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2592 {
2593 //If fHideCursorOnLock is set, then we hide the cursor to prevent
2594 //the app from corruption the mouse cursor (color/animated pointers)
2595 if(fHideCursorOnLock) ShowCursor(FALSE);
2596 }
2597 }
2598
2599 return rc;
2600}
2601//******************************************************************************
2602//******************************************************************************
2603HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc)
2604{
2605 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2606 struct
2607 {
2608 BITMAPINFOHEADER bmiHead;
2609 RGBQUAD bmiCols[256];
2610 } BitmapInfo;
2611 int rc;
2612
2613 dprintf(("DDRAW: SurfReleaseDC\n"));
2614
2615 if(hdc != me->hdcImage)
2616 return(DDERR_INVALIDOBJECT);
2617
2618 //unselect our bitmap
2619 SelectObject(me->hdcImage, me->hgdiOld);
2620
2621 memset(&BitmapInfo,0, sizeof(BitmapInfo));
2622 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
2623 BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
2624 BitmapInfo.bmiHead.biPlanes = 1;
2625 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.dwWidth; /// (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
2626 BitmapInfo.bmiHead.biHeight = me->DDSurfaceDesc.dwHeight;
2627
2628 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2629 {
2630 case 1:
2631 case 4:
2632 case 8:
2633 BitmapInfo.bmiHead.biCompression = BI_RGB;
2634 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
2635 rc = GetDIBits( hdc,
2636 me->hbmImage,
2637 0,
2638 me->DDSurfaceDesc.dwHeight,
2639 NULL,
2640 (PBITMAPINFO)&BitmapInfo,
2641 DIB_RGB_COLORS);
2642// BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight;
2643 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
2644 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
2645 rc,
2646 BitmapInfo.bmiHead.biSize,
2647 BitmapInfo.bmiHead.biWidth,
2648 BitmapInfo.bmiHead.biHeight,
2649 BitmapInfo.bmiHead.biPlanes,
2650 BitmapInfo.bmiHead.biBitCount,
2651 GetLastError(),
2652 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
2653
2654 rc = GetDIBits( hdc,
2655 me->hbmImage,
2656 0,
2657 me->DDSurfaceDesc.dwHeight,
2658 me->DDSurfaceDesc.lpSurface,
2659 (PBITMAPINFO)&BitmapInfo,
2660 DIB_RGB_COLORS);
2661 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
2662 rc,
2663 GetLastError(),
2664 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
2665 break;
2666 case 16:
2667 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2668 BitmapInfo.bmiHead.biClrUsed = 3;
2669 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2670 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2671 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2672 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2673 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2674 break;
2675
2676 case 32:
2677 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
2678 BitmapInfo.bmiHead.biClrUsed = 3;
2679 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
2680 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
2681 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
2682 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2683 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2684 break;
2685
2686 case 24:
2687 BitmapInfo.bmiHead.biCompression = BI_RGB;
2688 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
2689 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
2690 break;
2691 default:
2692 dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
2693 // we might could keep the surface locked and return an error but this is more "safe"
2694 break;
2695 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
2696
2697 me->Vtbl.Unlock(me,NULL);
2698 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
2699
2700 return(DD_OK);
2701}
2702//******************************************************************************
2703//******************************************************************************
2704HRESULT WIN32API SurfRestore(THIS)
2705{
2706 dprintf(("DDRAW: SurfRestore\n"));
2707
2708 return(DD_OK);
2709}
2710//******************************************************************************
2711//******************************************************************************
2712HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
2713{
2714 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2715
2716 dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper));
2717
2718 if(lpClipper == NULL)
2719 {
2720 //deattach surface
2721 if(me->lpClipper)
2722 {
2723 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
2724 me->lpClipper = NULL;
2725 return(DD_OK);
2726 }
2727 else
2728 return(DDERR_NOCLIPPERATTACHED);
2729 }
2730
2731 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
2732 return(DD_OK); //already attached
2733
2734 if(me->lpClipper != NULL)
2735 {
2736 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
2737 return(DD_OK);
2738 }
2739
2740 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
2741 me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
2742
2743 return(DD_OK);
2744}
2745//******************************************************************************
2746//******************************************************************************
2747HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
2748{
2749 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2750 HRESULT rc;
2751
2752 dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey));
2753
2754 if (0==dwFlags)
2755 {
2756 return (DDERR_INVALIDPARAMS);
2757 }
2758
2759 // as we report only src colorkey in the caps return error on all others flags
2760 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
2761 {
2762 dprintf(("Unspported colorkey\n"));
2763 return(DDERR_UNSUPPORTED);
2764 }
2765
2766 if(DDCKEY_SRCBLT & dwFlags)
2767 {
2768
2769 //(me->lpVtbl == me->Vtbl4)
2770 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
2771 if(NULL!=lpDDColKey)
2772 {
2773 dprintf(("copy colorkey"));
2774 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
2775 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
2776
2777 // ToDo: Generate a maskbitmap for transparent blitting here
2778 }
2779 else
2780 {
2781 dprintf(("clear colorkey"));
2782 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
2783 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
2784 }
2785 rc = DD_OK;
2786 }
2787 else
2788 {
2789 dprintf(("Unsupported flags"));
2790 _dump_DDCOLORKEY(dwFlags);
2791 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
2792 }
2793 return rc;
2794}
2795//******************************************************************************
2796//******************************************************************************
2797HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
2798{
2799 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2800
2801 dprintf(("DDRAW: SurfSetPalette\n"));
2802
2803 if(lpPalette == NULL)
2804 {
2805 //deattach palette
2806 if(me->lpPalette)
2807 {
2808 // If removed from a primary surface notify
2809 // palette that it is no longer attached to the
2810 // primary surface => doesn't modify physical palette
2811 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
2812 {
2813 me->lpPalette->SetIsPrimary(FALSE);
2814 }
2815 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
2816 me->lpPalette = NULL;
2817 return(DD_OK);
2818 }
2819 else
2820 return(DDERR_NOPALETTEATTACHED);
2821 }
2822
2823 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
2824 return(DD_OK); //already attached
2825
2826 if(me->lpPalette != NULL)
2827 {
2828 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
2829 //return(DD_OK);
2830 }
2831 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
2832 me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
2833
2834 // If Attached to a primary surface notify
2835 // palette that it is attached to the primary surface
2836 // => It does modify physical palette.
2837 // This is important as an palette can be attached to
2838 // multiple surfaces. If one is the primary surface
2839 // changes done to it via any surface must result in
2840 // changes in the phys pal.
2841
2842 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
2843 {
2844 me->lpPalette->SetIsPrimary(TRUE);
2845 }
2846 // me->lpVtbl->ChangeUniquenessValue(me);
2847
2848 return(DD_OK);
2849}
2850//******************************************************************************
2851//******************************************************************************
2852HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData)
2853{
2854
2855 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
2856 int i;
2857 DDRectangle *pIRectUnlock, *pIRectEnum;
2858 BOOL Found = FALSE;
2859 OS2RECTL CCRect;
2860 HRESULT rc;
2861
2862 dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData));
2863
2864 if(me->fLocked == FALSE)
2865 {
2866 dprintf(("DDRAW: Surface not locked!\n"));
2867 return(DDERR_NOTLOCKED);
2868 }
2869
2870 i=0;
2871 if(NULL!=lpSurfaceData)
2872 {
2873 dprintf(("DDRAW: Buffer Pointer Compare"));
2874
2875 // We got a pinter to the surface memory so we must search for
2876 // this pointer in the locked rects DPA to unlock the right rect.
2877
2878 while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2879 {
2880 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
2881 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
2882 i,
2883 pIRectEnum->Top(),
2884 pIRectEnum->Left(),
2885 pIRectEnum->Bottom(),
2886 pIRectEnum->Right(),
2887 pIRectEnum->GetMemPtr() ));
2888
2889 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
2890 if(!Found)
2891 {
2892 dprintf(("DDRAW: Not Found, try Next rect\n"));
2893 i++;
2894 }
2895 else
2896 {
2897 dprintf(("DDRAW: Found Rect\n"));
2898 }
2899 }
2900 }
2901 else
2902 {
2903 // If a NULL pointer was passed in the SW tries to unlock the
2904 // complete surface so we must compare the rects.
2905 dprintf(("DDRAW: Rectangle compare"));
2906
2907#if 1
2908 i = 0;
2909 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0);
2910 Found = (pIRectEnum != NULL);
2911#else
2912 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
2913
2914 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
2915 {
2916 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
2917 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
2918 i,
2919 pIRectEnum->Top(),
2920 pIRectEnum->Left(),
2921 pIRectEnum->Bottom(),
2922 pIRectEnum->Right(),
2923 pIRectEnum->GetMemPtr() ));
2924
2925 Found = (*pIRectEnum == *pIRectUnlock);
2926 if(!Found)
2927 {
2928 dprintf(("DDRAW: Not Found, try Next rect\n"));
2929 i++;
2930 }
2931 else
2932 {
2933 dprintf(("DDRAW: Found Rect\n"));
2934 }
2935 }
2936 delete pIRectUnlock;
2937#endif
2938 }
2939
2940 if(!Found)
2941 {
2942 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
2943 rc = DDERR_INVALIDRECT;
2944 }
2945 else
2946 {
2947 dprintf(("DDRAW: Remove Rect %d from Seq.\n",i));
2948
2949 DPA_DeletePtr(me->DPA_LockedRects,i);
2950
2951 dprintf(("DDRAW: Test if locked Rects main\n"));
2952
2953 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
2954 {
2955 dprintf(("DDRAW: No Locked Rects left for surface\n"));
2956 me->fLocked = FALSE;
2957 }
2958 else
2959 dprintf(( "%d Rects in Seq\n",
2960 DPA_GetPtrCount(me->DPA_LockedRects)));
2961
2962 if(me->pFrameBuffer != me->pDiveBuffer)
2963 {
2964 dprintf(( "ColorConversion Needed %08X != %08X\n",
2965 me->pFrameBuffer,
2966 me->pDiveBuffer));
2967 if(NULL!=lpSurfaceData)
2968 {
2969 CCRect.yTop = pIRectEnum->Top();
2970 CCRect.xLeft = pIRectEnum->Left();
2971 CCRect.xRight = pIRectEnum->Right();
2972 CCRect.yBottom = pIRectEnum->Bottom();
2973
2974 me->ColorConversion( (LPRECT)&CCRect);
2975 }
2976 else
2977 {
2978 me->ColorConversion(NULL);
2979 }
2980 }
2981 else
2982 dprintf( ("No ColorConversion Needed"));
2983
2984
2985#if 0
2986 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
2987 {
2988 OS2RECTL rectOS2;
2989
2990 rectOS2.xLeft = pIRectEnum->Left();
2991 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom();
2992 rectOS2.xRight = pIRectEnum->Right();
2993 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top();
2994 dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
2995 int ret = DiveDeacquireFrameBuffer(me->hDive);
2996 if(ret) {
2997 dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret));
2998 }
2999 }
3000#endif
3001
3002 // delete tne DDRectobject of the found rectangle
3003 delete pIRectEnum;
3004
3005 // me->lpVtbl->ChangeUniquenessValue(me);
3006
3007 dprintf(("DDRAW: Unlock OK\n\n"));
3008
3009 rc = DD_OK;
3010
3011 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
3012 {
3013 //If fHideCursorOnLock is set, then we hide the cursor to prevent in SurfLock4
3014 //the app from corruption the mouse cursor (color/animated pointers)
3015 //We need to show it again here
3016 if(fHideCursorOnLock) ShowCursor(TRUE);
3017 }
3018 }
3019
3020 return rc;
3021}
3022//******************************************************************************
3023//******************************************************************************
3024HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
3025{
3026 // MS changed the parameter from LPVOID to LPRECT with DX6
3027 // as DX-6 allways returns a DDSurface4 on create surface this
3028 // is a problem i not NULL is passed in.
3029 // Solution We first test with the pointer ns assuming a rectangle
3030 // if we don't find a rect Which is very likely if we get a pointer
3031 // SurfaceMemory we call SurfUnlock and test for the pointer there.
3032
3033
3034 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3035 int i;
3036 DDRectangle *pIRectUnlock, *pIRectEnum;
3037 BOOL Found = FALSE;
3038 HRESULT rc;
3039
3040 dprintf(("DDRAW: SurfUnlock4\n"));
3041
3042 if(me->fLocked == FALSE)
3043 {
3044 dprintf(("DDRAW: Surface not locked!\n"));
3045 return(DDERR_NOTLOCKED);
3046 }
3047
3048 if(NULL!=lpSurfaceRect)
3049 {
3050 dprintf(("DDRAW: Unlock rectangle\n"));
3051 pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top,
3052 lpSurfaceRect->right, lpSurfaceRect->bottom);
3053 }
3054 else
3055 {
3056 dprintf(("DDRAW: Unlock complete surface\n"));
3057 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
3058 }
3059
3060 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
3061 pIRectUnlock->Top(),
3062 pIRectUnlock->Left(),
3063 pIRectUnlock->Bottom(),
3064 pIRectUnlock->Right() ));
3065
3066 dprintf(("DDRAW: Start Enumeration of Locked Rects\n"));
3067
3068 i=0;
3069 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
3070 {
3071 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
3072 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
3073 pIRectEnum->Top(),
3074 pIRectEnum->Left(),
3075 pIRectEnum->Bottom(),
3076 pIRectEnum->Right() ));
3077
3078 Found = (*pIRectEnum == *pIRectUnlock);
3079 if(!Found)
3080 {
3081 dprintf(("DDRAW: Not Found, try Next rect\n"));
3082 i++;
3083 }
3084 else
3085 {
3086 dprintf(("DDRAW: Found Rect\n"));
3087 }
3088 }
3089
3090 if(!Found)
3091 {
3092
3093 if(NULL==lpSurfaceRect)
3094 {
3095 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
3096 return(DDERR_INVALIDRECT);
3097 }
3098 else
3099 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
3100 }
3101 else
3102 {
3103 dprintf(("DDRAW: Remove Rect from Seq.\n"));
3104
3105 DPA_DeletePtr(me->DPA_LockedRects,i);
3106
3107 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
3108 {
3109 dprintf(("DDRAW: No Locked Rects left for surface\n"));
3110 me->fLocked = FALSE;
3111 }
3112
3113 if(me->pFrameBuffer != me->pDiveBuffer)
3114 {
3115 dprintf(( "ColorConversion Needed %08X != %08X\n",
3116 me->pFrameBuffer,
3117 me->pDiveBuffer));
3118 me->ColorConversion(lpSurfaceRect);
3119 }
3120
3121 // me->lpVtbl->ChangeUniquenessValue(me);
3122
3123 dprintf(("DDRAW: Unlock OK\n\n"));
3124 rc = DD_OK;
3125 }
3126
3127 return rc;
3128}
3129//******************************************************************************
3130//******************************************************************************
3131HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
3132{
3133 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3134
3135 dprintf(("DDRAW: SurfGetDDInterface\n"));
3136 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
3137 return(DD_OK);
3138}
3139//******************************************************************************
3140//******************************************************************************
3141HRESULT WIN32API SurfPageLock(THIS, DWORD)
3142{
3143 // Only used for DMA memory access
3144 // If we implement this for the None dive buffers with a pdd the we must change
3145 // from malloc to DosAllocMem and use OBJ_TILE flag
3146 dprintf(("DDRAW: SurfPageLock\n"));
3147 return(DD_OK);
3148}
3149//******************************************************************************
3150//******************************************************************************
3151HRESULT WIN32API SurfPageUnlock(THIS, DWORD)
3152{
3153 dprintf(("DDRAW: SurfPageUnlock\n"));
3154 return(DD_OK);
3155}
3156//******************************************************************************
3157//******************************************************************************
3158// V3 Interface Functions
3159
3160HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
3161{
3162 dprintf(("DDRAW: SurfSetSurfaceDesc\n"));
3163
3164 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3165 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
3166 return DDERR_INVALIDPARAMS;
3167
3168 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
3169 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3170 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3171 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
3172 if(-1==me->diveBufNr)
3173 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
3174
3175 if (!me->Updated)
3176 {
3177 me->Updated = TRUE;
3178 // free our allocated Memory
3179 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
3180 {
3181 if(me->pFBreal)
3182 free(me->pFBreal);
3183 if(me->pDBreal)
3184 free(me->pFBreal);
3185 }
3186 }
3187 // me->lpVtbl->ChangeUniquenessValue(me);
3188 memcpy( (char*)&(me->DDSurfaceDesc),
3189 (char*)lpSurfDesc,
3190 sizeof(DDSURFACEDESC));
3191
3192 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
3193
3194 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
3195 {
3196 // create CC buffer ....
3197 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
3198 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
3199 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
3200 }
3201 return DD_OK;
3202}
3203//******************************************************************************
3204//******************************************************************************
3205HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
3206{
3207 dprintf(("DDRAW: SurfSetSurfaceDesc4\n"));
3208
3209 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3210 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
3211 return DDERR_INVALIDPARAMS;
3212
3213 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
3214 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3215 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
3216 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
3217 if(-1==me->diveBufNr)
3218 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
3219
3220 if (!me->Updated)
3221 {
3222 me->Updated = TRUE;
3223 // free our allocated Memory
3224 // free our allocated Memory
3225 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
3226 {
3227 if(me->pFBreal)
3228 free(me->pFBreal);
3229 if(me->pDBreal)
3230 free(me->pFBreal);
3231 }
3232 }
3233 // me->lpVtbl->ChangeUniquenessValue(me);
3234 memcpy( (char *)&(me->DDSurfaceDesc),
3235 (char*)lpSurfDesc,
3236 sizeof(DDSURFACEDESC2));
3237 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
3238
3239 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
3240 {
3241 // create CC buffer ....
3242 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
3243 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
3244 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
3245 }
3246
3247 return DD_OK;
3248}
3249//******************************************************************************
3250//******************************************************************************
3251// V4 Interface Functions
3252
3253HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
3254 DWORD dwDataSize, DWORD dwFlags)
3255{
3256 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3257 int i;
3258 PSURFPRIVATEDATA pSData;
3259 void *pBuffer;
3260 BOOL bFound = FALSE;
3261 HRESULT rc;
3262
3263 dprintf(("DDRAW: SurfSetPrivateData\n"));
3264
3265 if(NULL==me)
3266 return(DDERR_INVALIDOBJECT);
3267
3268 if((NULL==lpData)||(0==dwDataSize)||
3269 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
3270 return(DDERR_INVALIDPARAMS);
3271
3272 // first check if the refGUID is stored as then the content will be updated
3273 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
3274 {
3275 i=0;
3276 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3277 {
3278 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3279
3280 if (IsEqualGUID(pSData->guidTag,refGUID))
3281 bFound = TRUE;
3282
3283 i++;
3284 }
3285 }
3286
3287 if(bFound)
3288 {
3289 // update Private Data
3290
3291 if (!pSData->isValid)
3292 {
3293 // Current data is invalid we need to update/allocate
3294
3295 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3296 {
3297 pSData->pData = lpData;
3298 pSData->dwSize = 4;
3299 pSData->dwFlags = dwFlags;
3300 pSData->isValid = TRUE;
3301 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
3302 }
3303 else
3304 {
3305 pSData->pData = malloc(dwDataSize);
3306 if(NULL!=pSData->pData)
3307 {
3308 memcpy(pSData->pData,lpData,dwDataSize);
3309 pSData->dwSize = dwDataSize;
3310 pSData->dwFlags = dwFlags;
3311 pSData->isValid = TRUE;
3312 }
3313 else
3314 {
3315 delete pSData;
3316 rc = DDERR_OUTOFMEMORY;
3317 }
3318 }
3319 }
3320 else
3321 {
3322 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3323 {
3324 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3325 {
3326 if(pSData->pData != lpData)
3327 {
3328 // Change of IUNKOWNPOINTER => release old and add ref to new one
3329 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
3330 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
3331 pSData->pData = lpData;
3332 }
3333 pSData->dwFlags = dwFlags; // Update the flags, size is the same
3334 }
3335 else
3336 {
3337 // Replace IUNKOWN through data
3338 pBuffer = malloc(dwDataSize); // get new buffer first
3339 if(NULL!=pBuffer)
3340 {
3341 // release old ref and copy data
3342 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
3343 memcpy(pBuffer,lpData,dwDataSize);
3344 pSData->pData = pBuffer;
3345 pSData->dwSize = dwDataSize; // Update the size
3346 pSData->dwFlags = dwFlags; // Update the flags
3347 }
3348 else
3349 rc = DDERR_OUTOFMEMORY;
3350 }
3351 }
3352 else
3353 {
3354 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3355 {
3356 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
3357 free(pSData->pData);
3358 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
3359 pSData->pData = lpData;
3360 pSData->dwSize = dwDataSize; // Update the size
3361 pSData->dwFlags = dwFlags; // Update the flags
3362 }
3363 else
3364 {
3365 // Update/Replace data
3366 if(pSData->dwSize!=dwDataSize)
3367 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
3368 else
3369 pBuffer = pSData->pData;
3370
3371 if(NULL!=pBuffer)
3372 {
3373 // release old ref and copy data
3374 memcpy(pBuffer,lpData,dwDataSize);
3375 pSData->pData = pBuffer;
3376 pSData->dwSize = dwDataSize; // Update the size
3377 pSData->dwFlags = dwFlags; // Update the flags
3378 }
3379 else
3380 rc = DDERR_OUTOFMEMORY;
3381 }
3382 }
3383 }
3384 }
3385 else
3386 {
3387 // New data
3388
3389 pSData = new(SURFPRIVATEDATA);
3390 if (NULL!=pSData)
3391 {
3392 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
3393 {
3394 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
3395 pSData->pData = lpData;
3396 pSData->dwSize = 4;
3397 pSData->dwFlags = dwFlags;
3398 pSData->isValid = TRUE;
3399 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
3400 }
3401 else
3402 {
3403 pSData->pData = malloc(dwDataSize);
3404 if(NULL!=pSData->pData)
3405 {
3406 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
3407 memcpy(pSData->pData,lpData,dwDataSize);
3408 pSData->dwSize = dwDataSize;
3409 pSData->dwFlags = dwFlags;
3410 pSData->isValid = TRUE;
3411
3412 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
3413 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
3414 pSData) <0)
3415 {
3416 delete(pSData);
3417 rc = DDERR_OUTOFMEMORY;
3418 }
3419 }
3420 else
3421 {
3422 delete(pSData);
3423 rc = DDERR_OUTOFMEMORY;
3424 }
3425 }
3426
3427 }
3428 else
3429 rc = DDERR_OUTOFMEMORY;
3430 }
3431
3432 return rc;
3433}
3434//******************************************************************************
3435//******************************************************************************
3436HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
3437{
3438 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3439 int i;
3440 PSURFPRIVATEDATA pSData;
3441 HRESULT rc;
3442 BOOL bFound = FALSE;
3443
3444 dprintf(("DDRAW: SurfGetPrivateData\n"));
3445
3446 if(NULL==me)
3447 return(DDERR_INVALIDOBJECT);
3448
3449 if((NULL==lpData)||(NULL==lpDataSize))
3450 return(DDERR_INVALIDPARAMS);
3451
3452 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3453 {
3454 i=0;
3455 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3456 {
3457 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3458
3459 if (IsEqualGUID(pSData->guidTag,refGUID))
3460 bFound = TRUE;
3461
3462 i++;
3463 }
3464 }
3465
3466 if(bFound)
3467 {
3468 if(!pSData->isValid)
3469 {
3470 rc =DDERR_EXPIRED;
3471 }
3472 else
3473 {
3474 if(pSData->dwSize > *lpDataSize)
3475 {
3476 // Buffer to small return needed Size
3477 *lpDataSize = pSData->dwSize;
3478 rc = DDERR_MOREDATA;
3479 }
3480 else
3481 {
3482 memcpy(lpData,pSData->pData,pSData->dwSize);
3483 rc = DD_OK;
3484 }
3485 }
3486 }
3487 else
3488 rc = DDERR_NOTFOUND;
3489
3490
3491 return rc;
3492}
3493//******************************************************************************
3494//******************************************************************************
3495HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID)
3496{
3497 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3498 int i;
3499 PSURFPRIVATEDATA pSData;
3500 BOOL bFound = FALSE;
3501
3502 dprintf(("DDRAW: SurfFreePrivateData\n"));
3503
3504 if(NULL==me)
3505 return(DDERR_INVALIDOBJECT);
3506
3507 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3508 {
3509 i=0;
3510 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
3511 {
3512 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3513
3514 if (IsEqualGUID(pSData->guidTag,refGUID))
3515 {
3516 bFound = TRUE;
3517
3518 if(pSData->isValid)
3519 {
3520 // delete the data if valid
3521 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3522 {
3523 // pointer to com stored so calll its release
3524 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
3525 }
3526 else
3527 {
3528 // Free allocated data
3529 free( pSData->pData);
3530 }
3531 }
3532 // Now remove the entry from the list
3533 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
3534 }
3535 i++;
3536 }
3537 }
3538
3539 return (bFound?DD_OK:DDERR_NOTFOUND);
3540}
3541//******************************************************************************
3542//******************************************************************************
3543HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
3544{
3545 dprintf(("DDRAW: SurfGetUniquenessValue\n"));
3546 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3547 if (NULL==lpValue)
3548 return DDERR_INVALIDPARAMS;
3549
3550 *lpValue = me->dwUniqueValue;
3551 return DD_OK;
3552}
3553//******************************************************************************
3554//******************************************************************************
3555HRESULT WIN32API SurfChangeUniquenessValue(THIS This)
3556{
3557 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3558 int i;
3559 PSURFPRIVATEDATA pSData;
3560
3561
3562 dprintf(("DDRAW: SurfChangeUniquenessValue\n"));
3563 me->dwUniqueValue++;
3564
3565 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
3566 {
3567 i=0;
3568 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
3569 {
3570 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
3571 if (pSData->dwFlags & DDSPD_VOLATILE)
3572 {
3573 // Data becomes unvalid after a Surface change
3574 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
3575 {
3576 // pointer to com stored so call its release
3577 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
3578 }
3579 else
3580 {
3581 // Free allocated data
3582 free( pSData->pData);
3583 }
3584 pSData->pData = NULL;
3585 pSData->isValid = FALSE; // set flag to invalid
3586 }
3587 i++;
3588 }
3589 }
3590
3591 return (DD_OK);
3592}
3593
3594//******************************************************************************
3595//******************************************************************************
3596IDirectDrawSurface4Vtbl DDrawSurfaceV4Table =
3597{
3598 SurfQueryInterface,
3599 SurfAddRef,
3600 SurfRelease,
3601 SurfAddAttachedSurface4,
3602 SurfAddOverlayDirtyRect,
3603 SurfBlt4,
3604 SurfBltBatch,
3605 SurfBltFast4,
3606 SurfDeleteAttachedSurface4,
3607 SurfEnumAttachedSurfaces4,
3608 SurfEnumOverlayZOrders4,
3609 SurfFlip4,
3610 SurfGetAttachedSurface4,
3611 SurfGetBltStatus,
3612 SurfGetCaps4,
3613 SurfGetClipper,
3614 SurfGetColorKey,
3615 SurfGetDC,
3616 SurfGetFlipStatus,
3617 SurfGetOverlayPosition,
3618 SurfGetPalette,
3619 SurfGetPixelFormat,
3620 SurfGetSurfaceDesc4,
3621 SurfInitialize4,
3622 SurfIsLost,
3623 SurfLock4,
3624 SurfReleaseDC,
3625 SurfRestore,
3626 SurfSetClipper,
3627 SurfSetColorKey,
3628 SurfSetOverlayPosition,
3629 SurfSetPalette,
3630 SurfUnlock4,
3631 SurfUpdateOverlay4,
3632 SurfUpdateOverlayDisplay,
3633 SurfUpdateOverlayZOrder4,
3634 SurfGetDDInterface,
3635 SurfPageLock,
3636 SurfPageUnlock,
3637 SurfSetSurfaceDesc4,
3638 SurfSetPrivateData,
3639 SurfGetPrivateData,
3640 SurfFreePrivateData,
3641 SurfGetUniquenessValue,
3642 SurfChangeUniquenessValue
3643};
3644//******************************************************************************
3645//******************************************************************************
3646IDirectDrawSurface3Vtbl DDrawSurfaceV3Table =
3647{
3648 SurfQueryInterface,
3649 SurfAddRef,
3650 SurfRelease,
3651 SurfAddAttachedSurface3,
3652 SurfAddOverlayDirtyRect,
3653 SurfBlt3,
3654 SurfBltBatch,
3655 SurfBltFast3,
3656 SurfDeleteAttachedSurface3,
3657 SurfEnumAttachedSurfaces,
3658 SurfEnumOverlayZOrders,
3659 SurfFlip3,
3660 SurfGetAttachedSurface3,
3661 SurfGetBltStatus,
3662 SurfGetCaps,
3663 SurfGetClipper,
3664 SurfGetColorKey,
3665 SurfGetDC,
3666 SurfGetFlipStatus,
3667 SurfGetOverlayPosition,
3668 SurfGetPalette,
3669 SurfGetPixelFormat,
3670 SurfGetSurfaceDesc,
3671 SurfInitialize,
3672 SurfIsLost,
3673 SurfLock,
3674 SurfReleaseDC,
3675 SurfRestore,
3676 SurfSetClipper,
3677 SurfSetColorKey,
3678 SurfSetOverlayPosition,
3679 SurfSetPalette,
3680 SurfUnlock,
3681 SurfUpdateOverlay3,
3682 SurfUpdateOverlayDisplay,
3683 SurfUpdateOverlayZOrder3,
3684 SurfGetDDInterface,
3685 SurfPageLock,
3686 SurfPageUnlock,
3687 SurfSetSurfaceDesc
3688};
3689//******************************************************************************
3690//******************************************************************************
3691IDirectDrawSurface2Vtbl DDrawSurfaceV2Table =
3692{
3693 SurfQueryInterface,
3694 SurfAddRef,
3695 SurfRelease,
3696 SurfAddAttachedSurface,
3697 SurfAddOverlayDirtyRect,
3698 SurfBlt,
3699 SurfBltBatch,
3700 SurfBltFast,
3701 SurfDeleteAttachedSurface,
3702 SurfEnumAttachedSurfaces,
3703 SurfEnumOverlayZOrders,
3704 SurfFlip,
3705 SurfGetAttachedSurface,
3706 SurfGetBltStatus,
3707 SurfGetCaps,
3708 SurfGetClipper,
3709 SurfGetColorKey,
3710 SurfGetDC,
3711 SurfGetFlipStatus,
3712 SurfGetOverlayPosition,
3713 SurfGetPalette,
3714 SurfGetPixelFormat,
3715 SurfGetSurfaceDesc,
3716 SurfInitialize,
3717 SurfIsLost,
3718 SurfLock,
3719 SurfReleaseDC,
3720 SurfRestore,
3721 SurfSetClipper,
3722 SurfSetColorKey,
3723 SurfSetOverlayPosition,
3724 SurfSetPalette,
3725 SurfUnlock,
3726 SurfUpdateOverlay,
3727 SurfUpdateOverlayDisplay,
3728 SurfUpdateOverlayZOrder,
3729 SurfGetDDInterface,
3730 SurfPageLock,
3731 SurfPageUnlock
3732};
3733//******************************************************************************
3734//******************************************************************************
Note: See TracBrowser for help on using the repository browser.