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

Last change on this file since 9156 was 9156, checked in by sandervl, 23 years ago

PF: Added custom function to hide mouse cursor when the primary surface (screen) is locked by the app to prevent display corruption with color/animated mouse pointers

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