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

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

don't use dive for 8bpp surfaces

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