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

Last change on this file since 8605 was 8605, checked in by sandervl, 23 years ago

correct clipper bugfix

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