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

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

MoveRect fixes (src & dest surfaces the same + overlap); fill fixes + optimizations

File size: 194.8 KB
Line 
1/* $Id: OS2SURFACE.CPP,v 1.46 2002-07-03 15:44:37 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
4894 return rc;
4895}
4896//******************************************************************************
4897//******************************************************************************
4898HRESULT WIN32API SurfReleaseDC(THIS This, HDC hdc)
4899{
4900 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4901 struct
4902 {
4903 BITMAPINFOHEADER bmiHead;
4904 RGBQUAD bmiCols[256];
4905 } BitmapInfo;
4906 int rc;
4907
4908 dprintf(("DDRAW: SurfReleaseDC\n"));
4909
4910 if(hdc != me->hdcImage)
4911 return(DDERR_INVALIDOBJECT);
4912
4913 //unselect our bitmap
4914 SelectObject(me->hdcImage, me->hgdiOld);
4915
4916 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4917 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4918 BitmapInfo.bmiHead.biBitCount = me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4919 BitmapInfo.bmiHead.biPlanes = 1;
4920 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.dwWidth; /// (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4921 BitmapInfo.bmiHead.biHeight = me->DDSurfaceDesc.dwHeight;
4922
4923 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4924 {
4925 case 1:
4926 case 4:
4927 case 8:
4928 BitmapInfo.bmiHead.biCompression = BI_RGB;
4929 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4930 rc = GetDIBits( hdc,
4931 me->hbmImage,
4932 0,
4933 me->DDSurfaceDesc.dwHeight,
4934 NULL,
4935 (PBITMAPINFO)&BitmapInfo,
4936 DIB_RGB_COLORS);
4937// BitmapInfo.bmiHead.biHeight = -BitmapInfo.bmiHead.biHeight;
4938 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
4939 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
4940 rc,
4941 BitmapInfo.bmiHead.biSize,
4942 BitmapInfo.bmiHead.biWidth,
4943 BitmapInfo.bmiHead.biHeight,
4944 BitmapInfo.bmiHead.biPlanes,
4945 BitmapInfo.bmiHead.biBitCount,
4946 GetLastError(),
4947 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4948
4949 rc = GetDIBits( hdc,
4950 me->hbmImage,
4951 0,
4952 me->DDSurfaceDesc.dwHeight,
4953 me->DDSurfaceDesc.lpSurface,
4954 (PBITMAPINFO)&BitmapInfo,
4955 DIB_RGB_COLORS);
4956 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
4957 rc,
4958 GetLastError(),
4959 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4960 break;
4961 case 16:
4962 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4963 BitmapInfo.bmiHead.biClrUsed = 3;
4964 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4965 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4966 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4967 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4968 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4969 break;
4970
4971 case 32:
4972 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4973 BitmapInfo.bmiHead.biClrUsed = 3;
4974 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4975 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4976 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4977 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4978 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4979 break;
4980
4981 case 24:
4982 BitmapInfo.bmiHead.biCompression = BI_RGB;
4983 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4984 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4985 break;
4986 default:
4987 dprintf(("DDRAW: Unexpected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4988 // we might could keep the surface locked and return an error but this is more "safe"
4989 break;
4990 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4991
4992 me->Vtbl.Unlock(me,NULL);
4993 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
4994
4995 return(DD_OK);
4996}
4997//******************************************************************************
4998//******************************************************************************
4999HRESULT WIN32API SurfRestore(THIS)
5000{
5001 dprintf(("DDRAW: SurfRestore\n"));
5002
5003 return(DD_OK);
5004}
5005//******************************************************************************
5006//******************************************************************************
5007HRESULT WIN32API SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
5008{
5009 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5010
5011 dprintf(("DDRAW: SurfSetClipper %x %x", This, lpClipper));
5012
5013 if(lpClipper == NULL)
5014 {
5015 //deattach surface
5016 if(me->lpClipper)
5017 {
5018 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
5019 me->lpClipper = NULL;
5020 return(DD_OK);
5021 }
5022 else
5023 return(DDERR_NOCLIPPERATTACHED);
5024 }
5025
5026 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
5027 return(DD_OK); //already attached
5028
5029 if(me->lpClipper != NULL)
5030 {
5031 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
5032 return(DD_OK);
5033 }
5034
5035 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
5036 me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
5037
5038 return(DD_OK);
5039}
5040//******************************************************************************
5041//******************************************************************************
5042HRESULT WIN32API SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
5043{
5044 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5045 HRESULT rc;
5046
5047 dprintf(("DDRAW: SurfSetColorKey %d %08X\n", dwFlags, lpDDColKey));
5048
5049 if (0==dwFlags)
5050 {
5051 return (DDERR_INVALIDPARAMS);
5052 }
5053
5054 // as we report only src colorkey in the caps return error on all others flags
5055 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
5056 {
5057 dprintf(("Unspported colorkey\n"));
5058 return(DDERR_UNSUPPORTED);
5059 }
5060
5061 if(DDCKEY_SRCBLT & dwFlags)
5062 {
5063
5064 //(me->lpVtbl == me->Vtbl4)
5065 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
5066 if(NULL!=lpDDColKey)
5067 {
5068 dprintf(("copy colorkey"));
5069 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
5070 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
5071
5072 // ToDo: Generate a maskbitmap for transparent blitting here
5073 }
5074 else
5075 {
5076 dprintf(("clear colorkey"));
5077 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
5078 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
5079 }
5080 rc = DD_OK;
5081 }
5082 else
5083 {
5084 dprintf(("Unsupported flags"));
5085 #ifdef DEBUG
5086 _dump_DDCOLORKEY(dwFlags);
5087 #endif
5088 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
5089 }
5090 return rc;
5091}
5092//******************************************************************************
5093//******************************************************************************
5094HRESULT WIN32API SurfSetOverlayPosition(THIS This, LONG lX, LONG lY)
5095{
5096 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5097
5098 dprintf(("DDRAW: SurfSetOverlayPosition\n"));
5099
5100 if( (me->DDSurfaceDesc.dwFlags & DDSD_CAPS) &&
5101 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
5102 {
5103 if(me->fOverlayValid)
5104 return(DDERR_NOOVERLAYDEST);
5105
5106 if(!(me->DDSurfaceDesc.dwFlags & DDSCAPS_VISIBLE))
5107 return(DDERR_OVERLAYNOTVISIBLE);
5108
5109 // ToDo: If we implement alignment restricions to the Overlay position
5110 // check if the new values are OK otherwiese return DDERR_INVALIDPOSITION
5111
5112 me->lOverlayX = lX;
5113 me->lOverlayY = lY;
5114 return(DD_OK);
5115 }
5116
5117 return(DDERR_NOTAOVERLAYSURFACE);
5118}
5119//******************************************************************************
5120//******************************************************************************
5121HRESULT WIN32API SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
5122{
5123 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5124
5125 dprintf(("DDRAW: SurfSetPalette\n"));
5126
5127 if(lpPalette == NULL)
5128 {
5129 //deattach palette
5130 if(me->lpPalette)
5131 {
5132 // If removed from a primary surface notify
5133 // palette that it is no longer attached to the
5134 // primary surface => doesn't modify physical palette
5135 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
5136 {
5137 me->lpPalette->SetIsPrimary(FALSE);
5138 }
5139 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
5140 me->lpPalette = NULL;
5141 return(DD_OK);
5142 }
5143 else
5144 return(DDERR_NOPALETTEATTACHED);
5145 }
5146
5147 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
5148 return(DD_OK); //already attached
5149
5150 if(me->lpPalette != NULL)
5151 {
5152 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
5153 //return(DD_OK);
5154 }
5155 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
5156 me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
5157
5158 // If Attached to a primary surface notify
5159 // palette that it is attached to the primary surface
5160 // => It does modify physical palette.
5161 // This is important as an palette can be attached to
5162 // multiple surfaces. If one is the primary surface
5163 // changes done to it via any surface must result in
5164 // changes in the phys pal.
5165
5166 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
5167 {
5168 me->lpPalette->SetIsPrimary(TRUE);
5169 }
5170 // me->lpVtbl->ChangeUniquenessValue(me);
5171
5172 return(DD_OK);
5173}
5174//******************************************************************************
5175//******************************************************************************
5176HRESULT WIN32API SurfUnlock(THIS This, LPVOID lpSurfaceData)
5177{
5178
5179 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5180 int i;
5181 DDRectangle *pIRectUnlock, *pIRectEnum;
5182 BOOL Found = FALSE;
5183 OS2RECTL CCRect;
5184 HRESULT rc;
5185
5186 dprintf(("DDRAW: SurfUnlock at %08X\n",lpSurfaceData));
5187
5188 if(me->fLocked == FALSE)
5189 {
5190 dprintf(("DDRAW: Surface not locked!\n"));
5191 return(DDERR_NOTLOCKED);
5192 }
5193
5194 i=0;
5195 if(NULL!=lpSurfaceData)
5196 {
5197 dprintf(("DDRAW: Buffer Pointer Compare"));
5198
5199 // We got a pinter to the surface memory so we must search for
5200 // this pointer in the locked rects DPA to unlock the right rect.
5201
5202 while(i < DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5203 {
5204 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5205 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5206 i,
5207 pIRectEnum->Top(),
5208 pIRectEnum->Left(),
5209 pIRectEnum->Bottom(),
5210 pIRectEnum->Right(),
5211 pIRectEnum->GetMemPtr() ));
5212
5213 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
5214 if(!Found)
5215 {
5216 dprintf(("DDRAW: Not Found, try Next rect\n"));
5217 i++;
5218 }
5219 else
5220 {
5221 dprintf(("DDRAW: Found Rect\n"));
5222 }
5223 }
5224 }
5225 else
5226 {
5227 // If a NULL pointer was passed in the SW tries to unlock the
5228 // complete surface so we must compare the rects.
5229 dprintf(("DDRAW: Rectangle compare"));
5230
5231#if 1
5232 i = 0;
5233 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,0);
5234 Found = (pIRectEnum != NULL);
5235#else
5236 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
5237
5238 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5239 {
5240 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5241 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5242 i,
5243 pIRectEnum->Top(),
5244 pIRectEnum->Left(),
5245 pIRectEnum->Bottom(),
5246 pIRectEnum->Right(),
5247 pIRectEnum->GetMemPtr() ));
5248
5249 Found = (*pIRectEnum == *pIRectUnlock);
5250 if(!Found)
5251 {
5252 dprintf(("DDRAW: Not Found, try Next rect\n"));
5253 i++;
5254 }
5255 else
5256 {
5257 dprintf(("DDRAW: Found Rect\n"));
5258 }
5259 }
5260 delete pIRectUnlock;
5261#endif
5262 }
5263
5264 if(!Found)
5265 {
5266 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
5267 rc = DDERR_INVALIDRECT;
5268 }
5269 else
5270 {
5271 dprintf(("DDRAW: Remove Rect %d from Seq.\n",i));
5272
5273 DPA_DeletePtr(me->DPA_LockedRects,i);
5274
5275 dprintf(("DDRAW: Test if locked Rects main\n"));
5276
5277 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5278 {
5279 dprintf(("DDRAW: No Locked Rects left for surface\n"));
5280 me->fLocked = FALSE;
5281 }
5282 #ifdef DEBUG
5283 else
5284 dprintf(( "%d Rects in Seq\n",
5285 DPA_GetPtrCount(me->DPA_LockedRects)));
5286 #endif
5287
5288 if(me->pFrameBuffer != me->pDiveBuffer)
5289 {
5290 dprintf(( "ColorConversion Needed %08X != %08X\n",
5291 me->pFrameBuffer,
5292 me->pDiveBuffer));
5293 if(NULL!=lpSurfaceData)
5294 {
5295 CCRect.yTop = pIRectEnum->Top();
5296 CCRect.xLeft = pIRectEnum->Left();
5297 CCRect.xRight = pIRectEnum->Right();
5298 CCRect.yBottom = pIRectEnum->Bottom();
5299
5300 me->ColorConversion( (LPRECT)&CCRect);
5301 }
5302 else
5303 {
5304 me->ColorConversion(NULL);
5305 }
5306 }
5307 else
5308 dprintf( ("No ColorConversion Needed"));
5309
5310
5311#if 0
5312 if(me->diveBufNr == DIVE_BUFFER_SCREEN)
5313 {
5314 OS2RECTL rectOS2;
5315
5316 rectOS2.xLeft = pIRectEnum->Left();
5317 rectOS2.yBottom = me->DDSurfaceDesc.dwHeight - pIRectEnum->Bottom();
5318 rectOS2.xRight = pIRectEnum->Right();
5319 rectOS2.yTop = me->DDSurfaceDesc.dwHeight - pIRectEnum->Top();
5320 dprintf(("DiveDeacquireFrameBuffer (%d,%d)(%d,%d)", rectOS2.xLeft, rectOS2.yBottom, rectOS2.xRight, rectOS2.yTop));
5321 int ret = DiveDeacquireFrameBuffer(me->hDive);
5322 if(ret) {
5323 dprintf(("ERROR: DiveDeacquireFrameBuffer failed with %d", ret));
5324 }
5325 }
5326#endif
5327
5328 // delete tne DDRectobject of the found rectangle
5329 delete pIRectEnum;
5330
5331 // me->lpVtbl->ChangeUniquenessValue(me);
5332
5333 dprintf(("DDRAW: Unlock OK\n\n"));
5334
5335 rc = DD_OK;
5336 }
5337
5338 return rc;
5339}
5340//******************************************************************************
5341//******************************************************************************
5342HRESULT WIN32API SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
5343{
5344 // MS changed the parameter from LPVOID to LPRECT with DX6
5345 // as DX-6 allways returns a DDSurface4 on create surface this
5346 // is a problem i not NULL is passed in.
5347 // Solution We first test with the pointer ns assuming a rectangle
5348 // if we don't find a rect Which is very likely if we get a pointer
5349 // SurfaceMemory we call SurfUnlock and test for the pointer there.
5350
5351
5352 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5353 int i;
5354 DDRectangle *pIRectUnlock, *pIRectEnum;
5355 BOOL Found = FALSE;
5356 HRESULT rc;
5357
5358 dprintf(("DDRAW: SurfUnlock4\n"));
5359
5360 if(me->fLocked == FALSE)
5361 {
5362 dprintf(("DDRAW: Surface not locked!\n"));
5363 return(DDERR_NOTLOCKED);
5364 }
5365
5366 if(NULL!=lpSurfaceRect)
5367 {
5368 dprintf(("DDRAW: Unlock rectangle\n"));
5369 pIRectUnlock = new DDRectangle( lpSurfaceRect->left, lpSurfaceRect->top,
5370 lpSurfaceRect->right, lpSurfaceRect->bottom);
5371 }
5372 else
5373 {
5374 dprintf(("DDRAW: Unlock complete surface\n"));
5375 pIRectUnlock = new DDRectangle( 0, 0, me->width, me->height);
5376 }
5377
5378 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
5379 pIRectUnlock->Top(),
5380 pIRectUnlock->Left(),
5381 pIRectUnlock->Bottom(),
5382 pIRectUnlock->Right() ));
5383
5384 dprintf(("DDRAW: Start Enumeration of Locked Rects\n"));
5385
5386 i=0;
5387 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5388 {
5389 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5390 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
5391 pIRectEnum->Top(),
5392 pIRectEnum->Left(),
5393 pIRectEnum->Bottom(),
5394 pIRectEnum->Right() ));
5395
5396 Found = (*pIRectEnum == *pIRectUnlock);
5397 if(!Found)
5398 {
5399 dprintf(("DDRAW: Not Found, try Next rect\n"));
5400 i++;
5401 }
5402 else
5403 {
5404 dprintf(("DDRAW: Found Rect\n"));
5405 }
5406 }
5407
5408 if(!Found)
5409 {
5410
5411 if(NULL==lpSurfaceRect)
5412 {
5413 dprintf(("DDRAW: Rectangle not locked, wrong Rect!\n\n"));
5414 return(DDERR_INVALIDRECT);
5415 }
5416 else
5417 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
5418 }
5419 else
5420 {
5421 dprintf(("DDRAW: Remove Rect from Seq.\n"));
5422
5423 DPA_DeletePtr(me->DPA_LockedRects,i);
5424
5425 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5426 {
5427 dprintf(("DDRAW: No Locked Rects left for surface\n"));
5428 me->fLocked = FALSE;
5429 }
5430
5431 if(me->pFrameBuffer != me->pDiveBuffer)
5432 {
5433 dprintf(( "ColorConversion Needed %08X != %08X\n",
5434 me->pFrameBuffer,
5435 me->pDiveBuffer));
5436 me->ColorConversion(lpSurfaceRect);
5437 }
5438
5439 // me->lpVtbl->ChangeUniquenessValue(me);
5440
5441 dprintf(("DDRAW: Unlock OK\n\n"));
5442 rc = DD_OK;
5443
5444 }
5445
5446 return rc;
5447}
5448//******************************************************************************
5449//******************************************************************************
5450HRESULT WIN32API SurfUpdateOverlay(THIS This, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX)
5451{
5452 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5453 return(DD_OK);
5454}
5455//******************************************************************************
5456//******************************************************************************
5457HRESULT WIN32API SurfUpdateOverlay3(THIS This, LPRECT, LPDIRECTDRAWSURFACE3,LPRECT,DWORD, LPDDOVERLAYFX)
5458{
5459 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5460 return(DD_OK);
5461}
5462//******************************************************************************
5463//******************************************************************************
5464HRESULT WIN32API SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX)
5465{
5466 dprintf(("DDRAW: SurfUpdateOverlay\n"));
5467 return(DD_OK);
5468}
5469//******************************************************************************
5470//******************************************************************************
5471HRESULT WIN32API SurfUpdateOverlayDisplay(THIS, DWORD)
5472{
5473 dprintf(("DDRAW: SurfUpdateOverlayDisplay\n"));
5474 return(DD_OK);
5475}
5476//******************************************************************************
5477//******************************************************************************
5478HRESULT WIN32API SurfUpdateOverlayZOrder(THIS, DWORD, LPDIRECTDRAWSURFACE2)
5479{
5480 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
5481 return(DD_OK);
5482}
5483//******************************************************************************
5484//******************************************************************************
5485HRESULT WIN32API SurfUpdateOverlayZOrder3(THIS, DWORD, LPDIRECTDRAWSURFACE3)
5486{
5487 dprintf(("DDRAW: SurfUpdateOverlayZOrder\n"));
5488 return(DD_OK);
5489}
5490//******************************************************************************
5491//******************************************************************************
5492HRESULT WIN32API SurfUpdateOverlayZOrder4(THIS, DWORD, LPDIRECTDRAWSURFACE4)
5493{
5494 dprintf(("DDRAW: SurfUpdateOverlayZOrder4\n"));
5495 return(DD_OK);
5496}
5497//******************************************************************************
5498//******************************************************************************
5499HRESULT WIN32API SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
5500{
5501 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5502
5503 dprintf(("DDRAW: SurfGetDDInterface\n"));
5504 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
5505 return(DD_OK);
5506}
5507//******************************************************************************
5508//******************************************************************************
5509HRESULT WIN32API SurfPageLock(THIS, DWORD)
5510{
5511 // Only used for DMA memory access
5512 // If we implement this for the None dive buffers with a pdd the we must change
5513 // from malloc to DosAllocMem and use OBJ_TILE flag
5514 dprintf(("DDRAW: SurfPageLock\n"));
5515 return(DD_OK);
5516}
5517//******************************************************************************
5518//******************************************************************************
5519HRESULT WIN32API SurfPageUnlock(THIS, DWORD)
5520{
5521 dprintf(("DDRAW: SurfPageUnlock\n"));
5522 return(DD_OK);
5523}
5524//******************************************************************************
5525//******************************************************************************
5526// V3 Interface Functions
5527
5528HRESULT WIN32API SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
5529{
5530 dprintf(("DDRAW: SurfSetSurfaceDesc\n"));
5531
5532 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5533 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5534 return DDERR_INVALIDPARAMS;
5535
5536 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5537 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5538 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5539 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5540 if(-1==me->diveBufNr)
5541 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5542
5543 if (!me->Updated)
5544 {
5545 me->Updated = TRUE;
5546 // free our allocated Memory
5547 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5548 {
5549 if(me->pFBreal)
5550 free(me->pFBreal);
5551 if(me->pDBreal)
5552 free(me->pFBreal);
5553 }
5554 }
5555 // me->lpVtbl->ChangeUniquenessValue(me);
5556 memcpy( (char*)&(me->DDSurfaceDesc),
5557 (char*)lpSurfDesc,
5558 sizeof(DDSURFACEDESC));
5559
5560 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5561
5562 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5563 {
5564 // create CC buffer ....
5565 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5566 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5567 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5568 }
5569 return DD_OK;
5570}
5571//******************************************************************************
5572//******************************************************************************
5573HRESULT WIN32API SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
5574{
5575 dprintf(("DDRAW: SurfSetSurfaceDesc4\n"));
5576
5577 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5578 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5579 return DDERR_INVALIDPARAMS;
5580
5581 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5582 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5583 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5584 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5585 if(-1==me->diveBufNr)
5586 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5587
5588 if (!me->Updated)
5589 {
5590 me->Updated = TRUE;
5591 // free our allocated Memory
5592 // free our allocated Memory
5593 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5594 {
5595 if(me->pFBreal)
5596 free(me->pFBreal);
5597 if(me->pDBreal)
5598 free(me->pFBreal);
5599 }
5600 }
5601 // me->lpVtbl->ChangeUniquenessValue(me);
5602 memcpy( (char *)&(me->DDSurfaceDesc),
5603 (char*)lpSurfDesc,
5604 sizeof(DDSURFACEDESC2));
5605 me->dwPitchFB = me->DDSurfaceDesc.lPitch;
5606
5607 if( me->lpDraw->dCaps.ulDepth != me->lpDraw->GetScreenBpp() )
5608 {
5609 // create CC buffer ....
5610 me->dwPitchDB = (me->DDSurfaceDesc.dwWidth * me->dwBytesPPDive +7) & ~7;
5611 me->pDBreal = (char*)malloc( me->DDSurfaceDesc.dwHeight * me->dwPitchDB + 24);
5612 me->pDiveBuffer = (char*)(((int)me->pDBreal + 7) & ~7); // align to QWORD
5613 }
5614
5615 return DD_OK;
5616}
5617//******************************************************************************
5618//******************************************************************************
5619// V4 Interface Functions
5620
5621HRESULT WIN32API SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
5622 DWORD dwDataSize, DWORD dwFlags)
5623{
5624 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5625 int i;
5626 PSURFPRIVATEDATA pSData;
5627 void *pBuffer;
5628 BOOL bFound = FALSE;
5629 HRESULT rc;
5630
5631 dprintf(("DDRAW: SurfSetPrivateData\n"));
5632
5633 if(NULL==me)
5634 return(DDERR_INVALIDOBJECT);
5635
5636 if((NULL==lpData)||(0==dwDataSize)||
5637 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
5638 return(DDERR_INVALIDPARAMS);
5639
5640 // first check if the refGUID is stored as then the content will be updated
5641 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
5642 {
5643 i=0;
5644 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5645 {
5646 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5647
5648 if (IsEqualGUID(pSData->guidTag,refGUID))
5649 bFound = TRUE;
5650
5651 i++;
5652 }
5653 }
5654
5655 if(bFound)
5656 {
5657 // update Private Data
5658
5659 if (!pSData->isValid)
5660 {
5661 // Current data is invalid we need to update/allocate
5662
5663 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5664 {
5665 pSData->pData = lpData;
5666 pSData->dwSize = 4;
5667 pSData->dwFlags = dwFlags;
5668 pSData->isValid = TRUE;
5669 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
5670 }
5671 else
5672 {
5673 pSData->pData = malloc(dwDataSize);
5674 if(NULL!=pSData->pData)
5675 {
5676 memcpy(pSData->pData,lpData,dwDataSize);
5677 pSData->dwSize = dwDataSize;
5678 pSData->dwFlags = dwFlags;
5679 pSData->isValid = TRUE;
5680 }
5681 else
5682 {
5683 delete pSData;
5684 rc = DDERR_OUTOFMEMORY;
5685 }
5686 }
5687 }
5688 else
5689 {
5690 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5691 {
5692 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5693 {
5694 if(pSData->pData != lpData)
5695 {
5696 // Change of IUNKOWNPOINTER => release old and add ref to new one
5697 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5698 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5699 pSData->pData = lpData;
5700 }
5701 pSData->dwFlags = dwFlags; // Update the flags, size is the same
5702 }
5703 else
5704 {
5705 // Replace IUNKOWN through data
5706 pBuffer = malloc(dwDataSize); // get new buffer first
5707 if(NULL!=pBuffer)
5708 {
5709 // release old ref and copy data
5710 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5711 memcpy(pBuffer,lpData,dwDataSize);
5712 pSData->pData = pBuffer;
5713 pSData->dwSize = dwDataSize; // Update the size
5714 pSData->dwFlags = dwFlags; // Update the flags
5715 }
5716 else
5717 rc = DDERR_OUTOFMEMORY;
5718 }
5719 }
5720 else
5721 {
5722 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5723 {
5724 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
5725 free(pSData->pData);
5726 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5727 pSData->pData = lpData;
5728 pSData->dwSize = dwDataSize; // Update the size
5729 pSData->dwFlags = dwFlags; // Update the flags
5730 }
5731 else
5732 {
5733 // Update/Replace data
5734 if(pSData->dwSize!=dwDataSize)
5735 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
5736 else
5737 pBuffer = pSData->pData;
5738
5739 if(NULL!=pBuffer)
5740 {
5741 // release old ref and copy data
5742 memcpy(pBuffer,lpData,dwDataSize);
5743 pSData->pData = pBuffer;
5744 pSData->dwSize = dwDataSize; // Update the size
5745 pSData->dwFlags = dwFlags; // Update the flags
5746 }
5747 else
5748 rc = DDERR_OUTOFMEMORY;
5749 }
5750 }
5751 }
5752 }
5753 else
5754 {
5755 // New data
5756
5757 pSData = new(SURFPRIVATEDATA);
5758 if (NULL!=pSData)
5759 {
5760 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5761 {
5762 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5763 pSData->pData = lpData;
5764 pSData->dwSize = 4;
5765 pSData->dwFlags = dwFlags;
5766 pSData->isValid = TRUE;
5767 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5768 }
5769 else
5770 {
5771 pSData->pData = malloc(dwDataSize);
5772 if(NULL!=pSData->pData)
5773 {
5774 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5775 memcpy(pSData->pData,lpData,dwDataSize);
5776 pSData->dwSize = dwDataSize;
5777 pSData->dwFlags = dwFlags;
5778 pSData->isValid = TRUE;
5779
5780 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
5781 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
5782 pSData) <0)
5783 {
5784 delete(pSData);
5785 rc = DDERR_OUTOFMEMORY;
5786 }
5787 }
5788 else
5789 {
5790 delete(pSData);
5791 rc = DDERR_OUTOFMEMORY;
5792 }
5793 }
5794
5795 }
5796 else
5797 rc = DDERR_OUTOFMEMORY;
5798 }
5799
5800 return rc;
5801}
5802//******************************************************************************
5803//******************************************************************************
5804HRESULT WIN32API SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
5805{
5806 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5807 int i;
5808 PSURFPRIVATEDATA pSData;
5809 HRESULT rc;
5810 BOOL bFound = FALSE;
5811
5812 dprintf(("DDRAW: SurfGetPrivateData\n"));
5813
5814 if(NULL==me)
5815 return(DDERR_INVALIDOBJECT);
5816
5817 if((NULL==lpData)||(NULL==lpDataSize))
5818 return(DDERR_INVALIDPARAMS);
5819
5820 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5821 {
5822 i=0;
5823 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5824 {
5825 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5826
5827 if (IsEqualGUID(pSData->guidTag,refGUID))
5828 bFound = TRUE;
5829
5830 i++;
5831 }
5832 }
5833
5834 if(bFound)
5835 {
5836 if(!pSData->isValid)
5837 {
5838 rc =DDERR_EXPIRED;
5839 }
5840 else
5841 {
5842 if(pSData->dwSize > *lpDataSize)
5843 {
5844 // Buffer to small return needed Size
5845 *lpDataSize = pSData->dwSize;
5846 rc = DDERR_MOREDATA;
5847 }
5848 else
5849 {
5850 memcpy(lpData,pSData->pData,pSData->dwSize);
5851 rc = DD_OK;
5852 }
5853 }
5854 }
5855 else
5856 rc = DDERR_NOTFOUND;
5857
5858
5859 return rc;
5860}
5861//******************************************************************************
5862//******************************************************************************
5863HRESULT WIN32API SurfFreePrivateData(THIS This, REFGUID refGUID)
5864{
5865 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5866 int i;
5867 PSURFPRIVATEDATA pSData;
5868 BOOL bFound = FALSE;
5869
5870 dprintf(("DDRAW: SurfFreePrivateData\n"));
5871
5872 if(NULL==me)
5873 return(DDERR_INVALIDOBJECT);
5874
5875 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5876 {
5877 i=0;
5878 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5879 {
5880 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5881
5882 if (IsEqualGUID(pSData->guidTag,refGUID))
5883 {
5884 bFound = TRUE;
5885
5886 if(pSData->isValid)
5887 {
5888 // delete the data if valid
5889 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5890 {
5891 // pointer to com stored so calll its release
5892 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5893 }
5894 else
5895 {
5896 // Free allocated data
5897 free( pSData->pData);
5898 }
5899 }
5900 // Now remove the entry from the list
5901 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
5902 }
5903 i++;
5904 }
5905 }
5906
5907 return (bFound?DD_OK:DDERR_NOTFOUND);
5908}
5909//******************************************************************************
5910//******************************************************************************
5911HRESULT WIN32API SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
5912{
5913 dprintf(("DDRAW: SurfGetUniquenessValue\n"));
5914 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5915 if (NULL==lpValue)
5916 return DDERR_INVALIDPARAMS;
5917
5918 *lpValue = me->dwUniqueValue;
5919 return DD_OK;
5920}
5921//******************************************************************************
5922//******************************************************************************
5923HRESULT WIN32API SurfChangeUniquenessValue(THIS This)
5924{
5925 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5926 int i;
5927 PSURFPRIVATEDATA pSData;
5928
5929
5930 dprintf(("DDRAW: SurfChangeUniquenessValue\n"));
5931 me->dwUniqueValue++;
5932
5933 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5934 {
5935 i=0;
5936 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
5937 {
5938 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5939 if (pSData->dwFlags & DDSPD_VOLATILE)
5940 {
5941 // Data becomes unvalid after a Surface change
5942 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5943 {
5944 // pointer to com stored so call its release
5945 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5946 }
5947 else
5948 {
5949 // Free allocated data
5950 free( pSData->pData);
5951 }
5952 pSData->pData = NULL;
5953 pSData->isValid = FALSE; // set flag to invalid
5954 }
5955 i++;
5956 }
5957 }
5958
5959 return (DD_OK);
5960}
5961
5962
5963
5964//******************************************************************************
5965//
5966// Purpose function copies one part of the bitmap inside the same bitmap
5967//
5968//******************************************************************************
5969
5970void __cdecl MoveRects(char* pBuffer, LPRECT lpDestRect, LPRECT lpSrcRect, int bpp, LONG lPitch)
5971{
5972
5973 char *pBltPos, *pSrcPos;
5974 int BlitWidth,BlitHeight;
5975 static char Scanline[6400]; // sufficient for 1600 at 32 bit
5976
5977 if(sizeof(Scanline) < lPitch) {
5978 DebugInt3(); //oh, oh
5979 return;
5980 }
5981 // Bridge, we may got a problem ;)
5982 // Check for Overlapping Rects
5983
5984 pBltPos = pBuffer;
5985 pSrcPos = pBuffer;
5986
5987 if(lpDestRect->top > lpSrcRect->top)
5988 {
5989 // +-------+ +-------+ +-------+
5990 // |S | |S | |S |
5991 // | +---|---+ +-------+ +---|---+ |
5992 // | | D | | | D | | D | | |
5993 // +-------+ | +-------+ | +-------+
5994 // | | | | | |
5995 // +-------+ +-------+ +-------+
5996 //
5997 // We got one of the above cases (or no overlapping) so copy from bottom up
5998
5999 pBltPos += (lpDestRect->left * bpp) + lPitch * (lpDestRect->bottom-1);
6000 pSrcPos += (lpSrcRect->left * bpp) + lPitch * (lpSrcRect->bottom-1);
6001 BlitHeight = lpDestRect->bottom - lpDestRect->top;
6002 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
6003
6004 while(1)
6005 {
6006 memcpy(Scanline,pSrcPos,BlitWidth);
6007 memcpy(pBltPos,Scanline,BlitWidth);
6008 pBltPos -= lPitch;
6009 pSrcPos -= lPitch;
6010 if(! (--BlitHeight))
6011 break;
6012 }
6013 }
6014 else
6015 {
6016 // +-------+ +-------+ +-------+
6017 // | D | | D | | D |
6018 // | +---|---+ +-------+ +---|---+ | +---+---+---+
6019 // | |S | | |S | |S | | | |S |S/D| D |
6020 // +-------+ | +-------+ | +-------+ | | | |
6021 // | | | | | | | | | |
6022 // +-------+ +-------+ +-------+ +---+---+---+
6023 //
6024 // We got one of the above cases so copy top down
6025
6026 pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
6027 pSrcPos += (lpSrcRect->left * bpp) + lPitch * lpSrcRect->top;
6028 BlitHeight = lpDestRect->bottom - lpDestRect->top;
6029 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
6030
6031 while(1)
6032 {
6033 memcpy(Scanline,pSrcPos,BlitWidth);
6034 memcpy(pBltPos,Scanline,BlitWidth);
6035 pBltPos += lPitch;
6036 pSrcPos += lPitch;
6037 if(! (--BlitHeight))
6038 break;
6039 }
6040 }
6041
6042}
6043
6044//******************************************************************************
6045//
6046// Purpose : Do a blit using the precalced Transbuffer
6047// That is the only way to do fast blits if a colorrange is used
6048// and we can find totally transparent lines and don't blit them
6049// and detect if the part of the line is transparent
6050//
6051// Idea for a kind of mask buffer
6052// Format of Transparentbuffer (each line):
6053// the first DWORD contains 2 WORDS with Offset of First Non transparent
6054// pixel in the low word and the last non transparent pixel in a row in
6055// the high word. => 0 = line totally transparent!
6056// This limits the max supported width to 2^16 but I thing this is enougth
6057// The size per line is 1+((Width+31) & ~31) DWORDS => each Bit represents
6058// 1 pixel
6059//
6060// TransparentBufferCreate(lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
6061//
6062// Layout of a DWORD:
6063// UUVVWWXX dword is processed LS Byte FIRST ...
6064// Each bit in a byte stands for one pixel. MS Bit First
6065//
6066// example: Bitmap (16x5) (X= opaque, . = Transparent)
6067// ...XX...XX....XX
6068// ..XXXX....XXXX..
6069// ................
6070// .........XXXXXX.
6071// ...XX...X......X
6072//
6073// Transparent buffer (2DWORDS) per line
6074//
6075// 0x00100003, 0x0000C318
6076// 0x000E0002, 0x00003C3C
6077// 0x00000000, 0x00000000
6078// 0x000F000A, 0x00007E00
6079// 0x00100003, 0x00008118
6080//******************************************************************************
6081
6082void __cdecl TransSRCBlit8(LPDDSURFACEDESC2 pDestDesc, LPDDSURFACEDESC2 pSrcDesc, char *pAlpha, LPRECT lpSrcRect)
6083{
6084 DWORD *pdwTLine; // pointer to the transparent buffer
6085 DWORD dwTLineLen; // # of DWORDS in each tBuffer line
6086 DWORD dwTLineStart; // # DWORD in which the first transinfo is
6087 DWORD dwTDWStart; // byte in which the firs transinfo is
6088
6089 dwTLineLen = 1 + ((pSrcDesc->dwWidth + 31) & ~31);
6090 pdwTLine = (DWORD*)pAlpha + (dwTLineLen* lpSrcRect->top);
6091 dwTLineStart = 1+(lpSrcRect->left/32);
6092 dwTDWStart = (lpSrcRect->left+8)/8;
6093}
6094
6095
Note: See TracBrowser for help on using the repository browser.