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

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

Changhed from Isequence to DPA for managing rectangles and surfaces

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