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

Last change on this file since 2987 was 2987, checked in by hugh, 25 years ago

Bugfixes for moorhuhn

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