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

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

Changess in basic implementation of the IDrectDraw class
MS does assume 2 Vtables at the end and MS tools seam to use internal
knownledge of the implmentation. DDCAPS is one butn thsi does work/start now.

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