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

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

take clipping info into account when blitting

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