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

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

Changed dprintf to add DDRAW: at start of a entry
Also copied framebuffer for solid blits to the prinmary surface
Red Alert Map editor does work now ;)

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