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

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

Implemented new colorconversion routine and fixed bug in fastblt function.
Changed the palettehandling code

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