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

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

clipper bugfix

File size: 194.9 KB
Line 
1/* $Id: OS2SURFACE.CPP,v 1.41 2002-06-08 11:45:19 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 temp = pRectl[i].yTop;
2482 pRectl[i].yTop = dest->DDSurfaceDesc.dwHeight - pRectl[i].yBottom;
2483 pRectl[i].yBottom = dest->DDSurfaceDesc.dwHeight - temp;
2484 dprintf(("(%d,%d)(%d,%d)", pRectl[i].xLeft, pRectl[i].yBottom, pRectl[i].xRight, pRectl[i].yTop));
2485 //clip rectangle must be relative to lScreenPos
2486 pRectl[i].xLeft -= sBlt.lScreenPosX;
2487 pRectl[i].xRight -= sBlt.lScreenPosX;
2488 pRectl[i].yTop -= sBlt.lScreenPosY;
2489 pRectl[i].yBottom -= sBlt.lScreenPosY;
2490 dprintf(("(%d,%d)(%d,%d)", pRectl[i].xLeft, pRectl[i].yBottom, pRectl[i].xRight, pRectl[i].yTop));
2491 }
2492 fChanged = TRUE;
2493 sBlt.ulNumDstRects = lpRgnData->rdh.nCount;
2494 sBlt.pVisDstRects = (PRECTL)&lpRgnData->Buffer;
2495 }
2496 }
2497 }
2498dodiveblit:
2499#ifdef PERFTEST
2500 QueryPerformanceCounter(&liStart);
2501#endif
2502 if(fChanged || memcmp(&sBlt, &dest->sBlt, sizeof(sBlt)-sizeof(PRECTL)-sizeof(ULONG)))
2503 {
2504 dprintf(("Setting up blitter: src (%d,%d)(%d,%d)", sBlt.ulSrcPosX, sBlt.ulSrcPosY, sBlt.ulSrcWidth, sBlt.ulSrcHeight));
2505 dprintf(("Setting up blitter: dest (%d,%d)(%d,%d)", sBlt.lScreenPosX, sBlt.lScreenPosY, sBlt.ulDstWidth, sBlt.ulDstHeight));
2506 rc = DiveSetupBlitter(dest->hDive, &sBlt);
2507 if(rc) {
2508 dprintf(("DiveSetupBlitter returned %d", rc));
2509 return(DD_OK);
2510 }
2511 sBlt.ulNumDstRects = DIVE_FULLY_VISIBLE;
2512 sBlt.pVisDstRects = NULL;
2513 memcpy(&dest->sBlt, &sBlt, sizeof(sBlt));
2514 }
2515 dprintf(("DiveBlitImage %x %d->%d", dest->hDive, src->diveBufNr, dest->diveBufNr));
2516 rc = DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2517 if(rc) {
2518 dprintf(("DiveBlitImage returned %d", rc));
2519 return(DD_OK);
2520 }
2521#ifdef PERFTEST
2522 QueryPerformanceCounter(&liEnd);
2523 if(liEnd.HighPart == liStart.HighPart) {
2524 if(average == 0) {
2525 average = (liEnd.LowPart - liStart.LowPart);
2526 }
2527 else average = (average + (liEnd.LowPart - liStart.LowPart))/2;
2528 }
2529#endif
2530 return DD_OK;
2531 }
2532 }
2533
2534 //TODO: do we need to check the source for clipping information in case
2535 // the app wants to copy from the frame buffer?
2536 if(dest->lpClipper)
2537 {
2538 DWORD rgnsize;
2539 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, NULL, &rgnsize) == DD_OK)
2540 {
2541 LPRGNDATA lpRgnData = (LPRGNDATA)alloca(rgnsize);
2542 if(lpRgnData == NULL) {
2543 DebugInt3();
2544 goto doblit;
2545 }
2546 if(ClipGetClipList((IDirectDrawClipper*)dest->lpClipper, NULL, lpRgnData, &rgnsize) == DD_OK)
2547 {
2548 RECT newdest, newsrc;
2549 LPRECT lpClipRect = (LPRECT)&lpRgnData->Buffer;
2550
2551#ifdef PERFTEST
2552 QueryPerformanceCounter(&liStart);
2553#endif
2554 for(i=0;i<lpRgnData->rdh.nCount;i++)
2555 {
2556 if(IntersectRect(&newdest, &DestRect, &lpClipRect[i]) == TRUE)
2557 {
2558 //TODO: This is not correct for stretching blits
2559 if(lpSrcRect) {
2560 newsrc.left = SrcRect.left + (newdest.left - DestRect.left);
2561 newsrc.top = SrcRect.top + (newdest.top - DestRect.top);
2562 newsrc.right = newsrc.left + RECT_WIDTH(&newdest);
2563 newsrc.bottom = newsrc.top + RECT_HEIGHT(&newdest);
2564 }
2565// DDSURFACEDESC2 surfdesc = {0};
2566// SurfLock4(dest, &newdest, &surfdesc, 0, 0);
2567
2568 ret = SurfDoBlt(This, &newdest, lpDDSrcSurface, (lpSrcRect) ? &newsrc : NULL, dwFlags, lpDDBltFx);
2569 if(ret != DD_OK) {
2570 break;
2571 }
2572// SurfUnlock(dest, surfdesc.lpSurface);
2573 }
2574 }
2575#ifdef PERFTEST
2576 if(liEnd.HighPart == liStart.HighPart) {
2577 QueryPerformanceCounter(&liEnd);
2578 if(average == 0) {
2579 average = (liEnd.LowPart - liStart.LowPart);
2580 }
2581 else average = (average + (liEnd.LowPart - liStart.LowPart))/2;
2582 }
2583#endif
2584
2585 return ret;
2586 }
2587 }
2588 }
2589doblit:
2590 return SurfDoBlt(This, &DestRect, lpDDSrcSurface, (lpSrcRect) ? &SrcRect : NULL, dwFlags, lpDDBltFx);
2591}
2592//******************************************************************************
2593//******************************************************************************
2594HRESULT WIN32API SurfDoBlt(THIS This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
2595 LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
2596{
2597 // We have determine between 3 different blit senarios.
2598 // 1. Blitting between Divebuffers (Front/Backbuffer and primary surface)
2599 // 2. Blitting between memory and Divebuffers (Front/Backbuffer and primary surface).
2600 // 3. Blitting between memory buffers.
2601 // 1 and 3 are easy. DiveBlitImage or memcpy will do the job for non transparent blits
2602 // 2 is now also easy as we do colorconverion via Dive after each unlocking of a surface
2603 // The advantage is that we don't have to call DiveSetupBlitter each time. The Blitter will be
2604 // setup only when the screen resolution is changed by ddraw. I guess we should see a big performance
2605 // increase by doing it this way, unless the software blits directly from memory to the primary surface)
2606 // But even then this could be faster as the SetupBlitter call is timeconsumeing and DIVE does emulate
2607 // the blit in SW anyway as there is no interface in the driver to blit with HW support from the sysmem.
2608
2609 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
2610 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
2611
2612 int x, i, BlitWidth, BlitHeight;
2613 char *pBltPos, *pSrcPos;
2614 DDSURFACEDESC2 DestSurfaceDesc, SrcSurfaceDesc;
2615 BOOL Found;
2616 DWORD dwSrcColor, dwDestColor;
2617
2618 dprintf(("DDRAW: SurfDoBlt To Surf %08X, from Surf %08X\n",dest,src));
2619 if ( (NULL!=lpDestRect)&& (NULL!=lpSrcRect))
2620 dprintf(("DDRAW: SurfDoBlt to (%d,%d)(%d,%d) at %08X from (%d,%d)(%d,%d) at %08X\n", lpDestRect->left, lpDestRect->top,
2621 lpDestRect->right, lpDestRect->bottom, dest, lpSrcRect->left, lpSrcRect->top,
2622 lpSrcRect->right, lpSrcRect->bottom, src));
2623
2624 DestSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2625 SrcSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
2626
2627 // First check the simple first
2628
2629 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC); // FIXME: can't handle right now
2630
2631 if(dwFlags & DDBLT_COLORFILL)
2632 {
2633 dprintf(("DDRAW: ColorFill\n"));
2634 if((NULL==lpDDBltFx)||(lpDDBltFx->dwSize!=sizeof(DDBLTFX)) )
2635 return DDERR_INVALIDPARAMS;
2636
2637 dest->DoColorFill(lpDestRect,lpDDBltFx->dwFillColor);
2638
2639 return(DD_OK); // according to the M$ DDK only one flag shall/can be set.
2640 } // end of colorfill
2641
2642 if (dwFlags & DDBLT_DEPTHFILL)
2643 {
2644 dprintf(("DDRAW: DepthFill\n"));
2645 #ifdef USE_OPENGL
2646 GLboolean ztest;
2647 // Todo support more than one Z-Buffer
2648 // Clears the screen
2649 dprintf(("DDRAW: Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth));
2650 glClearDepth(lpDDBltFx->b.dwFillDepth / 65535.0); // We suppose a 16 bit Z Buffer
2651 glGetBooleanv(GL_DEPTH_TEST, &ztest);
2652 glDepthMask(GL_TRUE); // Enables Z writing to be sure to delete also the Z buffer
2653 glClear(GL_DEPTH_BUFFER_BIT);
2654 glDepthMask(ztest);
2655
2656 return (DD_OK);
2657 #endif // USE_OPENGL
2658 }
2659
2660 if(dwFlags & DDBLT_ROP)
2661 {
2662 // HEL and we only support the following ROPS
2663 // SRC_COPY
2664 // BLACKNESS
2665 // WHITENESS
2666 //
2667 if(lpDDBltFx->dwROP & SRCCOPY)
2668 dwFlags = 0; // srccopy is a normal fast blt
2669 else
2670 {
2671 if(lpDDBltFx->dwROP & BLACKNESS)
2672 {
2673 if(1==dest->dwBytesPPDive)
2674 {
2675 // ToDo: Realy implement code to get the correct index for black in 8 Bitmode
2676 dest->DoColorFill(lpDestRect, 0 );
2677 }
2678 else
2679 dest->DoColorFill(lpDestRect, 0);
2680 return DD_OK;
2681 }
2682
2683 if(lpDDBltFx->dwROP & WHITENESS)
2684 {
2685 if(1==dest->dwBytesPPDive)
2686 {
2687 // ToDo: Realy implement code to get the correct index for white in 8 Bitmode
2688 dest->DoColorFill(lpDestRect, 0xFFFFFFFF );
2689 }
2690 else
2691 dest->DoColorFill(lpDestRect, 0xFFFFFFFF);
2692 return (DD_OK);
2693 }
2694
2695 return DDERR_NORASTEROPHW;
2696 }
2697 }
2698
2699 if(NULL==src)
2700 {
2701 dprintf(("DDRAW: Unsupported sourceless FX operation. Flags = 0x%04X\n",dwFlags));
2702
2703 return DD_OK;
2704 }
2705
2706 if( ( (NULL==lpDestRect) && (NULL!=lpSrcRect) ) ||
2707 ( (NULL==lpSrcRect) && (NULL!=lpDestRect) ) )
2708 {
2709 dprintf(("DDRAW: Blitting with scaling\n Not supported.\n"));
2710
2711// return DDERR_NOSTRETCHHW;
2712 }
2713
2714 if( ( RECT_WIDTH(lpDestRect) != RECT_WIDTH(lpSrcRect) ) ||
2715 ( RECT_HEIGHT(lpDestRect) != RECT_HEIGHT(lpSrcRect) )
2716 )
2717 {
2718 // Stretching not supported
2719 dprintf(("DDRAW: No stretched blits\n"));
2720
2721 return DDERR_NOSTRETCHHW;
2722 }
2723
2724 if (dest->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2725 {
2726 dprintf(("DDRAW: Dest is Primary Surface\n"));
2727 if(src->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2728 {
2729 // special Type 1 : Bliting between parts of the screen
2730
2731 dprintf(("DDRAW: Src is Primary Surface\n"));
2732
2733 if( RECT_EQUAL(lpDestRect, lpSrcRect))
2734 return DD_OK; // rects are the same => no blit needed
2735
2736 // Todo: might add transparent blits but I don't think they are used here, so later!
2737
2738 MoveRects( dest->pDiveBuffer,
2739 lpDestRect,
2740 lpSrcRect,
2741 dest->dwBytesPPDive,
2742 dest->dwPitchDB);
2743 // MoveRects in framebuufer if we use colorconversion
2744 if(dest->pFrameBuffer != dest->pDiveBuffer)
2745 {
2746 MoveRects( dest->pFrameBuffer,
2747 lpDestRect,
2748 lpSrcRect,
2749 dest->lpDraw->GetScreenBpp()>>3,
2750 dest->dwPitchFB);
2751 }
2752
2753 // End of Special Type 1 blitting on the screen
2754 }
2755 else
2756 {
2757 if( src->diveBufNr>0)
2758 {
2759 dprintf(("DDRAW: DIVE Blit of all"));
2760 if( (NULL==lpSrcRect)&&( NULL== lpDestRect))
2761 {
2762 // No Rectangles so use Dive to blit everything
2763 // ToDo : Implement transparent blitting but that seams more
2764 // inportant for partial blits.
2765 // If we do this later we could skip this check and don't
2766 // use Dive .This keeps our simpler and smaler
2767 //
2768 DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2769
2770 }
2771 }
2772
2773 // Everything else we do yourselfs
2774 // Type 2 Sysmem to Primarysurface ca also be handled by this
2775
2776 if(!dwFlags)
2777 {
2778 dprintf(("DDRAW: Solid Blit\n"));
2779
2780 dest->BltSolid( dest->pDiveBuffer,
2781 dest->pFrameBuffer,
2782 lpDestRect->top,
2783 lpDestRect->left,
2784 dest->dwPitchDB,
2785 dest->dwPitchFB,
2786 src->pDiveBuffer,
2787 src->pFrameBuffer,
2788 lpSrcRect->top,
2789 lpSrcRect->left,
2790 RECT_WIDTH(lpDestRect),
2791 RECT_HEIGHT(lpDestRect),
2792 src->dwPitchDB,
2793 src->dwPitchFB
2794 );
2795
2796 }
2797 else
2798 {
2799 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2800 (lpDestRect->left * dest->dwBytesPPDive);
2801
2802 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2803 (lpSrcRect->left * src->dwBytesPPDive);
2804
2805 BlitHeight = RECT_HEIGHT(lpDestRect);
2806 BlitWidth = RECT_WIDTH(lpDestRect);
2807 // Transparent Blit
2808 if( (dwFlags &DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE) )
2809 {
2810 dprintf(("DDRAW: Transparent src blit not done yet for primary!!"));
2811 }
2812 else
2813 {
2814 dprintf(("DDRAW: Unhandled Flags Destination colorkey ? 0x%04X",dwFlags));
2815 }
2816 }
2817 } // end of handling blitting to primary
2818 } // end of target primary surface
2819 else
2820 {
2821 if(0==src->diveBufNr)
2822 {
2823 // copy from the screen to a buffer
2824
2825 if( (NULL==lpDestRect) &&
2826 (NULL==lpSrcRect) &&
2827 (dest->diveBufNr>0) )
2828 {
2829 // Blitting everything from frontbuffer to a Divebuffer
2830 // ToDo: Might should add checking for flags here
2831 DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2832 }
2833 else
2834 {
2835 // DIVE => DIVE or Mem => Dive
2836 // or a rectangle from streen to a buffer can be handelt in the same way
2837 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2838 (lpDestRect->left * dest->dwBytesPPDive);
2839
2840 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2841 (lpSrcRect->left * src->dwBytesPPDive);
2842
2843 BlitHeight = RECT_HEIGHT(lpDestRect);
2844 BlitWidth = RECT_WIDTH(lpDestRect);
2845
2846 // Check for transparent blit
2847 if(!dwFlags)
2848 {
2849 dest->BltSolid( dest->pDiveBuffer,
2850 dest->pFrameBuffer,
2851 lpDestRect->top,
2852 lpDestRect->left,
2853 dest->dwPitchDB,
2854 dest->dwPitchFB,
2855 src->pDiveBuffer,
2856 src->pFrameBuffer,
2857 lpSrcRect->top,
2858 lpSrcRect->left,
2859 RECT_WIDTH(lpDestRect),
2860 RECT_HEIGHT(lpDestRect),
2861 src->dwPitchDB,
2862 src->dwPitchFB
2863 );
2864 }
2865 else
2866 {
2867 dprintf(("DDRAW: Transblt not done yet"));
2868 if(dwFlags & DDBLT_KEYSRC)
2869 {
2870 if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT))
2871 {
2872 }
2873 }
2874 else
2875 {
2876 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2877 {
2878 }
2879 else
2880 {
2881 }
2882 }
2883 }
2884 }
2885 } // end handling source screen
2886 else
2887 {
2888 // DIVE => DIVE or Mem => Dive can be handelt in the same way
2889
2890 if( (src->pDiveBuffer == dest->pDiveBuffer) &&
2891 (intersects(lpDestRect, lpSrcRect) ) )
2892 {
2893 // Overlapping rects on the same surface ?
2894
2895 // ToDo : Maybe implement all the fancy blit flags here too ? ;)
2896
2897 MoveRects( dest->pDiveBuffer,
2898 lpDestRect,
2899 lpSrcRect,
2900 dest->dwBytesPPDive,
2901 dest->dwPitchDB);
2902
2903 // MoveRects in framebuufer if we use colorconversion
2904 if(dest->pFrameBuffer != dest->pDiveBuffer)
2905 {
2906 MoveRects( dest->pFrameBuffer,
2907 lpDestRect,
2908 lpSrcRect,
2909 dest->lpDraw->GetScreenBpp()>>3,
2910 dest->dwPitchFB);
2911 }
2912 return DD_OK;
2913 }
2914
2915 // Check for transparent blit
2916 if(!dwFlags)
2917 {
2918 dest->BltSolid( dest->pDiveBuffer,
2919 dest->pFrameBuffer,
2920 lpDestRect->top,
2921 lpDestRect->left,
2922 dest->dwPitchDB,
2923 dest->dwPitchFB,
2924 src->pDiveBuffer,
2925 src->pFrameBuffer,
2926 lpSrcRect->top,
2927 lpSrcRect->left,
2928 RECT_WIDTH(lpDestRect),
2929 RECT_HEIGHT(lpDestRect),
2930 src->dwPitchDB,
2931 src->dwPitchFB
2932 );
2933 }
2934 else
2935 {
2936 pBltPos = (char*) dest->pDiveBuffer + (lpDestRect->top * dest->dwPitchDB) +
2937 (lpDestRect->left * dest->dwBytesPPDive);
2938
2939 pSrcPos = (char*) src->pDiveBuffer + (lpSrcRect->top * src->dwPitchDB) +
2940 (lpSrcRect->left * src->dwBytesPPDive);
2941
2942 BlitHeight = RECT_HEIGHT(lpDestRect);
2943 BlitWidth = RECT_WIDTH(lpDestRect);
2944 DWORD dwPitch = dest->dwPitchDB;
2945
2946 if(dwFlags &DDBLT_ROTATIONANGLE)
2947 {
2948 return DDERR_NOROTATIONHW;
2949 }
2950
2951 if(dwFlags & DDBLT_DDFX)
2952 {
2953 DWORD dwFx;
2954
2955 dwFlags &= ~DDBLT_DDFX; // remove the handled flag
2956
2957 if( NULL==lpDDBltFx)
2958 return DDERR_INVALIDPARAMS;
2959
2960 dwFx = lpDDBltFx->dwDDFX;
2961
2962 // Remove unsupported Flags
2963 dwFx &= ~(DDBLTFX_ARITHSTRETCHY | // Not streach support
2964 DDBLTFX_ZBUFFERBASEDEST | // All ZBuffer flags are not
2965 DDBLTFX_ZBUFFERRANGE | // implementet in M$ Dx 6
2966 DDBLTFX_NOTEARING ); // No sync with VRetrace yet
2967
2968 if(dwFx & DDBLTFX_ROTATE180)
2969 {
2970 // 180 degree turn is a mix of a flip up/down and one left/right
2971 dwFx |= (DDBLTFX_MIRRORUPDOWN | DDBLTFX_MIRRORLEFTRIGHT);
2972 dwFx &= ~DDBLTFX_ROTATE180; // remove handled flag
2973 }
2974 if(dwFx & DDBLTFX_MIRRORUPDOWN)
2975 {
2976 // switching the the direction can be integrated with other flags
2977 dwPitch = -dwPitch;
2978 pBltPos = (char*) dest->pDiveBuffer +
2979 ((lpDestRect->top +BlitHeight)* dest->dwPitchDB) +
2980 (lpDestRect->left * dest->dwBytesPPDive);
2981
2982 dwFx &= ~DDBLTFX_MIRRORUPDOWN; // remove handled flag
2983 }
2984
2985 if(dwFx & DDBLTFX_MIRRORLEFTRIGHT)
2986 {
2987 // 180 degree turn or a LR Mirroring
2988 // don't support any other dwFlags like transparent at the moment
2989
2990 switch(dest->dwBytesPPDive)
2991 {
2992 case 1:
2993 while(BlitHeight--)
2994 {
2995 x = BlitWidth;
2996 while(x)
2997 {
2998 pBltPos[BlitWidth-x] = pSrcPos[x];
2999 x--;
3000 }
3001 pBltPos += dwPitch;
3002 pSrcPos += src->dwPitchDB;
3003 }
3004 break;
3005 case 2:
3006 while(BlitHeight--)
3007 {
3008 x = BlitWidth;
3009 while(x)
3010 {
3011 ((USHORT*)pBltPos)[BlitWidth-x] = ((USHORT*)pSrcPos)[x];
3012 x--;
3013 }
3014 pBltPos += dwPitch;
3015 pSrcPos += src->dwPitchDB;
3016 }
3017 break;
3018 case 3:
3019 BlitWidth *= 3;
3020 while(BlitHeight--)
3021 {
3022 x = BlitWidth;
3023 while(x)
3024 {
3025 pBltPos[BlitWidth-x] = pSrcPos[x-2];
3026 x--;
3027 pBltPos[BlitWidth-x] = pSrcPos[x];
3028 x--;
3029 pBltPos[BlitWidth-x] = pSrcPos[x+2];
3030 x--;
3031 }
3032 pBltPos += dwPitch;
3033 pSrcPos += src->dwPitchDB;
3034 }
3035 break;
3036 case 4:
3037 while(BlitHeight--)
3038 {
3039 x = BlitWidth;
3040 while(x)
3041 {
3042 ((DWORD*)pBltPos)[BlitWidth-x] = ((DWORD*)pSrcPos)[x];
3043 x--;
3044 }
3045 pBltPos += dwPitch;
3046 pSrcPos += src->dwPitchDB;
3047 }
3048 break;
3049 } // end switch
3050 //if(dest->lpVtbl == dest->Vtbl4)
3051 // dest->Vtbl4->ChangeUniquenessValue(dest);
3052 return DD_OK;
3053 }
3054
3055 #ifdef DEBUG
3056 if(dwFx)
3057 _dump_DDBLTFX(dwFx);
3058 #endif
3059 // We ignore unhandled flags at the moment
3060 }
3061
3062 if( (dwFlags & DDBLT_KEYSRC) |
3063 (dwFlags & DDBLT_KEYSRCOVERRIDE) )
3064 {
3065 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
3066 {
3067
3068 if( NULL==lpDDBltFx)
3069 return DDERR_INVALIDPARAMS;
3070
3071 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
3072
3073 // We work like the HEL and test only the low value
3074 dwSrcColor = lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue;
3075
3076 }
3077 else
3078 {
3079
3080 dwFlags &= ~DDBLT_KEYSRC;
3081
3082 // Not sure if that is OK maybe check if one is set ?
3083 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT)) return DDERR_WRONGPARAM;?
3084
3085 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
3086 }
3087
3088 // ToDo : We currently indicate that we don't support
3089 // DDBLT_KEYDEST but HEL does change that!
3090 // also add this key in the get/setColorKey functions
3091
3092 if( (dwFlags & DDBLT_KEYDEST) |
3093 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
3094 {
3095 // Source and dest color keying SLOW!!!
3096 if(dwFlags & DDBLT_KEYDESTOVERRIDE)
3097 {
3098 if( NULL==lpDDBltFx)
3099 return DDERR_INVALIDPARAMS;
3100
3101 dwFlags &= ~DDBLT_KEYDESTOVERRIDE;
3102
3103 // We work like the HEL and test only the low value
3104 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
3105
3106 }
3107 else
3108 {
3109
3110 dwFlags &= ~DDBLT_KEYDEST;
3111
3112 // Not sure if that is OK maybe check if one is set ?
3113 // if(!(Dest->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
3114
3115 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3116 }
3117
3118 // This will be be slow maybe move to ASM ?
3119 // using MMX should be much faster
3120 switch(dest->dwBytesPPDive)
3121 {
3122 case 1:
3123 while(BlitHeight--)
3124 {
3125 x = 0;
3126 while(x<BlitWidth)
3127 {
3128 if(pSrcPos[x] != (char) dwSrcColor)
3129 {
3130 if(pBltPos[x] != (char) dwDestColor)
3131 pBltPos[x] = pSrcPos[x];
3132 }
3133 x++;
3134 }
3135 pBltPos += dwPitch;
3136 pSrcPos += src->dwPitchDB;
3137 }
3138 break;
3139 case 2:
3140 while(BlitHeight--)
3141 {
3142 x = 0;
3143 while(x<BlitWidth)
3144 {
3145 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3146 {
3147 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3148 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3149 }
3150 x++;
3151 }
3152 pBltPos += dwPitch;
3153 pSrcPos += src->dwPitchDB;
3154 }
3155 break;
3156 case 3:
3157 {
3158 char *pSC, *pDC;
3159 pSC = (char*)&dwSrcColor;
3160 pDC = (char*)&dwDestColor;
3161 BlitWidth *=3;
3162
3163 while(BlitHeight--)
3164 {
3165 x = 0;
3166
3167 while(x<BlitWidth)
3168 {
3169 if( (pSrcPos[x] != pSC[1]) &&
3170 (pSrcPos[x+1] != pSC[2]) &&
3171 (pSrcPos[x+2] != pSC[3])
3172 )
3173 {
3174 if( (pBltPos[x] != pDC[1]) &&
3175 (pBltPos[x+1] != pDC[2]) &&
3176 (pBltPos[x+2] != pDC[3])
3177 )
3178 {
3179 pBltPos[x] = pSrcPos[x];
3180 pBltPos[x+1] = pSrcPos[x+2];
3181 pBltPos[x+1] = pSrcPos[x+2];
3182 }
3183 }
3184 x +=3;
3185 }
3186 pBltPos += dwPitch;
3187 pSrcPos += src->dwPitchDB;
3188 }
3189 break;
3190 }
3191 case 4:
3192 while(BlitHeight--)
3193 {
3194 x = 0;
3195 while(x<BlitWidth)
3196 {
3197 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3198 {
3199 if(((DWORD*)pBltPos)[x] != dwDestColor)
3200 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3201 }
3202 x++;
3203 }
3204 pBltPos += dwPitch;
3205 pSrcPos += src->dwPitchDB;
3206 }
3207 break;
3208 } // End switch
3209 }
3210 else
3211 {
3212 // This will be be slow maybe move to ASM ?
3213 // using MMX should be much faster
3214 switch(dest->dwBytesPPDive)
3215 {
3216 case 1:
3217 while(BlitHeight--)
3218 {
3219 x = 0;
3220 while(x<BlitWidth)
3221 {
3222 if(pSrcPos[x] != (char) dwSrcColor)
3223 {
3224 pBltPos[x] = pSrcPos[x];
3225 }
3226 x++;
3227 }
3228 pBltPos += dwPitch;
3229 pSrcPos += src->dwPitchDB;
3230 }
3231 break;
3232 case 2:
3233 while(BlitHeight--)
3234 {
3235 x = 0;
3236 while(x<BlitWidth)
3237 {
3238 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3239 {
3240 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3241 }
3242 x++;
3243 }
3244 pBltPos += dwPitch;
3245 pSrcPos += src->dwPitchDB;
3246 }
3247 break;
3248 case 3:
3249 {
3250 char *pSC, *pDC;
3251 pSC = (char*)&dwSrcColor;
3252 pDC = (char*)&dwDestColor;
3253 BlitWidth *=3;
3254
3255 while(BlitHeight--)
3256 {
3257 x = 0;
3258
3259 while(x<BlitWidth)
3260 {
3261 if( (pSrcPos[x] != pSC[1]) &&
3262 (pSrcPos[x+1] != pSC[2]) &&
3263 (pSrcPos[x+2] != pSC[3])
3264 )
3265 {
3266 pBltPos[x] = pSrcPos[x];
3267 pBltPos[x+1] = pSrcPos[x+2];
3268 pBltPos[x+1] = pSrcPos[x+2];
3269 }
3270 x +=3;
3271 }
3272 pBltPos += dwPitch;
3273 pSrcPos += src->dwPitchDB;
3274 }
3275 break;
3276 }
3277 case 4:
3278 while(BlitHeight--)
3279 {
3280 x = 0;
3281 while(x<BlitWidth)
3282 {
3283 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3284 {
3285 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3286 }
3287 x++;
3288 }
3289 pBltPos += dwPitch;
3290 pSrcPos += src->dwPitchDB;
3291 }
3292 break;
3293 } // End switch
3294 // Only Source colorkey
3295 }
3296 // if(dest->lpVtbl == dest->Vtbl4)
3297 // dest->Vtbl4->ChangeUniquenessValue(dest);
3298 return DD_OK;
3299 }
3300
3301 if( (dwFlags & DDBLT_KEYDEST) |
3302 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
3303 {
3304 // Dest color keying SLOW!!!
3305 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
3306 {
3307 if( NULL==lpDDBltFx)
3308 return DDERR_INVALIDPARAMS;
3309
3310 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
3311
3312 // We work like the HEL and test only the low value
3313 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
3314
3315 }
3316 else
3317 {
3318
3319 dwFlags &= ~DDBLT_KEYDEST;
3320
3321 // Not sure if that is OK maybe check if one is set ?
3322 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
3323
3324 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3325 }
3326
3327 // This will be be slow maybe move to ASM ?
3328 // using MMX should be much faster
3329 switch(dest->dwBytesPPDive)
3330 {
3331 case 1:
3332 while(BlitHeight--)
3333 {
3334 x = 0;
3335 while(x<BlitWidth)
3336 {
3337 if(pBltPos[x] != (char) dwDestColor)
3338 pBltPos[x] = pSrcPos[x];
3339 x++;
3340 }
3341 pBltPos += dwPitch;
3342 pSrcPos += src->dwPitchDB;
3343 }
3344 break;
3345 case 2:
3346 while(BlitHeight--)
3347 {
3348 x = 0;
3349 while(x<BlitWidth)
3350 {
3351 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3352 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3353 x++;
3354 }
3355 pBltPos += dwPitch;
3356 pSrcPos += src->dwPitchDB;
3357 }
3358 break;
3359 case 3:
3360 {
3361 char *pSC, *pDC;
3362 pSC = (char*)&dwSrcColor;
3363 pDC = (char*)&dwDestColor;
3364 BlitWidth *=3;
3365
3366 while(BlitHeight--)
3367 {
3368 x = 0;
3369
3370 while(x<BlitWidth)
3371 {
3372 if( (pBltPos[x] != pDC[1]) &&
3373 (pBltPos[x+1] != pDC[2]) &&
3374 (pBltPos[x+2] != pDC[3])
3375 )
3376 {
3377 pBltPos[x] = pSrcPos[x];
3378 pBltPos[x+1] = pSrcPos[x+2];
3379 pBltPos[x+1] = pSrcPos[x+2];
3380 }
3381 x +=3;
3382 }
3383 pBltPos += dwPitch;
3384 pSrcPos += src->dwPitchDB;
3385 }
3386 break;
3387 }
3388 case 4:
3389 while(BlitHeight--)
3390 {
3391 x = 0;
3392 while(x<BlitWidth)
3393 {
3394 if( ((DWORD*)pBltPos)[x] != dwDestColor)
3395 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3396 x++;
3397 }
3398 pBltPos += dwPitch;
3399 pSrcPos += src->dwPitchDB;
3400 }
3401 break;
3402 } // End switch
3403 } // End of Dest ColorKey
3404
3405
3406 }// end handling dwFlags
3407 } // End handling source not Framebuffer
3408
3409 }// end handling destination not framebuffer
3410
3411 // if(dest->lpVtbl == dest->Vtbl4)
3412 // dest->Vtbl4->ChangeUniquenessValue(dest);
3413 return(DD_OK);
3414}
3415//******************************************************************************
3416//******************************************************************************
3417HRESULT WIN32API SurfBltBatch(THIS, LPDDBLTBATCH, DWORD, DWORD )
3418{
3419 dprintf(("DDRAW: SurfBltBatch Not implemented by M$\n"));
3420
3421 return(DD_OK);
3422}
3423//******************************************************************************
3424//******************************************************************************
3425HRESULT WIN32API SurfBltFast( THIS This ,
3426 DWORD dwX,
3427 DWORD dwY,
3428 LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
3429 LPRECT lpSrcRect,
3430 DWORD dwTrans)
3431{
3432 dprintf(("DDRAW: SurfBltFast=>"));
3433 return SurfBltFast4( This,
3434 dwX,
3435 dwY,
3436 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
3437 lpSrcRect,
3438 dwTrans);
3439}
3440//******************************************************************************
3441//******************************************************************************
3442HRESULT WIN32API SurfBltFast3(THIS This ,
3443 DWORD dwX,
3444 DWORD dwY,
3445 LPDIRECTDRAWSURFACE3 lpDDSrcSurface,
3446 LPRECT lpSrcRect,
3447 DWORD dwTrans)
3448{
3449 dprintf(("DDRAW: SurfBltFast3=>"));
3450 return SurfBltFast4( This,
3451 dwX,
3452 dwY,
3453 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
3454 lpSrcRect,
3455 dwTrans);
3456}
3457//******************************************************************************
3458//******************************************************************************
3459HRESULT WIN32API SurfBltFast4( THIS This,
3460 DWORD dwX,
3461 DWORD dwY,
3462 LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
3463 LPRECT lpSrcRect,
3464 DWORD dwTrans)
3465{
3466 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
3467 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
3468 RECTL SrcRect;
3469 char *pBltPos, *pSrcPos;
3470 DWORD dwDestColor, dwSrcColor, BlitWidth, BlitHeight, x;
3471
3472 dprintf(("DDRAW: SurfBltFast4 %08X at(%d/%d) onto %08X with flags %08X\n",src, dwX,dwY, dest, dwTrans));
3473
3474 if( (NULL == lpDDSrcSurface) ||
3475 ((LONG)dwX < 0) || ((LONG)dwY < 0) ||
3476 (dwX > dest->width) ||
3477 (dwY > dest->height))
3478 {
3479 dprintf(("DDRAW: Invalid Parameters %08X, %d %d", lpDDSrcSurface ,dest->width , dest->height));
3480 return DDERR_INVALIDPARAMS;
3481 }
3482
3483 if (NULL != lpSrcRect)
3484 {
3485 memcpy(&SrcRect,lpSrcRect,sizeof(RECTL) );
3486 }
3487 else
3488 {
3489 SrcRect.top = 0;
3490 SrcRect.left = 0;
3491 SrcRect.bottom = src->height;
3492 SrcRect.right = src->width;
3493 }
3494
3495 // Todo: Test for locked src/dest
3496
3497 pBltPos = (char*) dest->pDiveBuffer + (dwY * dest->dwPitchDB) +
3498 (dwX * dest->dwBytesPPDive);
3499
3500 pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
3501 (SrcRect.left * src->dwBytesPPDive);
3502
3503 BlitHeight = SrcRect.bottom - SrcRect.top;
3504 BlitWidth = (SrcRect.right - SrcRect.left) * src->dwBytesPPDive;
3505
3506 // Remove unsupported wait flag
3507 dwTrans &= ~DDBLTFAST_WAIT;
3508
3509 if(DDBLTFAST_NOCOLORKEY == dwTrans )
3510 {
3511 dprintf(( "Solid Blit, %d bits => %d bytes per line\n",
3512 (SrcRect.right - SrcRect.left),
3513 BlitWidth) );
3514 #ifdef USE_ASM
3515 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
3516 dest->dwPitchDB,
3517 src->dwPitchDB);
3518 #else
3519 // Solid Blit
3520 while(1)
3521 {
3522 memcpy(pBltPos,pSrcPos,BlitWidth);
3523 pBltPos += dest->dwPitchDB;
3524 pSrcPos += src->dwPitchDB;
3525 if(! (--BlitHeight))
3526 break;
3527 }
3528 #endif
3529
3530 }
3531 else
3532 {
3533 dprintf(("DDRAW: TransBlit\n"));
3534
3535 if(dwTrans & DDBLTFAST_SRCCOLORKEY)
3536 {
3537 dprintf(("DDRAW: Trans SRC\n"));
3538 // transparent source
3539 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
3540 if(dwTrans & DDBLTFAST_DESTCOLORKEY)
3541 {
3542 dprintf(("DDRAW: And Dest Colorkey"));
3543 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3544 // Source and dest colorkeying
3545 switch(dest->dwBytesPPDive)
3546 {
3547 case 1:
3548 while(BlitHeight--)
3549 {
3550 x = 0;
3551 while(x<BlitWidth)
3552 {
3553 if(pSrcPos[x] != (char) dwSrcColor)
3554 {
3555 if(pBltPos[x] != (char) dwDestColor)
3556 pBltPos[x] = pSrcPos[x];
3557 }
3558 x++;
3559 }
3560 pBltPos += dest->dwPitchDB;
3561 pSrcPos += src->dwPitchDB;
3562 }
3563 break;
3564 case 2:
3565 while(BlitHeight--)
3566 {
3567 x = 0;
3568 while(x<BlitWidth)
3569 {
3570 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3571 {
3572 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3573 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3574 }
3575 x++;
3576 }
3577 pBltPos += dest->dwPitchDB;
3578 pSrcPos += src->dwPitchDB;
3579 }
3580 break;
3581 case 3:
3582 {
3583 char *pSC, *pDC;
3584 pSC = (char*)&dwSrcColor;
3585 pDC = (char*)&dwDestColor;
3586 BlitWidth *=3;
3587
3588 while(BlitHeight--)
3589 {
3590 x = 0;
3591
3592 while(x<BlitWidth)
3593 {
3594 if( (pSrcPos[x] != pSC[1]) &&
3595 (pSrcPos[x+1] != pSC[2]) &&
3596 (pSrcPos[x+2] != pSC[3])
3597 )
3598 {
3599 if( (pBltPos[x] != pDC[1]) &&
3600 (pBltPos[x+1] != pDC[2]) &&
3601 (pBltPos[x+2] != pDC[3])
3602 )
3603 {
3604 pBltPos[x] = pSrcPos[x];
3605 pBltPos[x+1] = pSrcPos[x+2];
3606 pBltPos[x+1] = pSrcPos[x+2];
3607 }
3608 }
3609 x +=3;
3610 }
3611 pBltPos += dest->dwPitchDB;
3612 pSrcPos += src->dwPitchDB;
3613 }
3614 break;
3615 }
3616 case 4:
3617 while(BlitHeight--)
3618 {
3619 x = 0;
3620 while(x<BlitWidth)
3621 {
3622 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3623 {
3624 if(((DWORD*)pBltPos)[x] != dwDestColor)
3625 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3626 }
3627 x++;
3628 }
3629 pBltPos += dest->dwPitchDB;
3630 pSrcPos += src->dwPitchDB;
3631 }
3632 break;
3633 } // End switch
3634 }
3635 else
3636 {
3637 // This MMX detection should be moved into OS2Draw
3638 // and into the surface constructor a setup for blitting pointers
3639 dprintf(("DDRAW: Only Src ColorKey"));
3640 switch(dest->dwBytesPPDive)
3641 {
3642 case 1:
3643 if (CPUHasMMX())
3644 while (BlitHeight--)
3645 {
3646 BlitColorKey8MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3647 pBltPos += dest->dwPitchDB;
3648 pSrcPos += src->dwPitchDB;
3649 }
3650 else
3651 while (BlitHeight--)
3652 {
3653 BlitColorKey8((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3654 pBltPos += dest->dwPitchDB;
3655 pSrcPos += src->dwPitchDB;
3656 }
3657 break;
3658 case 2:
3659
3660 if (CPUHasMMX())
3661 while(BlitHeight--)
3662 {
3663 BlitColorKey16MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3664 pBltPos += dest->dwPitchDB;
3665 pSrcPos += src->dwPitchDB;
3666 }
3667 else
3668 while(BlitHeight--)
3669 {
3670 BlitColorKey16((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3671 pBltPos += dest->dwPitchDB;
3672 pSrcPos += src->dwPitchDB;
3673 }
3674 break;
3675 case 3:
3676 char *pSC;
3677 pSC = (char*)&dwSrcColor;
3678 BlitWidth *=3;
3679
3680 while(BlitHeight--)
3681 {
3682 x = 0;
3683
3684 while(x<BlitWidth)
3685 {
3686 if( (pSrcPos[x] != pSC[1]) &&
3687 (pSrcPos[x+1] != pSC[2]) &&
3688 (pSrcPos[x+2] != pSC[3])
3689 )
3690 {
3691 pBltPos[x] = pSrcPos[x];
3692 pBltPos[x+1] = pSrcPos[x+1];
3693 pBltPos[x+1] = pSrcPos[x+2];
3694 }
3695 x +=3;
3696 }
3697 pBltPos += dest->dwPitchDB;
3698 pSrcPos += src->dwPitchDB;
3699 }
3700 break;
3701 case 4:
3702 break;
3703 }
3704 }
3705 }
3706 else
3707 {
3708 if (dwTrans & DDBLTFAST_DESTCOLORKEY)
3709 {
3710 dprintf(("DDRAW: DestColorKey\n"));
3711
3712 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3713 switch(dest->dwBytesPPDive)
3714 {
3715 case 1:
3716 while(BlitHeight--)
3717 {
3718 x = 0;
3719 while(x<BlitWidth)
3720 {
3721 if(pBltPos[x] != (char) dwDestColor)
3722 pBltPos[x] = pSrcPos[x];
3723 x++;
3724 }
3725 pBltPos += dest->dwPitchDB;
3726 pSrcPos += src->dwPitchDB;
3727 }
3728 break;
3729 case 2:
3730 while(BlitHeight--)
3731 {
3732 x = 0;
3733 while(x<BlitWidth)
3734 {
3735 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3736 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3737 x++;
3738 }
3739 pBltPos += dest->dwPitchDB;
3740 pSrcPos += src->dwPitchDB;
3741 }
3742 break;
3743 case 3:
3744 {
3745 char *pSC, *pDC;
3746 pSC = (char*)&dwSrcColor;
3747 pDC = (char*)&dwDestColor;
3748 BlitWidth *=3;
3749
3750 while(BlitHeight--)
3751 {
3752 x = 0;
3753
3754 while(x<BlitWidth)
3755 {
3756 if( (pBltPos[x] != pDC[1]) &&
3757 (pBltPos[x+1] != pDC[2]) &&
3758 (pBltPos[x+2] != pDC[3])
3759 )
3760 {
3761 pBltPos[x] = pSrcPos[x];
3762 pBltPos[x+1] = pSrcPos[x+2];
3763 pBltPos[x+1] = pSrcPos[x+2];
3764 }
3765 x +=3;
3766 }
3767 pBltPos += dest->dwPitchDB;
3768 pSrcPos += src->dwPitchDB;
3769 }
3770 break;
3771 }
3772 case 4:
3773 while(BlitHeight--)
3774 {
3775 x = 0;
3776 while(x<BlitWidth)
3777 {
3778 if(((DWORD*)pBltPos)[x] != dwDestColor)
3779 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3780 x++;
3781 }
3782 pBltPos += dest->dwPitchDB;
3783 pSrcPos += src->dwPitchDB;
3784 }
3785 break;
3786 } // End switch
3787 }
3788 else
3789 {
3790 dprintf(("DDRAW: Unexpected Flags"));
3791 }
3792 }
3793 }
3794
3795 // if(dest->lpVtbl == dest->Vtbl4)
3796 // dest->Vtbl4->ChangeUniquenessValue(dest);
3797
3798 return DD_OK;
3799}
3800//******************************************************************************
3801//******************************************************************************
3802HRESULT WIN32API SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
3803{
3804 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3805 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3806
3807 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3808}
3809//******************************************************************************
3810//******************************************************************************
3811HRESULT WIN32API SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface)
3812{
3813 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3814 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3815
3816 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3817}
3818//******************************************************************************
3819//******************************************************************************
3820HRESULT WIN32API SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
3821{
3822
3823 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3824 OS2IDirectDrawSurface *AttachedSurface;
3825 OS2IDirectDrawSurface *SurfaceCursor;
3826 int i;
3827
3828 BOOL Found = FALSE;
3829 dprintf(("DDRAW: SurfDeleteAttachedSurface\n"));
3830
3831 if((0!=dwFlags)||(NULL==lpDDSurface))
3832 return(DDERR_INVALIDPARAMS);
3833
3834 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
3835 if (AttachedSurface->IsImplicitSurface())
3836 return (DDERR_CANNOTDETACHSURFACE);
3837
3838 if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
3839 !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
3840 {
3841 // Surface seams to be a backbuffer in a flipchain search it
3842
3843 // Goto top of list
3844 if(me->FrontBuffer!=NULL)
3845 {
3846 SurfaceCursor = me->FrontBuffer;
3847 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3848 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3849 }
3850 else
3851 SurfaceCursor = me;
3852
3853 // now iterrate through the list skip first in list as we don't remove the frontbuffer
3854
3855 SurfaceCursor = SurfaceCursor->BackBuffer;
3856 while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
3857 SurfaceCursor = SurfaceCursor->BackBuffer;
3858
3859 if(SurfaceCursor!=NULL)
3860 {
3861 Found = TRUE;
3862 // remove the Surface from the list
3863 SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
3864 if(SurfaceCursor->BackBuffer!=NULL)
3865 {
3866 SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
3867
3868 }
3869 else
3870 {
3871 // we were the last buffer in the list have we been the only backbuffer?
3872 if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
3873 {
3874 // Yepp so "destroy" the flipchain
3875 SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3876 SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3877 }
3878 }
3879 // decrement the backbuffer count of all buffers in the chain in front of us
3880 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3881 {
3882 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3883 SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
3884 }
3885
3886 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3887 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3888 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3889 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
3890 AttachedSurface->lpVtbl->Release(AttachedSurface);
3891
3892 }
3893 } //endif delete back/frontbuffers
3894
3895 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
3896 {
3897 // seams like someone wants a new frontbuffer
3898
3899 // Goto top of list
3900
3901 if(me->FrontBuffer!=NULL)
3902 {
3903 SurfaceCursor = me->FrontBuffer;
3904 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3905 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3906 }
3907 else
3908 SurfaceCursor = me;
3909
3910 if(SurfaceCursor == AttachedSurface)
3911 {
3912 Found = TRUE;
3913 SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
3914 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3915 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3916 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3917 AttachedSurface->lpVtbl->Release(AttachedSurface);
3918 }
3919
3920 }
3921
3922
3923 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) )
3924 {
3925 // Surface seams to be a mipmap
3926 i = 0;
3927 while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found)
3928 {
3929 if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface)
3930 {
3931 Found = TRUE;
3932 DPA_DeletePtr(me->DPA_SurfaceMipMaps,i);
3933 AttachedSurface->lpVtbl->Release(AttachedSurface);
3934 // adjust our info
3935 me->DDSurfaceDesc.dwMipMapCount-- ;
3936 if (!me->DDSurfaceDesc.dwMipMapCount)
3937 {
3938 me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
3939 }
3940 }
3941 i++;
3942 }
3943 }
3944
3945 if(!Found)
3946 {
3947 // Surface seams to be an attached one
3948 i = 0;
3949 while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found)
3950 {
3951 if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface)
3952 {
3953 Found = TRUE;
3954 DPA_DeletePtr(me->DPA_SurfaceAttached,i);
3955 AttachedSurface->lpVtbl->Release(AttachedSurface);
3956 }
3957 i++;
3958 }
3959 }
3960
3961
3962 return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
3963}
3964//******************************************************************************
3965//******************************************************************************
3966HRESULT WIN32API SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
3967{
3968 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3969 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
3970
3971 return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
3972}
3973//******************************************************************************
3974//******************************************************************************
3975HRESULT WIN32API SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
3976{
3977 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3978 OS2IDirectDrawSurface *EnumSurface;
3979 DDSURFACEDESC2 EnumDesc;
3980 int i,count;
3981 HRESULT rc;
3982
3983 dprintf(("DDRAW: SurfEnumAttachedSurfaces\n"));
3984 if (NULL==lpCallBack)
3985 return (DDERR_INVALIDPARAMS);
3986
3987 rc = DDENUMRET_OK;
3988
3989
3990 if(me->BackBuffer != NULL)
3991 {
3992 memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
3993 rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
3994 }
3995
3996 count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps);
3997
3998 if(count>0)
3999 {
4000 i=0;
4001 while( (DDENUMRET_OK == rc) && i<count )
4002 {
4003 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
4004 memcpy( &EnumDesc,
4005 &(EnumSurface->DDSurfaceDesc),
4006 sizeof(DDSURFACEDESC2));
4007 // Calling back into WIN32 app so we had to reset FS
4008 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
4009 i++;
4010 }
4011 }
4012
4013 count = DPA_GetPtrCount(me->DPA_SurfaceAttached);
4014
4015 if(count>0)
4016 {
4017 i=0;
4018 while( (DDENUMRET_OK == rc) && i<count )
4019 {
4020 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
4021 memcpy( &EnumDesc,
4022 &(EnumSurface->DDSurfaceDesc),
4023 sizeof(DDSURFACEDESC2));
4024 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
4025 i++;
4026 }
4027 }
4028
4029 return(DD_OK);
4030}
4031//******************************************************************************
4032//******************************************************************************
4033HRESULT WIN32API SurfEnumOverlayZOrders(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK)
4034{
4035 dprintf(("DDRAW: SurfEnumOverlayZOrders\n"));
4036
4037 return(DD_OK);
4038}
4039//******************************************************************************
4040//******************************************************************************
4041HRESULT WIN32API SurfEnumOverlayZOrders4(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK2)
4042{
4043 dprintf(("DDRAW: SurfEnumOverlayZOrders\n"));
4044
4045 return(DD_OK);
4046}
4047//******************************************************************************
4048//******************************************************************************
4049HRESULT WIN32API SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
4050{
4051 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4052
4053 dprintf(("DDRAW: SurfFlip\n"));
4054
4055 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
4056}
4057//******************************************************************************
4058//******************************************************************************
4059HRESULT WIN32API SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags)
4060{
4061 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4062
4063 dprintf(("DDRAW: SurfFlip\n"));
4064
4065 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
4066}
4067//******************************************************************************
4068//******************************************************************************
4069HRESULT WIN32API SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
4070{
4071 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4072 OS2IDirectDrawSurface *FlipSurface;
4073 OS2IDirectDrawSurface *FlipCursor;
4074 LPVOID Data;
4075 char *pcrFB,*pcFB,*pcrDB,*pcDB;
4076
4077 dprintf(("DDRAW: SurfFlip4\n"));
4078
4079 if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
4080 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
4081 )
4082 {
4083 #ifdef DEBUG
4084 dprintf(("DDRAW: Flip called on none Frontbuffer/Flip surface\n Flags:\n"));
4085 _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
4086 dprintf(("DDRAW: \n"));
4087 #endif
4088 return(DDERR_NOTFLIPPABLE);
4089 }
4090
4091 if(NULL!=lpDDSurf)
4092 {
4093 dprintf(("DDRAW: Check if Surface is in Flipchain!\n"));
4094
4095 // We got an override surface check if it is in the flipchain
4096 FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
4097 FlipCursor = me->BackBuffer;
4098 while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
4099 {
4100 FlipCursor = FlipCursor->BackBuffer;
4101 }
4102
4103 if(FlipCursor!=FlipSurface)
4104 {
4105 dprintf(("DDRAW: Surface not in Flipchain!\n"));
4106
4107 return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
4108 }
4109 }
4110 else
4111 {
4112 FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
4113 dprintf(("DDRAW: Next Surface @ 0x%08X\n",FlipSurface));
4114 }
4115
4116 if((me->fLocked)||(FlipSurface->fLocked))
4117 {
4118 dprintf(("DDRAW: Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked));
4119
4120 return(DDERR_SURFACEBUSY);
4121 }
4122
4123 if (-1 != me->diveBufNr)
4124 {
4125 //dprintf(("DDRAW: DIVE Flipchain DiveBuffer #%d",FlipSurface->diveBufNr));
4126
4127 // we got some DIVE surfaces
4128 // On Dive Buffers More then Double buffering won't get any perf. gain
4129 // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
4130 // Doulebuffering should work best.
4131
4132 //rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
4133 //dprintf(("DDRAW: DiveBlitImage rc = 0x%08X\n"));
4134 SurfBltFast4( me,
4135 0,
4136 0,
4137 (LPDIRECTDRAWSURFACE4)FlipSurface,
4138 NULL,
4139 DDBLTFAST_NOCOLORKEY);
4140
4141 if(NULL==lpDDSurf)
4142 {
4143 // advance in the flipchain if no valid override surface was passed in
4144 // if we reached the end of the flipchain The Frontbuffer is the next to flip to
4145 me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
4146 }
4147 }
4148 else
4149 {
4150 dprintf(("DDRAW: Memory Flipchain"));
4151 // Memory Flipchain
4152 //
4153 // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
4154 //
4155 // We only change the memory pointer to the buffers no need to copy all the data
4156 // So the NextFlip is here allways the Backbuffer so we won't advance this
4157 //
4158 // Sample (triple buffering) : Before Flip After Flip
4159 // Buffer: FB BB TB FB BB TB
4160 // Memory: 11 22 33 22 33 11
4161 //
4162
4163 Data = me->DDSurfaceDesc.lpSurface;
4164 pcrFB = me->pFBreal;
4165 pcFB = me->pFrameBuffer;
4166 pcrDB = me->pDBreal;
4167 pcDB = me->pDiveBuffer;
4168 me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
4169 me->pFBreal = FlipSurface->pFBreal;
4170 me->pFrameBuffer = FlipSurface->pFrameBuffer;
4171 me->pDBreal = FlipSurface->pDBreal;
4172 me->pDiveBuffer = FlipSurface->pDiveBuffer;
4173
4174 if (NULL==lpDDSurf)
4175 {
4176 while (NULL!=FlipSurface->BackBuffer)
4177 {
4178 FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
4179 FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal;
4180 FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer;
4181 FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal;
4182 FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer;
4183 FlipSurface = FlipSurface->BackBuffer;
4184 }
4185 }
4186 FlipSurface->DDSurfaceDesc.lpSurface = Data;
4187 FlipSurface->pFBreal = pcrFB;
4188 FlipSurface->pFrameBuffer = pcFB;
4189 FlipSurface->pDBreal = pcrDB;
4190 FlipSurface->pDiveBuffer = pcDB;
4191 }
4192
4193 return DD_OK;
4194}
4195
4196//******************************************************************************
4197//******************************************************************************
4198HRESULT WIN32API SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
4199 LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
4200{
4201 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4202 dprintf(("DDRAW: SurfGetAttachedSurface\n"));
4203
4204 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
4205}
4206//******************************************************************************
4207//******************************************************************************
4208HRESULT WIN32API SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps,
4209 LPDIRECTDRAWSURFACE3 FAR * lpDDSurf)
4210{
4211 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4212 dprintf(("DDRAW: SurfGetAttachedSurface3\n"));
4213
4214 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
4215}
4216//******************************************************************************
4217//******************************************************************************
4218HRESULT WIN32API SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
4219 LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
4220{
4221 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4222 OS2IDirectDrawSurface *EnumSurface = NULL;
4223 OS2IDirectDrawSurface *AttachedSurface = NULL;
4224 HRESULT rc;
4225 int i;
4226
4227 #ifdef DEBUG
4228 dprintf(("DDRAW: SurfGetAttachedSurface4\n>Requested Caps: "));
4229 _dump_DDSCAPS(lpDDCaps->dwCaps);
4230 dprintf(("DDRAW: \n"));
4231 #endif
4232
4233 if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
4234 {
4235 dprintf(("DDRAW: Invalid params\n\n"));
4236 return (DDERR_INVALIDPARAMS);
4237 }
4238
4239
4240 rc = DD_OK;
4241
4242 if( (me->BackBuffer!=NULL) &&
4243 (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
4244 {
4245 dprintf(("DDRAW: Return Backbuffer\n"));
4246 AttachedSurface = me->BackBuffer;
4247 }
4248
4249 if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0)
4250 {
4251 i=0;
4252 while( i<DPA_GetPtrCount(me->DPA_SurfaceMipMaps) )
4253 {
4254 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
4255 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
4256 {
4257 if(NULL==AttachedSurface)
4258 AttachedSurface = EnumSurface;
4259 else
4260 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
4261 // but function must fail if more then one surface fits
4262
4263 }
4264 i++;
4265 }
4266 }
4267
4268 if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0)
4269 {
4270 i=0;
4271 while( i<DPA_GetPtrCount(me->DPA_SurfaceAttached) )
4272 {
4273 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
4274 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
4275 {
4276 if(NULL==AttachedSurface)
4277 AttachedSurface = EnumSurface;
4278 else
4279 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
4280 // but function must fail if more then one surface fits
4281
4282 }
4283 i++;
4284 }
4285 }
4286
4287 if( (DD_OK==rc) &&
4288 (NULL!=AttachedSurface) )
4289 {
4290 *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
4291 // not sure but as we returned an reference rains usage count
4292 AttachedSurface->lpVtbl->AddRef(AttachedSurface);
4293 }
4294 else
4295 {
4296 *lpDDSurf = NULL;
4297 rc = DDERR_NOTFOUND;
4298 }
4299
4300
4301 return rc;
4302}
4303//******************************************************************************
4304//******************************************************************************
4305HRESULT WIN32API SurfGetBltStatus(THIS This, DWORD)
4306{
4307 dprintf(("DDRAW: SurfGetBltStatus\n"));
4308
4309 return(DD_OK);
4310}
4311//******************************************************************************
4312//******************************************************************************
4313HRESULT WIN32API SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
4314{
4315 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4316
4317 dprintf(("DDRAW: SurfGetCaps\n"));
4318
4319 if(NULL==lpDDCaps)
4320 return(DDERR_INVALIDPARAMS);
4321
4322 lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
4323 #ifdef DEBUG
4324 _dump_DDSCAPS(lpDDCaps->dwCaps);
4325 #endif
4326 return(DD_OK);
4327}
4328//******************************************************************************
4329//******************************************************************************
4330HRESULT WIN32API SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
4331{
4332 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4333 dprintf(("DDRAW: SurfGetCaps4\n"));
4334
4335 if(NULL==lpDDCaps)
4336 return(DDERR_INVALIDPARAMS);
4337
4338 memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
4339 #ifdef DEBUG
4340 _dump_DDSCAPS(lpDDCaps->dwCaps);
4341 _dump_DDSCAPS2(lpDDCaps->dwCaps2);
4342 #endif
4343
4344 return(DD_OK);
4345}
4346//******************************************************************************
4347//******************************************************************************
4348HRESULT WIN32API SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
4349{
4350 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4351
4352 dprintf(("DDRAW: SurfGetClipper\n"));
4353
4354 if(me->lpClipper)
4355 {
4356 *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
4357 return(DD_OK);
4358 }
4359 else
4360 return(DDERR_NOCLIPPERATTACHED);
4361}
4362//******************************************************************************
4363//******************************************************************************
4364HRESULT WIN32API SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
4365{
4366 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4367 dprintf(("DDRAW: SurfGetColorKey\n"));
4368
4369 if ((0==dwFlags) || (NULL==lpDDColKey))
4370 return (DDERR_INVALIDPARAMS);
4371
4372 // as we report only src colorkey in the caps return error on all others flags
4373 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
4374 return(DDERR_UNSUPPORTED);
4375
4376 if(me->DDSurfaceDesc.dwFlags & dwFlags)
4377 {
4378 if(DDCKEY_SRCBLT & dwFlags)
4379 {
4380 memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
4381 }
4382 else
4383 return (DDERR_INVALIDPARAMS); // some other flags where set => error
4384 }
4385 else
4386 return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
4387
4388 return (DD_OK);
4389}
4390//******************************************************************************
4391//******************************************************************************
4392HRESULT WIN32API SurfGetDC(THIS This, HDC FAR *hdc)
4393{
4394 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4395 DDSURFACEDESC2 LockedSurfaceDesc;
4396 HRESULT rc;
4397 BITMAPINFOHEADER bmihHdr;
4398 BITMAP bmpSurface;
4399 struct
4400 {
4401 BITMAPINFOHEADER bmiHead;
4402 RGBQUAD bmiCols[256];
4403 } BitmapInfo;
4404
4405 dprintf(("DDRAW: SurfGetDC\n"));
4406
4407 if (hdc == NULL)
4408 return(DDERR_INVALIDPARAMS);
4409
4410 LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
4411
4412 if(DD_OK != me->Vtbl.Lock(me,NULL,&LockedSurfaceDesc,0,0))
4413 {
4414 return(DDERR_DCALREADYCREATED);
4415 }
4416
4417 rc = DD_OK;
4418
4419 if(me->hdcImage == NULL)
4420 {
4421 // Create a Device context
4422 me->hdcImage = CreateCompatibleDC(NULL);
4423 if(me->hdcImage == NULL)
4424 {
4425 dprintf(("DDRAW: Can't create compatible DC!\n"));
4426 me->Vtbl.Unlock(me,NULL);
4427 rc = DDERR_GENERIC;
4428 }
4429 }
4430
4431 if( (DD_OK==rc) && (me->hbmImage == NULL) )
4432 {
4433 OS2IDirectDrawPalette *ddpal = NULL;
4434
4435 dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n",
4436 LockedSurfaceDesc.dwWidth,
4437 LockedSurfaceDesc.dwHeight,
4438 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount
4439 ));
4440 #if 1
4441 memset(&BitmapInfo, 0, sizeof(BitmapInfo));
4442 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4443 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
4444 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
4445 BitmapInfo.bmiHead.biPlanes = 1;
4446 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4447 memset(&bmihHdr, 0, sizeof(bmihHdr));
4448 bmihHdr.biSize = sizeof(BITMAPINFOHEADER);
4449 bmihHdr.biWidth = LockedSurfaceDesc.dwWidth;
4450 bmihHdr.biHeight = LockedSurfaceDesc.dwHeight;
4451 bmihHdr.biPlanes = 1;
4452 bmihHdr.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4453 #else
4454 bmpSurface.bmType = 0;
4455 bmpSurface.bmWidth = LockedSurfaceDesc.dwWidth;
4456 bmpSurface.bmHeight = LockedSurfaceDesc.dwHeight;
4457 bmpSurface.bmWidthBytes = LockedSurfaceDesc.lPitch;
4458 bmpSurface.bmPlanes = 1;
4459 bmpSurface.bmBits = LockedSurfaceDesc.lpSurface;
4460 #endif
4461 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4462 {
4463 case 1:
4464 case 4:
4465 dprintf(("DDRAW: 1/4 Bit Not yet supported\n"));
4466 break;
4467 case 8:
4468 #if 1
4469 BitmapInfo.bmiHead.biCompression = BI_RGB;
4470 if (me->lpPalette != NULL)
4471 ddpal = me->lpPalette;
4472 if ((me->FrontBuffer != NULL) && (me->FrontBuffer->lpPalette != NULL))
4473 ddpal = me->FrontBuffer->lpPalette;
4474 if (ddpal != NULL) {
4475 ddpal->Vtbl.GetEntries((IDirectDrawPalette*)ddpal,
4476 0, 0, 256, (PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4477 }
4478 else {
4479 dprintf(("DDRAW: Using default palette\n"));
4480 for (DWORD i = 0; i < 256; i++) {
4481 BitmapInfo.bmiCols[i].rgbBlue = DefaultPalette[i*3+2];
4482 BitmapInfo.bmiCols[i].rgbGreen = DefaultPalette[i*3+1];
4483 BitmapInfo.bmiCols[i].rgbRed = DefaultPalette[i*3];
4484 BitmapInfo.bmiCols[i].rgbReserved = 0;
4485 }
4486 }
4487 me->hbmImage = CreateDIBitmap( me->hdcImage,
4488 &bmihHdr,
4489 CBM_INIT,
4490 LockedSurfaceDesc.lpSurface,
4491 (PBITMAPINFO)&BitmapInfo,
4492 DIB_RGB_COLORS);
4493 #else
4494 bmpSurface.bmBitsPixel = 8;
4495 me->hbmImage = CreateBitmapIndirect( &bmpSurface);
4496 #endif
4497 break;
4498 case 16:
4499 case 32:
4500 dprintf(("DDRAW: 16/32 Bit not supported by OS/2"));
4501 break;
4502 case 24:
4503 #if 0
4504 BitmapInfo.bmiHead.biCompression = BI_RGB;
4505 me->hbmImage = CreateDIBitmap( me->hdcImage,
4506 NULL,
4507 CBM_CREATEDIB,
4508 LockedSurfaceDesc.lpSurface,
4509 (PBITMAPINFO)&BitmapInfo,
4510 DIB_RGB_COLORS );
4511 #else
4512 bmpSurface.bmBitsPixel = 24;
4513 me->hbmImage = CreateBitmapIndirect( &bmpSurface);
4514 #endif
4515 break;
4516 default:
4517 dprintf( ("Unexpected BitCount %d \n",
4518 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4519 me->hbmImage=NULL;
4520 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4521
4522 if(me->hbmImage == NULL)
4523 {
4524 dprintf(("DDRAW: Can't create bitmap!\n"));
4525 DeleteDC(me->hdcImage);
4526 me->hdcImage = NULL;
4527 me->Vtbl.Unlock(me,NULL);
4528 rc = DDERR_GENERIC;
4529 }
4530 }
4531 else
4532 {
4533 if( (DD_OK==rc) && (me->dwLastDCUnique != me->dwUniqueValue) )
4534 {
4535 dprintf(("DDRAW: The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n"));
4536
4537 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4538 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4539 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.dwWidth;
4540 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
4541 BitmapInfo.bmiHead.biPlanes = 1;
4542 BitmapInfo.bmiHead.biBitCount = (WORD)LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4543
4544 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4545 {
4546 case 1:
4547 case 4:
4548 case 8:
4549 BitmapInfo.bmiHead.biCompression = BI_RGB;
4550 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4551 SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
4552 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4553 break;
4554 case 16:
4555 case 32:
4556 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4557 BitmapInfo.bmiHead.biClrUsed = 3;
4558 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4559 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4560 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4561 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4562 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4563 break;
4564 case 24:
4565 BitmapInfo.bmiHead.biCompression = BI_RGB;
4566 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4567 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4568 break;
4569 default:
4570 dprintf(("DDRAW: Unexpected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4571 break;
4572 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4573
4574 }
4575 }
4576
4577 // Allways select the bitmap into the DC! No matter if the old or a new one
4578
4579 if (DD_OK==rc)
4580 {
4581 if ((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
4582 {
4583 dprintf(("DDRAW: Can't select bitmap into DC!\n"));
4584 DeleteDC(me->hdcImage);
4585 me->hdcImage = NULL;
4586 DeleteObject(me->hbmImage);
4587 me->hbmImage = NULL;
4588 me->Vtbl.Unlock(me,NULL);
4589 rc = DDERR_GENERIC;
4590 }
4591 else
4592 {
4593 *hdc = me->hdcImage;
4594 }
4595 }
4596
4597 return rc;
4598}
4599//******************************************************************************
4600//******************************************************************************
4601HRESULT WIN32API SurfGetFlipStatus(THIS This, DWORD dwFlags)
4602{
4603 dprintf(("DDRAW: SurfGetFlipStatus\n"));
4604
4605 if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
4606 return DDERR_INVALIDPARAMS;
4607
4608 return(DD_OK);
4609}
4610//******************************************************************************
4611//******************************************************************************
4612HRESULT WIN32API SurfGetOverlayPosition(THIS This, LPLONG lplX, LPLONG lplY)
4613{
4614 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4615 dprintf(("DDRAW: SurfGetOverlayPosition\n"));
4616
4617 // Maybe simply return dderr_notsupported as we retun a max overlay value of 0 in the caps ?
4618
4619 if( (NULL==lplX) || (NULL==lplY))
4620 return DDERR_INVALIDPARAMS;
4621
4622 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
4623 return DDERR_NOTAOVERLAYSURFACE;
4624
4625 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_VISIBLE))
4626 return DDERR_OVERLAYNOTVISIBLE;
4627
4628 if(!me->fOverlayValid)
4629 return DDERR_NOOVERLAYDEST;
4630
4631 *lplX = me->lOverlayX;
4632 *lplY = me->lOverlayY;
4633
4634 return(DD_OK);
4635}
4636//******************************************************************************
4637//******************************************************************************
4638HRESULT WIN32API SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
4639{
4640 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4641
4642 dprintf(("DDRAW: SurfGetPalette\n"));
4643
4644 if(me->lpPalette)
4645 {
4646 *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
4647 return(DD_OK);
4648 }
4649 else
4650 return(DDERR_NOPALETTEATTACHED);
4651}
4652//******************************************************************************
4653//******************************************************************************
4654HRESULT WIN32API SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
4655{
4656 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4657
4658 dprintf(("DDRAW: SurfGetPixelFormat %x %x", This, lpPixelFormat));
4659
4660 if(NULL==lpPixelFormat)
4661 return DDERR_INVALIDPARAMS;
4662
4663#ifdef DEBUG
4664 _dump_pixelformat(&me->DDSurfaceDesc.ddpfPixelFormat);
4665#endif
4666
4667 memcpy( (char*)lpPixelFormat,
4668 (char*)&(me->DDSurfaceDesc.ddpfPixelFormat),
4669 sizeof(DDPIXELFORMAT));
4670
4671 return(DD_OK);
4672}
4673//******************************************************************************
4674//******************************************************************************
4675HRESULT WIN32API SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
4676{
4677 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4678
4679 dprintf(("DDRAW: SurfGetSurfaceDesc\n"));
4680
4681 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
4682 return(DDERR_INVALIDPARAMS);
4683
4684 memcpy( (char *)lpSurface,
4685 (char *)&me->DDSurfaceDesc,
4686 sizeof(DDSURFACEDESC));
4687
4688 return(DD_OK);
4689}
4690//******************************************************************************
4691//******************************************************************************
4692HRESULT WIN32API SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
4693{
4694 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4695
4696 dprintf(("DDRAW: SurfGetSurfaceDesc4\n"));
4697
4698 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
4699 return(DDERR_INVALIDPARAMS);
4700
4701 memcpy( (char *)lpSurface,
4702 (char *)&me->DDSurfaceDesc,
4703 sizeof(DDSURFACEDESC2));
4704
4705 return(DD_OK);
4706}
4707//******************************************************************************
4708//******************************************************************************
4709HRESULT WIN32API SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
4710{
4711 dprintf(("DDRAW: SurfInitialize\n"));
4712
4713 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4714}
4715//******************************************************************************
4716//******************************************************************************
4717HRESULT WIN32API SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
4718{
4719 dprintf(("DDRAW: SurfInitialize\n"));
4720
4721 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4722}
4723//******************************************************************************
4724//******************************************************************************
4725HRESULT WIN32API SurfIsLost(THIS)
4726{
4727 // We don't loose any surface ;)
4728 // But we might shoud check for primary and/or Dive Buffers as I don't know
4729 // if they are preserved if switching to a FS DOS/OS2 session
4730 //
4731 dprintf(("DDRAW: SurfIsLost\n"));
4732
4733 return(DD_OK);
4734}
4735//******************************************************************************
4736//******************************************************************************
4737HRESULT WIN32API SurfLock( THIS This,
4738 LPRECT lpRect,
4739 LPDDSURFACEDESC lpSurfaceDesc,
4740 DWORD dwFlags,
4741 HANDLE hEvent)
4742{
4743 DDSURFACEDESC2 SurfaceDesc4;
4744 HRESULT rc;
4745
4746 dprintf(("DDRAW: SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent));
4747
4748 if((NULL==lpSurfaceDesc)|| ((dwFlags & DDLOCK_EVENT) && NULL != hEvent)) {
4749 dprintf(("Invalid parameters"));
4750 return DDERR_INVALIDPARAMS;
4751 }
4752
4753 if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC) && lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC2)) {
4754 dprintf(("Invalid parameters"));
4755 return DDERR_INVALIDPARAMS;
4756 }
4757
4758 SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
4759
4760 rc = SurfLock4( This,
4761 lpRect,
4762 &SurfaceDesc4,
4763 dwFlags,
4764 hEvent);
4765 if (DD_OK==rc)
4766 {
4767 memcpy( (char*)lpSurfaceDesc,
4768 (char*)&SurfaceDesc4,
4769 lpSurfaceDesc->dwSize );
4770 }
4771
4772 return(rc);
4773}
4774//******************************************************************************
4775//******************************************************************************
4776HRESULT WIN32API SurfLock4( THIS This,
4777 LPRECT lpRect,
4778 LPDDSURFACEDESC2 lpSurfaceDesc,
4779 DWORD dwFlags,
4780 HANDLE hEvent)
4781{
4782
4783 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4784 int i;
4785
4786 BOOL Found;
4787 DDRectangle *pIRectCurrent,*pIRectNew;
4788 HRESULT rc;
4789
4790 dprintf( ("SurfLock4 %08X %08X %08X %d %d\n",
4791 me,
4792 (int)lpRect,
4793 (int)lpSurfaceDesc,
4794 dwFlags,
4795 hEvent) );
4796
4797 if( (NULL==lpSurfaceDesc) ||
4798 (NULL!=hEvent)
4799 )
4800 {
4801 dprintf(("DDERR_INVALIDPARAMS"));
4802 return DDERR_INVALIDPARAMS;
4803 }
4804
4805 if (NULL!=lpRect)
4806 pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->right, lpRect->bottom );
4807 else
4808 pIRectNew = new DDRectangle( 0, 0, me->width, me->height);
4809
4810 // ToDo : the lockchecking should be done in a critcal seq.
4811 dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n",
4812 pIRectNew->Left(),
4813 pIRectNew->Top(),
4814 pIRectNew->Right(),
4815 pIRectNew->Bottom()));
4816
4817 rc = DD_OK;
4818
4819 if(me->fLocked)
4820 {
4821 if (NULL==lpRect)
4822 {
4823 // If anything is locked we can't lock the complete surface
4824 dprintf(("DDRAW: Surface has locked Rectangles and we want to completely lock it\n"));
4825 Found = TRUE;
4826 }
4827 else
4828 {
4829 // If the new Rectangle intersects with any of the already locked rectangles it can't
4830 // be locked so check for this
4831
4832 dprintf(("DDRAW: Surface has locked Rectangles, check if they overlap\n"));
4833
4834 i=0;
4835 Found = FALSE;
4836
4837 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4838 {
4839 pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
4840 dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n",
4841 pIRectCurrent->Top(),
4842 pIRectCurrent->Left(),
4843 pIRectCurrent->Bottom(),
4844 pIRectCurrent->Right() ));
4845 Found = pIRectCurrent->intersects(*pIRectNew);
4846 i++;
4847 }
4848
4849 }
4850
4851 if (Found)
4852 {
4853 delete pIRectNew;
4854 dprintf(("DDRAW: SurfLock4: Surface already locked\n\n"));
4855 rc = DDERR_SURFACEBUSY;
4856 }
4857
4858 }
4859
4860 if(DD_OK == rc)
4861 {
4862 memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
4863
4864 if(lpRect != NULL)
4865 {
4866 lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer +
4867 (lpRect->top * me->dwPitchFB) +
4868 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
4869 dprintf(("DDRAW: SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left));
4870 }
4871 else
4872 {
4873 dprintf(("DDRAW: SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface));
4874 }
4875 // Add the rectangle to the list of locked rectangles
4876
4877 pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
4878
4879 DPA_InsertPtr( me->DPA_LockedRects,
4880 DPA_GetPtrCount(me->DPA_LockedRects),
4881 pIRectNew);
4882
4883#if 0
4884 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
4885 {
4886 OS2RECTL rectOS2;
4887
4888 rectOS2.xLeft = pIRectNew->Left();
4889 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectNew->Bottom();
4890 rectOS2.xRight = pIRectNew->Right();
4891 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectNew->Top();
4892 dprintf(("DiveAcquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
4893 int ret = DiveAcquireFrameBuffer(me->hDive, (PRECTL)&rectOS2);
4894 if(ret) {
4895 dprintf(("ERROR: DiveAcquireFrameBuffer failed with %d", ret));
4896 }
4897 }
4898#endif
4899 me->fLocked = TRUE;
4900 }
4901
4902 return rc;
4903}
4904//******************************************************************************
4905//******************************************************************************
4906HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc)
4907{
4908 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4909 struct
4910 {
4911 BITMAPINFOHEADER bmiHead;
4912 RGBQUAD bmiCols[256];
4913 } BitmapInfo;
4914// BITMAP bmpData;
4915 int rc;
4916
4917 dprintf(("DDRAW: SurfReleaseDC\n"));
4918
4919 if(hdc != me->hdcImage)
4920 return(DDERR_INVALIDOBJECT);
4921
4922 #if 1
4923 //unselect our bitmap
4924 SelectObject(me->hdcImage, me->hgdiOld);
4925 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4926 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4927 /*
4928 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.lPitch/ (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4929 BitmapInfo.bmiHead.biHeight = me->DDSurfaceDesc.dwHeight;
4930 BitmapInfo.bmiHead.biPlanes = 1;
4931 BitmapInfo.bmiHead.biBitCount = 0; // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4932 */
4933 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4934 {
4935 case 1:
4936 case 4:
4937 case 8:
4938 BitmapInfo.bmiHead.biCompression = BI_RGB;
4939 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4940 rc = GetDIBits( hdc,
4941 me->hbmImage,
4942 0,
4943 me->DDSurfaceDesc.dwHeight,
4944 NULL,
4945 (PBITMAPINFO)&BitmapInfo,
4946 DIB_RGB_COLORS);
4947// BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight;
4948 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
4949 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
4950 rc,
4951 BitmapInfo.bmiHead.biSize,
4952 BitmapInfo.bmiHead.biWidth,
4953 BitmapInfo.bmiHead.biHeight,
4954 BitmapInfo.bmiHead.biPlanes,
4955 BitmapInfo.bmiHead.biBitCount,
4956 GetLastError(),
4957 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4958
4959 rc = GetDIBits( hdc,
4960 me->hbmImage,
4961 0,
4962 me->DDSurfaceDesc.dwHeight,
4963 me->DDSurfaceDesc.lpSurface,
4964 (PBITMAPINFO)&BitmapInfo,
4965 DIB_RGB_COLORS);
4966 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
4967 rc,
4968 GetLastError(),
4969 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4970 break;
4971 case 16:
4972 case 32:
4973 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4974 BitmapInfo.bmiHead.biClrUsed = 3;
4975 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4976 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4977 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4978 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4979 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4980 break;
4981 case 24:
4982 BitmapInfo.bmiHead.biCompression = BI_RGB;
4983 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4984 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4985 break;
4986 default:
4987 dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4988 // we might could keep the surface locked and return an error but this is more "safe"
4989 break;
4990 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4991 #else
4992
4993 rc = GetObjectA( me->hbmImage,
4994 sizeof(BITMAP),
4995 &bmpData);
4996 dprintf( ("GetObject returned rc=%d\n BitmapInfo:\n Size:(%dx%d)\n Pitch: %d\n Bits %d\n @mem %08X",
4997 rc,
4998 bmpData.bmWidth, bmpData.bmHeight,
4999 bmpData.bmWidthBytes,
5000 bmpData.bmBitsPixel,
5001 bmpData.bmBits));
5002 #endif
5003 me->Vtbl.Unlock(me,NULL);
5004 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
5005
5006 return(DD_OK);
5007}
5008//******************************************************************************
5009//******************************************************************************
5010HRESULT WIN32API SurfRestore(THIS)
5011{
5012 dprintf(("DDRAW: SurfRestore\n"));
5013
5014 return(DD_OK);
5015}
5016//******************************************************************************
5017//******************************************************************************
5018HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
5019{
5020 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5021
5022 dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper));
5023
5024 if(lpClipper == NULL)
5025 {
5026 //deattach surface
5027 if(me->lpClipper)
5028 {
5029 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
5030 me->lpClipper = NULL;
5031 return(DD_OK);
5032 }
5033 else
5034 return(DDERR_NOCLIPPERATTACHED);
5035 }
5036
5037 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
5038 return(DD_OK); //already attached
5039
5040 if(me->lpClipper != NULL)
5041 {
5042 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
5043 return(DD_OK);
5044 }
5045
5046 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
5047 me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
5048
5049 return(DD_OK);
5050}
5051//******************************************************************************
5052//******************************************************************************
5053HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
5054{
5055 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5056 HRESULT rc;
5057
5058 dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey));
5059
5060 if (0==dwFlags)
5061 {
5062 return (DDERR_INVALIDPARAMS);
5063 }
5064
5065 // as we report only src colorkey in the caps return error on all others flags
5066 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
5067 {
5068 dprintf(("Unspported colorkey\n"));
5069 return(DDERR_UNSUPPORTED);
5070 }
5071
5072 if(DDCKEY_SRCBLT & dwFlags)
5073 {
5074
5075 //(me->lpVtbl == me->Vtbl4)
5076 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
5077 if(NULL!=lpDDColKey)
5078 {
5079 dprintf(("copy colorkey"));
5080 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
5081 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
5082
5083 // ToDo: Generate a maskbitmap for transparent blitting here
5084 }
5085 else
5086 {
5087 dprintf(("clear colorkey"));
5088 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
5089 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
5090 }
5091 rc = DD_OK;
5092 }
5093 else
5094 {
5095 dprintf(("Unsupported flags"));
5096 #ifdef DEBUG
5097 _dump_DDCOLORKEY(dwFlags);
5098 #endif
5099 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
5100 }
5101 return rc;
5102}
5103//******************************************************************************
5104//******************************************************************************
5105HRESULT WIN32API SurfSetOverlayPosition(THIS This, LONG lX, LONG lY)
5106{
5107 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5108
5109 dprintf(("DDRAW: SurfSetOverlayPosition\n"));
5110
5111 if( (me->DDSurfaceDesc.dwFlags & DDSD_CAPS) &&
5112 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
5113 {
5114 if(me->fOverlayValid)
5115 return(DDERR_NOOVERLAYDEST);
5116
5117 if(!(me->DDSurfaceDesc.dwFlags & DDSCAPS_VISIBLE))
5118 return(DDERR_OVERLAYNOTVISIBLE);
5119
5120 // ToDo: If we implement alignment restricions to the Overlay position
5121 // check if the new values are OK otherwiese return DDERR_INVALIDPOSITION
5122
5123 me->lOverlayX = lX;
5124 me->lOverlayY = lY;
5125 return(DD_OK);
5126 }
5127
5128 return(DDERR_NOTAOVERLAYSURFACE);
5129}
5130//******************************************************************************
5131//******************************************************************************
5132HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
5133{
5134 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5135
5136 dprintf(("DDRAW: SurfSetPalette\n"));
5137
5138 if(lpPalette == NULL)
5139 {
5140 //deattach palette
5141 if(me->lpPalette)
5142 {
5143 // If removed from a primary surface notify
5144 // palette that it is no longer attached to the
5145 // primary surface => doesn't modify physical palette
5146 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
5147 {
5148 me->lpPalette->SetIsPrimary(FALSE);
5149 }
5150 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
5151 me->lpPalette = NULL;
5152 return(DD_OK);
5153 }
5154 else
5155 return(DDERR_NOPALETTEATTACHED);
5156 }
5157
5158 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
5159 return(DD_OK); //already attached
5160
5161 if(me->lpPalette != NULL)
5162 {
5163 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
5164 //return(DD_OK);
5165 }
5166 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
5167 me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
5168
5169 // If Attached to a primary surface notify
5170 // palette that it is attached to the primary surface
5171 // => It does modify physical palette.
5172 // This is important as an palette can be attached to
5173 // multiple surfaces. If one is the primary surface
5174 // changes done to it via any surface must result in
5175 // changes in the phys pal.
5176
5177 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
5178 {
5179 me->lpPalette->SetIsPrimary(TRUE);
5180 }
5181 // me->lpVtbl->ChangeUniquenessValue(me);
5182
5183 return(DD_OK);
5184}
5185//******************************************************************************
5186//******************************************************************************
5187HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData)
5188{
5189
5190 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5191 int i;
5192 DDRectangle *pIRectUnlock, *pIRectEnum;
5193 BOOL Found = FALSE;
5194 OS2RECTL CCRect;
5195 HRESULT rc;
5196
5197 dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData));
5198
5199 if(me->fLocked == FALSE)
5200 {
5201 dprintf(("DDRAW: Surface not locked!\n"));
5202 return(DDERR_NOTLOCKED);
5203 }
5204
5205 i=0;
5206 if(NULL!=lpSurfaceData)
5207 {
5208 dprintf(("DDRAW: Buffer Pointer Compare"));
5209
5210 // We got a pinter to the surface memory so we must search for
5211 // this pointer in the locked rects DPA to unlock the right rect.
5212
5213 while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5214 {
5215 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5216 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5217 i,
5218 pIRectEnum->Top(),
5219 pIRectEnum->Left(),
5220 pIRectEnum->Bottom(),
5221 pIRectEnum->Right(),
5222 pIRectEnum->GetMemPtr() ));
5223
5224 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
5225 if(!Found)
5226 {
5227 dprintf(("DDRAW: Not Found, try Next rect\n"));
5228 i++;
5229 }
5230 else
5231 {
5232 dprintf(("DDRAW: Found Rect\n"));
5233 }
5234 }
5235 }
5236 else
5237 {
5238 // If a NULL pointer was passed in the SW tries to unlock the
5239 // complete surface so we must compare the rects.
5240 dprintf(("DDRAW: Rectangle compare"));
5241
5242#if 1
5243 i = 0;
5244 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0);
5245 Found = (pIRectEnum != NULL);
5246#else
5247 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
5248
5249 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5250 {
5251 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5252 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5253 i,
5254 pIRectEnum->Top(),
5255 pIRectEnum->Left(),
5256 pIRectEnum->Bottom(),
5257 pIRectEnum->Right(),
5258 pIRectEnum->GetMemPtr() ));
5259
5260 Found = (*pIRectEnum == *pIRectUnlock);
5261 if(!Found)
5262 {
5263 dprintf(("DDRAW: Not Found, try Next rect\n"));
5264 i++;
5265 }
5266 else
5267 {
5268 dprintf(("DDRAW: Found Rect\n"));
5269 }
5270 }
5271 delete pIRectUnlock;
5272#endif
5273 }
5274
5275 if(!Found)
5276 {
5277 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
5278 rc = DDERR_INVALIDRECT;
5279 }
5280 else
5281 {
5282 dprintf(("DDRAW: Remove Rect %d from Seq.\n",i));
5283
5284 DPA_DeletePtr(me->DPA_LockedRects,i);
5285
5286 dprintf(("DDRAW: Test if locked Rects main\n"));
5287
5288 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5289 {
5290 dprintf(("DDRAW: No Locked Rects left for surface\n"));
5291 me->fLocked = FALSE;
5292 }
5293 #ifdef DEBUG
5294 else
5295 dprintf(( "%d Rects in Seq\n",
5296 DPA_GetPtrCount(me->DPA_LockedRects)));
5297 #endif
5298
5299 if(me->pFrameBuffer != me->pDiveBuffer)
5300 {
5301 dprintf(( "ColorConversion Needed %08X != %08X\n",
5302 me->pFrameBuffer,
5303 me->pDiveBuffer));
5304 if(NULL!=lpSurfaceData)
5305 {
5306 CCRect.yTop = pIRectEnum->Top();
5307 CCRect.xLeft = pIRectEnum->Left();
5308 CCRect.xRight = pIRectEnum->Right();
5309 CCRect.yBottom = pIRectEnum->Bottom();
5310
5311 me->ColorConversion( (LPRECT)&CCRect);
5312 }
5313 else
5314 {
5315 me->ColorConversion(NULL);
5316 }
5317 }
5318 else
5319 dprintf( ("No ColorConversion Needed"));
5320
5321
5322#if 0
5323 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
5324 {
5325 OS2RECTL rectOS2;
5326
5327 rectOS2.xLeft = pIRectEnum->Left();
5328 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom();
5329 rectOS2.xRight = pIRectEnum->Right();
5330 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top();
5331 dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
5332 int ret = DiveDeacquireFrameBuffer(me->hDive);
5333 if(ret) {
5334 dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret));
5335 }
5336 }
5337#endif
5338
5339 // delete tne DDRectobject of the found rectangle
5340 delete pIRectEnum;
5341
5342 // me->lpVtbl->ChangeUniquenessValue(me);
5343
5344 dprintf(("DDRAW: Unlock OK\n\n"));
5345
5346 rc = DD_OK;
5347 }
5348
5349 return rc;
5350}
5351//******************************************************************************
5352//******************************************************************************
5353HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
5354{
5355 // MS changed the parameter from LPVOID to LPRECT with DX6
5356 // as DX-6 allways returns a DDSurface4 on create surface this
5357 // is a problem i not NULL is passed in.
5358 // Solution We first test with the pointer ns assuming a rectangle
5359 // if we don't find a rect Which is very likely if we get a pointer
5360 // SurfaceMemory we call SurfUnlock and test for the pointer there.
5361
5362
5363 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5364 int i;
5365 DDRectangle *pIRectUnlock, *pIRectEnum;
5366 BOOL Found = FALSE;
5367 HRESULT rc;
5368
5369 dprintf(("DDRAW: SurfUnlock4\n"));
5370
5371 if(me->fLocked == FALSE)
5372 {
5373 dprintf(("DDRAW: Surface not locked!\n"));
5374 return(DDERR_NOTLOCKED);
5375 }
5376
5377 if(NULL!=lpSurfaceRect)
5378 {
5379 dprintf(("DDRAW: Unlock rectangle\n"));
5380 pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top,
5381 lpSurfaceRect->right, lpSurfaceRect->bottom);
5382 }
5383 else
5384 {
5385 dprintf(("DDRAW: Unlock complete surface\n"));
5386 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
5387 }
5388
5389 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
5390 pIRectUnlock->Top(),
5391 pIRectUnlock->Left(),
5392 pIRectUnlock->Bottom(),
5393 pIRectUnlock->Right() ));
5394
5395 dprintf(("DDRAW: Start Enumeration of Locked Rects\n"));
5396
5397 i=0;
5398 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5399 {
5400 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5401 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
5402 pIRectEnum->Top(),
5403 pIRectEnum->Left(),
5404 pIRectEnum->Bottom(),
5405 pIRectEnum->Right() ));
5406
5407 Found = (*pIRectEnum == *pIRectUnlock);
5408 if(!Found)
5409 {
5410 dprintf(("DDRAW: Not Found, try Next rect\n"));
5411 i++;
5412 }
5413 else
5414 {
5415 dprintf(("DDRAW: Found Rect\n"));
5416 }
5417 }
5418
5419 if(!Found)
5420 {
5421
5422 if(NULL==lpSurfaceRect)
5423 {
5424 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
5425 return(DDERR_INVALIDRECT);
5426 }
5427 else
5428 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
5429 }
5430 else
5431 {
5432 dprintf(("DDRAW: Remove Rect from Seq.\n"));
5433
5434 DPA_DeletePtr(me->DPA_LockedRects,i);
5435
5436 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5437 {
5438 dprintf(("DDRAW: No Locked Rects left for surface\n"));
5439 me->fLocked = FALSE;
5440 }
5441
5442 if(me->pFrameBuffer != me->pDiveBuffer)
5443 {
5444 dprintf(( "ColorConversion Needed %08X != %08X\n",
5445 me->pFrameBuffer,
5446 me->pDiveBuffer));
5447 me->ColorConversion(lpSurfaceRect);
5448 }
5449
5450 // me->lpVtbl->ChangeUniquenessValue(me);
5451
5452 dprintf(("DDRAW: Unlock OK\n\n"));
5453 rc = DD_OK;
5454
5455 }
5456
5457 return rc;
5458}
5459//******************************************************************************
5460//******************************************************************************
5461HRESULT WIN32API SurfUpdateOverlay(THIS This, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX)
5462{
5463 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5464 return(DD_OK);
5465}
5466//******************************************************************************
5467//******************************************************************************
5468HRESULT WIN32API SurfUpdateOverlay3(THIS This, LPRECT, LPDIRECTDRAWSURFACE3,LPRECT,DWORD, LPDDOVERLAYFX)
5469{
5470 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5471 return(DD_OK);
5472}
5473//******************************************************************************
5474//******************************************************************************
5475HRESULT WIN32API SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX)
5476{
5477 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5478 return(DD_OK);
5479}
5480//******************************************************************************
5481//******************************************************************************
5482HRESULT WIN32API SurfUpdateOverlayDisplay(THIS, DWORD)
5483{
5484 dprintf(("DDRAW: SurfUpdateOverlayDisplay\n"));
5485 return(DD_OK);
5486}
5487//******************************************************************************
5488//******************************************************************************
5489HRESULT WIN32API SurfUpdateOverlayZOrder(THIS, DWORD, LPDIRECTDRAWSURFACE2)
5490{
5491 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
5492 return(DD_OK);
5493}
5494//******************************************************************************
5495//******************************************************************************
5496HRESULT WIN32API SurfUpdateOverlayZOrder3(THIS, DWORD, LPDIRECTDRAWSURFACE3)
5497{
5498 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
5499 return(DD_OK);
5500}
5501//******************************************************************************
5502//******************************************************************************
5503HRESULT WIN32API SurfUpdateOverlayZOrder4(THIS, DWORD, LPDIRECTDRAWSURFACE4)
5504{
5505 dprintf(("DDRAW: SurfUpdateOverlayZOrder4\n"));
5506 return(DD_OK);
5507}
5508//******************************************************************************
5509//******************************************************************************
5510HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
5511{
5512 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5513
5514 dprintf(("DDRAW: SurfGetDDInterface\n"));
5515 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
5516 return(DD_OK);
5517}
5518//******************************************************************************
5519//******************************************************************************
5520HRESULT WIN32API SurfPageLock(THIS, DWORD)
5521{
5522 // Only used for DMA memory access
5523 // If we implement this for the None dive buffers with a pdd the we must change
5524 // from malloc to DosAllocMem and use OBJ_TILE flag
5525 dprintf(("DDRAW: SurfPageLock\n"));
5526 return(DD_OK);
5527}
5528//******************************************************************************
5529//******************************************************************************
5530HRESULT WIN32API SurfPageUnlock(THIS, DWORD)
5531{
5532 dprintf(("DDRAW: SurfPageUnlock\n"));
5533 return(DD_OK);
5534}
5535//******************************************************************************
5536//******************************************************************************
5537// V3 Interface Functions
5538
5539HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
5540{
5541 dprintf(("DDRAW: SurfSetSurfaceDesc\n"));
5542
5543 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5544 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5545 return DDERR_INVALIDPARAMS;
5546
5547 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5548 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5549 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5550 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5551 if(-1==me->diveBufNr)
5552 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5553
5554 if (!me->Updated)
5555 {
5556 me->Updated = TRUE;
5557 // free our allocated Memory
5558 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5559 {
5560 if(me->pFBreal)
5561 free(me->pFBreal);
5562 if(me->pDBreal)
5563 free(me->pFBreal);
5564 }
5565 }
5566 // me->lpVtbl->ChangeUniquenessValue(me);
5567 memcpy( (char*)&(me->DDSurfaceDesc),
5568 (char*)lpSurfDesc,
5569 sizeof(DDSURFACEDESC));
5570
5571 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5572
5573 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5574 {
5575 // create CC buffer ....
5576 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5577 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5578 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5579 }
5580 return DD_OK;
5581}
5582//******************************************************************************
5583//******************************************************************************
5584HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
5585{
5586 dprintf(("DDRAW: SurfSetSurfaceDesc4\n"));
5587
5588 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5589 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5590 return DDERR_INVALIDPARAMS;
5591
5592 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5593 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5594 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5595 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5596 if(-1==me->diveBufNr)
5597 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5598
5599 if (!me->Updated)
5600 {
5601 me->Updated = TRUE;
5602 // free our allocated Memory
5603 // free our allocated Memory
5604 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5605 {
5606 if(me->pFBreal)
5607 free(me->pFBreal);
5608 if(me->pDBreal)
5609 free(me->pFBreal);
5610 }
5611 }
5612 // me->lpVtbl->ChangeUniquenessValue(me);
5613 memcpy( (char *)&(me->DDSurfaceDesc),
5614 (char*)lpSurfDesc,
5615 sizeof(DDSURFACEDESC2));
5616 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5617
5618 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5619 {
5620 // create CC buffer ....
5621 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5622 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5623 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5624 }
5625
5626 return DD_OK;
5627}
5628//******************************************************************************
5629//******************************************************************************
5630// V4 Interface Functions
5631
5632HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
5633 DWORD dwDataSize, DWORD dwFlags)
5634{
5635 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5636 int i;
5637 PSURFPRIVATEDATA pSData;
5638 void *pBuffer;
5639 BOOL bFound = FALSE;
5640 HRESULT rc;
5641
5642 dprintf(("DDRAW: SurfSetPrivateData\n"));
5643
5644 if(NULL==me)
5645 return(DDERR_INVALIDOBJECT);
5646
5647 if((NULL==lpData)||(0==dwDataSize)||
5648 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
5649 return(DDERR_INVALIDPARAMS);
5650
5651 // first check if the refGUID is stored as then the content will be updated
5652 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
5653 {
5654 i=0;
5655 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5656 {
5657 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5658
5659 if (IsEqualGUID(pSData->guidTag,refGUID))
5660 bFound = TRUE;
5661
5662 i++;
5663 }
5664 }
5665
5666 if(bFound)
5667 {
5668 // update Private Data
5669
5670 if (!pSData->isValid)
5671 {
5672 // Current data is invalid we need to update/allocate
5673
5674 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5675 {
5676 pSData->pData = lpData;
5677 pSData->dwSize = 4;
5678 pSData->dwFlags = dwFlags;
5679 pSData->isValid = TRUE;
5680 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
5681 }
5682 else
5683 {
5684 pSData->pData = malloc(dwDataSize);
5685 if(NULL!=pSData->pData)
5686 {
5687 memcpy(pSData->pData,lpData,dwDataSize);
5688 pSData->dwSize = dwDataSize;
5689 pSData->dwFlags = dwFlags;
5690 pSData->isValid = TRUE;
5691 }
5692 else
5693 {
5694 delete pSData;
5695 rc = DDERR_OUTOFMEMORY;
5696 }
5697 }
5698 }
5699 else
5700 {
5701 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5702 {
5703 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5704 {
5705 if(pSData->pData != lpData)
5706 {
5707 // Change of IUNKOWNPOINTER => release old and add ref to new one
5708 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5709 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5710 pSData->pData = lpData;
5711 }
5712 pSData->dwFlags = dwFlags; // Update the flags, size is the same
5713 }
5714 else
5715 {
5716 // Replace IUNKOWN through data
5717 pBuffer = malloc(dwDataSize); // get new buffer first
5718 if(NULL!=pBuffer)
5719 {
5720 // release old ref and copy data
5721 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5722 memcpy(pBuffer,lpData,dwDataSize);
5723 pSData->pData = pBuffer;
5724 pSData->dwSize = dwDataSize; // Update the size
5725 pSData->dwFlags = dwFlags; // Update the flags
5726 }
5727 else
5728 rc = DDERR_OUTOFMEMORY;
5729 }
5730 }
5731 else
5732 {
5733 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5734 {
5735 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
5736 free(pSData->pData);
5737 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5738 pSData->pData = lpData;
5739 pSData->dwSize = dwDataSize; // Update the size
5740 pSData->dwFlags = dwFlags; // Update the flags
5741 }
5742 else
5743 {
5744 // Update/Replace data
5745 if(pSData->dwSize!=dwDataSize)
5746 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
5747 else
5748 pBuffer = pSData->pData;
5749
5750 if(NULL!=pBuffer)
5751 {
5752 // release old ref and copy data
5753 memcpy(pBuffer,lpData,dwDataSize);
5754 pSData->pData = pBuffer;
5755 pSData->dwSize = dwDataSize; // Update the size
5756 pSData->dwFlags = dwFlags; // Update the flags
5757 }
5758 else
5759 rc = DDERR_OUTOFMEMORY;
5760 }
5761 }
5762 }
5763 }
5764 else
5765 {
5766 // New data
5767
5768 pSData = new(SURFPRIVATEDATA);
5769 if (NULL!=pSData)
5770 {
5771 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5772 {
5773 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5774 pSData->pData = lpData;
5775 pSData->dwSize = 4;
5776 pSData->dwFlags = dwFlags;
5777 pSData->isValid = TRUE;
5778 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5779 }
5780 else
5781 {
5782 pSData->pData = malloc(dwDataSize);
5783 if(NULL!=pSData->pData)
5784 {
5785 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5786 memcpy(pSData->pData,lpData,dwDataSize);
5787 pSData->dwSize = dwDataSize;
5788 pSData->dwFlags = dwFlags;
5789 pSData->isValid = TRUE;
5790
5791 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
5792 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
5793 pSData) <0)
5794 {
5795 delete(pSData);
5796 rc = DDERR_OUTOFMEMORY;
5797 }
5798 }
5799 else
5800 {
5801 delete(pSData);
5802 rc = DDERR_OUTOFMEMORY;
5803 }
5804 }
5805
5806 }
5807 else
5808 rc = DDERR_OUTOFMEMORY;
5809 }
5810
5811 return rc;
5812}
5813//******************************************************************************
5814//******************************************************************************
5815HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
5816{
5817 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5818 int i;
5819 PSURFPRIVATEDATA pSData;
5820 HRESULT rc;
5821 BOOL bFound = FALSE;
5822
5823 dprintf(("DDRAW: SurfGetPrivateData\n"));
5824
5825 if(NULL==me)
5826 return(DDERR_INVALIDOBJECT);
5827
5828 if((NULL==lpData)||(NULL==lpDataSize))
5829 return(DDERR_INVALIDPARAMS);
5830
5831 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5832 {
5833 i=0;
5834 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5835 {
5836 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5837
5838 if (IsEqualGUID(pSData->guidTag,refGUID))
5839 bFound = TRUE;
5840
5841 i++;
5842 }
5843 }
5844
5845 if(bFound)
5846 {
5847 if(!pSData->isValid)
5848 {
5849 rc =DDERR_EXPIRED;
5850 }
5851 else
5852 {
5853 if(pSData->dwSize > *lpDataSize)
5854 {
5855 // Buffer to small return needed Size
5856 *lpDataSize = pSData->dwSize;
5857 rc = DDERR_MOREDATA;
5858 }
5859 else
5860 {
5861 memcpy(lpData,pSData->pData,pSData->dwSize);
5862 rc = DD_OK;
5863 }
5864 }
5865 }
5866 else
5867 rc = DDERR_NOTFOUND;
5868
5869
5870 return rc;
5871}
5872//******************************************************************************
5873//******************************************************************************
5874HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID)
5875{
5876 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5877 int i;
5878 PSURFPRIVATEDATA pSData;
5879 BOOL bFound = FALSE;
5880
5881 dprintf(("DDRAW: SurfFreePrivateData\n"));
5882
5883 if(NULL==me)
5884 return(DDERR_INVALIDOBJECT);
5885
5886 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5887 {
5888 i=0;
5889 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5890 {
5891 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5892
5893 if (IsEqualGUID(pSData->guidTag,refGUID))
5894 {
5895 bFound = TRUE;
5896
5897 if(pSData->isValid)
5898 {
5899 // delete the data if valid
5900 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5901 {
5902 // pointer to com stored so calll its release
5903 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5904 }
5905 else
5906 {
5907 // Free allocated data
5908 free( pSData->pData);
5909 }
5910 }
5911 // Now remove the entry from the list
5912 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
5913 }
5914 i++;
5915 }
5916 }
5917
5918 return (bFound?DD_OK:DDERR_NOTFOUND);
5919}
5920//******************************************************************************
5921//******************************************************************************
5922HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
5923{
5924 dprintf(("DDRAW: SurfGetUniquenessValue\n"));
5925 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5926 if (NULL==lpValue)
5927 return DDERR_INVALIDPARAMS;
5928
5929 *lpValue = me->dwUniqueValue;
5930 return DD_OK;
5931}
5932//******************************************************************************
5933//******************************************************************************
5934HRESULT WIN32API SurfChangeUniquenessValue(THIS This)
5935{
5936 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5937 int i;
5938 PSURFPRIVATEDATA pSData;
5939
5940
5941 dprintf(("DDRAW: SurfChangeUniquenessValue\n"));
5942 me->dwUniqueValue++;
5943
5944 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5945 {
5946 i=0;
5947 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
5948 {
5949 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5950 if (pSData->dwFlags & DDSPD_VOLATILE)
5951 {
5952 // Data becomes unvalid after a Surface change
5953 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5954 {
5955 // pointer to com stored so call its release
5956 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5957 }
5958 else
5959 {
5960 // Free allocated data
5961 free( pSData->pData);
5962 }
5963 pSData->pData = NULL;
5964 pSData->isValid = FALSE; // set flag to invalid
5965 }
5966 i++;
5967 }
5968 }
5969
5970 return (DD_OK);
5971}
5972
5973
5974
5975//******************************************************************************
5976//
5977// Purpose function copies one part of the bitmap inside the same bitmap
5978//
5979//******************************************************************************
5980
5981void __cdecl MoveRects(char* pBuffer, LPRECT lpDestRect, LPRECT lpSrcRect, int bpp, LONG lPitch)
5982{
5983
5984 char *pBltPos, *pSrcPos;
5985 int BlitWidth,BlitHeight;
5986 static char Scanline[6400]; // sufficient for 1600 at 32 bit
5987
5988 // Bridge, we may got a problem ;)
5989 // Check for Overlapping Rects
5990
5991 pBltPos = pBuffer;
5992 pSrcPos = pBuffer;
5993
5994 if(lpDestRect->top <= lpSrcRect->top)
5995 {
5996 // +-------+ +-------+ +-------+
5997 // |S | |S | |S | +---+---+---+
5998 // | +---|---+ +-------+ +---|---+ | |S/D|D/S| |
5999 // | | D | | | D | | D | | | | | | |
6000 // +-------+ | +-------+ | +-------+ | | | |
6001 // | | | | | | +---+---+---+
6002 // +-------+ +-------+ +-------+
6003 //
6004 // We got one of the above cases (or no overlapping) so copy from bottom up
6005
6006 pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
6007 pSrcPos += (lpSrcRect->left * bpp) + lPitch * (lpSrcRect->bottom-1);
6008 BlitHeight = lpDestRect->bottom - lpDestRect->top;
6009 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
6010
6011 while(1)
6012 {
6013 memcpy(Scanline,pSrcPos,BlitWidth);
6014 memcpy(pBltPos,Scanline,BlitWidth);
6015 pBltPos += lPitch;
6016 pSrcPos -= lPitch;
6017 if(! (--BlitHeight))
6018 break;
6019 }
6020 }
6021 else
6022 {
6023 // +-------+ +-------+ +-------+
6024 // | D | | D | | D |
6025 // | +---|---+ +-------+ +---|---+ |
6026 // | |S | | |S | |S | | |
6027 // +-------+ | +-------+ | +-------+
6028 // | | | | | |
6029 // +-------+ +-------+ +-------+
6030 //
6031 // We got one of the above cases so copy top down
6032
6033 pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
6034 pSrcPos += (lpSrcRect->left * bpp) + lPitch * lpSrcRect->top;
6035 BlitHeight = lpDestRect->bottom - lpDestRect->top;
6036 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
6037
6038 while(1)
6039 {
6040 memcpy(Scanline,pSrcPos,BlitWidth);
6041 memcpy(pBltPos,Scanline,BlitWidth);
6042 pBltPos += lPitch;
6043 pSrcPos += lPitch;
6044 if(! (--BlitHeight))
6045 break;
6046 }
6047 }
6048
6049}
6050
6051//******************************************************************************
6052//
6053// Purpose : Do a blit using the precalced Transbuffer
6054// That is the only way to do fast blits if a colorrange is used
6055// and we can find totally transparent lines and don't blit them
6056// and detect if the part of the line is transparent
6057//
6058// Idea for a kind of mask buffer
6059// Format of Transparentbuffer (each line):
6060// the first DWORD contains 2 WORDS with Offset of First Non transparent
6061// pixel in the low word and the last non transparent pixel in a row in
6062// the high word. => 0 = line totally transparent!
6063// This limits the max supported width to 2^16 but I thing this is enougth
6064// The size per line is 1+((Width+31) & ~31) DWORDS => each Bit represents
6065// 1 pixel
6066//
6067// TransparentBufferCreate(lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
6068//
6069// Layout of a DWORD:
6070// UUVVWWXX dword is processed LS Byte FIRST ...
6071// Each bit in a byte stands for one pixel. MS Bit First
6072//
6073// example: Bitmap (16x5) (X= opaque, . = Transparent)
6074// ...XX...XX....XX
6075// ..XXXX....XXXX..
6076// ................
6077// .........XXXXXX.
6078// ...XX...X......X
6079//
6080// Transparent buffer (2DWORDS) per line
6081//
6082// 0x00100003, 0x0000C318
6083// 0x000E0002, 0x00003C3C
6084// 0x00000000, 0x00000000
6085// 0x000F000A, 0x00007E00
6086// 0x00100003, 0x00008118
6087//******************************************************************************
6088
6089void __cdecl TransSRCBlit8(LPDDSURFACEDESC2 pDestDesc, LPDDSURFACEDESC2 pSrcDesc, char *pAlpha, LPRECT lpSrcRect)
6090{
6091 DWORD *pdwTLine; // pointer to the transparent buffer
6092 DWORD dwTLineLen; // # of DWORDS in each tBuffer line
6093 DWORD dwTLineStart; // # DWORD in which the first transinfo is
6094 DWORD dwTDWStart; // byte in which the firs transinfo is
6095
6096 dwTLineLen = 1 + ((pSrcDesc->dwWidth + 31) & ~31);
6097 pdwTLine = (DWORD*)pAlpha + (dwTLineLen* lpSrcRect->top);
6098 dwTLineStart = 1+(lpSrcRect->left/32);
6099 dwTDWStart = (lpSrcRect->left+8)/8;
6100}
6101
6102
Note: See TracBrowser for help on using the repository browser.