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

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

updates for stretch blitting

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