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

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

Fixed bug in locked region handling

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