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

Last change on this file since 4146 was 4146, checked in by sandervl, 25 years ago

more logging + implemented GetClipList

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