source: trunk/src/ddraw/new/os2surface.cpp@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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