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

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

minor updates

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