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

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

commented out Dive(De)AcquireFrameBuffer in SurfLock/Unlock

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