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

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

Uses DIVEWRAP and fixed bug in surface generation (not setting up all values (Pixelformat))

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