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

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

colorfill fix

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