source: trunk/src/ddraw/OS2SURFACE.CPP@ 522

Last change on this file since 522 was 522, checked in by sandervl, 26 years ago

divewrap bugfixes + removal of FS save/restore macro calls

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