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

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

color fill fixes (heap corruption & missing lines)

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