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

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

Fixes to let RA run

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