source: trunk/src/ddraw/new/OS2SURFACE.CPP@ 5280

Last change on this file since 5280 was 4326, checked in by mike, 25 years ago

Fixed FS corruption

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