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

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

FOURCC checking during surface creation

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