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

Last change on this file since 2638 was 2638, checked in by hugh, 26 years ago

Bugfixes at many places

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