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

Last change on this file since 2192 was 2192, checked in by hugh, 26 years ago

Fixed bug in destructor of surfaces

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