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

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

Fixed callconvention bug, added src transblt code

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