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

Last change on this file since 7940 was 7940, checked in by sandervl, 24 years ago

compile fixes

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