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

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

back buffer fix

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