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

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

Changed to from IRectangel to new DDRectangle type

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