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

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

Changed to use ODINCRT macros to preserve FS, but still does crash

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