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

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

compile fix

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