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

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

Post resize message in SetCooperativeLevel instead of calling SetWindowPos

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