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

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

Updated colorconversion and added some more debugoutput

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