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

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

cleanup + don't change the window size/status in SetCooperativeLevel

File size: 174.4 KB
Line 
1/* $Id: surface.cpp,v 1.1 2002-12-04 10:35: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
49
50
51//******************************************************************************
52//******************************************************************************
53OS2IDirectDrawSurface::OS2IDirectDrawSurface(OS2IDirectDraw *lpDirectDraw,
54 LPDDSURFACEDESC2 lpDDSurfaceDesc, BOOL Implicit, BOOL Mainchain) :
55 Referenced(0), lastError(DD_OK),
56 diveBufNr(-1), lpClipper(NULL),
57 lpPalette(NULL), lpDraw(NULL),
58 fLocked(FALSE), hdcImage(NULL),
59 hbmImage(NULL),
60 pFrameBuffer(NULL),Updated(FALSE),
61 fOverlayValid(FALSE),
62 BackBuffer(NULL),FrontBuffer(NULL),
63 pDBreal(NULL),pFBreal(NULL), hwndFullScreen(0)
64
65{
66 DWORD rc;
67 DDSURFACEDESC2 ComplexSurfaceDesc;
68 OS2IDirectDrawSurface *MipMapSurface;
69
70 memset(&sBlt, 0, sizeof(sBlt));
71
72 lpVtbl = &Vtbl2;
73 lpVtbl2 = &Vtbl2;
74 dwUnknownData = 0xDEADDEAD;
75 Vtbl.AddRef = SurfAddRef;
76 Vtbl.Release = SurfRelease;
77 Vtbl.QueryInterface = SurfQueryInterface;
78 Vtbl.AddAttachedSurface = SurfAddAttachedSurface4;
79 Vtbl.AddOverlayDirtyRect = SurfAddOverlayDirtyRect;
80 Vtbl.Blt = SurfBlt4;
81 Vtbl.BltBatch = SurfBltBatch;
82 Vtbl.BltFast = SurfBltFast4;
83 Vtbl.DeleteAttachedSurface = SurfDeleteAttachedSurface4;
84 Vtbl.EnumAttachedSurfaces = SurfEnumAttachedSurfaces4;
85 Vtbl.EnumOverlayZOrders = SurfEnumOverlayZOrders4;
86 Vtbl.Flip = SurfFlip4;
87 Vtbl.GetAttachedSurface = SurfGetAttachedSurface4;
88 Vtbl.GetBltStatus = SurfGetBltStatus;
89 Vtbl.GetCaps = SurfGetCaps4;
90 Vtbl.GetClipper = SurfGetClipper;
91 Vtbl.GetColorKey = SurfGetColorKey;
92 Vtbl.GetDC = SurfGetDC;
93 Vtbl.GetFlipStatus = SurfGetFlipStatus;
94 Vtbl.GetOverlayPosition = SurfGetOverlayPosition;
95 Vtbl.GetPalette = SurfGetPalette;
96 Vtbl.GetPixelFormat = SurfGetPixelFormat;
97 Vtbl.GetSurfaceDesc = SurfGetSurfaceDesc4;
98 Vtbl.Initialize = SurfInitialize4;
99 Vtbl.IsLost = SurfIsLost;
100 Vtbl.Lock = SurfLock4;
101 Vtbl.ReleaseDC = SurfReleaseDC;
102 Vtbl.Restore = SurfRestore;
103 Vtbl.SetClipper = SurfSetClipper;
104 Vtbl.SetColorKey = SurfSetColorKey;
105 Vtbl.SetOverlayPosition = SurfSetOverlayPosition;
106 Vtbl.SetPalette = SurfSetPalette;
107 Vtbl.Unlock = SurfUnlock4;
108 Vtbl.UpdateOverlay = SurfUpdateOverlay4;
109 Vtbl.UpdateOverlayDisplay = SurfUpdateOverlayDisplay;
110 Vtbl.UpdateOverlayZOrder = SurfUpdateOverlayZOrder4;
111 Vtbl.GetDDInterface = SurfGetDDInterface;
112 Vtbl.PageLock = SurfPageLock;
113 Vtbl.PageUnlock = SurfPageUnlock;
114 Vtbl.SetSurfaceDesc = SurfSetSurfaceDesc4;
115 Vtbl.SetPrivateData = SurfSetPrivateData;
116 Vtbl.GetPrivateData = SurfGetPrivateData;
117 Vtbl.FreePrivateData = SurfFreePrivateData;
118 Vtbl.ChangeUniquenessValue = SurfChangeUniquenessValue;
119 Vtbl.GetUniquenessValue = SurfGetUniquenessValue;
120
121 Vtbl3.AddRef = SurfAddRef;
122 Vtbl3.Release = SurfRelease;
123 Vtbl3.QueryInterface = SurfQueryInterface;
124 Vtbl3.AddAttachedSurface = SurfAddAttachedSurface3;
125 Vtbl3.AddOverlayDirtyRect = SurfAddOverlayDirtyRect;
126 Vtbl3.Blt = SurfBlt3;
127 Vtbl3.BltBatch = SurfBltBatch;
128 Vtbl3.BltFast = SurfBltFast3;
129 Vtbl3.DeleteAttachedSurface = SurfDeleteAttachedSurface3;
130 Vtbl3.EnumAttachedSurfaces = SurfEnumAttachedSurfaces;
131 Vtbl3.EnumOverlayZOrders = SurfEnumOverlayZOrders;
132 Vtbl3.Flip = SurfFlip3;
133 Vtbl3.GetAttachedSurface = SurfGetAttachedSurface3;
134 Vtbl3.GetBltStatus = SurfGetBltStatus;
135 Vtbl3.GetCaps = SurfGetCaps;
136 Vtbl3.GetClipper = SurfGetClipper;
137 Vtbl3.GetColorKey = SurfGetColorKey;
138 Vtbl3.GetDC = SurfGetDC;
139 Vtbl3.GetFlipStatus = SurfGetFlipStatus;
140 Vtbl3.GetOverlayPosition = SurfGetOverlayPosition;
141 Vtbl3.GetPalette = SurfGetPalette;
142 Vtbl3.GetPixelFormat = SurfGetPixelFormat;
143 Vtbl3.GetSurfaceDesc = SurfGetSurfaceDesc;
144 Vtbl3.Initialize = SurfInitialize;
145 Vtbl3.IsLost = SurfIsLost;
146 Vtbl3.Lock = SurfLock;
147 Vtbl3.ReleaseDC = SurfReleaseDC;
148 Vtbl3.Restore = SurfRestore;
149 Vtbl3.SetClipper = SurfSetClipper;
150 Vtbl3.SetColorKey = SurfSetColorKey;
151 Vtbl3.SetOverlayPosition = SurfSetOverlayPosition;
152 Vtbl3.SetPalette = SurfSetPalette;
153 Vtbl3.Unlock = SurfUnlock;
154 Vtbl3.UpdateOverlay = SurfUpdateOverlay3;
155 Vtbl3.UpdateOverlayDisplay = SurfUpdateOverlayDisplay;
156 Vtbl3.UpdateOverlayZOrder = SurfUpdateOverlayZOrder3;
157 Vtbl3.GetDDInterface = SurfGetDDInterface;
158 Vtbl3.PageLock = SurfPageLock;
159 Vtbl3.PageUnlock = SurfPageUnlock;
160 Vtbl3.SetSurfaceDesc = SurfSetSurfaceDesc;
161
162 Vtbl2.AddRef = SurfAddRef;
163 Vtbl2.Release = SurfRelease;
164 Vtbl2.QueryInterface = SurfQueryInterface;
165 Vtbl2.AddAttachedSurface = SurfAddAttachedSurface;
166 Vtbl2.AddOverlayDirtyRect = SurfAddOverlayDirtyRect;
167 Vtbl2.Blt = SurfBlt;
168 Vtbl2.BltBatch = SurfBltBatch;
169 Vtbl2.BltFast = SurfBltFast;
170 Vtbl2.DeleteAttachedSurface = SurfDeleteAttachedSurface;
171 Vtbl2.EnumAttachedSurfaces = SurfEnumAttachedSurfaces;
172 Vtbl2.EnumOverlayZOrders = SurfEnumOverlayZOrders;
173 Vtbl2.Flip = SurfFlip;
174 Vtbl2.GetAttachedSurface = SurfGetAttachedSurface;
175 Vtbl2.GetBltStatus = SurfGetBltStatus;
176 Vtbl2.GetCaps = SurfGetCaps;
177 Vtbl2.GetClipper = SurfGetClipper;
178 Vtbl2.GetColorKey = SurfGetColorKey;
179 Vtbl2.GetDC = SurfGetDC;
180 Vtbl2.GetFlipStatus = SurfGetFlipStatus;
181 Vtbl2.GetOverlayPosition = SurfGetOverlayPosition;
182 Vtbl2.GetPalette = SurfGetPalette;
183 Vtbl2.GetPixelFormat = SurfGetPixelFormat;
184 Vtbl2.GetSurfaceDesc = SurfGetSurfaceDesc;
185 Vtbl2.Initialize = SurfInitialize;
186 Vtbl2.IsLost = SurfIsLost;
187 Vtbl2.Lock = SurfLock;
188 Vtbl2.ReleaseDC = SurfReleaseDC;
189 Vtbl2.Restore = SurfRestore;
190 Vtbl2.SetClipper = SurfSetClipper;
191 Vtbl2.SetColorKey = SurfSetColorKey;
192 Vtbl2.SetOverlayPosition = SurfSetOverlayPosition;
193 Vtbl2.SetPalette = SurfSetPalette;
194 Vtbl2.Unlock = SurfUnlock;
195 Vtbl2.UpdateOverlay = SurfUpdateOverlay;
196 Vtbl2.UpdateOverlayDisplay = SurfUpdateOverlayDisplay;
197 Vtbl2.UpdateOverlayZOrder = SurfUpdateOverlayZOrder;
198 Vtbl2.GetDDInterface = SurfGetDDInterface;
199 Vtbl2.PageLock = SurfPageLock;
200 Vtbl2.PageUnlock = SurfPageUnlock;
201
202 lpDraw = lpDirectDraw;
203 lpDraw->Vtbl.AddRef(lpDraw);
204
205 ImplicitSurface = Implicit;
206
207 hDive = lpDirectDraw->GetDiveInstance();
208 hDiveCC = lpDirectDraw->GetCCDiveInstance();
209 surfaceType = DDSCAPS_OFFSCREENPLAIN;
210 memcpy((char *)&DDSurfaceDesc, (char *)lpDDSurfaceDesc, sizeof(DDSURFACEDESC2));
211
212 dprintf(("Pixel format:"));
213 _dump_pixelformat(&lpDDSurfaceDesc->ddpfPixelFormat);
214 dprintf(("Capabilities"));
215 _dump_DDSCAPS(lpDDSurfaceDesc->ddsCaps.dwCaps);
216 _dump_DDSCAPS2(lpDDSurfaceDesc->ddsCaps.dwCaps2);
217
218 if(lpDraw->dCaps.ulDepth != 15)
219 {
220 if(lpDraw->dCaps.ulDepth >= 8)
221 dwBytesPPDive = lpDraw->dCaps.ulDepth >> 3;
222 else
223 dwBytesPPDive = 1; // not sure if this is the case
224 }
225 else
226 dwBytesPPDive = 2; // 2 bytes for 15Bit
227
228 // Setting up Cursors for handling attached Surfaces
229
230 DPA_SurfaceMipMaps = DPA_Create(8);
231 if(NULL==DPA_SurfaceMipMaps)
232 {
233 dprintf(("DDRAW: Internal : Error creating DPA for MipMaps\n"));
234 lastError = DDERR_OUTOFMEMORY ;
235 return;
236 }
237
238 DPA_SurfaceAttached = DPA_Create(8);
239 if(NULL==DPA_SurfaceAttached)
240 {
241 dprintf(("DDRAW: Internal : Error creating DPA for attached surfaces\n"));
242 lastError = DDERR_OUTOFMEMORY ;
243 return;
244 }
245
246 DPA_LockedRects = DPA_Create(8);
247 if(NULL==DPA_LockedRects)
248 {
249 dprintf(("DDRAW: Internal : Error creating DPA for Locked Rectangles\n"));
250 lastError = DDERR_OUTOFMEMORY ;
251 return;
252 }
253
254 DPA_SurfacePrivateData = DPA_Create(8);
255 if(NULL==DPA_SurfacePrivateData)
256 {
257 dprintf(("DDRAW: Internal : Error creating DPA for private surface Data\n"));
258 lastError = DDERR_OUTOFMEMORY ;
259 return;
260 }
261
262 switch(lpDraw->GetScreenBpp())
263 {
264 case 8:
265 switch(lpDraw->dCaps.ulDepth)
266 {
267 case 8:
268 BltSolid = &BltSolid8to8;
269 ColorConv = NULL;
270 ColorFill = &Fill8on8;
271 break;
272 case 16:
273 BltSolid = &BltSolid8to16;
274 ColorConv = &Conv8to16;
275 ColorFill = &Fill8on16;
276 break;
277 case 24:
278 BltSolid = &BltSolid8to24;
279 ColorConv = &Conv8to24;
280 ColorFill = &Fill8on24;
281 break;
282 case 32:
283 BltSolid = &BltSolid8to32;
284 ColorConv = &Conv8to32;
285 ColorFill = &Fill8on32;
286 break;
287 default:
288 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
289 BltSolid = NULL;
290 ColorConv = NULL;
291 ColorFill = NULL;
292 break;
293 }
294 break;
295 case 16:
296 switch(lpDraw->dCaps.ulDepth)
297 {
298 case 8:
299 BltSolid = &BltSolid16to8;
300 ColorConv = &Conv16to8;
301 ColorFill = &Fill16on8;
302 break;
303 case 16:
304 BltSolid = &BltSolid16to16;
305 ColorConv = NULL;
306 ColorFill = &Fill16on16;
307 break;
308 case 24:
309 BltSolid = &BltSolid16to24;
310 ColorConv = &Conv16to24;
311 ColorFill = &Fill16on24;
312 break;
313 case 32:
314 BltSolid = &BltSolid16to32;
315 ColorConv = &Conv16to32;
316 ColorFill = &Fill16on32;
317 break;
318 default:
319 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
320 BltSolid = NULL;
321 ColorConv = NULL;
322 ColorFill = NULL;
323 break;
324 }
325 break;
326 case 24:
327 switch(lpDraw->dCaps.ulDepth)
328 {
329 case 8:
330 BltSolid = &BltSolid24to8;
331 ColorConv = &Conv24to8;
332 ColorFill = &Fill24on8;
333 break;
334 case 16:
335 BltSolid = &BltSolid24to16;
336 ColorConv = &Conv24to16;
337 ColorFill = &Fill24on16;
338 break;
339 case 24:
340 BltSolid = &BltSolid24to24;
341 ColorConv = NULL;
342 ColorFill = &Fill24on24;
343 break;
344 case 32:
345 BltSolid = &BltSolid24to32;
346 ColorConv = &Conv24to32;
347 ColorFill = &Fill24on32;
348 break;
349 default:
350 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
351 BltSolid = NULL;
352 ColorConv = NULL;
353 ColorFill = NULL;
354 break;
355 }
356 break;
357 case 32:
358 switch(lpDraw->dCaps.ulDepth)
359 {
360 case 8:
361 BltSolid = &BltSolid32to8;
362 ColorConv = &Conv32to8;
363 ColorFill = &Fill32on8;
364 break;
365 case 16:
366 BltSolid = &BltSolid32to16;
367 ColorConv = &Conv32to16;
368 ColorFill = &Fill32on16;
369 break;
370 case 24:
371 BltSolid = &BltSolid32to24;
372 ColorConv = &Conv32to24;
373 ColorFill = &Fill32on24;
374 break;
375 case 32:
376 BltSolid = &BltSolid32to32;
377 ColorConv = NULL;
378 ColorFill = &Fill32on32;
379 break;
380 default:
381 dprintf(("DDRAW: Unsupported System ColorDepth %d",lpDraw->dCaps.ulDepth));
382 BltSolid = NULL;
383 ColorConv = NULL;
384 ColorFill = NULL;
385 break;
386 }
387 break;
388 default:
389 dprintf(("DDRAW: Unsupported DX ColorDepth %d",lpDraw->GetScreenBpp()));
390 BltSolid = NULL;
391 ColorConv = NULL;
392 ColorFill = NULL;
393 break;
394 }
395 // hack set DDSD_CAPS if the value is other than 0
396 if( DDSurfaceDesc.ddsCaps.dwCaps)
397 DDSurfaceDesc.dwFlags |= DDSD_CAPS;
398
399 if( DDSurfaceDesc.dwFlags & DDSD_CAPS )
400 {
401#if 0
402//TODO: Docs say this is done, but does it really happen in windows?
403 // check for invalid flag combinations
404 switch(lpDDSurfaceDesc->ddsCaps.dwCaps2 & (DDSCAPS2_OPAQUE|DDSCAPS2_HINTDYNAMIC|DDSCAPS2_HINTSTATIC))
405 {
406 case 0:
407 case DDSCAPS2_OPAQUE:
408 case DDSCAPS2_HINTDYNAMIC:
409 case DDSCAPS2_HINTSTATIC:
410 break;
411
412 default:
413 dprintf(("DDRAW: Internal : illegal ddscaps2 flag combination (static/dynamic/opaque)"));
414 lastError = DDERR_INVALIDCAPS ;
415 return;
416 }
417#endif
418
419 // First check if we want to create a primary surface while the ddraw object already has one
420 surfaceType = DDSurfaceDesc.ddsCaps.dwCaps;
421
422 if( surfaceType & DDSCAPS_PRIMARYSURFACE)
423 {
424 dprintf(("DDRAW: Primary surface!\n"));
425 if( lpDraw->HasPrimarySurface())
426 {
427 dprintf(("DDRAW: Primary surface already exits!\n"));
428 lastError = DDERR_PRIMARYSURFACEALREADYEXISTS;
429 return;
430 }
431
432 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) ||
433 (DDSurfaceDesc.dwFlags & DDSD_WIDTH) ||
434 (DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT)
435 )
436 {
437 // Dx doc says passing width,height etc. for primary surface in not permitted!!
438 dprintf(("DDRAW: Invalid parameters\n\n"));
439 lastError = DDERR_INVALIDPARAMS;
440 return;
441 }
442
443 // Check if OS/2 is running in the requested colormode
444
445 diveBufNr = DIVE_BUFFER_SCREEN;
446 if( lpDraw->dCaps.ulDepth == lpDraw->GetScreenBpp() )
447 {
448 dprintf(("DDRAW: Direct Screen Access possible\n"));
449
450 // Yes so direct access to framebuffer is possible
451
452 pFrameBuffer = lpDraw->GetFrameBuffer();
453 pDiveBuffer = pFrameBuffer;
454 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
455 dwPitchFB = dwPitchDB;
456 DDSurfaceDesc.lPitch = dwPitchDB;
457 }
458 else
459 {
460 // No so we create a virtual framebuffer which the program can access
461 // and blit to the real framebuffer on Unlock to do color conversion
462
463 dprintf( ("Need Color conversion %d => %d Bit\n",
464 lpDraw->GetScreenBpp(),
465 lpDraw->dCaps.ulDepth
466 ));
467
468 dwPitchFB = (lpDraw->GetScreenWidth() * lpDraw->GetScreenBpp() +7) & ~7;
469 DDSurfaceDesc.lPitch = dwPitchFB;
470
471 // 24 byte more to enable alignment and speed up blitting
472
473 pFBreal = (char*)malloc( lpDraw->GetScreenHeight() * dwPitchFB + 24);
474 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
475
476 // DiveBuffer points to real framebuffer
477 dwPitchDB = lpDraw->dCaps.ulScanLineBytes;
478 pDiveBuffer = lpDraw->GetFrameBuffer();
479
480 }
481
482 // Update passed in and local Surface description
483
484 dprintf(("DDRAW: Setting up Surface\n"));
485 DDSurfaceDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT |
486 DDSD_PITCH | DDSD_LPSURFACE |
487 DDSD_PIXELFORMAT;
488 DDSurfaceDesc.dwHeight = lpDraw->GetScreenHeight();
489 DDSurfaceDesc.dwWidth = lpDraw->GetScreenWidth();
490 DDSurfaceDesc.lpSurface = pFrameBuffer;
491 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
492 lpDraw->SetPrimarySurface(TRUE);
493 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
494 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
495 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = lpDraw->GetScreenBpp();
496
497 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
498 {
499 case 4:
500 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
501 break;
502 case 8:
503 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
504 break;
505 case 16:
506 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
507 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
508 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
509 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
510 break;
511 case 24:
512 case 32:
513 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
514 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
515 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
516 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
517 break;
518 default:
519 // Remove the Pixelformat flag
520 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
521 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
522 break;
523 } // end switch
524
525 dprintf(("DDRAW: Surface set up, checking other Caps\n"));
526
527 if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
528 {
529 dprintf(("DDRAW: Complex Surface\n"));
530
531 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
532 {
533 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
534 memset( &ComplexSurfaceDesc,
535 0,
536 sizeof(DDSURFACEDESC2));
537
538 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
539 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
540 DDSD_WIDTH |
541 DDSD_HEIGHT |
542 DDSD_PIXELFORMAT;
543 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
544 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
545 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
546 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
547 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
548 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
549 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
550 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
551
552 if(DDSurfaceDesc.dwBackBufferCount>1)
553 {
554 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
555 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
556 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
557 }
558
559 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
560 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
561
562 if (BackBuffer->GetLastError()==DD_OK)
563 {
564 dprintf(("DDRAW: created backbuffer"));
565 // Our Primary Buffer is also the frontbuffer of a flipchain
566 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP;
567 BackBuffer->SetFrontBuffer(this);
568 }
569 else
570 {
571 dprintf(("DDRAW: Error creating backbuffer"));
572 }
573 }
574 else
575 {
576 dprintf(("DDRAW: Unsupported Complex Surface\n"));
577 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
578
579 lastError = DDERR_OUTOFMEMORY;
580 return;
581 } //endif Backbuffer
582 } // endif DDSCAPS_COMPLEX
583
584 width = DDSurfaceDesc.dwWidth;
585 height = DDSurfaceDesc.dwHeight;
586
587 lpDraw->pPrimSurf = this;
588
589 lastError = DD_OK;
590
591#if 0
592 if(lpDraw->GetCooperativeLevel() & DDSCL_FULLSCREEN)
593 {
594 SetWindowPos(lpDraw->GetClientWindow(), HWND_TOP, 0, 0, DDSurfaceDesc.dwWidth, DDSurfaceDesc.dwHeight,0);
595 }
596
597//NOTE: This isn't working at all (interferes with mouse messages for application
598// window)
599 //If in fullscreen mode, create transparent window covering the entire desktop
600 if(lpDraw->GetCooperativeLevel() & DDSCL_FULLSCREEN)
601 {
602 DirectDrawSurface_RegisterClass();
603 hwndFullScreen = DirectDrawSurface_CreateWindow(DDSurfaceDesc.dwWidth,
604 DDSurfaceDesc.dwHeight,
605 lpDraw->GetClientWindow());
606
607 if(hwndFullScreen == 0) {
608 DebugInt3();
609 lastError = DDERR_OUTOFMEMORY;
610 }
611 dprintf(("DDRAW: Created fullscreen transparent window %x", hwndFullScreen));
612 }
613#endif
614 return;
615 } // endif DDSCAPS_PRIMARYSURFACE
616
617 //
618 // ToDo : Do better calulation of Bitmap Size to support the compressed Bitmaps in Dx6
619 //
620
621 if( (DDSurfaceDesc.dwFlags & DDSD_HEIGHT) &&
622 (DDSurfaceDesc.dwFlags & DDSD_WIDTH)
623 )
624
625 {
626 DWORD dwBpp;
627 DWORD dwCaps;
628 dprintf(( " Requested Size %dx%d\n",
629 DDSurfaceDesc.dwWidth,
630 DDSurfaceDesc.dwHeight));
631
632 if(DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT) // Pixelformat passed in ?
633 {
634 dprintf(("DDRAW: Pixelformat requested :"));
635 // YES use it
636 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB)
637 {
638 dwBpp = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
639 }
640 else
641 {
642 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
643 dwBpp = 8;
644 else
645 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4)
646 dwBpp = 4;
647 else
648 if(DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
649 dprintf(("DDRAW: Pixelformat FOURCC %4s", &DDSurfaceDesc.ddpfPixelFormat.dwFourCC));
650 switch(DDSurfaceDesc.ddpfPixelFormat.dwFourCC) {
651 case FOURCC_RGB3:
652 dwBpp = 24;
653 break;
654 case FOURCC_RGB4:
655 dwBpp = 32;
656 break;
657 default:
658 dprintf(("DDRAW: Unsupported FOURCC!"));
659 lastError = DDERR_UNSUPPORTEDFORMAT;
660 return;
661 }
662 }
663 }
664 }
665 else
666 {
667 dprintf(("DDRAW: Use Screen Format :"));
668 dwBpp = lpDraw->GetScreenBpp(); // No use Screenformat
669 DDSurfaceDesc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
670 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = (DWORD) lpDraw->GetScreenFourCC();
671 DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = dwBpp;
672 switch(DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
673 {
674 case 4:
675 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED4 | DDPF_RGB;
676 break;
677 case 8:
678 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_RGB;
679 break;
680 case 16:
681 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
682 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x0000F800;
683 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x000007E0;
684 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x0000001F;
685 break;
686 case 24:
687 case 32:
688 DDSurfaceDesc.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_RGB;
689 DDSurfaceDesc.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
690 DDSurfaceDesc.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
691 DDSurfaceDesc.ddpfPixelFormat.dwBBitMask = 0x000000FF;
692 break;
693 default:
694 // Remove the Pixelformat flag
695 DDSurfaceDesc.dwFlags &= ~DDSD_PIXELFORMAT;
696 dprintf(("DDRAW: Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
697 break;
698 } // end switch
699
700 }
701
702 dprintf(("DDRAW: %d Bits\n",dwBpp));
703
704 // three possible situaltions
705 // 1. User supplied pointer to surface -> use it
706 // 2. Delayed allocation of a texture -> don't alloc
707 // 3. Normal allocation
708 // After this check for complex flag.
709
710 dwCaps = DDSurfaceDesc.ddsCaps.dwCaps;
711
712 if(DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
713 {
714 // 1.
715
716 dprintf(("DDRAW: Usersupplied Surface\n"));
717
718 if(NULL==DDSurfaceDesc.lpSurface)
719 {
720 // pointer is NULL! Stupid user ;)
721 lastError = DDERR_INVALIDPARAMS;
722 return;
723 }
724
725 // User allocated the Buffer for the surface so we don't have to
726
727 Updated = TRUE; // Set Flag to indicate User supplied buffer so we don't free it
728
729 // As we allready copied the surface description we are done if the # of colors
730 // of the surface is the same then the screen
731
732 pFrameBuffer = (char*)DDSurfaceDesc.lpSurface;
733 diveBufNr = -1;
734 dwPitchFB = DDSurfaceDesc.lPitch;
735
736 if( lpDraw->dCaps.ulDepth == dwBpp )
737 {
738 // Yes No Colorconversion is needed so point to the same buffer
739 dwPitchDB = dwPitchFB;
740 pDiveBuffer = pFrameBuffer;
741 }
742 else
743 {
744 // No so we must create the Divebuffer to do the color conversion
745 // and blit to the real framebuffer on Unlock to do color conversion
746
747 dwPitchDB = (DDSurfaceDesc.dwWidth * dwBytesPPDive +7) & ~7;
748
749 // 24 byte more to enable alignment and speed up blitting
750
751 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchDB + 24);
752 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
753
754 // Not sure if that is ok but we need this for translation
755 // I hope no game uses YUV or such a crap
756
757 DDSurfaceDesc.ddpfPixelFormat.dwFourCC = SupportedFourCCs[dwBpp>>3];
758 }
759
760 }
761 else
762 {
763
764 if(dwCaps & DDSCAPS_ALLOCONLOAD)
765 {
766 // 2.
767
768 dprintf(("DDRAW: Alloc on Load Texture?!\n"));
769
770 dwCaps &= ~DDSCAPS_ALLOCONLOAD; // remove flag
771
772 // only allow this flag for textures
773 if(!dwCaps & DDSCAPS_TEXTURE)
774 {
775 lastError = DDERR_INVALIDPARAMS;
776 return;
777 }
778
779 dwCaps &= ~DDSCAPS_TEXTURE; // remove flag
780 pFrameBuffer = NULL;
781 pDiveBuffer = NULL;
782
783 // This surface isn't allocated yet, but when the texture is loaded
784 dprintf(("DDRAW: Warning : Delayed memory allocation on request\n"));
785 DDSurfaceDesc.lpSurface = NULL;
786 }
787 else
788 {
789 // 3.
790
791 dprintf(("DDRAW: Alloc now!\n"));
792
793 DDSurfaceDesc.dwFlags = DDSurfaceDesc.dwFlags;
794
795 dwPitchFB = DDSurfaceDesc.dwWidth * (dwBpp<8?1:dwBpp/8);
796 dwPitchFB = (dwPitchFB +7) & ~7; // Align on QWords
797 DDSurfaceDesc.lPitch = dwPitchFB;
798 if(dwBpp<8)
799 {
800 dprintf(("DDRAW: 1 or 4 Bit Surface encountered may not work !"));
801 }
802
803
804 // 24 byte more to enable alignment and speed up blitting
805
806 pFBreal = (char*)malloc( DDSurfaceDesc.dwHeight * dwPitchFB + 24);
807
808 if(NULL==pFBreal)
809 {
810 lastError = DDERR_OUTOFMEMORY;
811 return;
812 }
813
814 pFrameBuffer = (char*)(((int)pFBreal + 7) & ~7); // align to QWORD
815
816 dprintf(("DDRAW: Framebuffer @ %08X QWAligned @ %08X with a Pitch of %d\n",
817 pFBreal, pFrameBuffer, dwPitchFB));
818
819 DDSurfaceDesc.lpSurface = pFrameBuffer;
820
821 if( (lpDraw->dCaps.ulDepth ) == dwBpp )
822 {
823 dprintf(("DDRAW: No CC_Buffer needed\n"));
824 // Yes => No Colorconversion is needed so point to the same buffer
825 pDiveBuffer = pFrameBuffer;
826 dwPitchDB = dwPitchFB;
827 }
828 else
829 {
830 dwPitchDB = (DDSurfaceDesc.dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7;
831 dprintf( ("DDRAW: Alloc CCBuf with malloc (%dx%d) Pitch %d ",
832 DDSurfaceDesc.dwHeight,
833 DDSurfaceDesc.dwWidth,
834 dwPitchDB));
835 // No so we must create the Divebuffer to do the colortranslation
836 // and blit to the real framebuffer on Unlock to do color conversion
837 pDBreal = (char*)malloc( DDSurfaceDesc.dwHeight *
838 dwPitchDB + 24);
839 pDiveBuffer = (char*)(((int)pDBreal + 7) & ~7); // align to QWORD
840 dprintf(( " @ %08X\n", pDiveBuffer));
841
842 }
843
844// if(Mainchain)
845// {
846 diveBufNr = 0;
847 rc = DiveAllocImageBuffer( hDive,
848 &diveBufNr,
849 lpDraw->dCaps.fccColorEncoding,
850 DDSurfaceDesc.dwWidth,
851 DDSurfaceDesc.dwHeight,
852 dwPitchDB,
853 (PBYTE)pDiveBuffer);
854 dprintf(("DDRAW: DiveAllocImageBuffer %x -> %d (rc=%d)",pDiveBuffer, diveBufNr, rc));
855// }
856
857 } // end of 3rd case
858 } // End of alloc surfaces
859
860 width = DDSurfaceDesc.dwWidth;
861 height = DDSurfaceDesc.dwHeight;
862
863 if( dwCaps & DDSCAPS_COMPLEX)
864 {
865 // remove the flag
866 dwCaps &= ~DDSCAPS_COMPLEX;
867 dprintf(("DDRAW: Complex Surface\n"));
868
869 if(DDSurfaceDesc.dwFlags & DDSD_BACKBUFFERCOUNT)
870 {
871 dprintf(("DDRAW: Backbuffer # = %d\n",DDSurfaceDesc.dwBackBufferCount));
872
873#if 1
874 memset( &ComplexSurfaceDesc,
875 0,
876 sizeof(DDSURFACEDESC2));
877
878 ComplexSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
879 ComplexSurfaceDesc.dwFlags = DDSD_CAPS |
880 DDSD_WIDTH |
881 DDSD_HEIGHT |
882 DDSD_PIXELFORMAT;
883 ComplexSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
884 ComplexSurfaceDesc.dwHeight = DDSurfaceDesc.dwHeight;
885 ComplexSurfaceDesc.dwWidth = DDSurfaceDesc.dwWidth;
886 ComplexSurfaceDesc.ddpfPixelFormat.dwFlags = DDSurfaceDesc.ddpfPixelFormat.dwFlags;
887 ComplexSurfaceDesc.ddpfPixelFormat.dwRBitMask = DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
888 ComplexSurfaceDesc.ddpfPixelFormat.dwGBitMask = DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
889 ComplexSurfaceDesc.ddpfPixelFormat.dwBBitMask = DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
890 ComplexSurfaceDesc.ddpfPixelFormat.dwRGBBitCount = DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
891
892 if(DDSurfaceDesc.dwBackBufferCount>1)
893 {
894 ComplexSurfaceDesc.dwFlags |=DDSD_BACKBUFFERCOUNT;
895 ComplexSurfaceDesc.dwBackBufferCount = DDSurfaceDesc.dwBackBufferCount -1;
896 ComplexSurfaceDesc.ddsCaps.dwCaps|= DDSCAPS_COMPLEX;
897 }
898
899 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, TRUE);
900 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
901
902 if (BackBuffer->GetLastError()==DD_OK)
903 {
904 dprintf(("DDRAW: created backbuffer"));
905 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
906 BackBuffer->SetFrontBuffer(this);
907 }
908 else
909 {
910 dprintf(("DDRAW: Error creating backbuffer"));
911 }
912#else
913 memcpy( &ComplexSurfaceDesc,
914 &DDSurfaceDesc,
915 sizeof(DDSURFACEDESC2));
916 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
917 ComplexSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP; // set flip
918 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; // remove backbuffer
919
920 if(ComplexSurfaceDesc.dwBackBufferCount>1)
921 {
922 ComplexSurfaceDesc.dwBackBufferCount--;
923 }
924 else
925 {
926 ComplexSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
927 ComplexSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_COMPLEX;
928 }
929 BackBuffer = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE, Mainchain);
930 BackBuffer->Vtbl.AddRef((IDirectDrawSurface *)BackBuffer);
931
932 if (BackBuffer->GetLastError()==DD_OK)
933 {
934 DDSurfaceDesc.dwFlags |= DDSCAPS_FLIP;
935 BackBuffer->SetFrontBuffer(this);
936 }
937#endif
938 }
939
940 // MipMap Surfaces are handled here
941 if( (DDSurfaceDesc.dwFlags & DDSD_MIPMAPCOUNT) &&
942 (dwCaps & DDSCAPS_TEXTURE) &&
943 (dwCaps & DDSCAPS_MIPMAP) )
944 {
945 dwCaps &= ~ (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP);
946
947 dprintf(("DDRAW: Mipmpa # = %d\n",DDSurfaceDesc.dwMipMapCount));
948 memcpy( &ComplexSurfaceDesc,
949 &DDSurfaceDesc,
950 sizeof(DDSURFACEDESC2));
951 ComplexSurfaceDesc.dwMipMapCount = 0;
952 ComplexSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
953
954 for(int i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
955 {
956 dprintf(("DDRAW: Creating MipMap %d\n",i));
957 // Mpmaps shirnk by 2
958 ComplexSurfaceDesc.dwWidth /= 2;
959 ComplexSurfaceDesc.dwHeight /= 2;
960
961 MipMapSurface = new OS2IDirectDrawSurface(lpDraw, &ComplexSurfaceDesc, TRUE);
962 MipMapSurface->Vtbl.AddRef((IDirectDrawSurface *)MipMapSurface);
963
964 DPA_InsertPtr( DPA_SurfaceMipMaps,
965 DPA_GetPtrCount(DPA_SurfaceMipMaps),
966 MipMapSurface);
967
968 if(MipMapSurface->GetLastError() != DD_OK)
969 {
970 lastError = MipMapSurface->GetLastError();
971 dprintf(("DDRAW: Attached surface creation returned error %d\n",lastError));
972 return;
973 } // Endif Errorcheck
974 } //End for(i =0; i < DDSurfaceDesc.dwMipMapCount; i++)
975 } // End of MipMaps
976
977 #if 0
978 if(DDSurfaceDesc.dwFlags)
979 dprintf(("DDRAW: Unsupported Complex Surface\n"));
980 #endif
981 } // Endif DDSCAPS_COMPLEX
982 }
983 else
984 {
985 lastError = DDERR_INVALIDPARAMS;
986 }
987 } // Endif DDCAPS is valid
988 else
989 {
990 dprintf(("DDRAW: CAPS not valid\n"));
991 lastError = DDERR_INVALIDPARAMS;
992 }
993 dprintf(("DDRAW: Buf %X Screen Caps (%d,%d), bitcount %d\n\n", this, lpDraw->GetScreenHeight(), lpDraw->GetScreenWidth(),
994 lpDraw->dCaps.ulDepth));
995 if(DD_OK!=lastError)
996 {
997 dprintf(("DDRAW: Some Error Check Flags\n"));
998 _dump_DDSCAPS(DDSurfaceDesc.dwFlags);
999 }
1000}
1001//******************************************************************************
1002//******************************************************************************
1003HRESULT OS2IDirectDrawSurface::DoColorFill(LPRECT lpDestRect,DWORD dwFillColor)
1004{
1005
1006 int FillWidth, FillHeight, Top, Left;
1007 DWORD *pPal24;
1008 WORD *pPal16;
1009 dprintf(("DDRAW: ColorFill with %08X\n", dwFillColor));
1010
1011 if(NULL!=lpDestRect)
1012 {
1013 dprintf(("DDRAW: Fill only Rect(%d,%d)(%d,%d) (%d,%d)", lpDestRect->left, lpDestRect->top,
1014 lpDestRect->right, lpDestRect->bottom, width, height));
1015 FillWidth = RECT_WIDTH(lpDestRect);
1016 FillHeight = RECT_HEIGHT(lpDestRect);
1017 Top = lpDestRect->top;
1018 Left = lpDestRect->left;
1019 if(Top + FillHeight > height) {
1020 FillHeight = height - Top;
1021 dprintf(("correcting FillHeight to %d", FillHeight));
1022 }
1023 if(Left + FillWidth > width) {
1024 FillWidth = width - Left;
1025 dprintf(("correcting FillWidth to %d", FillWidth));
1026 }
1027 }
1028 else
1029 {
1030 dprintf(("DDRAW: Fill all at addr "));
1031 Top = 0;
1032 Left = 0;
1033 FillWidth = width;
1034 FillHeight = height;
1035 //pLine = pDiveBuffer;
1036 }
1037 //dprintf(("DDRAW: 0x%08X (%d/%d) at\n", pLine,FillWidth,FillHeight));
1038
1039 // Better safe than sorry
1040 if (FillHeight <= 0)
1041 return(DD_OK);
1042
1043 if(pDiveBuffer!=pFrameBuffer)
1044 {
1045 if( (NULL== lpDraw->pPrimSurf) ||
1046 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
1047 {
1048 if(!fPalInit)
1049 {
1050 for(DWORD i=0;i<256;i++)
1051 {
1052 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
1053 ((DefaultPalette[i*3+1]>>2) <<5) +
1054 ((DefaultPalette[i*3]>>3) << 11);
1055 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
1056 ((DefaultPalette[i*3+1]>>2) <<16) +
1057 ((DefaultPalette[i*3]>>3) << 24);
1058 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
1059 i,
1060 DefaultPalette[i*3],
1061 DefaultPalette[i*3+1],
1062 DefaultPalette[i*3+2],
1063 wDefaultPalete16[i]));
1064 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
1065 // (lpColorTable[i].peGreen<<16) +
1066 // (lpColorTable[i].peRed<<24);
1067 }
1068 fPalInit = TRUE;
1069 }
1070 pPal16 = &wDefaultPalete16[0];
1071 pPal24 = &dwDefaultPalete24[0];
1072 }
1073 else
1074 {
1075 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
1076 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
1077 }
1078 }
1079
1080 if(NULL!=ColorFill) {
1081 ColorFill( pDiveBuffer, pFrameBuffer, Top, Left,
1082 FillWidth, FillHeight, dwPitchDB,dwPitchFB,
1083 dwFillColor,(16==lpDraw->dCaps.ulDepth)?(VOID*)pPal16:(VOID*)pPal24);
1084 SurfChangeUniquenessValue(this);
1085 }
1086 else
1087 {
1088 dprintf(("DDRAW: ColorFill function is NULL!!"));
1089 }
1090
1091 return(DD_OK);
1092}
1093//******************************************************************************
1094//******************************************************************************
1095void OS2IDirectDrawSurface::ColorConversion(LPRECT lpRect)
1096{
1097 //char *pSrc,*pDst,*pSLine,*pDLine;
1098 DWORD CCwidth,CCheight,x,y;
1099 DWORD *pPal24;
1100 WORD *pPal16;
1101
1102 if( (NULL== lpDraw->pPrimSurf) ||
1103 (NULL== ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette) )
1104 {
1105 if(!fPalInit)
1106 {
1107 for(DWORD i=0;i<256;i++)
1108 {
1109 wDefaultPalete16[i] = (DefaultPalette[i*3+2]>>3) +
1110 ((DefaultPalette[i*3+1]>>2) <<5) +
1111 ((DefaultPalette[i*3]>>3) << 11);
1112 dwDefaultPalete24[i]= ((DefaultPalette[i*3+2]>>3) <<8)+
1113 ((DefaultPalette[i*3+1]>>2) <<16) +
1114 ((DefaultPalette[i*3]>>3) << 24);
1115 dprintf(( " # %d : RGB=%02X/%02X/%02X => %04X\n",
1116 i,
1117 DefaultPalette[i*3],
1118 DefaultPalette[i*3+1],
1119 DefaultPalette[i*3+2],
1120 wDefaultPalete16[i]));
1121 // aPal24[i] = (lpColorTable[i].peBlue <<8) +
1122 // (lpColorTable[i].peGreen<<16) +
1123 // (lpColorTable[i].peRed<<24);
1124 }
1125 fPalInit = TRUE;
1126 }
1127 pPal16 = &wDefaultPalete16[0];
1128 pPal24 = &dwDefaultPalete24[0];
1129 }
1130 else
1131 {
1132 pPal16 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal16;
1133 pPal24 = ((OS2IDirectDrawSurface*)lpDraw->pPrimSurf)->lpPalette->aPal24;
1134 }
1135
1136 if(NULL==lpRect)
1137 {
1138 //pSrc = pFrameBuffer;
1139 //pDst = pDiveBuffer;
1140 CCwidth = width;
1141 CCheight = height;
1142 x = 0;
1143 y = 0;
1144 }
1145 else
1146 {
1147 // ToDo: Check why the top/bottom values come in swaped here
1148 // for now simply reverse them with the following 3 lines
1149 y = lpRect->top;
1150 lpRect->top = lpRect->bottom;
1151 lpRect->bottom = y;
1152 // end of hack
1153 #if 0
1154 pSrc = pFrameBuffer +
1155 (lpRect->top * dwPitchFB) +
1156 (lpRect->left* (lpDraw->dCaps.ulDepth/8));
1157 pDst = pDiveBuffer +
1158 (lpRect->top * dwPitchDB) +
1159 (lpRect->left* dwBytesPPDive);
1160 #endif
1161 y = lpRect->top;
1162 x = lpRect->left;
1163 CCwidth = lpRect->right - lpRect->left;
1164 CCheight = lpRect->bottom - lpRect->top;
1165
1166 }
1167
1168// dprintf( ("H: %d W: %d\n SRC @ %08X\n DST @ %08X\n",
1169// CCheight, CCwidth, pSrc,pDst));
1170 if(NULL!=ColorConv)
1171 ColorConv( pDiveBuffer, pFrameBuffer, y, x,
1172 CCwidth, CCheight, dwPitchDB,dwPitchFB,
1173 16==lpDraw->dCaps.ulDepth?(VOID*)pPal16:(VOID*)pPal24);
1174 else
1175 {
1176 dprintf(("DDRAW: ColorConv function is NULL!!"));
1177 }
1178
1179/*
1180 pSLine = pSrc;
1181 pDLine = pDst;
1182
1183 switch(lpDraw->dCaps.ulDepth)
1184 {
1185 case 8:
1186 dprintf(("DDRAW: 8Bit target CC not implemented\n"));
1187 break;
1188 case 15:
1189 dprintf(("DDRAW: 15 Bit not implemented using 16bit might look ugly\n"));
1190 case 16:
1191 if(8==lpDraw->GetScreenBpp())
1192 {
1193 dprintf(("DDRAW: 8->16Bit CC\n"));
1194 for(y=0;CCheight;CCheight--,y++)
1195 {
1196 for(x=0;x<width;x++)
1197 {
1198 *(((WORD*)pDLine)+x) = pPal16[pSLine[x]];
1199
1200 }
1201 pSLine += dwPitchFB;
1202 pDLine += dwPitchDB;
1203 }
1204 }
1205 else
1206 {
1207 dprintf(("DDRAW: %d ->16Bit Not implemented",lpDraw->GetScreenBpp()));
1208 }
1209 break;
1210 case 24:
1211 if(8==lpDraw->GetScreenBpp())
1212 {
1213 dprintf(("DDRAW: 8->24Bit CC"));
1214 for(y=0;CCheight;CCheight--,y++)
1215 {
1216 char *pIter;
1217 for(x=0,pIter=pDLine;x<width;x++,pIter=pDLine)
1218 {
1219 *((DWORD*)pIter) = pPal24[pSLine[x]];
1220 pIter+=3;
1221 }
1222 pSLine += dwPitchFB;
1223 pDLine += dwPitchDB;
1224 }
1225 }
1226 else
1227 {
1228 dprintf(("DDRAW: %d ->24Bit Not implemented",lpDraw->GetScreenBpp()));
1229 }
1230 break;
1231 case 32:
1232 if(8==lpDraw->GetScreenBpp())
1233 {
1234 dprintf(("DDRAW: 8->32Bit CC"));
1235 for(y=0;CCheight;CCheight--,y++)
1236 {
1237 for(x=0;x<width;x++)
1238 {
1239 *(((DWORD*)pDLine)+x) = pPal24[pSLine[x]];
1240
1241 }
1242 pSLine += dwPitchFB;
1243 pDLine += dwPitchDB;
1244 }
1245 }
1246 else
1247 {
1248 dprintf(("DDRAW: %d ->32Bit Not implemented",lpDraw->GetScreenBpp()));
1249 }
1250 break;
1251 default:
1252 dprintf( ("Unexpected Screen Bitdepth %d\n",
1253 lpDraw->dCaps.ulDepth));
1254 break;
1255 }
1256*/
1257}
1258//******************************************************************************
1259//******************************************************************************
1260// Internal callbacks uses by destructor
1261INT CALLBACK DestroyRects(LPVOID lpItem, DWORD dwRes)
1262{
1263 DDRectangle *pItem = (DDRectangle*) lpItem;
1264 delete(pItem);
1265 return 1;
1266}
1267
1268INT CALLBACK ReleaseSurfaces(LPVOID lpItem, DWORD dwRes)
1269{
1270 OS2IDirectDrawSurface *pSurf;
1271 pSurf = (OS2IDirectDrawSurface *)lpItem;
1272 pSurf->Vtbl.Release(pSurf);
1273 return 1;
1274}
1275//******************************************************************************
1276//******************************************************************************
1277OS2IDirectDrawSurface::~OS2IDirectDrawSurface()
1278{
1279 if(hwndFullScreen) {
1280 DestroyWindow(hwndFullScreen);
1281 }
1282
1283 if(DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1284 {
1285 lpDraw->SetPrimarySurface(FALSE);
1286 if(lpPalette)
1287 lpPalette->RestorePhysPalette();
1288
1289 }
1290 else
1291 {
1292 if( diveBufNr != -1)
1293 {
1294 if(fLocked)
1295 DiveEndImageBufferAccess(hDive, diveBufNr);
1296 DiveFreeImageBuffer(hDive, diveBufNr);
1297
1298 }
1299
1300 fLocked = FALSE;
1301 diveBufNr = -1;
1302 }
1303 // Free Buffers if they have been allocated
1304 // DIVE Buffer
1305
1306 if(NULL!=pDBreal)
1307 free(pDBreal);
1308
1309 // FrameBuffer
1310
1311 if(NULL!=pFBreal)
1312 free(pFBreal);
1313
1314 // Clear the list of locked rectangles
1315 if (DPA_GetPtrCount(DPA_LockedRects)>0)
1316 {
1317 DPA_DestroyCallback( DPA_LockedRects,
1318 DestroyRects,
1319 0);
1320 }
1321
1322 if(lpClipper)
1323 {
1324 lpClipper->Vtbl.Release((IDirectDrawClipper*)lpClipper);
1325 lpClipper = NULL;
1326 }
1327
1328 if(lpPalette)
1329 {
1330 lpPalette->Vtbl.Release((IDirectDrawPalette*)lpPalette);
1331 lpPalette = NULL;
1332 }
1333
1334 if(hbmImage)
1335 DeleteObject(hbmImage);
1336
1337 if(hdcImage)
1338 DeleteDC(hdcImage);
1339
1340 if (NULL!=BackBuffer)
1341 BackBuffer->Vtbl.Release(BackBuffer);
1342
1343 if (DPA_GetPtrCount(DPA_SurfaceMipMaps)>0)
1344 {
1345 DPA_DestroyCallback( DPA_SurfaceMipMaps,
1346 ReleaseSurfaces,
1347 0);
1348 }
1349
1350 if (DPA_GetPtrCount(DPA_SurfaceAttached)>0)
1351 {
1352 DPA_DestroyCallback( DPA_SurfaceAttached,
1353 ReleaseSurfaces,
1354 0);
1355 }
1356
1357 lpDraw->Vtbl.Release(lpDraw);
1358}
1359
1360//******************************************************************************
1361//******************************************************************************
1362inline void OS2IDirectDrawSurface::SetFrontBuffer( OS2IDirectDrawSurface* NewFBuffer)
1363{
1364 FrontBuffer = NewFBuffer;
1365 if (NULL==NewFBuffer)
1366 {
1367
1368 dprintf(("DDRAW: Remove Frontbuffer\n"));
1369
1370 // The real Frontbuffer was removed check if I'm now the one
1371 if(NULL!=BackBuffer)
1372 {
1373 dprintf(("DDRAW: We have the a backbuffer so we're the Frontbuffer\n"));
1374 NextFlip = BackBuffer;
1375 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER;
1376 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1377 BackBuffer->SetFrontBuffer(this);
1378 }
1379 else
1380 {
1381 // Flipchain is destroyed
1382 dprintf(("DDRAW: No longer part of a flipchain\n"));
1383 DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);
1384 }
1385 }
1386 else
1387 {
1388 dprintf(("DDRAW: Set new Frontbuffer to 0x%08X\n",NewFBuffer));
1389 if(NULL==NewFBuffer->GetFrontBuffer())
1390 {
1391 dprintf(("DDRAW: We're the 1st backbuffer\n"));
1392 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
1393 FrontBuffer->NextFlip = this;
1394 }
1395 else
1396 {
1397 dprintf(("DDRAW: We are one of many buffers\n"));
1398 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER ;
1399 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1400 }
1401
1402 if(NULL!=BackBuffer)
1403 BackBuffer->SetFrontBuffer(this);
1404
1405 DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER;
1406 }
1407}
1408//******************************************************************************
1409//******************************************************************************
1410HRESULT WIN32API SurfQueryInterface(THIS This, REFIID riid, LPVOID FAR * ppvObj)
1411{
1412 // ToDo: Add Interface handling for D3D Textures
1413 HRESULT rc;
1414 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1415
1416 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfQueryInterface\n"));
1417
1418 if(NULL==ppvObj)
1419 {
1420 rc = DDERR_INVALIDPARAMS;
1421 goto RetFn;
1422 }
1423
1424 rc = E_NOINTERFACE;
1425 *ppvObj = NULL;
1426
1427 if(IsEqualGUID(riid, IID_IDirectDrawSurface))
1428 {
1429 *ppvObj = &me->lpVtbl; // ToDo DO a real V1 table
1430 rc = DD_OK;
1431 goto RetFn;
1432 }
1433 if(IsEqualGUID(riid, IID_IDirectDrawSurface2))
1434 {
1435 *ppvObj = &me->lpVtbl2;
1436 rc = DD_OK;
1437 goto RetFn;
1438 }
1439 if(IsEqualGUID(riid, IID_IDirectDrawSurface3))
1440 {
1441 *ppvObj = &me->Vtbl3;
1442 rc = DD_OK;
1443 goto RetFn;
1444 }
1445 if(IsEqualGUID(riid, IID_IDirectDrawSurface4))
1446 {
1447 *ppvObj = This;
1448 rc =DD_OK;
1449 }
1450
1451 //if(IsEqualGUID(riid, IID_IUnknown)) ...
1452
1453RetFn:
1454
1455 if(DD_OK==rc)
1456 SurfAddRef(This);
1457
1458 return(rc);
1459}
1460//******************************************************************************
1461//******************************************************************************
1462ULONG WIN32API SurfAddRef(THIS This)
1463{
1464 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1465
1466 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfAddRef %d\n", me->Referenced+1));
1467
1468 return ++me->Referenced;
1469}
1470//******************************************************************************
1471//******************************************************************************
1472ULONG WIN32API SurfRelease(THIS This)
1473{
1474 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1475
1476 dprintf(("DDRAW: OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1));
1477 dprintf(("DDRAW: OS2IDirectDrawSurface::Surface %X\n", me));
1478 if(me->Referenced)
1479 {
1480 me->Referenced--;
1481 if(me->Referenced == 0)
1482 {
1483 delete( me);
1484 #ifndef __WATCOMC__
1485 //_interrupt(3);
1486 #endif
1487 return(0);
1488 }
1489 else
1490 return me->Referenced;
1491 }
1492 else
1493 return(0);
1494}
1495//******************************************************************************
1496//******************************************************************************
1497HRESULT WIN32API SurfAddAttachedSurface(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurface)
1498{
1499
1500 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1501 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1502}
1503//******************************************************************************
1504//******************************************************************************
1505HRESULT WIN32API SurfAddAttachedSurface3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurface)
1506{
1507
1508 dprintf(("DDRAW: SurfAddAttachedSurface\n"));
1509 return SurfAddAttachedSurface4(This, (LPDIRECTDRAWSURFACE4)lpDDSurface);
1510}
1511//******************************************************************************
1512//******************************************************************************
1513HRESULT WIN32API SurfAddAttachedSurface4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurface)
1514{
1515 OS2IDirectDrawSurface *AttachedSurface;
1516 OS2IDirectDrawSurface *BBCursor;
1517 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
1518 int rc;
1519
1520 dprintf(("DDRAW: SurfAddAttachedSurface4\n"));
1521
1522 if (NULL==lpDDSurface)
1523 return DDERR_INVALIDPARAMS;
1524
1525 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
1526
1527 if(AttachedSurface->IsImplicitSurface())
1528 {
1529 dprintf(("DDRAW: Internal : Can't attach an implicitly created surface to another surface\n"));
1530 return(DDERR_CANNOTATTACHSURFACE);
1531 }
1532
1533 if(This == AttachedSurface)
1534 {
1535 dprintf(("DDRAW: Can't attach a surface to itself\n"));
1536 return(DDERR_CANNOTATTACHSURFACE);
1537 }
1538
1539 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)
1540 {
1541 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1542 {
1543 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1544 {
1545 rc = DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1546 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1547 AttachedSurface);
1548
1549 if( rc>=0)
1550 {
1551 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1552 me->DDSurfaceDesc.dwMipMapCount++;
1553
1554 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1555 }
1556 else
1557 {
1558 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1559 return(DDERR_CANNOTATTACHSURFACE);
1560 }
1561 }
1562 else
1563 {
1564 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1565 return(DDERR_CANNOTATTACHSURFACE);
1566 }
1567 }
1568 else
1569 {
1570 rc = DPA_InsertPtr( me->DPA_SurfaceAttached,
1571 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1572 AttachedSurface);
1573
1574 if(rc>=0)
1575 {
1576 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1577 }
1578 else
1579 {
1580 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1581 return(DDERR_CANNOTATTACHSURFACE);
1582 }
1583 }
1584 } // endif DDSCAPS_TEXTURE
1585 else
1586 {
1587 if( (AttachedSurface->DDSurfaceDesc.dwWidth != me->DDSurfaceDesc.dwWidth)
1588 || (AttachedSurface->DDSurfaceDesc.dwHeight != me->DDSurfaceDesc.dwHeight)
1589 // || (AttachedSurface->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount !=
1590 // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
1591 )
1592 {
1593 dprintf(("DDRAW: Surfaces don't have equal dimensions\n"));
1594 return(DDERR_CANNOTATTACHSURFACE);
1595 }
1596 else
1597 {
1598 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)
1599 {
1600 if( (AttachedSurface->GetFrontBuffer()!=NULL) || (AttachedSurface->BackBuffer!= NULL))
1601 {
1602 dprintf(("DDRAW: Surface already has a front/backbuffer\n"));
1603 return(DDERR_SURFACEALREADYATTACHED);
1604 }
1605
1606 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
1607 {
1608 if(NULL!=me->BackBuffer)
1609 {
1610 BBCursor = me->BackBuffer;
1611 while(NULL!=BBCursor)
1612 {
1613 BBCursor->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1614 BBCursor->DDSurfaceDesc.dwBackBufferCount++;
1615 BBCursor->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1616 BBCursor = BBCursor->BackBuffer;
1617 }
1618 BBCursor->BackBuffer = AttachedSurface;
1619 AttachedSurface->SetFrontBuffer(BBCursor);
1620 }
1621 else
1622 {
1623 me->BackBuffer = AttachedSurface;
1624 AttachedSurface->SetFrontBuffer(me);
1625 }
1626 me->DDSurfaceDesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
1627 me->DDSurfaceDesc.dwBackBufferCount++;
1628 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
1629
1630 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1631 return (DD_OK);
1632 }
1633 else
1634 {
1635 dprintf(("DDRAW: Can't attach backbuffer to anything but a frontbuffer\n"));
1636 return(DDERR_CANNOTATTACHSURFACE);
1637 }
1638 }
1639 else
1640 {
1641 if(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1642 {
1643 if(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
1644 {
1645 if( DPA_InsertPtr( me->DPA_SurfaceMipMaps,
1646 DPA_GetPtrCount(me->DPA_SurfaceMipMaps),
1647 AttachedSurface) >=0)
1648 {
1649 me->DDSurfaceDesc.dwFlags |= DDSD_MIPMAPCOUNT;
1650 me->DDSurfaceDesc.dwMipMapCount++;
1651 me->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1652
1653 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1654 }
1655 else
1656 {
1657 dprintf(("DDRAW: Internal : Error attaching to MipMap\n"));
1658 return(DDERR_CANNOTATTACHSURFACE);
1659 }
1660 }
1661 else
1662 {
1663 dprintf(("DDRAW: Target Surface isn't a MipMap\n"));
1664 return(DDERR_CANNOTATTACHSURFACE);
1665 }
1666 }
1667 else
1668 {
1669 if( DPA_InsertPtr( me->DPA_SurfaceAttached,
1670 DPA_GetPtrCount(me->DPA_SurfaceAttached),
1671 AttachedSurface) >=0)
1672 {
1673 AttachedSurface->Vtbl.AddRef(AttachedSurface);
1674 }
1675 else
1676 {
1677 dprintf(("DDRAW: Internal : Error attaching to general Set\n"));
1678 return(DDERR_CANNOTATTACHSURFACE);
1679 }
1680 }
1681 }// End if not DDSCAPS_BACKBUFFER
1682 }
1683 }
1684 dprintf(("DDRAW: Surface attached\n"));
1685 return(DD_OK);
1686}
1687//******************************************************************************
1688//******************************************************************************
1689HRESULT WIN32API SurfAddOverlayDirtyRect(THIS, LPRECT)
1690{
1691 dprintf(("DDRAW: SurfAddOverlayDirtyRect Not implemented by M$ in DX 6.0!\n"));
1692
1693 return(DD_OK);
1694}
1695//******************************************************************************
1696//******************************************************************************
1697HRESULT WIN32API SurfBlt(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
1698 LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
1699{
1700 return SurfBlt4( This,
1701 lpDestRect,
1702 (LPDIRECTDRAWSURFACE4)lpDDSrcSurface,
1703 lpSrcRect,
1704 dwFlags,
1705 lpDDBltFx);
1706}
1707//******************************************************************************
1708//******************************************************************************
1709HRESULT WIN32API SurfBlt3(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE3 lpDDSrcSurface,
1710 LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
1711{
1712 return SurfBlt4( This,
1713 lpDestRect,
1714 (LPDIRECTDRAWSURFACE4)lpDDSrcSurface,
1715 lpSrcRect,
1716 dwFlags,
1717 lpDDBltFx);
1718}
1719//******************************************************************************
1720//******************************************************************************
1721HRESULT WIN32API SurfBlt4(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
1722 LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
1723{
1724 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
1725 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
1726
1727 DDSURFACEDESC2 DestSurfaceDesc, SrcSurfaceDesc;
1728 DDRectangle *pIRectDest,*pIRectSrc,*pIRectTest;
1729 RECT DestRect, SrcRect;
1730 BOOL Found;
1731 int i;
1732 HRESULT ret = DD_OK;
1733
1734 dprintf(("DDRAW: SurfBlt4 To Surf %08X, from Surf %08X\n",dest,src));
1735 if ( (NULL!=lpDestRect)&& (NULL!=lpSrcRect))
1736 dprintf(("DDRAW: SurfBlt4 to (%d,%d)(%d,%d) at %08X from (%d,%d)(%d,%d) at %08X\n", lpDestRect->left, lpDestRect->top,
1737 lpDestRect->right, lpDestRect->bottom, dest, lpSrcRect->left, lpSrcRect->top,
1738 lpSrcRect->right, lpSrcRect->bottom, src));
1739
1740 _dump_DDBLT(dwFlags);
1741
1742 if (NULL!=lpDestRect)
1743 {
1744 // HACK: RA does pass in negative values we might be better return an error,
1745 //for now we clip
1746#define RA_HACK 1
1747
1748#ifdef RA_HACK
1749 int top,left,bottom,right;
1750
1751 top = lpDestRect->top;
1752 left = lpDestRect->left;
1753 bottom = lpDestRect->bottom;
1754 right = lpDestRect->right;
1755
1756 if(top<0)
1757 {
1758 bottom += top;
1759 top = 0;
1760 }
1761
1762 if(top > dest->height)
1763 return DDERR_INVALIDPARAMS;
1764
1765 if(bottom<0)
1766 return DDERR_INVALIDPARAMS;
1767
1768 if(bottom>dest->height)
1769 bottom=dest->height;
1770
1771 if(left<0)
1772 {
1773 right += left;
1774 left = 0;
1775 }
1776
1777 if(left>dest->width)
1778 return DDERR_INVALIDPARAMS;
1779
1780 if(right<0)
1781 return DDERR_INVALIDPARAMS;
1782
1783 if(right>dest->width)
1784 right = dest->width;
1785#endif // RA_HACK
1786
1787 pIRectDest = new DDRectangle( left, top, right, bottom);
1788#ifdef RA_HACK
1789 DestRect.top = top;
1790 DestRect.left = left;
1791 DestRect.bottom = bottom;
1792 DestRect.right = right;
1793#else
1794 memcpy(&DestRect,lpDestRect,sizeof(RECT) );
1795#endif //RA_HACK
1796 }
1797 else
1798 {
1799 pIRectDest = new DDRectangle( 0, 0, dest->width, dest->height);
1800 DestRect.top = 0;
1801 DestRect.left = 0;
1802 DestRect.bottom = dest->height;
1803 DestRect.right = dest->width;
1804 }
1805
1806 if(dest->fLocked)
1807 {
1808 if (NULL==lpDestRect)
1809 {
1810 // If anything is locked we can't blit to the complete surface as
1811 // a part is locked
1812 Found = TRUE;
1813 }
1814 else
1815 {
1816 // If the dest Rectangle intersects with any of the locked rectangles
1817 // we can't blit to it
1818
1819 Found = FALSE;
1820 i=0;
1821 while( (i<DPA_GetPtrCount(dest->DPA_LockedRects)) && !Found)
1822 {
1823 pIRectTest = (DDRectangle*) DPA_FastGetPtr(dest->DPA_LockedRects,i);
1824 Found = pIRectDest->intersects(*pIRectTest);
1825 i++;
1826 }
1827
1828 }
1829 if (Found)
1830 {
1831 delete pIRectDest;
1832 dprintf(("DDRAW: Blt: Dest Surface partially locked\n"));
1833 return(DDERR_SURFACEBUSY);
1834 }
1835 }
1836 delete pIRectDest;
1837
1838 //src == NULL for colorfill
1839 if(src)
1840 {
1841 if (NULL!=lpSrcRect)
1842 {
1843#ifdef RA_HACK
1844 // Same as for dest rectangle now for src
1845
1846 int top,left,bottom,right;
1847
1848 top = lpSrcRect->top;
1849 left = lpSrcRect->left;
1850 bottom = lpSrcRect->bottom;
1851 right = lpSrcRect->right;
1852
1853 if(top<0)
1854 {
1855 bottom += top;
1856 top = 0;
1857 }
1858
1859 if(top > src->height)
1860 return DDERR_INVALIDPARAMS;
1861
1862 if(bottom<0)
1863 return DDERR_INVALIDPARAMS;
1864
1865 if(bottom>src->height)
1866 bottom=src->height;
1867
1868 if(left<0)
1869 {
1870 right += left;
1871 left = 0;
1872 }
1873
1874 if(left>src->width)
1875 return DDERR_INVALIDPARAMS;
1876
1877 if(right<0)
1878 return DDERR_INVALIDPARAMS;
1879
1880 if(right>src->width)
1881 right = src->width;
1882#endif // RA_HACK
1883
1884 pIRectSrc = new DDRectangle( left, top, right, bottom );
1885#ifdef RA_HACK
1886 SrcRect.top = top;
1887 SrcRect.left = left;
1888 SrcRect.bottom = bottom;
1889 SrcRect.right = right;
1890#else
1891 memcpy(&SrcRect,lpSrcRect,sizeof(RECT) );
1892#endif
1893 }
1894 else
1895 {
1896 pIRectSrc = new DDRectangle( 0, 0, src->width, src->height);
1897 SrcRect.top = 0;
1898 SrcRect.left = 0;
1899 SrcRect.bottom = src->height;
1900 SrcRect.right = src->width;
1901 }
1902
1903 if(src->fLocked)
1904 {
1905 if (NULL==lpSrcRect)
1906 {
1907 // If anything is locked we can't blit from the complete surface as
1908 // a part is locked
1909 Found = TRUE;
1910 }
1911 else
1912 {
1913 // If the src Rectangle intersects with any of the locked rectangles of the
1914 // source surface we can't blit from it
1915
1916 Found = FALSE;
1917 i=0;
1918
1919 while((i<DPA_GetPtrCount(src->DPA_LockedRects) ) && !Found)
1920 {
1921 pIRectTest = (DDRectangle*) DPA_FastGetPtr(src->DPA_LockedRects,i);
1922 Found = pIRectDest->intersects(*pIRectTest);
1923 i++;
1924 }
1925
1926 }
1927
1928 if (Found)
1929 {
1930 delete pIRectSrc;
1931 dprintf(("DDRAW: Blt: Src Surface partly locked\n"));
1932
1933 return(DDERR_SURFACEBUSY);
1934 }
1935 }
1936 delete pIRectSrc;
1937 } //if(src)
1938
1939 if(dest->diveBufNr == DIVE_BUFFER_SCREEN &&
1940 !(dwFlags & (DDBLT_COLORFILL|DDBLT_DEPTHFILL|DDBLT_ROP) ) &&
1941 dest->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount > 8 &&
1942 src->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount > 8)
1943 {
1944 int rc, temp, fChanged = FALSE;
1945 int destheight = RECT_HEIGHT(&DestRect);
1946 int destwidth = RECT_WIDTH(&DestRect);
1947 int srcheight = RECT_HEIGHT(&SrcRect);
1948 int srcwidth = RECT_WIDTH(&SrcRect);
1949
1950 //if full surface blit or stretching blit, then use Dive
1951 if( (src->DDSurfaceDesc.dwHeight == srcheight &&
1952 src->DDSurfaceDesc.dwWidth == srcwidth) ||
1953 (srcwidth != destwidth && srcheight != destheight) )
1954 {
1955 SETUP_BLITTER sBlt = {0};
1956
1957 sBlt.ulStructLen = sizeof(sBlt);
1958 sBlt.fInvert = 0;
1959 sBlt.fccSrcColorFormat = src->DDSurfaceDesc.ddpfPixelFormat.dwFourCC;
1960 sBlt.ulSrcWidth = srcwidth;
1961 sBlt.ulSrcHeight = srcheight;
1962 sBlt.ulSrcPosX = SrcRect.left;
1963 sBlt.ulSrcPosY = src->DDSurfaceDesc.dwHeight-SrcRect.bottom;
1964 sBlt.ulDitherType = 0;
1965 sBlt.fccDstColorFormat = dest->DDSurfaceDesc.ddpfPixelFormat.dwFourCC;
1966 sBlt.ulDstWidth = destwidth;
1967 sBlt.ulDstHeight = destheight;
1968 sBlt.lDstPosX = 0;
1969 sBlt.lDstPosY = 0;
1970 sBlt.lScreenPosX = DestRect.left;
1971 sBlt.lScreenPosY = dest->DDSurfaceDesc.dwHeight-DestRect.bottom;
1972 sBlt.ulNumDstRects = DIVE_FULLY_VISIBLE;
1973 sBlt.pVisDstRects = NULL;
1974
1975 if(dest->lpClipper && dest->lpClipper->IsClipListChangedInt())
1976 {
1977 DWORD rgnsize;
1978 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, NULL, &rgnsize) == DD_OK)
1979 {
1980 LPRGNDATA lpRgnData = (LPRGNDATA)alloca(rgnsize);
1981 if(lpRgnData == NULL) {
1982 DebugInt3();
1983 goto dodiveblit;
1984 }
1985 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, lpRgnData, &rgnsize) == DD_OK)
1986 {
1987 OS2RECTL *pRectl = (OS2RECTL *)&lpRgnData->Buffer;
1988
1989 if(sBlt.ulNumDstRects == 0) {
1990 dprintf(("empty cliplist, return"));
1991 return DD_OK;
1992 }
1993 dprintf(("visible region"));
1994 for(i=0;i<lpRgnData->rdh.nCount;i++)
1995 {
1996 //win32 -> os2 coordinates (region data in screen coordinates)
1997 temp = pRectl[i].yTop;
1998 pRectl[i].yTop = src->lpDraw->GetScreenHeight() - pRectl[i].yBottom;
1999 pRectl[i].yBottom = src->lpDraw->GetScreenHeight() - temp;
2000 dprintf(("(%d,%d)(%d,%d)", pRectl[i].xLeft, pRectl[i].yBottom, pRectl[i].xRight, pRectl[i].yTop));
2001
2002 //clip rectangle must be relative to lScreenPos
2003 pRectl[i].xLeft -= sBlt.lScreenPosX;
2004 pRectl[i].xRight -= sBlt.lScreenPosX;
2005 pRectl[i].yTop -= sBlt.lScreenPosY;
2006 pRectl[i].yBottom -= sBlt.lScreenPosY;
2007 dprintf(("(%d,%d)(%d,%d)", pRectl[i].xLeft, pRectl[i].yBottom, pRectl[i].xRight, pRectl[i].yTop));
2008 }
2009 fChanged = TRUE;
2010 sBlt.ulNumDstRects = lpRgnData->rdh.nCount;
2011 sBlt.pVisDstRects = (PRECTL)&lpRgnData->Buffer;
2012 }
2013 }
2014 }
2015dodiveblit:
2016#ifdef PERFTEST
2017 QueryPerformanceCounter(&liStart);
2018#endif
2019 if(fChanged || memcmp(&sBlt, &dest->sBlt, sizeof(sBlt)-sizeof(PRECTL)-sizeof(ULONG)))
2020 {
2021 dprintf(("Setting up blitter: src (%d,%d)(%d,%d)", sBlt.ulSrcPosX, sBlt.ulSrcPosY, sBlt.ulSrcWidth, sBlt.ulSrcHeight));
2022 dprintf(("Setting up blitter: dest (%d,%d)(%d,%d)", sBlt.lScreenPosX, sBlt.lScreenPosY, sBlt.ulDstWidth, sBlt.ulDstHeight));
2023 rc = DiveSetupBlitter(dest->hDive, &sBlt);
2024 if(rc) {
2025 dprintf(("DiveSetupBlitter returned %d", rc));
2026 return(DD_OK);
2027 }
2028 sBlt.ulNumDstRects = DIVE_FULLY_VISIBLE;
2029 sBlt.pVisDstRects = NULL;
2030 memcpy(&dest->sBlt, &sBlt, sizeof(sBlt));
2031 }
2032 dprintf(("DiveBlitImage %x %d->%d", dest->hDive, src->diveBufNr, dest->diveBufNr));
2033 rc = DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2034 if(rc) {
2035 dprintf(("DiveBlitImage returned %d", rc));
2036 return(DD_OK);
2037 }
2038#ifdef PERFTEST
2039 QueryPerformanceCounter(&liEnd);
2040 if(liEnd.HighPart == liStart.HighPart) {
2041 if(average == 0) {
2042 average = (liEnd.LowPart - liStart.LowPart);
2043 }
2044 else average = (average + (liEnd.LowPart - liStart.LowPart))/2;
2045 }
2046#endif
2047 SurfChangeUniquenessValue(dest);
2048 return DD_OK;
2049 }
2050 }
2051
2052 //TODO: do we need to check the source for clipping information in case
2053 // the app wants to copy from the frame buffer?
2054 if(dest->lpClipper)
2055 {
2056 DWORD rgnsize;
2057 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, NULL, &rgnsize) == DD_OK)
2058 {
2059 LPRGNDATA lpRgnData = (LPRGNDATA)alloca(rgnsize);
2060 if(lpRgnData == NULL) {
2061 DebugInt3();
2062 goto doblit;
2063 }
2064 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, lpRgnData, &rgnsize) == DD_OK)
2065 {
2066 RECT newdest, newsrc;
2067 LPRECT lpClipRect = (LPRECT)&lpRgnData->Buffer;
2068
2069#ifdef PERFTEST
2070 QueryPerformanceCounter(&liStart);
2071#endif
2072 for(i=0;i<lpRgnData->rdh.nCount;i++)
2073 {
2074 if(IntersectRect(&newdest, &DestRect, &lpClipRect[i]) == TRUE)
2075 {
2076 //TODO: This is not correct for stretching blits
2077 if(lpSrcRect) {
2078 newsrc.left = SrcRect.left + (newdest.left - DestRect.left);
2079 newsrc.top = SrcRect.top + (newdest.top - DestRect.top);
2080 newsrc.right = newsrc.left + RECT_WIDTH(&newdest);
2081 newsrc.bottom = newsrc.top + RECT_HEIGHT(&newdest);
2082 }
2083// DDSURFACEDESC2 surfdesc = {0};
2084// SurfLock4(dest, &newdest, &surfdesc, 0, 0);
2085
2086 ret = SurfDoBlt(This, &newdest, lpDDSrcSurface, (lpSrcRect) ? &newsrc : NULL, dwFlags, lpDDBltFx);
2087 if(ret != DD_OK) {
2088 break;
2089 }
2090// SurfUnlock(dest, surfdesc.lpSurface);
2091 }
2092 }
2093#ifdef PERFTEST
2094 if(liEnd.HighPart == liStart.HighPart) {
2095 QueryPerformanceCounter(&liEnd);
2096 if(average == 0) {
2097 average = (liEnd.LowPart - liStart.LowPart);
2098 }
2099 else average = (average + (liEnd.LowPart - liStart.LowPart))/2;
2100 }
2101#endif
2102
2103 return ret;
2104 }
2105 }
2106 }
2107doblit:
2108 return SurfDoBlt(This, &DestRect, lpDDSrcSurface, (lpSrcRect) ? &SrcRect : NULL, dwFlags, lpDDBltFx);
2109}
2110//******************************************************************************
2111//******************************************************************************
2112HRESULT WIN32API SurfDoBlt(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
2113 LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
2114{
2115 // We have determine between 3 different blit senarios.
2116 // 1. Blitting between Divebuffers (Front/Backbuffer and primary surface)
2117 // 2. Blitting between memory and Divebuffers (Front/Backbuffer and primary surface).
2118 // 3. Blitting between memory buffers.
2119 // 1 and 3 are easy. DiveBlitImage or memcpy will do the job for non transparent blits
2120 // 2 is now also easy as we do colorconverion via Dive after each unlocking of a surface
2121 // The advantage is that we don't have to call DiveSetupBlitter each time. The Blitter will be
2122 // setup only when the screen resolution is changed by ddraw. I guess we should see a big performance
2123 // increase by doing it this way, unless the software blits directly from memory to the primary surface)
2124 // But even then this could be faster as the SetupBlitter call is timeconsumeing and DIVE does emulate
2125 // the blit in SW anyway as there is no interface in the driver to blit with HW support from the sysmem.
2126
2127 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
2128 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
2129
2130 int x, i, BlitWidth, BlitHeight;
2131 char *pBltPos, *pSrcPos;
2132 DDSURFACEDESC2 DestSurfaceDesc, SrcSurfaceDesc;
2133 BOOL Found;
2134 DWORD dwSrcColor, dwDestColor;
2135
2136 dprintf(("DDRAW: SurfDoBlt To Surf %08X, from Surf %08X\n",dest,src));
2137 if ( (NULL!=lpDestRect)&& (NULL!=lpSrcRect))
2138 dprintf(("DDRAW: SurfDoBlt to (%d,%d)(%d,%d) at %08X from (%d,%d)(%d,%d) at %08X\n", lpDestRect->left, lpDestRect->top,
2139 lpDestRect->right, lpDestRect->bottom, dest, lpSrcRect->left, lpSrcRect->top,
2140 lpSrcRect->right, lpSrcRect->bottom, src));
2141
2142 DestSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2143 SrcSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2144
2145 // First check the simple first
2146
2147 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC); // FIXME: can't handle right now
2148
2149 if(dwFlags & DDBLT_COLORFILL)
2150 {
2151 dprintf(("DDRAW: ColorFill\n"));
2152 if((NULL==lpDDBltFx)||(lpDDBltFx->dwSize!=sizeof(DDBLTFX)) )
2153 return DDERR_INVALIDPARAMS;
2154
2155 dest->DoColorFill(lpDestRect,lpDDBltFx->dwFillColor);
2156
2157 return(DD_OK); // according to the M$ DDK only one flag shall/can be set.
2158 } // end of colorfill
2159
2160 if (dwFlags & DDBLT_DEPTHFILL)
2161 {
2162 dprintf(("DDRAW: DepthFill\n"));
2163 #ifdef USE_OPENGL
2164 GLboolean ztest;
2165 // Todo support more than one Z-Buffer
2166 // Clears the screen
2167 dprintf(("DDRAW: Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth));
2168 glClearDepth(lpDDBltFx->b.dwFillDepth / 65535.0); // We suppose a 16 bit Z Buffer
2169 glGetBooleanv(GL_DEPTH_TEST, &ztest);
2170 glDepthMask(GL_TRUE); // Enables Z writing to be sure to delete also the Z buffer
2171 glClear(GL_DEPTH_BUFFER_BIT);
2172 glDepthMask(ztest);
2173
2174 return (DD_OK);
2175 #endif // USE_OPENGL
2176 }
2177
2178 if(dwFlags & DDBLT_ROP)
2179 {
2180 // HEL and we only support the following ROPS
2181 // SRC_COPY
2182 // BLACKNESS
2183 // WHITENESS
2184 //
2185 if(lpDDBltFx->dwROP & SRCCOPY)
2186 dwFlags = 0; // srccopy is a normal fast blt
2187 else
2188 {
2189 if(lpDDBltFx->dwROP & BLACKNESS)
2190 {
2191 if(1==dest->dwBytesPPDive)
2192 {
2193 // ToDo: Realy implement code to get the correct index for black in 8 Bitmode
2194 dest->DoColorFill(lpDestRect, 0 );
2195 }
2196 else
2197 dest->DoColorFill(lpDestRect, 0);
2198 return DD_OK;
2199 }
2200
2201 if(lpDDBltFx->dwROP & WHITENESS)
2202 {
2203 if(1==dest->dwBytesPPDive)
2204 {
2205 // ToDo: Realy implement code to get the correct index for white in 8 Bitmode
2206 dest->DoColorFill(lpDestRect, 0xFFFFFFFF );
2207 }
2208 else
2209 dest->DoColorFill(lpDestRect, 0xFFFFFFFF);
2210 return (DD_OK);
2211 }
2212
2213 return DDERR_NORASTEROPHW;
2214 }
2215 }
2216
2217 if(NULL==src)
2218 {
2219 dprintf(("DDRAW: Unsupported sourceless FX operation. Flags = 0x%04X\n",dwFlags));
2220
2221 return DD_OK;
2222 }
2223
2224 if( ( (NULL==lpDestRect) && (NULL!=lpSrcRect) ) ||
2225 ( (NULL==lpSrcRect) && (NULL!=lpDestRect) ) )
2226 {
2227 dprintf(("DDRAW: Blitting with scaling\n Not supported.\n"));
2228
2229 return DDERR_NOSTRETCHHW;
2230 }
2231
2232 if( ( RECT_WIDTH(lpDestRect) != RECT_WIDTH(lpSrcRect) ) ||
2233 ( RECT_HEIGHT(lpDestRect) != RECT_HEIGHT(lpSrcRect) )
2234 )
2235 {
2236 // Stretching not supported
2237 dprintf(("DDRAW: No stretched blits\n"));
2238
2239 return DDERR_NOSTRETCHHW;
2240 }
2241
2242 if (dest->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2243 {
2244 dprintf(("DDRAW: Dest is Primary Surface\n"));
2245 if(src->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2246 {
2247 // special Type 1 : Bliting between parts of the screen
2248
2249 dprintf(("DDRAW: Src is Primary Surface\n"));
2250
2251 if( RECT_EQUAL(lpDestRect, lpSrcRect))
2252 return DD_OK; // rects are the same => no blit needed
2253
2254 // Todo: might add transparent blits but I don't think they are used here, so later!
2255
2256 MoveRects( dest->pDiveBuffer,
2257 lpDestRect,
2258 lpSrcRect,
2259 dest->dwBytesPPDive,
2260 dest->dwPitchDB);
2261 // MoveRects in framebuufer if we use colorconversion
2262 if(dest->pFrameBuffer != dest->pDiveBuffer)
2263 {
2264 MoveRects( dest->pFrameBuffer,
2265 lpDestRect,
2266 lpSrcRect,
2267 dest->lpDraw->GetScreenBpp()>>3,
2268 dest->dwPitchFB);
2269 }
2270
2271 // End of Special Type 1 blitting on the screen
2272 }
2273 else
2274 {
2275 if( src->diveBufNr>0)
2276 {
2277 dprintf(("DDRAW: DIVE Blit of all"));
2278 if( (NULL==lpSrcRect)&&( NULL== lpDestRect))
2279 {
2280 // No Rectangles so use Dive to blit everything
2281 // ToDo : Implement transparent blitting but that seams more
2282 // inportant for partial blits.
2283 // If we do this later we could skip this check and don't
2284 // use Dive .This keeps our simpler and smaler
2285 //
2286 DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2287
2288 }
2289 }
2290
2291 // Everything else we do yourselfs
2292 // Type 2 Sysmem to Primarysurface ca also be handled by this
2293
2294 if(!dwFlags)
2295 {
2296 dprintf(("DDRAW: Solid Blit\n"));
2297
2298 dest->BltSolid( dest->pDiveBuffer,
2299 dest->pFrameBuffer,
2300 lpDestRect->top,
2301 lpDestRect->left,
2302 dest->dwPitchDB,
2303 dest->dwPitchFB,
2304 src->pDiveBuffer,
2305 src->pFrameBuffer,
2306 lpSrcRect->top,
2307 lpSrcRect->left,
2308 RECT_WIDTH(lpDestRect),
2309 RECT_HEIGHT(lpDestRect),
2310 src->dwPitchDB,
2311 src->dwPitchFB
2312 );
2313
2314 }
2315 else
2316 {
2317 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2318 (lpDestRect->left * dest->dwBytesPPDive);
2319
2320 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2321 (lpSrcRect->left * src->dwBytesPPDive);
2322
2323 BlitHeight = RECT_HEIGHT(lpDestRect);
2324 BlitWidth = RECT_WIDTH(lpDestRect);
2325 // Transparent Blit
2326 if( (dwFlags &DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE) )
2327 {
2328 dprintf(("DDRAW: Transparent src blit not done yet for primary!!"));
2329 }
2330 else
2331 {
2332 dprintf(("DDRAW: Unhandled Flags Destination colorkey ? 0x%04X",dwFlags));
2333 }
2334 }
2335 } // end of handling blitting to primary
2336 } // end of target primary surface
2337 else
2338 {
2339 if(0==src->diveBufNr)
2340 {
2341 // copy from the screen to a buffer
2342
2343 if( (NULL==lpDestRect) &&
2344 (NULL==lpSrcRect) &&
2345 (dest->diveBufNr>0) )
2346 {
2347 // Blitting everything from frontbuffer to a Divebuffer
2348 // ToDo: Might should add checking for flags here
2349 DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2350 }
2351 else
2352 {
2353 // DIVE => DIVE or Mem => Dive
2354 // or a rectangle from streen to a buffer can be handelt in the same way
2355 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2356 (lpDestRect->left * dest->dwBytesPPDive);
2357
2358 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2359 (lpSrcRect->left * src->dwBytesPPDive);
2360
2361 BlitHeight = RECT_HEIGHT(lpDestRect);
2362 BlitWidth = RECT_WIDTH(lpDestRect);
2363
2364 // Check for transparent blit
2365 if(!dwFlags)
2366 {
2367 dest->BltSolid( dest->pDiveBuffer,
2368 dest->pFrameBuffer,
2369 lpDestRect->top,
2370 lpDestRect->left,
2371 dest->dwPitchDB,
2372 dest->dwPitchFB,
2373 src->pDiveBuffer,
2374 src->pFrameBuffer,
2375 lpSrcRect->top,
2376 lpSrcRect->left,
2377 RECT_WIDTH(lpDestRect),
2378 RECT_HEIGHT(lpDestRect),
2379 src->dwPitchDB,
2380 src->dwPitchFB
2381 );
2382 }
2383 else
2384 {
2385 dprintf(("DDRAW: Transblt not done yet"));
2386 if(dwFlags & DDBLT_KEYSRC)
2387 {
2388 if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT))
2389 {
2390 }
2391 }
2392 else
2393 {
2394 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2395 {
2396 }
2397 else
2398 {
2399 }
2400 }
2401 }
2402 }
2403 } // end handling source screen
2404 else
2405 {
2406 // DIVE => DIVE or Mem => Dive can be handelt in the same way
2407
2408 if( (src->pDiveBuffer == dest->pDiveBuffer) &&
2409 (intersects(lpDestRect, lpSrcRect) ) )
2410 {
2411 // Overlapping rects on the same surface ?
2412
2413 // ToDo : Maybe implement all the fancy blit flags here too ? ;)
2414
2415 MoveRects( dest->pDiveBuffer,
2416 lpDestRect,
2417 lpSrcRect,
2418 dest->dwBytesPPDive,
2419 dest->dwPitchDB);
2420
2421 // MoveRects in framebuufer if we use colorconversion
2422 if(dest->pFrameBuffer != dest->pDiveBuffer)
2423 {
2424 MoveRects( dest->pFrameBuffer,
2425 lpDestRect,
2426 lpSrcRect,
2427 dest->lpDraw->GetScreenBpp()>>3,
2428 dest->dwPitchFB);
2429 }
2430 return DD_OK;
2431 }
2432
2433 // Check for transparent blit
2434 if(!dwFlags)
2435 {
2436 dest->BltSolid( dest->pDiveBuffer,
2437 dest->pFrameBuffer,
2438 lpDestRect->top,
2439 lpDestRect->left,
2440 dest->dwPitchDB,
2441 dest->dwPitchFB,
2442 src->pDiveBuffer,
2443 src->pFrameBuffer,
2444 lpSrcRect->top,
2445 lpSrcRect->left,
2446 RECT_WIDTH(lpDestRect),
2447 RECT_HEIGHT(lpDestRect),
2448 src->dwPitchDB,
2449 src->dwPitchFB
2450 );
2451 }
2452 else
2453 {
2454 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2455 (lpDestRect->left * dest->dwBytesPPDive);
2456
2457 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2458 (lpSrcRect->left * src->dwBytesPPDive);
2459
2460 BlitHeight = RECT_HEIGHT(lpDestRect);
2461 BlitWidth = RECT_WIDTH(lpDestRect);
2462 DWORD dwPitch = dest->dwPitchDB;
2463
2464 if(dwFlags &DDBLT_ROTATIONANGLE)
2465 {
2466 return DDERR_NOROTATIONHW;
2467 }
2468
2469 if(dwFlags & DDBLT_DDFX)
2470 {
2471 DWORD dwFx;
2472
2473 dwFlags &= ~DDBLT_DDFX; // remove the handled flag
2474
2475 if( NULL==lpDDBltFx)
2476 return DDERR_INVALIDPARAMS;
2477
2478 dwFx = lpDDBltFx->dwDDFX;
2479
2480 // Remove unsupported Flags
2481 dwFx &= ~(DDBLTFX_ARITHSTRETCHY | // Not streach support
2482 DDBLTFX_ZBUFFERBASEDEST | // All ZBuffer flags are not
2483 DDBLTFX_ZBUFFERRANGE | // implementet in M$ Dx 6
2484 DDBLTFX_NOTEARING ); // No sync with VRetrace yet
2485
2486 if(dwFx & DDBLTFX_ROTATE180)
2487 {
2488 // 180 degree turn is a mix of a flip up/down and one left/right
2489 dwFx |= (DDBLTFX_MIRRORUPDOWN | DDBLTFX_MIRRORLEFTRIGHT);
2490 dwFx &= ~DDBLTFX_ROTATE180; // remove handled flag
2491 }
2492 if(dwFx & DDBLTFX_MIRRORUPDOWN)
2493 {
2494 // switching the the direction can be integrated with other flags
2495 dwPitch = -dwPitch;
2496 pBltPos = (char*) dest->pDiveBuffer +
2497 ((lpDestRect->top +BlitHeight)* dest->dwPitchDB) +
2498 (lpDestRect->left * dest->dwBytesPPDive);
2499
2500 dwFx &= ~DDBLTFX_MIRRORUPDOWN; // remove handled flag
2501 }
2502
2503 if(dwFx & DDBLTFX_MIRRORLEFTRIGHT)
2504 {
2505 // 180 degree turn or a LR Mirroring
2506 // don't support any other dwFlags like transparent at the moment
2507
2508 switch(dest->dwBytesPPDive)
2509 {
2510 case 1:
2511 while(BlitHeight--)
2512 {
2513 x = BlitWidth;
2514 while(x)
2515 {
2516 pBltPos[BlitWidth-x] = pSrcPos[x];
2517 x--;
2518 }
2519 pBltPos += dwPitch;
2520 pSrcPos += src->dwPitchDB;
2521 }
2522 break;
2523 case 2:
2524 while(BlitHeight--)
2525 {
2526 x = BlitWidth;
2527 while(x)
2528 {
2529 ((USHORT*)pBltPos)[BlitWidth-x] = ((USHORT*)pSrcPos)[x];
2530 x--;
2531 }
2532 pBltPos += dwPitch;
2533 pSrcPos += src->dwPitchDB;
2534 }
2535 break;
2536 case 3:
2537 BlitWidth *= 3;
2538 while(BlitHeight--)
2539 {
2540 x = BlitWidth;
2541 while(x)
2542 {
2543 pBltPos[BlitWidth-x] = pSrcPos[x-2];
2544 x--;
2545 pBltPos[BlitWidth-x] = pSrcPos[x];
2546 x--;
2547 pBltPos[BlitWidth-x] = pSrcPos[x+2];
2548 x--;
2549 }
2550 pBltPos += dwPitch;
2551 pSrcPos += src->dwPitchDB;
2552 }
2553 break;
2554 case 4:
2555 while(BlitHeight--)
2556 {
2557 x = BlitWidth;
2558 while(x)
2559 {
2560 ((DWORD*)pBltPos)[BlitWidth-x] = ((DWORD*)pSrcPos)[x];
2561 x--;
2562 }
2563 pBltPos += dwPitch;
2564 pSrcPos += src->dwPitchDB;
2565 }
2566 break;
2567 } // end switch
2568 SurfChangeUniquenessValue(dest);
2569 return DD_OK;
2570 }
2571
2572 if(dwFx)
2573 _dump_DDBLTFX(dwFx);
2574
2575 // We ignore unhandled flags at the moment
2576 }
2577
2578 if( (dwFlags & DDBLT_KEYSRC) |
2579 (dwFlags & DDBLT_KEYSRCOVERRIDE) )
2580 {
2581 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2582 {
2583
2584 if( NULL==lpDDBltFx)
2585 return DDERR_INVALIDPARAMS;
2586
2587 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
2588
2589 // We work like the HEL and test only the low value
2590 dwSrcColor = lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue;
2591
2592 }
2593 else
2594 {
2595
2596 dwFlags &= ~DDBLT_KEYSRC;
2597
2598 // Not sure if that is OK maybe check if one is set ?
2599 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT)) return DDERR_WRONGPARAM;?
2600
2601 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
2602 }
2603
2604 // ToDo : We currently indicate that we don't support
2605 // DDBLT_KEYDEST but HEL does change that!
2606 // also add this key in the get/setColorKey functions
2607
2608 if( (dwFlags & DDBLT_KEYDEST) |
2609 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
2610 {
2611 // Source and dest color keying SLOW!!!
2612 if(dwFlags & DDBLT_KEYDESTOVERRIDE)
2613 {
2614 if( NULL==lpDDBltFx)
2615 return DDERR_INVALIDPARAMS;
2616
2617 dwFlags &= ~DDBLT_KEYDESTOVERRIDE;
2618
2619 // We work like the HEL and test only the low value
2620 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
2621
2622 }
2623 else
2624 {
2625
2626 dwFlags &= ~DDBLT_KEYDEST;
2627
2628 // Not sure if that is OK maybe check if one is set ?
2629 // if(!(Dest->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
2630
2631 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
2632 }
2633
2634 // This will be be slow maybe move to ASM ?
2635 // using MMX should be much faster
2636 switch(dest->dwBytesPPDive)
2637 {
2638 case 1:
2639 while(BlitHeight--)
2640 {
2641 x = 0;
2642 while(x<BlitWidth)
2643 {
2644 if(pSrcPos[x] != (char) dwSrcColor)
2645 {
2646 if(pBltPos[x] != (char) dwDestColor)
2647 pBltPos[x] = pSrcPos[x];
2648 }
2649 x++;
2650 }
2651 pBltPos += dwPitch;
2652 pSrcPos += src->dwPitchDB;
2653 }
2654 break;
2655 case 2:
2656 while(BlitHeight--)
2657 {
2658 x = 0;
2659 while(x<BlitWidth)
2660 {
2661 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
2662 {
2663 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
2664 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
2665 }
2666 x++;
2667 }
2668 pBltPos += dwPitch;
2669 pSrcPos += src->dwPitchDB;
2670 }
2671 break;
2672 case 3:
2673 {
2674 char *pSC, *pDC;
2675 pSC = (char*)&dwSrcColor;
2676 pDC = (char*)&dwDestColor;
2677 BlitWidth *=3;
2678
2679 while(BlitHeight--)
2680 {
2681 x = 0;
2682
2683 while(x<BlitWidth)
2684 {
2685 if( (pSrcPos[x] != pSC[1]) &&
2686 (pSrcPos[x+1] != pSC[2]) &&
2687 (pSrcPos[x+2] != pSC[3])
2688 )
2689 {
2690 if( (pBltPos[x] != pDC[1]) &&
2691 (pBltPos[x+1] != pDC[2]) &&
2692 (pBltPos[x+2] != pDC[3])
2693 )
2694 {
2695 pBltPos[x] = pSrcPos[x];
2696 pBltPos[x+1] = pSrcPos[x+2];
2697 pBltPos[x+1] = pSrcPos[x+2];
2698 }
2699 }
2700 x +=3;
2701 }
2702 pBltPos += dwPitch;
2703 pSrcPos += src->dwPitchDB;
2704 }
2705 break;
2706 }
2707 case 4:
2708 while(BlitHeight--)
2709 {
2710 x = 0;
2711 while(x<BlitWidth)
2712 {
2713 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
2714 {
2715 if(((DWORD*)pBltPos)[x] != dwDestColor)
2716 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
2717 }
2718 x++;
2719 }
2720 pBltPos += dwPitch;
2721 pSrcPos += src->dwPitchDB;
2722 }
2723 break;
2724 } // End switch
2725 }
2726 else
2727 {
2728 // This will be be slow maybe move to ASM ?
2729 // using MMX should be much faster
2730 switch(dest->dwBytesPPDive)
2731 {
2732 case 1:
2733 while(BlitHeight--)
2734 {
2735 x = 0;
2736 while(x<BlitWidth)
2737 {
2738 if(pSrcPos[x] != (char) dwSrcColor)
2739 {
2740 pBltPos[x] = pSrcPos[x];
2741 }
2742 x++;
2743 }
2744 pBltPos += dwPitch;
2745 pSrcPos += src->dwPitchDB;
2746 }
2747 break;
2748 case 2:
2749 while(BlitHeight--)
2750 {
2751 x = 0;
2752 while(x<BlitWidth)
2753 {
2754 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
2755 {
2756 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
2757 }
2758 x++;
2759 }
2760 pBltPos += dwPitch;
2761 pSrcPos += src->dwPitchDB;
2762 }
2763 break;
2764 case 3:
2765 {
2766 char *pSC, *pDC;
2767 pSC = (char*)&dwSrcColor;
2768 pDC = (char*)&dwDestColor;
2769 BlitWidth *=3;
2770
2771 while(BlitHeight--)
2772 {
2773 x = 0;
2774
2775 while(x<BlitWidth)
2776 {
2777 if( (pSrcPos[x] != pSC[1]) &&
2778 (pSrcPos[x+1] != pSC[2]) &&
2779 (pSrcPos[x+2] != pSC[3])
2780 )
2781 {
2782 pBltPos[x] = pSrcPos[x];
2783 pBltPos[x+1] = pSrcPos[x+2];
2784 pBltPos[x+1] = pSrcPos[x+2];
2785 }
2786 x +=3;
2787 }
2788 pBltPos += dwPitch;
2789 pSrcPos += src->dwPitchDB;
2790 }
2791 break;
2792 }
2793 case 4:
2794 while(BlitHeight--)
2795 {
2796 x = 0;
2797 while(x<BlitWidth)
2798 {
2799 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
2800 {
2801 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
2802 }
2803 x++;
2804 }
2805 pBltPos += dwPitch;
2806 pSrcPos += src->dwPitchDB;
2807 }
2808 break;
2809 } // End switch
2810 // Only Source colorkey
2811 }
2812 SurfChangeUniquenessValue(dest);
2813 return DD_OK;
2814 }
2815
2816 if( (dwFlags & DDBLT_KEYDEST) |
2817 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
2818 {
2819 // Dest color keying SLOW!!!
2820 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2821 {
2822 if( NULL==lpDDBltFx)
2823 return DDERR_INVALIDPARAMS;
2824
2825 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
2826
2827 // We work like the HEL and test only the low value
2828 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
2829
2830 }
2831 else
2832 {
2833
2834 dwFlags &= ~DDBLT_KEYDEST;
2835
2836 // Not sure if that is OK maybe check if one is set ?
2837 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
2838
2839 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
2840 }
2841
2842 // This will be be slow maybe move to ASM ?
2843 // using MMX should be much faster
2844 switch(dest->dwBytesPPDive)
2845 {
2846 case 1:
2847 while(BlitHeight--)
2848 {
2849 x = 0;
2850 while(x<BlitWidth)
2851 {
2852 if(pBltPos[x] != (char) dwDestColor)
2853 pBltPos[x] = pSrcPos[x];
2854 x++;
2855 }
2856 pBltPos += dwPitch;
2857 pSrcPos += src->dwPitchDB;
2858 }
2859 break;
2860 case 2:
2861 while(BlitHeight--)
2862 {
2863 x = 0;
2864 while(x<BlitWidth)
2865 {
2866 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
2867 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
2868 x++;
2869 }
2870 pBltPos += dwPitch;
2871 pSrcPos += src->dwPitchDB;
2872 }
2873 break;
2874 case 3:
2875 {
2876 char *pSC, *pDC;
2877 pSC = (char*)&dwSrcColor;
2878 pDC = (char*)&dwDestColor;
2879 BlitWidth *=3;
2880
2881 while(BlitHeight--)
2882 {
2883 x = 0;
2884
2885 while(x<BlitWidth)
2886 {
2887 if( (pBltPos[x] != pDC[1]) &&
2888 (pBltPos[x+1] != pDC[2]) &&
2889 (pBltPos[x+2] != pDC[3])
2890 )
2891 {
2892 pBltPos[x] = pSrcPos[x];
2893 pBltPos[x+1] = pSrcPos[x+2];
2894 pBltPos[x+1] = pSrcPos[x+2];
2895 }
2896 x +=3;
2897 }
2898 pBltPos += dwPitch;
2899 pSrcPos += src->dwPitchDB;
2900 }
2901 break;
2902 }
2903 case 4:
2904 while(BlitHeight--)
2905 {
2906 x = 0;
2907 while(x<BlitWidth)
2908 {
2909 if( ((DWORD*)pBltPos)[x] != dwDestColor)
2910 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
2911 x++;
2912 }
2913 pBltPos += dwPitch;
2914 pSrcPos += src->dwPitchDB;
2915 }
2916 break;
2917 } // End switch
2918 } // End of Dest ColorKey
2919
2920
2921 }// end handling dwFlags
2922 } // End handling source not Framebuffer
2923
2924 }// end handling destination not framebuffer
2925
2926 SurfChangeUniquenessValue(dest);
2927 return(DD_OK);
2928}
2929//******************************************************************************
2930//******************************************************************************
2931HRESULT WIN32API SurfBltBatch(THIS, LPDDBLTBATCH, DWORD, DWORD )
2932{
2933 dprintf(("DDRAW: SurfBltBatch Not implemented by M$\n"));
2934
2935 return(DD_OK);
2936}
2937//******************************************************************************
2938//******************************************************************************
2939HRESULT WIN32API SurfBltFast( THIS This ,
2940 DWORD dwX,
2941 DWORD dwY,
2942 LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
2943 LPRECT lpSrcRect,
2944 DWORD dwTrans)
2945{
2946 dprintf(("DDRAW: SurfBltFast=>"));
2947 return SurfBltFast4( This,
2948 dwX,
2949 dwY,
2950 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
2951 lpSrcRect,
2952 dwTrans);
2953}
2954//******************************************************************************
2955//******************************************************************************
2956HRESULT WIN32API SurfBltFast3(THIS This ,
2957 DWORD dwX,
2958 DWORD dwY,
2959 LPDIRECTDRAWSURFACE3 lpDDSrcSurface,
2960 LPRECT lpSrcRect,
2961 DWORD dwTrans)
2962{
2963 dprintf(("DDRAW: SurfBltFast3=>"));
2964 return SurfBltFast4( This,
2965 dwX,
2966 dwY,
2967 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
2968 lpSrcRect,
2969 dwTrans);
2970}
2971//******************************************************************************
2972//******************************************************************************
2973HRESULT WIN32API SurfBltFast4( THIS This,
2974 DWORD dwX,
2975 DWORD dwY,
2976 LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
2977 LPRECT lpSrcRect,
2978 DWORD dwTrans)
2979{
2980 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
2981 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
2982 RECTL SrcRect;
2983 char *pBltPos, *pSrcPos;
2984 DWORD dwDestColor, dwSrcColor, BlitWidth, BlitHeight, x;
2985
2986 dprintf(("DDRAW: SurfBltFast4 %08X at(%d/%d) onto %08X with flags %08X\n",src, dwX,dwY, dest, dwTrans));
2987
2988 if( (NULL == lpDDSrcSurface) ||
2989 ((LONG)dwX < 0) || ((LONG)dwY < 0) ||
2990 (dwX > dest->width) ||
2991 (dwY > dest->height))
2992 {
2993 dprintf(("DDRAW: Invalid Parameters %08X, %d %d", lpDDSrcSurface ,dest->width , dest->height));
2994 return DDERR_INVALIDPARAMS;
2995 }
2996
2997 if (NULL != lpSrcRect)
2998 {
2999 memcpy(&SrcRect,lpSrcRect,sizeof(RECTL) );
3000 }
3001 else
3002 {
3003 SrcRect.top = 0;
3004 SrcRect.left = 0;
3005 SrcRect.bottom = src->height;
3006 SrcRect.right = src->width;
3007 }
3008
3009 // Todo: Test for locked src/dest
3010
3011 pBltPos = (char*) dest->pDiveBuffer + (dwY * dest->dwPitchDB) +
3012 (dwX * dest->dwBytesPPDive);
3013
3014 pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
3015 (SrcRect.left * src->dwBytesPPDive);
3016
3017 BlitHeight = SrcRect.bottom - SrcRect.top;
3018 BlitWidth = (SrcRect.right - SrcRect.left) * src->dwBytesPPDive;
3019
3020 // Remove unsupported wait flag
3021 dwTrans &= ~DDBLTFAST_WAIT;
3022
3023 if(DDBLTFAST_NOCOLORKEY == dwTrans )
3024 {
3025 dprintf(( "Solid Blit, %d bits => %d bytes per line\n",
3026 (SrcRect.right - SrcRect.left),
3027 BlitWidth) );
3028 #ifdef USE_ASM
3029 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
3030 dest->dwPitchDB,
3031 src->dwPitchDB);
3032 #else
3033 // Solid Blit
3034 while(1)
3035 {
3036 memcpy(pBltPos,pSrcPos,BlitWidth);
3037 pBltPos += dest->dwPitchDB;
3038 pSrcPos += src->dwPitchDB;
3039 if(! (--BlitHeight))
3040 break;
3041 }
3042 #endif
3043
3044 }
3045 else
3046 {
3047 dprintf(("DDRAW: TransBlit\n"));
3048
3049 if(dwTrans & DDBLTFAST_SRCCOLORKEY)
3050 {
3051 dprintf(("DDRAW: Trans SRC\n"));
3052 // transparent source
3053 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
3054 if(dwTrans & DDBLTFAST_DESTCOLORKEY)
3055 {
3056 dprintf(("DDRAW: And Dest Colorkey"));
3057 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3058 // Source and dest colorkeying
3059 switch(dest->dwBytesPPDive)
3060 {
3061 case 1:
3062 while(BlitHeight--)
3063 {
3064 x = 0;
3065 while(x<BlitWidth)
3066 {
3067 if(pSrcPos[x] != (char) dwSrcColor)
3068 {
3069 if(pBltPos[x] != (char) dwDestColor)
3070 pBltPos[x] = pSrcPos[x];
3071 }
3072 x++;
3073 }
3074 pBltPos += dest->dwPitchDB;
3075 pSrcPos += src->dwPitchDB;
3076 }
3077 break;
3078 case 2:
3079 while(BlitHeight--)
3080 {
3081 x = 0;
3082 while(x<BlitWidth)
3083 {
3084 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3085 {
3086 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3087 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3088 }
3089 x++;
3090 }
3091 pBltPos += dest->dwPitchDB;
3092 pSrcPos += src->dwPitchDB;
3093 }
3094 break;
3095 case 3:
3096 {
3097 char *pSC, *pDC;
3098 pSC = (char*)&dwSrcColor;
3099 pDC = (char*)&dwDestColor;
3100 BlitWidth *=3;
3101
3102 while(BlitHeight--)
3103 {
3104 x = 0;
3105
3106 while(x<BlitWidth)
3107 {
3108 if( (pSrcPos[x] != pSC[1]) &&
3109 (pSrcPos[x+1] != pSC[2]) &&
3110 (pSrcPos[x+2] != pSC[3])
3111 )
3112 {
3113 if( (pBltPos[x] != pDC[1]) &&
3114 (pBltPos[x+1] != pDC[2]) &&
3115 (pBltPos[x+2] != pDC[3])
3116 )
3117 {
3118 pBltPos[x] = pSrcPos[x];
3119 pBltPos[x+1] = pSrcPos[x+2];
3120 pBltPos[x+1] = pSrcPos[x+2];
3121 }
3122 }
3123 x +=3;
3124 }
3125 pBltPos += dest->dwPitchDB;
3126 pSrcPos += src->dwPitchDB;
3127 }
3128 break;
3129 }
3130 case 4:
3131 while(BlitHeight--)
3132 {
3133 x = 0;
3134 while(x<BlitWidth)
3135 {
3136 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3137 {
3138 if(((DWORD*)pBltPos)[x] != dwDestColor)
3139 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3140 }
3141 x++;
3142 }
3143 pBltPos += dest->dwPitchDB;
3144 pSrcPos += src->dwPitchDB;
3145 }
3146 break;
3147 } // End switch
3148 }
3149 else
3150 {
3151 // This MMX detection should be moved into OS2Draw
3152 // and into the surface constructor a setup for blitting pointers
3153 dprintf(("DDRAW: Only Src ColorKey"));
3154 switch(dest->dwBytesPPDive)
3155 {
3156 case 1:
3157 if (CPUHasMMX())
3158 while (BlitHeight--)
3159 {
3160 BlitColorKey8MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3161 pBltPos += dest->dwPitchDB;
3162 pSrcPos += src->dwPitchDB;
3163 }
3164 else
3165 while (BlitHeight--)
3166 {
3167 BlitColorKey8((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3168 pBltPos += dest->dwPitchDB;
3169 pSrcPos += src->dwPitchDB;
3170 }
3171 break;
3172 case 2:
3173
3174 if (CPUHasMMX())
3175 while(BlitHeight--)
3176 {
3177 BlitColorKey16MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3178 pBltPos += dest->dwPitchDB;
3179 pSrcPos += src->dwPitchDB;
3180 }
3181 else
3182 while(BlitHeight--)
3183 {
3184 BlitColorKey16((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3185 pBltPos += dest->dwPitchDB;
3186 pSrcPos += src->dwPitchDB;
3187 }
3188 break;
3189 case 3:
3190 char *pSC;
3191 pSC = (char*)&dwSrcColor;
3192 BlitWidth *=3;
3193
3194 while(BlitHeight--)
3195 {
3196 x = 0;
3197
3198 while(x<BlitWidth)
3199 {
3200 if( (pSrcPos[x] != pSC[1]) &&
3201 (pSrcPos[x+1] != pSC[2]) &&
3202 (pSrcPos[x+2] != pSC[3])
3203 )
3204 {
3205 pBltPos[x] = pSrcPos[x];
3206 pBltPos[x+1] = pSrcPos[x+1];
3207 pBltPos[x+1] = pSrcPos[x+2];
3208 }
3209 x +=3;
3210 }
3211 pBltPos += dest->dwPitchDB;
3212 pSrcPos += src->dwPitchDB;
3213 }
3214 break;
3215 case 4:
3216 break;
3217 }
3218 }
3219 }
3220 else
3221 {
3222 if (dwTrans & DDBLTFAST_DESTCOLORKEY)
3223 {
3224 dprintf(("DDRAW: DestColorKey\n"));
3225
3226 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3227 switch(dest->dwBytesPPDive)
3228 {
3229 case 1:
3230 while(BlitHeight--)
3231 {
3232 x = 0;
3233 while(x<BlitWidth)
3234 {
3235 if(pBltPos[x] != (char) dwDestColor)
3236 pBltPos[x] = pSrcPos[x];
3237 x++;
3238 }
3239 pBltPos += dest->dwPitchDB;
3240 pSrcPos += src->dwPitchDB;
3241 }
3242 break;
3243 case 2:
3244 while(BlitHeight--)
3245 {
3246 x = 0;
3247 while(x<BlitWidth)
3248 {
3249 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3250 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3251 x++;
3252 }
3253 pBltPos += dest->dwPitchDB;
3254 pSrcPos += src->dwPitchDB;
3255 }
3256 break;
3257 case 3:
3258 {
3259 char *pSC, *pDC;
3260 pSC = (char*)&dwSrcColor;
3261 pDC = (char*)&dwDestColor;
3262 BlitWidth *=3;
3263
3264 while(BlitHeight--)
3265 {
3266 x = 0;
3267
3268 while(x<BlitWidth)
3269 {
3270 if( (pBltPos[x] != pDC[1]) &&
3271 (pBltPos[x+1] != pDC[2]) &&
3272 (pBltPos[x+2] != pDC[3])
3273 )
3274 {
3275 pBltPos[x] = pSrcPos[x];
3276 pBltPos[x+1] = pSrcPos[x+2];
3277 pBltPos[x+1] = pSrcPos[x+2];
3278 }
3279 x +=3;
3280 }
3281 pBltPos += dest->dwPitchDB;
3282 pSrcPos += src->dwPitchDB;
3283 }
3284 break;
3285 }
3286 case 4:
3287 while(BlitHeight--)
3288 {
3289 x = 0;
3290 while(x<BlitWidth)
3291 {
3292 if(((DWORD*)pBltPos)[x] != dwDestColor)
3293 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3294 x++;
3295 }
3296 pBltPos += dest->dwPitchDB;
3297 pSrcPos += src->dwPitchDB;
3298 }
3299 break;
3300 } // End switch
3301 }
3302 else
3303 {
3304 dprintf(("DDRAW: Unexpected Flags"));
3305 }
3306 }
3307 }
3308
3309 // if(dest->lpVtbl == dest->Vtbl4)
3310 // dest->Vtbl4->ChangeUniquenessValue(dest);
3311
3312 return DD_OK;
3313}
3314//******************************************************************************
3315//******************************************************************************
3316HRESULT WIN32API SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
3317{
3318 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3319 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3320
3321 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3322}
3323//******************************************************************************
3324//******************************************************************************
3325HRESULT WIN32API SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface)
3326{
3327 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3328 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3329
3330 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3331}
3332//******************************************************************************
3333//******************************************************************************
3334HRESULT WIN32API SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
3335{
3336
3337 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3338 OS2IDirectDrawSurface *AttachedSurface;
3339 OS2IDirectDrawSurface *SurfaceCursor;
3340 int i;
3341
3342 BOOL Found = FALSE;
3343 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3344
3345 if((0!=dwFlags)||(NULL==lpDDSurface))
3346 return(DDERR_INVALIDPARAMS);
3347
3348 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
3349 if (AttachedSurface->IsImplicitSurface())
3350 return (DDERR_CANNOTDETACHSURFACE);
3351
3352 if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
3353 !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
3354 {
3355 // Surface seams to be a backbuffer in a flipchain search it
3356
3357 // Goto top of list
3358 if(me->FrontBuffer!=NULL)
3359 {
3360 SurfaceCursor = me->FrontBuffer;
3361 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3362 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3363 }
3364 else
3365 SurfaceCursor = me;
3366
3367 // now iterrate through the list skip first in list as we don't remove the frontbuffer
3368
3369 SurfaceCursor = SurfaceCursor->BackBuffer;
3370 while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
3371 SurfaceCursor = SurfaceCursor->BackBuffer;
3372
3373 if(SurfaceCursor!=NULL)
3374 {
3375 Found = TRUE;
3376 // remove the Surface from the list
3377 SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
3378 if(SurfaceCursor->BackBuffer!=NULL)
3379 {
3380 SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
3381
3382 }
3383 else
3384 {
3385 // we were the last buffer in the list have we been the only backbuffer?
3386 if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
3387 {
3388 // Yepp so "destroy" the flipchain
3389 SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3390 SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3391 }
3392 }
3393 // decrement the backbuffer count of all buffers in the chain in front of us
3394 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3395 {
3396 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3397 SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
3398 }
3399
3400 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3401 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3402 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3403 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
3404 AttachedSurface->lpVtbl->Release(AttachedSurface);
3405
3406 }
3407 } //endif delete back/frontbuffers
3408
3409 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
3410 {
3411 // seams like someone wants a new frontbuffer
3412
3413 // Goto top of list
3414
3415 if(me->FrontBuffer!=NULL)
3416 {
3417 SurfaceCursor = me->FrontBuffer;
3418 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3419 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3420 }
3421 else
3422 SurfaceCursor = me;
3423
3424 if(SurfaceCursor == AttachedSurface)
3425 {
3426 Found = TRUE;
3427 SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
3428 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3429 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3430 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3431 AttachedSurface->lpVtbl->Release(AttachedSurface);
3432 }
3433
3434 }
3435
3436
3437 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) )
3438 {
3439 // Surface seams to be a mipmap
3440 i = 0;
3441 while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found)
3442 {
3443 if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface)
3444 {
3445 Found = TRUE;
3446 DPA_DeletePtr(me->DPA_SurfaceMipMaps,i);
3447 AttachedSurface->lpVtbl->Release(AttachedSurface);
3448 // adjust our info
3449 me->DDSurfaceDesc.dwMipMapCount-- ;
3450 if (!me->DDSurfaceDesc.dwMipMapCount)
3451 {
3452 me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
3453 }
3454 }
3455 i++;
3456 }
3457 }
3458
3459 if(!Found)
3460 {
3461 // Surface seams to be an attached one
3462 i = 0;
3463 while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found)
3464 {
3465 if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface)
3466 {
3467 Found = TRUE;
3468 DPA_DeletePtr(me->DPA_SurfaceAttached,i);
3469 AttachedSurface->lpVtbl->Release(AttachedSurface);
3470 }
3471 i++;
3472 }
3473 }
3474
3475
3476 return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
3477}
3478//******************************************************************************
3479//******************************************************************************
3480HRESULT WIN32API SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
3481{
3482 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3483 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
3484
3485 return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
3486}
3487//******************************************************************************
3488//******************************************************************************
3489HRESULT WIN32API SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
3490{
3491 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3492 OS2IDirectDrawSurface *EnumSurface;
3493 DDSURFACEDESC2 EnumDesc;
3494 int i,count;
3495 HRESULT rc;
3496
3497 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
3498 if (NULL==lpCallBack)
3499 return (DDERR_INVALIDPARAMS);
3500
3501 rc = DDENUMRET_OK;
3502
3503
3504 if(me->BackBuffer != NULL)
3505 {
3506 memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
3507 rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
3508 }
3509
3510 count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps);
3511
3512 if(count>0)
3513 {
3514 i=0;
3515 while( (DDENUMRET_OK == rc) && i<count )
3516 {
3517 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
3518 memcpy( &EnumDesc,
3519 &(EnumSurface->DDSurfaceDesc),
3520 sizeof(DDSURFACEDESC2));
3521 // Calling back into WIN32 app so we had to reset FS
3522 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
3523 i++;
3524 }
3525 }
3526
3527 count = DPA_GetPtrCount(me->DPA_SurfaceAttached);
3528
3529 if(count>0)
3530 {
3531 i=0;
3532 while( (DDENUMRET_OK == rc) && i<count )
3533 {
3534 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
3535 memcpy( &EnumDesc,
3536 &(EnumSurface->DDSurfaceDesc),
3537 sizeof(DDSURFACEDESC2));
3538 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
3539 i++;
3540 }
3541 }
3542
3543 return(DD_OK);
3544}
3545//******************************************************************************
3546//******************************************************************************
3547HRESULT WIN32API SurfEnumOverlayZOrders(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK)
3548{
3549 dprintf(("DDRAW: SurfEnumOverlayZOrders\n"));
3550
3551 return(DD_OK);
3552}
3553//******************************************************************************
3554//******************************************************************************
3555HRESULT WIN32API SurfEnumOverlayZOrders4(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK2)
3556{
3557 dprintf(("DDRAW: SurfEnumOverlayZOrders\n"));
3558
3559 return(DD_OK);
3560}
3561//******************************************************************************
3562//******************************************************************************
3563HRESULT WIN32API SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
3564{
3565 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3566
3567 dprintf(("DDRAW: SurfFlip\n"));
3568
3569 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
3570}
3571//******************************************************************************
3572//******************************************************************************
3573HRESULT WIN32API SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags)
3574{
3575 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3576
3577 dprintf(("DDRAW: SurfFlip\n"));
3578
3579 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
3580}
3581//******************************************************************************
3582//******************************************************************************
3583HRESULT WIN32API SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
3584{
3585 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3586 OS2IDirectDrawSurface *FlipSurface;
3587 OS2IDirectDrawSurface *FlipCursor;
3588 LPVOID Data;
3589 char *pcrFB,*pcFB,*pcrDB,*pcDB;
3590
3591 dprintf(("DDRAW: SurfFlip4\n"));
3592
3593 if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
3594 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
3595 )
3596 {
3597 dprintf(("DDRAW: Flip called on none Frontbuffer/Flip surface\n Flags:\n"));
3598 _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
3599 dprintf(("DDRAW: \n"));
3600 return(DDERR_NOTFLIPPABLE);
3601 }
3602
3603 if(NULL!=lpDDSurf)
3604 {
3605 dprintf(("DDRAW: Check if Surface is in Flipchain!\n"));
3606
3607 // We got an override surface check if it is in the flipchain
3608 FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
3609 FlipCursor = me->BackBuffer;
3610 while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
3611 {
3612 FlipCursor = FlipCursor->BackBuffer;
3613 }
3614
3615 if(FlipCursor!=FlipSurface)
3616 {
3617 dprintf(("DDRAW: Surface not in Flipchain!\n"));
3618
3619 return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
3620 }
3621 }
3622 else
3623 {
3624 FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
3625 dprintf(("DDRAW: Next Surface @ 0x%08X\n",FlipSurface));
3626 }
3627
3628 if((me->fLocked)||(FlipSurface->fLocked))
3629 {
3630 dprintf(("DDRAW: Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked));
3631
3632 return(DDERR_SURFACEBUSY);
3633 }
3634
3635 if (-1 != me->diveBufNr)
3636 {
3637 //dprintf(("DDRAW: DIVE Flipchain DiveBuffer #%d",FlipSurface->diveBufNr));
3638
3639 // we got some DIVE surfaces
3640 // On Dive Buffers More then Double buffering won't get any perf. gain
3641 // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
3642 // Doulebuffering should work best.
3643
3644 //rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
3645 //dprintf(("DDRAW: DiveBlitImage rc = 0x%08X\n"));
3646 SurfBltFast4( me,
3647 0,
3648 0,
3649 (LPDIRECTDRAWSURFACE4)FlipSurface,
3650 NULL,
3651 DDBLTFAST_NOCOLORKEY);
3652
3653 if(NULL==lpDDSurf)
3654 {
3655 // advance in the flipchain if no valid override surface was passed in
3656 // if we reached the end of the flipchain The Frontbuffer is the next to flip to
3657 me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
3658 }
3659 }
3660 else
3661 {
3662 dprintf(("DDRAW: Memory Flipchain"));
3663 // Memory Flipchain
3664 //
3665 // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
3666 //
3667 // We only change the memory pointer to the buffers no need to copy all the data
3668 // So the NextFlip is here allways the Backbuffer so we won't advance this
3669 //
3670 // Sample (triple buffering) : Before Flip After Flip
3671 // Buffer: FB BB TB FB BB TB
3672 // Memory: 11 22 33 22 33 11
3673 //
3674
3675 Data = me->DDSurfaceDesc.lpSurface;
3676 pcrFB = me->pFBreal;
3677 pcFB = me->pFrameBuffer;
3678 pcrDB = me->pDBreal;
3679 pcDB = me->pDiveBuffer;
3680 me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
3681 me->pFBreal = FlipSurface->pFBreal;
3682 me->pFrameBuffer = FlipSurface->pFrameBuffer;
3683 me->pDBreal = FlipSurface->pDBreal;
3684 me->pDiveBuffer = FlipSurface->pDiveBuffer;
3685
3686 if (NULL==lpDDSurf)
3687 {
3688 while (NULL!=FlipSurface->BackBuffer)
3689 {
3690 FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
3691 FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal;
3692 FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer;
3693 FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal;
3694 FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer;
3695 FlipSurface = FlipSurface->BackBuffer;
3696 }
3697 }
3698 FlipSurface->DDSurfaceDesc.lpSurface = Data;
3699 FlipSurface->pFBreal = pcrFB;
3700 FlipSurface->pFrameBuffer = pcFB;
3701 FlipSurface->pDBreal = pcrDB;
3702 FlipSurface->pDiveBuffer = pcDB;
3703 }
3704
3705 return DD_OK;
3706}
3707
3708//******************************************************************************
3709//******************************************************************************
3710HRESULT WIN32API SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
3711 LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
3712{
3713 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3714 dprintf(("DDRAW: SurfGetAttachedSurface\n"));
3715
3716 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
3717}
3718//******************************************************************************
3719//******************************************************************************
3720HRESULT WIN32API SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps,
3721 LPDIRECTDRAWSURFACE3 FAR * lpDDSurf)
3722{
3723 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3724 dprintf(("DDRAW: SurfGetAttachedSurface3\n"));
3725
3726 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
3727}
3728//******************************************************************************
3729//******************************************************************************
3730HRESULT WIN32API SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
3731 LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
3732{
3733 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3734 OS2IDirectDrawSurface *EnumSurface = NULL;
3735 OS2IDirectDrawSurface *AttachedSurface = NULL;
3736 HRESULT rc;
3737 int i;
3738
3739 dprintf(("DDRAW: SurfGetAttachedSurface4\n>Requested Caps: "));
3740 _dump_DDSCAPS(lpDDCaps->dwCaps);
3741 dprintf(("DDRAW: \n"));
3742
3743 if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
3744 {
3745 dprintf(("DDRAW: Invalid params\n\n"));
3746 return (DDERR_INVALIDPARAMS);
3747 }
3748
3749
3750 rc = DD_OK;
3751
3752 if( (me->BackBuffer!=NULL) &&
3753 (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
3754 {
3755 dprintf(("DDRAW: Return Backbuffer\n"));
3756 AttachedSurface = me->BackBuffer;
3757 }
3758
3759 if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0)
3760 {
3761 i=0;
3762 while( i<DPA_GetPtrCount(me->DPA_SurfaceMipMaps) )
3763 {
3764 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
3765 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
3766 {
3767 if(NULL==AttachedSurface)
3768 AttachedSurface = EnumSurface;
3769 else
3770 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
3771 // but function must fail if more then one surface fits
3772
3773 }
3774 i++;
3775 }
3776 }
3777
3778 if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0)
3779 {
3780 i=0;
3781 while( i<DPA_GetPtrCount(me->DPA_SurfaceAttached) )
3782 {
3783 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
3784 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
3785 {
3786 if(NULL==AttachedSurface)
3787 AttachedSurface = EnumSurface;
3788 else
3789 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
3790 // but function must fail if more then one surface fits
3791
3792 }
3793 i++;
3794 }
3795 }
3796
3797 if( (DD_OK==rc) &&
3798 (NULL!=AttachedSurface) )
3799 {
3800 *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
3801 // not sure but as we returned an reference rains usage count
3802 AttachedSurface->lpVtbl->AddRef(AttachedSurface);
3803 }
3804 else
3805 {
3806 *lpDDSurf = NULL;
3807 rc = DDERR_NOTFOUND;
3808 }
3809
3810
3811 return rc;
3812}
3813//******************************************************************************
3814//******************************************************************************
3815HRESULT WIN32API SurfGetBltStatus(THIS This, DWORD)
3816{
3817 dprintf(("DDRAW: SurfGetBltStatus\n"));
3818
3819 return(DD_OK);
3820}
3821//******************************************************************************
3822//******************************************************************************
3823HRESULT WIN32API SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
3824{
3825 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3826
3827 dprintf(("DDRAW: SurfGetCaps\n"));
3828
3829 if(NULL==lpDDCaps)
3830 return(DDERR_INVALIDPARAMS);
3831
3832 lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
3833 _dump_DDSCAPS(lpDDCaps->dwCaps);
3834 return(DD_OK);
3835}
3836//******************************************************************************
3837//******************************************************************************
3838HRESULT WIN32API SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
3839{
3840 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3841 dprintf(("DDRAW: SurfGetCaps4\n"));
3842
3843 if(NULL==lpDDCaps)
3844 return(DDERR_INVALIDPARAMS);
3845
3846 memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
3847 _dump_DDSCAPS(lpDDCaps->dwCaps);
3848 _dump_DDSCAPS2(lpDDCaps->dwCaps2);
3849
3850 return(DD_OK);
3851}
3852//******************************************************************************
3853//******************************************************************************
3854HRESULT WIN32API SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
3855{
3856 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3857
3858 dprintf(("DDRAW: SurfGetClipper\n"));
3859
3860 if(me->lpClipper)
3861 {
3862 *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
3863 return(DD_OK);
3864 }
3865 else
3866 return(DDERR_NOCLIPPERATTACHED);
3867}
3868//******************************************************************************
3869//******************************************************************************
3870HRESULT WIN32API SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
3871{
3872 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3873 dprintf(("DDRAW: SurfGetColorKey\n"));
3874
3875 if ((0==dwFlags) || (NULL==lpDDColKey))
3876 return (DDERR_INVALIDPARAMS);
3877
3878 // as we report only src colorkey in the caps return error on all others flags
3879 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
3880 return(DDERR_UNSUPPORTED);
3881
3882 if(me->DDSurfaceDesc.dwFlags & dwFlags)
3883 {
3884 if(DDCKEY_SRCBLT & dwFlags)
3885 {
3886 memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
3887 }
3888 else
3889 return (DDERR_INVALIDPARAMS); // some other flags where set => error
3890 }
3891 else
3892 return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
3893
3894 return (DD_OK);
3895}
3896//******************************************************************************
3897//******************************************************************************
3898HRESULT WIN32API SurfGetDC(THIS This, HDC FAR *hdc)
3899{
3900 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3901 DDSURFACEDESC2 LockedSurfaceDesc;
3902 HRESULT rc;
3903 BITMAP bmpSurface;
3904 struct
3905 {
3906 BITMAPINFOHEADER bmiHead;
3907 RGBQUAD bmiCols[256];
3908 } BitmapInfo;
3909
3910 dprintf(("DDRAW: SurfGetDC\n"));
3911
3912 if (hdc == NULL)
3913 return(DDERR_INVALIDPARAMS);
3914
3915 LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
3916
3917 if(DD_OK != me->Vtbl.Lock(me,NULL,&LockedSurfaceDesc,0,0))
3918 {
3919 return(DDERR_DCALREADYCREATED);
3920 }
3921
3922 rc = DD_OK;
3923
3924 if(me->hdcImage == NULL)
3925 {
3926 // Create a Device context
3927 me->hdcImage = CreateCompatibleDC(NULL);
3928 if(me->hdcImage == NULL)
3929 {
3930 dprintf(("DDRAW: Can't create compatible DC!\n"));
3931 me->Vtbl.Unlock(me,NULL);
3932 rc = DDERR_GENERIC;
3933 }
3934 }
3935
3936 if( (DD_OK==rc) && (me->hbmImage == NULL) )
3937 {
3938 OS2IDirectDrawPalette *ddpal = NULL;
3939
3940 dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n",
3941 LockedSurfaceDesc.dwWidth,
3942 LockedSurfaceDesc.dwHeight,
3943 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount
3944 ));
3945 memset(&BitmapInfo, 0, sizeof(BitmapInfo));
3946 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
3947 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
3948 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
3949 BitmapInfo.bmiHead.biPlanes = 1;
3950 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
3951
3952 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
3953 {
3954 case 1:
3955 case 4:
3956 dprintf(("DDRAW: 1/4 Bit Not yet supported\n"));
3957 break;
3958 case 8:
3959 BitmapInfo.bmiHead.biCompression = BI_RGB;
3960 if (me->lpPalette != NULL)
3961 ddpal = me->lpPalette;
3962 if ((me->FrontBuffer != NULL) && (me->FrontBuffer->lpPalette != NULL))
3963 ddpal = me->FrontBuffer->lpPalette;
3964 if (ddpal != NULL) {
3965 ddpal->Vtbl.GetEntries((IDirectDrawPalette*)ddpal,
3966 0, 0, 256, (PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
3967 }
3968 else {
3969 dprintf(("DDRAW: Using default palette\n"));
3970 for (DWORD i = 0; i < 256; i++) {
3971 BitmapInfo.bmiCols[i].rgbBlue = DefaultPalette[i*3+2];
3972 BitmapInfo.bmiCols[i].rgbGreen = DefaultPalette[i*3+1];
3973 BitmapInfo.bmiCols[i].rgbRed = DefaultPalette[i*3];
3974 BitmapInfo.bmiCols[i].rgbReserved = 0;
3975 }
3976 }
3977 me->hbmImage = CreateDIBitmap( me->hdcImage,
3978 &BitmapInfo.bmiHead,
3979 CBM_INIT,
3980 LockedSurfaceDesc.lpSurface,
3981 (PBITMAPINFO)&BitmapInfo,
3982 DIB_RGB_COLORS);
3983 break;
3984
3985 case 16:
3986 case 24:
3987 case 32:
3988 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
3989 BitmapInfo.bmiHead.biClrUsed = 3;
3990 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
3991 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
3992 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
3993 me->hbmImage = CreateDIBitmap( me->hdcImage,
3994 &BitmapInfo.bmiHead,
3995 CBM_INIT,
3996 LockedSurfaceDesc.lpSurface,
3997 (PBITMAPINFO)&BitmapInfo,
3998 DIB_RGB_COLORS );
3999 break;
4000
4001 default:
4002 dprintf( ("Unexpected BitCount %d \n",
4003 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4004 me->hbmImage=NULL;
4005 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4006
4007 if(me->hbmImage == NULL)
4008 {
4009 dprintf(("DDRAW: Can't create bitmap!\n"));
4010 DeleteDC(me->hdcImage);
4011 me->hdcImage = NULL;
4012 me->Vtbl.Unlock(me,NULL);
4013 rc = DDERR_GENERIC;
4014 }
4015 }
4016 else
4017 {
4018 if( (DD_OK==rc) && (me->dwLastDCUnique != me->dwUniqueValue) )
4019 {
4020 dprintf(("DDRAW: The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n"));
4021
4022 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4023 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4024 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
4025 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
4026 BitmapInfo.bmiHead.biPlanes = 1;
4027 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4028
4029 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4030 {
4031 case 1:
4032 case 4:
4033 case 8:
4034 BitmapInfo.bmiHead.biCompression = BI_RGB;
4035 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4036 SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
4037 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4038 break;
4039 case 16:
4040 case 32:
4041 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4042 BitmapInfo.bmiHead.biClrUsed = 3;
4043 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4044 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4045 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4046 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4047 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4048 break;
4049 case 24:
4050 BitmapInfo.bmiHead.biCompression = BI_RGB;
4051 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4052 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4053 break;
4054 default:
4055 dprintf(("DDRAW: Unexpected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4056 break;
4057 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4058
4059 }
4060 }
4061
4062 // Allways select the bitmap into the DC! No matter if the old or a new one
4063
4064 if (DD_OK==rc)
4065 {
4066 if ((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
4067 {
4068 dprintf(("DDRAW: Can't select bitmap into DC!\n"));
4069 DeleteDC(me->hdcImage);
4070 me->hdcImage = NULL;
4071 DeleteObject(me->hbmImage);
4072 me->hbmImage = NULL;
4073 me->Vtbl.Unlock(me,NULL);
4074 rc = DDERR_GENERIC;
4075 }
4076 else
4077 {
4078 *hdc = me->hdcImage;
4079 }
4080 }
4081
4082 return rc;
4083}
4084//******************************************************************************
4085//******************************************************************************
4086HRESULT WIN32API SurfGetFlipStatus(THIS This, DWORD dwFlags)
4087{
4088 dprintf(("DDRAW: SurfGetFlipStatus\n"));
4089
4090 if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
4091 return DDERR_INVALIDPARAMS;
4092
4093 return(DD_OK);
4094}
4095//******************************************************************************
4096//******************************************************************************
4097HRESULT WIN32API SurfGetOverlayPosition(THIS This, LPLONG lplX, LPLONG lplY)
4098{
4099 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4100 dprintf(("DDRAW: SurfGetOverlayPosition\n"));
4101
4102 // Maybe simply return dderr_notsupported as we retun a max overlay value of 0 in the caps ?
4103
4104 if( (NULL==lplX) || (NULL==lplY))
4105 return DDERR_INVALIDPARAMS;
4106
4107 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
4108 return DDERR_NOTAOVERLAYSURFACE;
4109
4110 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_VISIBLE))
4111 return DDERR_OVERLAYNOTVISIBLE;
4112
4113 if(!me->fOverlayValid)
4114 return DDERR_NOOVERLAYDEST;
4115
4116 *lplX = me->lOverlayX;
4117 *lplY = me->lOverlayY;
4118
4119 return(DD_OK);
4120}
4121//******************************************************************************
4122//******************************************************************************
4123HRESULT WIN32API SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
4124{
4125 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4126
4127 dprintf(("DDRAW: SurfGetPalette\n"));
4128
4129 if(me->lpPalette)
4130 {
4131 *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
4132 return(DD_OK);
4133 }
4134 else
4135 return(DDERR_NOPALETTEATTACHED);
4136}
4137//******************************************************************************
4138//******************************************************************************
4139HRESULT WIN32API SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
4140{
4141 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4142
4143 dprintf(("DDRAW: SurfGetPixelFormat %x %x", This, lpPixelFormat));
4144
4145 if(NULL==lpPixelFormat)
4146 return DDERR_INVALIDPARAMS;
4147
4148 _dump_pixelformat(&me->DDSurfaceDesc.ddpfPixelFormat);
4149
4150 memcpy( (char*)lpPixelFormat,
4151 (char*)&(me->DDSurfaceDesc.ddpfPixelFormat),
4152 sizeof(DDPIXELFORMAT));
4153
4154 return(DD_OK);
4155}
4156//******************************************************************************
4157//******************************************************************************
4158HRESULT WIN32API SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
4159{
4160 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4161
4162 dprintf(("DDRAW: SurfGetSurfaceDesc\n"));
4163
4164 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
4165 return(DDERR_INVALIDPARAMS);
4166
4167 memcpy( (char *)lpSurface,
4168 (char *)&me->DDSurfaceDesc,
4169 sizeof(DDSURFACEDESC));
4170
4171 return(DD_OK);
4172}
4173//******************************************************************************
4174//******************************************************************************
4175HRESULT WIN32API SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
4176{
4177 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4178
4179 dprintf(("DDRAW: SurfGetSurfaceDesc4\n"));
4180
4181 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
4182 return(DDERR_INVALIDPARAMS);
4183
4184 memcpy( (char *)lpSurface,
4185 (char *)&me->DDSurfaceDesc,
4186 sizeof(DDSURFACEDESC2));
4187
4188 return(DD_OK);
4189}
4190//******************************************************************************
4191//******************************************************************************
4192HRESULT WIN32API SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
4193{
4194 dprintf(("DDRAW: SurfInitialize\n"));
4195
4196 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4197}
4198//******************************************************************************
4199//******************************************************************************
4200HRESULT WIN32API SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
4201{
4202 dprintf(("DDRAW: SurfInitialize\n"));
4203
4204 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4205}
4206//******************************************************************************
4207//******************************************************************************
4208HRESULT WIN32API SurfIsLost(THIS)
4209{
4210 // We don't loose any surface ;)
4211 // But we might shoud check for primary and/or Dive Buffers as I don't know
4212 // if they are preserved if switching to a FS DOS/OS2 session
4213 //
4214 dprintf(("DDRAW: SurfIsLost\n"));
4215
4216 return(DD_OK);
4217}
4218//******************************************************************************
4219//******************************************************************************
4220HRESULT WIN32API SurfLock( THIS This,
4221 LPRECT lpRect,
4222 LPDDSURFACEDESC lpSurfaceDesc,
4223 DWORD dwFlags,
4224 HANDLE hEvent)
4225{
4226 DDSURFACEDESC2 SurfaceDesc4;
4227 HRESULT rc;
4228
4229 dprintf(("DDRAW: SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent));
4230
4231 if((NULL==lpSurfaceDesc)|| ((dwFlags & DDLOCK_EVENT) && NULL != hEvent)) {
4232 dprintf(("Invalid parameters"));
4233 return DDERR_INVALIDPARAMS;
4234 }
4235
4236 if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC) && lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC2)) {
4237 dprintf(("Invalid parameters"));
4238 return DDERR_INVALIDPARAMS;
4239 }
4240
4241 SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
4242
4243 rc = SurfLock4( This,
4244 lpRect,
4245 &SurfaceDesc4,
4246 dwFlags,
4247 hEvent);
4248 if (DD_OK==rc)
4249 {
4250 memcpy( (char*)lpSurfaceDesc,
4251 (char*)&SurfaceDesc4,
4252 lpSurfaceDesc->dwSize );
4253 }
4254
4255 return(rc);
4256}
4257//******************************************************************************
4258//******************************************************************************
4259HRESULT WIN32API SurfLock4( THIS This,
4260 LPRECT lpRect,
4261 LPDDSURFACEDESC2 lpSurfaceDesc,
4262 DWORD dwFlags,
4263 HANDLE hEvent)
4264{
4265
4266 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4267 int i;
4268
4269 BOOL Found;
4270 DDRectangle *pIRectCurrent,*pIRectNew;
4271 HRESULT rc;
4272
4273 dprintf( ("SurfLock4 %08X %08X %08X %d %d\n",
4274 me,
4275 (int)lpRect,
4276 (int)lpSurfaceDesc,
4277 dwFlags,
4278 hEvent) );
4279
4280 if( (NULL==lpSurfaceDesc) ||
4281 (NULL!=hEvent)
4282 )
4283 {
4284 dprintf(("DDERR_INVALIDPARAMS"));
4285 return DDERR_INVALIDPARAMS;
4286 }
4287
4288 if (NULL!=lpRect)
4289 pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
4290 else
4291 pIRectNew = new DDRectangle( 0, 0, me->width, me->height);
4292
4293 // ToDo : the lockchecking should be done in a critcal seq.
4294 dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n",
4295 pIRectNew->Left(),
4296 pIRectNew->Top(),
4297 pIRectNew->Right(),
4298 pIRectNew->Bottom()));
4299
4300 rc = DD_OK;
4301
4302 if(me->fLocked)
4303 {
4304 if (NULL==lpRect)
4305 {
4306 // If anything is locked we can't lock the complete surface
4307 dprintf(("DDRAW: Surface has locked Rectangles and we want to completely lock it\n"));
4308 Found = TRUE;
4309 }
4310 else
4311 {
4312 // If the new Rectangle intersects with any of the already locked rectangles it can't
4313 // be locked so check for this
4314
4315 dprintf(("DDRAW: Surface has locked Rectangles, check if they overlap\n"));
4316
4317 i=0;
4318 Found = FALSE;
4319
4320 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4321 {
4322 pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
4323 dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n",
4324 pIRectCurrent->Top(),
4325 pIRectCurrent->Left(),
4326 pIRectCurrent->Bottom(),
4327 pIRectCurrent->Right() ));
4328 Found = pIRectCurrent->intersects(*pIRectNew);
4329 i++;
4330 }
4331
4332 }
4333
4334 if (Found)
4335 {
4336 delete pIRectNew;
4337 dprintf(("DDRAW: SurfLock4: Surface already locked\n\n"));
4338 rc = DDERR_SURFACEBUSY;
4339 }
4340
4341 }
4342
4343 if(DD_OK == rc)
4344 {
4345 memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
4346
4347 if(lpRect != NULL)
4348 {
4349 lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer +
4350 (lpRect->top * me->dwPitchFB) +
4351 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
4352 dprintf(("DDRAW: SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left));
4353 }
4354 else
4355 {
4356 dprintf(("DDRAW: SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface));
4357 }
4358 // Add the rectangle to the list of locked rectangles
4359
4360 pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
4361
4362 DPA_InsertPtr( me->DPA_LockedRects,
4363 DPA_GetPtrCount(me->DPA_LockedRects),
4364 pIRectNew);
4365
4366#if 0
4367 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
4368 {
4369 OS2RECTL rectOS2;
4370
4371 rectOS2.xLeft = pIRectNew->Left();
4372 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectNew->Bottom();
4373 rectOS2.xRight = pIRectNew->Right();
4374 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectNew->Top();
4375 dprintf(("DiveAcquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
4376 int ret = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectOS2);
4377 if(ret) {
4378 dprintf(("ERROR: DiveAcquireFrameBuffer failed with %d", ret));
4379 }
4380 }
4381#endif
4382 me->fLocked = TRUE;
4383
4384 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
4385 {
4386 //If fHideCursorOnLock is set, then we hide the cursor to prevent
4387 //the app from corruption the mouse cursor (color/animated pointers)
4388 if(fHideCursorOnLock) ShowCursor(FALSE);
4389 }
4390 }
4391
4392 return rc;
4393}
4394//******************************************************************************
4395//******************************************************************************
4396HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc)
4397{
4398 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4399 struct
4400 {
4401 BITMAPINFOHEADER bmiHead;
4402 RGBQUAD bmiCols[256];
4403 } BitmapInfo;
4404 int rc;
4405
4406 dprintf(("DDRAW: SurfReleaseDC\n"));
4407
4408 if(hdc != me->hdcImage)
4409 return(DDERR_INVALIDOBJECT);
4410
4411 //unselect our bitmap
4412 SelectObject(me->hdcImage, me->hgdiOld);
4413
4414 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4415 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4416 BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4417 BitmapInfo.bmiHead.biPlanes = 1;
4418 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.dwWidth; /// (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4419 BitmapInfo.bmiHead.biHeight = me->DDSurfaceDesc.dwHeight;
4420
4421 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4422 {
4423 case 1:
4424 case 4:
4425 case 8:
4426 BitmapInfo.bmiHead.biCompression = BI_RGB;
4427 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4428 rc = GetDIBits( hdc,
4429 me->hbmImage,
4430 0,
4431 me->DDSurfaceDesc.dwHeight,
4432 NULL,
4433 (PBITMAPINFO)&BitmapInfo,
4434 DIB_RGB_COLORS);
4435// BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight;
4436 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
4437 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
4438 rc,
4439 BitmapInfo.bmiHead.biSize,
4440 BitmapInfo.bmiHead.biWidth,
4441 BitmapInfo.bmiHead.biHeight,
4442 BitmapInfo.bmiHead.biPlanes,
4443 BitmapInfo.bmiHead.biBitCount,
4444 GetLastError(),
4445 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4446
4447 rc = GetDIBits( hdc,
4448 me->hbmImage,
4449 0,
4450 me->DDSurfaceDesc.dwHeight,
4451 me->DDSurfaceDesc.lpSurface,
4452 (PBITMAPINFO)&BitmapInfo,
4453 DIB_RGB_COLORS);
4454 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
4455 rc,
4456 GetLastError(),
4457 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4458 break;
4459 case 16:
4460 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4461 BitmapInfo.bmiHead.biClrUsed = 3;
4462 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4463 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4464 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4465 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4466 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4467 break;
4468
4469 case 32:
4470 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4471 BitmapInfo.bmiHead.biClrUsed = 3;
4472 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4473 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4474 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4475 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4476 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4477 break;
4478
4479 case 24:
4480 BitmapInfo.bmiHead.biCompression = BI_RGB;
4481 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4482 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4483 break;
4484 default:
4485 dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4486 // we might could keep the surface locked and return an error but this is more "safe"
4487 break;
4488 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4489
4490 me->Vtbl.Unlock(me,NULL);
4491 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
4492
4493 return(DD_OK);
4494}
4495//******************************************************************************
4496//******************************************************************************
4497HRESULT WIN32API SurfRestore(THIS)
4498{
4499 dprintf(("DDRAW: SurfRestore\n"));
4500
4501 return(DD_OK);
4502}
4503//******************************************************************************
4504//******************************************************************************
4505HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
4506{
4507 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4508
4509 dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper));
4510
4511 if(lpClipper == NULL)
4512 {
4513 //deattach surface
4514 if(me->lpClipper)
4515 {
4516 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
4517 me->lpClipper = NULL;
4518 return(DD_OK);
4519 }
4520 else
4521 return(DDERR_NOCLIPPERATTACHED);
4522 }
4523
4524 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
4525 return(DD_OK); //already attached
4526
4527 if(me->lpClipper != NULL)
4528 {
4529 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
4530 return(DD_OK);
4531 }
4532
4533 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
4534 me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
4535
4536 return(DD_OK);
4537}
4538//******************************************************************************
4539//******************************************************************************
4540HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
4541{
4542 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4543 HRESULT rc;
4544
4545 dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey));
4546
4547 if (0==dwFlags)
4548 {
4549 return (DDERR_INVALIDPARAMS);
4550 }
4551
4552 // as we report only src colorkey in the caps return error on all others flags
4553 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
4554 {
4555 dprintf(("Unspported colorkey\n"));
4556 return(DDERR_UNSUPPORTED);
4557 }
4558
4559 if(DDCKEY_SRCBLT & dwFlags)
4560 {
4561
4562 //(me->lpVtbl == me->Vtbl4)
4563 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
4564 if(NULL!=lpDDColKey)
4565 {
4566 dprintf(("copy colorkey"));
4567 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
4568 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
4569
4570 // ToDo: Generate a maskbitmap for transparent blitting here
4571 }
4572 else
4573 {
4574 dprintf(("clear colorkey"));
4575 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
4576 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
4577 }
4578 rc = DD_OK;
4579 }
4580 else
4581 {
4582 dprintf(("Unsupported flags"));
4583 _dump_DDCOLORKEY(dwFlags);
4584 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
4585 }
4586 return rc;
4587}
4588//******************************************************************************
4589//******************************************************************************
4590HRESULT WIN32API SurfSetOverlayPosition(THIS This, LONG lX, LONG lY)
4591{
4592 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4593
4594 dprintf(("DDRAW: SurfSetOverlayPosition\n"));
4595
4596 if( (me->DDSurfaceDesc.dwFlags & DDSD_CAPS) &&
4597 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
4598 {
4599 if(me->fOverlayValid)
4600 return(DDERR_NOOVERLAYDEST);
4601
4602 if(!(me->DDSurfaceDesc.dwFlags & DDSCAPS_VISIBLE))
4603 return(DDERR_OVERLAYNOTVISIBLE);
4604
4605 // ToDo: If we implement alignment restricions to the Overlay position
4606 // check if the new values are OK otherwiese return DDERR_INVALIDPOSITION
4607
4608 me->lOverlayX = lX;
4609 me->lOverlayY = lY;
4610 return(DD_OK);
4611 }
4612
4613 return(DDERR_NOTAOVERLAYSURFACE);
4614}
4615//******************************************************************************
4616//******************************************************************************
4617HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
4618{
4619 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4620
4621 dprintf(("DDRAW: SurfSetPalette\n"));
4622
4623 if(lpPalette == NULL)
4624 {
4625 //deattach palette
4626 if(me->lpPalette)
4627 {
4628 // If removed from a primary surface notify
4629 // palette that it is no longer attached to the
4630 // primary surface => doesn't modify physical palette
4631 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
4632 {
4633 me->lpPalette->SetIsPrimary(FALSE);
4634 }
4635 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
4636 me->lpPalette = NULL;
4637 return(DD_OK);
4638 }
4639 else
4640 return(DDERR_NOPALETTEATTACHED);
4641 }
4642
4643 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
4644 return(DD_OK); //already attached
4645
4646 if(me->lpPalette != NULL)
4647 {
4648 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
4649 //return(DD_OK);
4650 }
4651 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
4652 me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
4653
4654 // If Attached to a primary surface notify
4655 // palette that it is attached to the primary surface
4656 // => It does modify physical palette.
4657 // This is important as an palette can be attached to
4658 // multiple surfaces. If one is the primary surface
4659 // changes done to it via any surface must result in
4660 // changes in the phys pal.
4661
4662 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
4663 {
4664 me->lpPalette->SetIsPrimary(TRUE);
4665 }
4666 // me->lpVtbl->ChangeUniquenessValue(me);
4667
4668 return(DD_OK);
4669}
4670//******************************************************************************
4671//******************************************************************************
4672HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData)
4673{
4674
4675 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4676 int i;
4677 DDRectangle *pIRectUnlock, *pIRectEnum;
4678 BOOL Found = FALSE;
4679 OS2RECTL CCRect;
4680 HRESULT rc;
4681
4682 dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData));
4683
4684 if(me->fLocked == FALSE)
4685 {
4686 dprintf(("DDRAW: Surface not locked!\n"));
4687 return(DDERR_NOTLOCKED);
4688 }
4689
4690 i=0;
4691 if(NULL!=lpSurfaceData)
4692 {
4693 dprintf(("DDRAW: Buffer Pointer Compare"));
4694
4695 // We got a pinter to the surface memory so we must search for
4696 // this pointer in the locked rects DPA to unlock the right rect.
4697
4698 while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4699 {
4700 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
4701 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
4702 i,
4703 pIRectEnum->Top(),
4704 pIRectEnum->Left(),
4705 pIRectEnum->Bottom(),
4706 pIRectEnum->Right(),
4707 pIRectEnum->GetMemPtr() ));
4708
4709 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
4710 if(!Found)
4711 {
4712 dprintf(("DDRAW: Not Found, try Next rect\n"));
4713 i++;
4714 }
4715 else
4716 {
4717 dprintf(("DDRAW: Found Rect\n"));
4718 }
4719 }
4720 }
4721 else
4722 {
4723 // If a NULL pointer was passed in the SW tries to unlock the
4724 // complete surface so we must compare the rects.
4725 dprintf(("DDRAW: Rectangle compare"));
4726
4727#if 1
4728 i = 0;
4729 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0);
4730 Found = (pIRectEnum != NULL);
4731#else
4732 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
4733
4734 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4735 {
4736 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
4737 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
4738 i,
4739 pIRectEnum->Top(),
4740 pIRectEnum->Left(),
4741 pIRectEnum->Bottom(),
4742 pIRectEnum->Right(),
4743 pIRectEnum->GetMemPtr() ));
4744
4745 Found = (*pIRectEnum == *pIRectUnlock);
4746 if(!Found)
4747 {
4748 dprintf(("DDRAW: Not Found, try Next rect\n"));
4749 i++;
4750 }
4751 else
4752 {
4753 dprintf(("DDRAW: Found Rect\n"));
4754 }
4755 }
4756 delete pIRectUnlock;
4757#endif
4758 }
4759
4760 if(!Found)
4761 {
4762 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
4763 rc = DDERR_INVALIDRECT;
4764 }
4765 else
4766 {
4767 dprintf(("DDRAW: Remove Rect %d from Seq.\n",i));
4768
4769 DPA_DeletePtr(me->DPA_LockedRects,i);
4770
4771 dprintf(("DDRAW: Test if locked Rects main\n"));
4772
4773 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
4774 {
4775 dprintf(("DDRAW: No Locked Rects left for surface\n"));
4776 me->fLocked = FALSE;
4777 }
4778 else
4779 dprintf(( "%d Rects in Seq\n",
4780 DPA_GetPtrCount(me->DPA_LockedRects)));
4781
4782 if(me->pFrameBuffer != me->pDiveBuffer)
4783 {
4784 dprintf(( "ColorConversion Needed %08X != %08X\n",
4785 me->pFrameBuffer,
4786 me->pDiveBuffer));
4787 if(NULL!=lpSurfaceData)
4788 {
4789 CCRect.yTop = pIRectEnum->Top();
4790 CCRect.xLeft = pIRectEnum->Left();
4791 CCRect.xRight = pIRectEnum->Right();
4792 CCRect.yBottom = pIRectEnum->Bottom();
4793
4794 me->ColorConversion( (LPRECT)&CCRect);
4795 }
4796 else
4797 {
4798 me->ColorConversion(NULL);
4799 }
4800 }
4801 else
4802 dprintf( ("No ColorConversion Needed"));
4803
4804
4805#if 0
4806 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
4807 {
4808 OS2RECTL rectOS2;
4809
4810 rectOS2.xLeft = pIRectEnum->Left();
4811 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom();
4812 rectOS2.xRight = pIRectEnum->Right();
4813 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top();
4814 dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
4815 int ret = DiveDeacquireFrameBuffer(me->hDive);
4816 if(ret) {
4817 dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret));
4818 }
4819 }
4820#endif
4821
4822 // delete tne DDRectobject of the found rectangle
4823 delete pIRectEnum;
4824
4825 // me->lpVtbl->ChangeUniquenessValue(me);
4826
4827 dprintf(("DDRAW: Unlock OK\n\n"));
4828
4829 rc = DD_OK;
4830
4831 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
4832 {
4833 //If fHideCursorOnLock is set, then we hide the cursor to prevent in SurfLock4
4834 //the app from corruption the mouse cursor (color/animated pointers)
4835 //We need to show it again here
4836 if(fHideCursorOnLock) ShowCursor(TRUE);
4837 }
4838 }
4839
4840 return rc;
4841}
4842//******************************************************************************
4843//******************************************************************************
4844HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
4845{
4846 // MS changed the parameter from LPVOID to LPRECT with DX6
4847 // as DX-6 allways returns a DDSurface4 on create surface this
4848 // is a problem i not NULL is passed in.
4849 // Solution We first test with the pointer ns assuming a rectangle
4850 // if we don't find a rect Which is very likely if we get a pointer
4851 // SurfaceMemory we call SurfUnlock and test for the pointer there.
4852
4853
4854 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4855 int i;
4856 DDRectangle *pIRectUnlock, *pIRectEnum;
4857 BOOL Found = FALSE;
4858 HRESULT rc;
4859
4860 dprintf(("DDRAW: SurfUnlock4\n"));
4861
4862 if(me->fLocked == FALSE)
4863 {
4864 dprintf(("DDRAW: Surface not locked!\n"));
4865 return(DDERR_NOTLOCKED);
4866 }
4867
4868 if(NULL!=lpSurfaceRect)
4869 {
4870 dprintf(("DDRAW: Unlock rectangle\n"));
4871 pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top,
4872 lpSurfaceRect->right, lpSurfaceRect->bottom);
4873 }
4874 else
4875 {
4876 dprintf(("DDRAW: Unlock complete surface\n"));
4877 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
4878 }
4879
4880 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
4881 pIRectUnlock->Top(),
4882 pIRectUnlock->Left(),
4883 pIRectUnlock->Bottom(),
4884 pIRectUnlock->Right() ));
4885
4886 dprintf(("DDRAW: Start Enumeration of Locked Rects\n"));
4887
4888 i=0;
4889 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4890 {
4891 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
4892 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
4893 pIRectEnum->Top(),
4894 pIRectEnum->Left(),
4895 pIRectEnum->Bottom(),
4896 pIRectEnum->Right() ));
4897
4898 Found = (*pIRectEnum == *pIRectUnlock);
4899 if(!Found)
4900 {
4901 dprintf(("DDRAW: Not Found, try Next rect\n"));
4902 i++;
4903 }
4904 else
4905 {
4906 dprintf(("DDRAW: Found Rect\n"));
4907 }
4908 }
4909
4910 if(!Found)
4911 {
4912
4913 if(NULL==lpSurfaceRect)
4914 {
4915 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
4916 return(DDERR_INVALIDRECT);
4917 }
4918 else
4919 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
4920 }
4921 else
4922 {
4923 dprintf(("DDRAW: Remove Rect from Seq.\n"));
4924
4925 DPA_DeletePtr(me->DPA_LockedRects,i);
4926
4927 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
4928 {
4929 dprintf(("DDRAW: No Locked Rects left for surface\n"));
4930 me->fLocked = FALSE;
4931 }
4932
4933 if(me->pFrameBuffer != me->pDiveBuffer)
4934 {
4935 dprintf(( "ColorConversion Needed %08X != %08X\n",
4936 me->pFrameBuffer,
4937 me->pDiveBuffer));
4938 me->ColorConversion(lpSurfaceRect);
4939 }
4940
4941 // me->lpVtbl->ChangeUniquenessValue(me);
4942
4943 dprintf(("DDRAW: Unlock OK\n\n"));
4944 rc = DD_OK;
4945 }
4946
4947 return rc;
4948}
4949//******************************************************************************
4950//******************************************************************************
4951HRESULT WIN32API SurfUpdateOverlay(THIS This, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX)
4952{
4953 dprintf(("DDRAW: SurfUpdateOverlay\n"));
4954 return(DD_OK);
4955}
4956//******************************************************************************
4957//******************************************************************************
4958HRESULT WIN32API SurfUpdateOverlay3(THIS This, LPRECT, LPDIRECTDRAWSURFACE3,LPRECT,DWORD, LPDDOVERLAYFX)
4959{
4960 dprintf(("DDRAW: SurfUpdateOverlay\n"));
4961 return(DD_OK);
4962}
4963//******************************************************************************
4964//******************************************************************************
4965HRESULT WIN32API SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX)
4966{
4967 dprintf(("DDRAW: SurfUpdateOverlay\n"));
4968 return(DD_OK);
4969}
4970//******************************************************************************
4971//******************************************************************************
4972HRESULT WIN32API SurfUpdateOverlayDisplay(THIS, DWORD)
4973{
4974 dprintf(("DDRAW: SurfUpdateOverlayDisplay\n"));
4975 return(DD_OK);
4976}
4977//******************************************************************************
4978//******************************************************************************
4979HRESULT WIN32API SurfUpdateOverlayZOrder(THIS, DWORD, LPDIRECTDRAWSURFACE2)
4980{
4981 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
4982 return(DD_OK);
4983}
4984//******************************************************************************
4985//******************************************************************************
4986HRESULT WIN32API SurfUpdateOverlayZOrder3(THIS, DWORD, LPDIRECTDRAWSURFACE3)
4987{
4988 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
4989 return(DD_OK);
4990}
4991//******************************************************************************
4992//******************************************************************************
4993HRESULT WIN32API SurfUpdateOverlayZOrder4(THIS, DWORD, LPDIRECTDRAWSURFACE4)
4994{
4995 dprintf(("DDRAW: SurfUpdateOverlayZOrder4\n"));
4996 return(DD_OK);
4997}
4998//******************************************************************************
4999//******************************************************************************
5000HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
5001{
5002 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5003
5004 dprintf(("DDRAW: SurfGetDDInterface\n"));
5005 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
5006 return(DD_OK);
5007}
5008//******************************************************************************
5009//******************************************************************************
5010HRESULT WIN32API SurfPageLock(THIS, DWORD)
5011{
5012 // Only used for DMA memory access
5013 // If we implement this for the None dive buffers with a pdd the we must change
5014 // from malloc to DosAllocMem and use OBJ_TILE flag
5015 dprintf(("DDRAW: SurfPageLock\n"));
5016 return(DD_OK);
5017}
5018//******************************************************************************
5019//******************************************************************************
5020HRESULT WIN32API SurfPageUnlock(THIS, DWORD)
5021{
5022 dprintf(("DDRAW: SurfPageUnlock\n"));
5023 return(DD_OK);
5024}
5025//******************************************************************************
5026//******************************************************************************
5027// V3 Interface Functions
5028
5029HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
5030{
5031 dprintf(("DDRAW: SurfSetSurfaceDesc\n"));
5032
5033 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5034 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5035 return DDERR_INVALIDPARAMS;
5036
5037 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5038 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5039 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5040 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5041 if(-1==me->diveBufNr)
5042 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5043
5044 if (!me->Updated)
5045 {
5046 me->Updated = TRUE;
5047 // free our allocated Memory
5048 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5049 {
5050 if(me->pFBreal)
5051 free(me->pFBreal);
5052 if(me->pDBreal)
5053 free(me->pFBreal);
5054 }
5055 }
5056 // me->lpVtbl->ChangeUniquenessValue(me);
5057 memcpy( (char*)&(me->DDSurfaceDesc),
5058 (char*)lpSurfDesc,
5059 sizeof(DDSURFACEDESC));
5060
5061 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5062
5063 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5064 {
5065 // create CC buffer ....
5066 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5067 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5068 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5069 }
5070 return DD_OK;
5071}
5072//******************************************************************************
5073//******************************************************************************
5074HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
5075{
5076 dprintf(("DDRAW: SurfSetSurfaceDesc4\n"));
5077
5078 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5079 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5080 return DDERR_INVALIDPARAMS;
5081
5082 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5083 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5084 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5085 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5086 if(-1==me->diveBufNr)
5087 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5088
5089 if (!me->Updated)
5090 {
5091 me->Updated = TRUE;
5092 // free our allocated Memory
5093 // free our allocated Memory
5094 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5095 {
5096 if(me->pFBreal)
5097 free(me->pFBreal);
5098 if(me->pDBreal)
5099 free(me->pFBreal);
5100 }
5101 }
5102 // me->lpVtbl->ChangeUniquenessValue(me);
5103 memcpy( (char *)&(me->DDSurfaceDesc),
5104 (char*)lpSurfDesc,
5105 sizeof(DDSURFACEDESC2));
5106 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5107
5108 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5109 {
5110 // create CC buffer ....
5111 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5112 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5113 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5114 }
5115
5116 return DD_OK;
5117}
5118//******************************************************************************
5119//******************************************************************************
5120// V4 Interface Functions
5121
5122HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
5123 DWORD dwDataSize, DWORD dwFlags)
5124{
5125 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5126 int i;
5127 PSURFPRIVATEDATA pSData;
5128 void *pBuffer;
5129 BOOL bFound = FALSE;
5130 HRESULT rc;
5131
5132 dprintf(("DDRAW: SurfSetPrivateData\n"));
5133
5134 if(NULL==me)
5135 return(DDERR_INVALIDOBJECT);
5136
5137 if((NULL==lpData)||(0==dwDataSize)||
5138 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
5139 return(DDERR_INVALIDPARAMS);
5140
5141 // first check if the refGUID is stored as then the content will be updated
5142 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
5143 {
5144 i=0;
5145 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5146 {
5147 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5148
5149 if (IsEqualGUID(pSData->guidTag,refGUID))
5150 bFound = TRUE;
5151
5152 i++;
5153 }
5154 }
5155
5156 if(bFound)
5157 {
5158 // update Private Data
5159
5160 if (!pSData->isValid)
5161 {
5162 // Current data is invalid we need to update/allocate
5163
5164 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5165 {
5166 pSData->pData = lpData;
5167 pSData->dwSize = 4;
5168 pSData->dwFlags = dwFlags;
5169 pSData->isValid = TRUE;
5170 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
5171 }
5172 else
5173 {
5174 pSData->pData = malloc(dwDataSize);
5175 if(NULL!=pSData->pData)
5176 {
5177 memcpy(pSData->pData,lpData,dwDataSize);
5178 pSData->dwSize = dwDataSize;
5179 pSData->dwFlags = dwFlags;
5180 pSData->isValid = TRUE;
5181 }
5182 else
5183 {
5184 delete pSData;
5185 rc = DDERR_OUTOFMEMORY;
5186 }
5187 }
5188 }
5189 else
5190 {
5191 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5192 {
5193 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5194 {
5195 if(pSData->pData != lpData)
5196 {
5197 // Change of IUNKOWNPOINTER => release old and add ref to new one
5198 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5199 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5200 pSData->pData = lpData;
5201 }
5202 pSData->dwFlags = dwFlags; // Update the flags, size is the same
5203 }
5204 else
5205 {
5206 // Replace IUNKOWN through data
5207 pBuffer = malloc(dwDataSize); // get new buffer first
5208 if(NULL!=pBuffer)
5209 {
5210 // release old ref and copy data
5211 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5212 memcpy(pBuffer,lpData,dwDataSize);
5213 pSData->pData = pBuffer;
5214 pSData->dwSize = dwDataSize; // Update the size
5215 pSData->dwFlags = dwFlags; // Update the flags
5216 }
5217 else
5218 rc = DDERR_OUTOFMEMORY;
5219 }
5220 }
5221 else
5222 {
5223 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5224 {
5225 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
5226 free(pSData->pData);
5227 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5228 pSData->pData = lpData;
5229 pSData->dwSize = dwDataSize; // Update the size
5230 pSData->dwFlags = dwFlags; // Update the flags
5231 }
5232 else
5233 {
5234 // Update/Replace data
5235 if(pSData->dwSize!=dwDataSize)
5236 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
5237 else
5238 pBuffer = pSData->pData;
5239
5240 if(NULL!=pBuffer)
5241 {
5242 // release old ref and copy data
5243 memcpy(pBuffer,lpData,dwDataSize);
5244 pSData->pData = pBuffer;
5245 pSData->dwSize = dwDataSize; // Update the size
5246 pSData->dwFlags = dwFlags; // Update the flags
5247 }
5248 else
5249 rc = DDERR_OUTOFMEMORY;
5250 }
5251 }
5252 }
5253 }
5254 else
5255 {
5256 // New data
5257
5258 pSData = new(SURFPRIVATEDATA);
5259 if (NULL!=pSData)
5260 {
5261 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5262 {
5263 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5264 pSData->pData = lpData;
5265 pSData->dwSize = 4;
5266 pSData->dwFlags = dwFlags;
5267 pSData->isValid = TRUE;
5268 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5269 }
5270 else
5271 {
5272 pSData->pData = malloc(dwDataSize);
5273 if(NULL!=pSData->pData)
5274 {
5275 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5276 memcpy(pSData->pData,lpData,dwDataSize);
5277 pSData->dwSize = dwDataSize;
5278 pSData->dwFlags = dwFlags;
5279 pSData->isValid = TRUE;
5280
5281 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
5282 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
5283 pSData) <0)
5284 {
5285 delete(pSData);
5286 rc = DDERR_OUTOFMEMORY;
5287 }
5288 }
5289 else
5290 {
5291 delete(pSData);
5292 rc = DDERR_OUTOFMEMORY;
5293 }
5294 }
5295
5296 }
5297 else
5298 rc = DDERR_OUTOFMEMORY;
5299 }
5300
5301 return rc;
5302}
5303//******************************************************************************
5304//******************************************************************************
5305HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
5306{
5307 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5308 int i;
5309 PSURFPRIVATEDATA pSData;
5310 HRESULT rc;
5311 BOOL bFound = FALSE;
5312
5313 dprintf(("DDRAW: SurfGetPrivateData\n"));
5314
5315 if(NULL==me)
5316 return(DDERR_INVALIDOBJECT);
5317
5318 if((NULL==lpData)||(NULL==lpDataSize))
5319 return(DDERR_INVALIDPARAMS);
5320
5321 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5322 {
5323 i=0;
5324 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5325 {
5326 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5327
5328 if (IsEqualGUID(pSData->guidTag,refGUID))
5329 bFound = TRUE;
5330
5331 i++;
5332 }
5333 }
5334
5335 if(bFound)
5336 {
5337 if(!pSData->isValid)
5338 {
5339 rc =DDERR_EXPIRED;
5340 }
5341 else
5342 {
5343 if(pSData->dwSize > *lpDataSize)
5344 {
5345 // Buffer to small return needed Size
5346 *lpDataSize = pSData->dwSize;
5347 rc = DDERR_MOREDATA;
5348 }
5349 else
5350 {
5351 memcpy(lpData,pSData->pData,pSData->dwSize);
5352 rc = DD_OK;
5353 }
5354 }
5355 }
5356 else
5357 rc = DDERR_NOTFOUND;
5358
5359
5360 return rc;
5361}
5362//******************************************************************************
5363//******************************************************************************
5364HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID)
5365{
5366 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5367 int i;
5368 PSURFPRIVATEDATA pSData;
5369 BOOL bFound = FALSE;
5370
5371 dprintf(("DDRAW: SurfFreePrivateData\n"));
5372
5373 if(NULL==me)
5374 return(DDERR_INVALIDOBJECT);
5375
5376 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5377 {
5378 i=0;
5379 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5380 {
5381 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5382
5383 if (IsEqualGUID(pSData->guidTag,refGUID))
5384 {
5385 bFound = TRUE;
5386
5387 if(pSData->isValid)
5388 {
5389 // delete the data if valid
5390 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5391 {
5392 // pointer to com stored so calll its release
5393 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5394 }
5395 else
5396 {
5397 // Free allocated data
5398 free( pSData->pData);
5399 }
5400 }
5401 // Now remove the entry from the list
5402 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
5403 }
5404 i++;
5405 }
5406 }
5407
5408 return (bFound?DD_OK:DDERR_NOTFOUND);
5409}
5410//******************************************************************************
5411//******************************************************************************
5412HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
5413{
5414 dprintf(("DDRAW: SurfGetUniquenessValue\n"));
5415 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5416 if (NULL==lpValue)
5417 return DDERR_INVALIDPARAMS;
5418
5419 *lpValue = me->dwUniqueValue;
5420 return DD_OK;
5421}
5422//******************************************************************************
5423//******************************************************************************
5424HRESULT WIN32API SurfChangeUniquenessValue(THIS This)
5425{
5426 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5427 int i;
5428 PSURFPRIVATEDATA pSData;
5429
5430
5431 dprintf(("DDRAW: SurfChangeUniquenessValue\n"));
5432 me->dwUniqueValue++;
5433
5434 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5435 {
5436 i=0;
5437 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
5438 {
5439 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5440 if (pSData->dwFlags & DDSPD_VOLATILE)
5441 {
5442 // Data becomes unvalid after a Surface change
5443 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5444 {
5445 // pointer to com stored so call its release
5446 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5447 }
5448 else
5449 {
5450 // Free allocated data
5451 free( pSData->pData);
5452 }
5453 pSData->pData = NULL;
5454 pSData->isValid = FALSE; // set flag to invalid
5455 }
5456 i++;
5457 }
5458 }
5459
5460 return (DD_OK);
5461}
5462
5463
5464
Note: See TracBrowser for help on using the repository browser.