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

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

Added io_init2 function
Fixed some bugs in the ColorFillCode

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