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

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

Changed to put logging info back to common logfile odin32_x.log

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