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

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

Changes handling of Interfaces.
Now DX2 interface is default (shouldf be DX1 but no SW uses it)
and the others can be queried.

RESULT: Quake II runs again!!!

Remarked out ChangeUniqueValue in the functions
as this is a DX6 funciton so for the DX6 interface I should
implement these functions again with the code reenabled.

File size: 184.2 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(("%s ",flags[i].name));
314 };
315 dprintf(("\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(("%s ",flags[i].name));
334 dprintf(("\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(("%s ",flags[i].name));
374 dprintf(("\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(("%s ",flags[i].name));
418 dprintf(("\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(("%s ",flags[i].name));
438 dprintf(("\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(("%s ",flags[i].name));
469 dprintf(("\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(("%s ",flags[i].name));
497 dprintf(("\n"));
498}
499
500static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
501 _dump_DDCOLORKEY(pf->dwFlags);
502 dprintf(("dwFourCC : %ld\n", pf->dwFourCC));
503 dprintf(("RBG bit cbout : %ld\n", pf->dwRGBBitCount));
504 dprintf(("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(("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(("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(("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(("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(("Primary surface!\n"));
733 #endif
734
735 if( lpDraw->HasPrimarySurface())
736 {
737 #ifdef DEBUG
738 dprintf(("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(("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(("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(("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(("Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
858 #endif
859 break;
860 } // end switch
861
862 #ifdef DEBUG
863 dprintf(("Surface set up, checking other Caps\n"));
864 #endif
865
866 if( DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
867 {
868 #ifdef DEBUG
869 dprintf(("Complex Surface\n"));
870 #endif
871
872 if(lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
873 {
874 #ifdef DEBUG
875 dprintf(("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(("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(("Error creating backbuffer"));
916 }
917 }
918 else
919 {
920 #ifdef DEBUG
921 dprintf(("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((" 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((" 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(("Unexpected BitDepth : %d\n",lpDraw->GetScreenBpp()));
1016 #endif
1017 break;
1018 } // end switch
1019
1020 }
1021
1022 dprintf(("%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((" 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((" 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(("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((" 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(("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((" 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((" 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((" Alloc CCBuf "));
1160 dwPitchDB = (lpDDSurfaceDesc->dwWidth * (lpDraw->dCaps.ulDepth/8) +7) & ~7;
1161 if(Mainchain)
1162 {
1163 dprintf(("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(("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(("Complex Surface\n"));
1203 #endif
1204
1205 if(lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
1206 {
1207 lpDDSurfaceDesc->dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1208 #ifdef DEBUG
1209 dprintf(("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(("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(("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(("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(("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(("CAPS not valid\n"));
1291 lastError = DDERR_INVALIDPARAMS;
1292 }
1293 #ifdef DEBUG
1294 dprintf(("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(("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(("ColorFill with %08X\n", dwFillColor));
1316 #endif
1317
1318 if(NULL!=lpDestRect)
1319 {
1320 #ifdef DEBUG
1321 dprintf(("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(("Fill all at addr "));
1333 FillWidth = width;
1334 FillHeight = height -1;
1335 pLine = pDiveBuffer;
1336 }
1337 dprintf(("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(("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(("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(("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(("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(("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(("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(("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(("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(("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((" 8Bit target CC not implemented\n"));
1662 break;
1663 case 15:
1664 dprintf((" 15 Bit not implemented using 16bit might look ugly\n"));
1665 case 16:
1666 if(8==lpDraw->GetScreenBpp())
1667 {
1668 dprintf(("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(("%d ->16Bit Not implemented",lpDraw->GetScreenBpp()));
1683 }
1684 break;
1685 case 24:
1686 if(8==lpDraw->GetScreenBpp())
1687 {
1688 dprintf(("8->24Bit CC"));
1689 }
1690 else
1691 {
1692 dprintf(("%d ->24Bit Not implemented",lpDraw->GetScreenBpp()));
1693 }
1694 break;
1695 case 32:
1696 if(8==lpDraw->GetScreenBpp())
1697 {
1698 dprintf(("8->32Bit CC"));
1699 }
1700 else
1701 {
1702 dprintf(("%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(("AllocDiveDst Buffer rc= 0x%08X\n",rc));
1764
1765 rc = DiveSetupBlitter( hDiveCC,
1766 &sBlt);
1767 dprintf(("SetupBlitter rc= %X\n",rc));
1768
1769 rc = DiveBlitImage( hDiveCC,
1770 ulDN1,
1771 ulDN2);
1772
1773 dprintf(("Blit rc= %X\n",rc));
1774
1775 rc = DiveFreeImageBuffer( hDiveCC,
1776 ulDN1);
1777 dprintf(("Free Src rc= %X\n",rc));
1778
1779 rc = DiveFreeImageBuffer( hDiveCC,
1780 ulDN2);
1781
1782 dprintf(("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(("Remove Frontbuffer\n"));
1895
1896 // The real Frontbuffer was removed check if I'm now the one
1897 if(NULL!=BackBuffer)
1898 {
1899 dprintf(("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(("No longer part of a flipchain\n"));
1909 DDSurfaceDesc.ddsCaps.dwCaps &= ~(DDSCAPS_BACKBUFFER | DDSCAPS_FLIP);
1910 }
1911 }
1912 else
1913 {
1914 dprintf(("Set new Frontbuffer to 0x%08X\n",NewFBuffer));
1915 if(NULL==NewFBuffer->GetFrontBuffer())
1916 {
1917 dprintf(("We're the 1st backbuffer\n"));
1918 DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER | DDSCAPS_FLIP;
1919 FrontBuffer->NextFlip = this;
1920 }
1921 else
1922 {
1923 dprintf(("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(("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(("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(("OS2IDirectDrawSurface::SurfRelease %d\n", me->Referenced-1));
2006 dprintf(("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(("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(("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(("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(("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(("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(("Internal : Error attaching to MipMap\n"));
2100 #endif
2101 return(DDERR_CANNOTATTACHSURFACE);
2102 }
2103 }
2104 else
2105 {
2106 #ifdef DEBUG
2107 dprintf(("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(("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(("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(("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(("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(("Internal : Error attaching to MipMap\n"));
2211 #endif
2212 return(DDERR_CANNOTATTACHSURFACE);
2213 }
2214 }
2215 else
2216 {
2217 #ifdef DEBUG
2218 dprintf(("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(("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(("Surface attached\n"));
2243 return(DD_OK);
2244}
2245//******************************************************************************
2246//******************************************************************************
2247HRESULT __stdcall SurfAddOverlayDirtyRect(THIS, LPRECT)
2248{
2249 #ifdef DEBUG
2250 dprintf(("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(("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(("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(("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(("DepthFill\n"));
2448 #ifdef USE_OPENGL
2449 GLboolean ztest;
2450 // Todo support more than one Z-Buffer
2451 // Clears the screen
2452 dprintf(("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(("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(("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(("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(("No stretched blits\n"));
2625
2626 return DDERR_NOSTRETCHHW;
2627 }
2628
2629 if (dest->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2630 {
2631 dprintf(("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(("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
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 BlitWidth *= dest->dwBytesPPDive;
2684
2685 #ifdef USE_ASM
2686 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
2687 dest->dwPitchDB,
2688 src->dwPitchDB);
2689 #else
2690 // Solid Blit
2691 while(1)
2692 {
2693 memcpy(pBltPos,pSrcPos,BlitWidth);
2694 pBltPos += dest->dwPitchDB;
2695 pSrcPos += src->dwPitchDB;
2696 if(! (--BlitHeight))
2697 break;
2698 }
2699 #endif
2700 }
2701 else
2702 {
2703 // Transparent Blit
2704 if( (dwFlags &DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE) )
2705 {
2706 dprintf(("Transparent src blit not done yet for primary!!"));
2707 }
2708 else
2709 {
2710 dprintf(("Unhandled Flags Destination colorkey ? 0x%04X",dwFlags));
2711 }
2712 }
2713 } // end of handling blitting to primary
2714 } // end of target primary surface
2715 else
2716 {
2717 if(0==src->diveBufNr)
2718 {
2719 // copy from the screen to a buffer
2720
2721 if( (NULL==lpDestRect) &&
2722 (NULL==lpSrcRect) &&
2723 (dest->diveBufNr>0) )
2724 {
2725 // Blitting everything from frontbuffer to a Divebuffer
2726 // ToDo: Might should add checking for flags here
2727 DiveBlitImage(dest->hDive, src->diveBufNr, dest->diveBufNr);
2728 }
2729 else
2730 {
2731 // DIVE => DIVE or Mem => Dive
2732 // or a rectangle from streen to a buffer can be handelt in the same way
2733 pBltPos = (char*) dest->pDiveBuffer + (DestRect.top * dest->dwPitchDB) +
2734 (DestRect.left * dest->dwBytesPPDive);
2735
2736 pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
2737 (SrcRect.left * src->dwBytesPPDive);
2738
2739 BlitHeight = pIRectDest->height();
2740 BlitWidth = pIRectDest->width();
2741
2742 // Check for transparent blit
2743 if(!dwFlags)
2744 {
2745 BlitWidth *= dest->dwBytesPPDive;
2746
2747 #ifdef USE_ASM
2748 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
2749 dest->dwPitchDB,
2750 src->dwPitchDB);
2751 #else
2752 // Solid Blit
2753 while(1)
2754 {
2755 memcpy(pBltPos,pSrcPos,BlitWidth);
2756 pBltPos += dest->dwPitchDB;
2757 pSrcPos += src->dwPitchDB;
2758 if(! (--BlitHeight))
2759 break;
2760 }
2761 #endif
2762 }
2763 else
2764 {
2765 dprintf(("Transblt not done yet"));
2766 if(dwFlags & DDBLT_KEYSRC)
2767 {
2768 if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT))
2769 {
2770 }
2771 }
2772 else
2773 {
2774 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2775 {
2776 }
2777 else
2778 {
2779 }
2780 }
2781 }
2782 }
2783 } // end handling source screen
2784 else
2785 {
2786 // DIVE => DIVE or Mem => Dive can be handelt in the same way
2787
2788 if( (src->pDiveBuffer == dest->pDiveBuffer) &&
2789 (pIRectDest->intersects(*pIRectSrc) ) )
2790 {
2791 // Overlapping rects on the same surface ?
2792
2793 // ToDo : Maybe implement all the fancy blit flags here too ? ;)
2794
2795 MoveRects( dest->pDiveBuffer,
2796 (LPRECT)&DestRect,
2797 (LPRECT)&SrcRect,
2798 dest->dwBytesPPDive,
2799 dest->dwPitchDB);
2800
2801 return DD_OK;
2802 }
2803
2804 pBltPos = (char*) dest->pDiveBuffer + (DestRect.top * dest->dwPitchDB) +
2805 (DestRect.left * dest->dwBytesPPDive);
2806
2807 pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
2808 (SrcRect.left * src->dwBytesPPDive);
2809
2810 BlitHeight = pIRectDest->height();
2811 BlitWidth = pIRectDest->width();
2812
2813 // Check for transparent blit
2814 if(!dwFlags)
2815 {
2816 BlitWidth *= dest->dwBytesPPDive;
2817
2818 #ifdef USE_ASM
2819 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
2820 dest->dwPitchDB,
2821 src->dwPitchDB);
2822 #else
2823 // Solid Blit
2824 while(1)
2825 {
2826 memcpy(pBltPos,pSrcPos,BlitWidth);
2827 pBltPos += dest->dwPitchDB;
2828 pSrcPos += src->dwPitchDB;
2829 if(! (--BlitHeight))
2830 break;
2831 }
2832 #endif
2833 }
2834 else
2835 {
2836 DWORD dwPitch = dest->dwPitchDB;
2837
2838 if(dwFlags &DDBLT_ROTATIONANGLE)
2839 {
2840 return DDERR_NOROTATIONHW;
2841 }
2842
2843 if(dwFlags & DDBLT_DDFX)
2844 {
2845 DWORD dwFx;
2846 DWORD dwSrcColor, dwDestColor;
2847
2848 dwFlags &= ~DDBLT_DDFX; // remove the handled flag
2849
2850 if( NULL==lpDDBltFx)
2851 return DDERR_INVALIDPARAMS;
2852
2853 dwFx = lpDDBltFx->dwDDFX;
2854
2855 // Remove unsupported Flags
2856 dwFx &= ~(DDBLTFX_ARITHSTRETCHY | // Not streach support
2857 DDBLTFX_ZBUFFERBASEDEST | // All ZBuffer flags are not
2858 DDBLTFX_ZBUFFERRANGE | // implementet in M$ Dx 6
2859 DDBLTFX_NOTEARING ); // No sync with VRetrace yet
2860
2861 if(dwFx & DDBLTFX_ROTATE180)
2862 {
2863 // 180 degree turn is a mix of a flip up/down and one left/right
2864 dwFx |= (DDBLTFX_MIRRORUPDOWN | DDBLTFX_MIRRORLEFTRIGHT);
2865 dwFx &= ~DDBLTFX_ROTATE180; // remove handled flag
2866 }
2867 if(dwFx & DDBLTFX_MIRRORUPDOWN)
2868 {
2869 // switching the the direction can be integrated with other flags
2870 dwPitch = -dwPitch;
2871 pBltPos = (char*) dest->pDiveBuffer +
2872 ((DestRect.top +BlitHeight)* dest->dwPitchDB) +
2873 (DestRect.left * dest->dwBytesPPDive);
2874
2875 dwFx &= ~DDBLTFX_MIRRORUPDOWN; // remove handled flag
2876 }
2877
2878 if(dwFx & DDBLTFX_MIRRORLEFTRIGHT)
2879 {
2880 // 180 degree turn or a LR Mirroring
2881 // don't support any other dwFlags like transparent at the moment
2882
2883 switch(dest->dwBytesPPDive)
2884 {
2885 case 1:
2886 while(BlitHeight--)
2887 {
2888 x = BlitWidth;
2889 while(x)
2890 {
2891 pBltPos[BlitWidth-x] = pSrcPos[x];
2892 x--;
2893 }
2894 pBltPos += dwPitch;
2895 pSrcPos += src->dwPitchDB;
2896 }
2897 break;
2898 case 2:
2899 while(BlitHeight--)
2900 {
2901 x = BlitWidth;
2902 while(x)
2903 {
2904 ((USHORT*)pBltPos)[BlitWidth-x] = ((USHORT*)pSrcPos)[x];
2905 x--;
2906 }
2907 pBltPos += dwPitch;
2908 pSrcPos += src->dwPitchDB;
2909 }
2910 break;
2911 case 3:
2912 BlitWidth *= 3;
2913 while(BlitHeight--)
2914 {
2915 x = BlitWidth;
2916 while(x)
2917 {
2918 pBltPos[BlitWidth-x] = pSrcPos[x-2];
2919 x--;
2920 pBltPos[BlitWidth-x] = pSrcPos[x];
2921 x--;
2922 pBltPos[BlitWidth-x] = pSrcPos[x+2];
2923 x--;
2924 }
2925 pBltPos += dwPitch;
2926 pSrcPos += src->dwPitchDB;
2927 }
2928 break;
2929 case 4:
2930 while(BlitHeight--)
2931 {
2932 x = BlitWidth;
2933 while(x)
2934 {
2935 ((DWORD*)pBltPos)[BlitWidth-x] = ((DWORD*)pSrcPos)[x];
2936 x--;
2937 }
2938 pBltPos += dwPitch;
2939 pSrcPos += src->dwPitchDB;
2940 }
2941 break;
2942 } // end switch
2943 //if(dest->lpVtbl == dest->Vtbl4)
2944 // dest->Vtbl4->ChangeUniquenessValue(dest);
2945 return DD_OK;
2946 }
2947
2948 #ifdef DEBUG
2949 if(dwFx)
2950 _dump_DDBLTFX(dwFx);
2951 #endif
2952 // We ignore unhandled flags at the moment
2953 }
2954
2955 if( (dwFlags & DDBLT_KEYSRC) |
2956 (dwFlags & DDBLT_KEYSRCOVERRIDE) )
2957 {
2958 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
2959 {
2960
2961 if( NULL==lpDDBltFx)
2962 return DDERR_INVALIDPARAMS;
2963
2964 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
2965
2966 // We work like the HEL and test only the low value
2967 dwSrcColor = lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue;
2968
2969 }
2970 else
2971 {
2972
2973 dwFlags &= ~DDBLT_KEYSRC;
2974
2975 // Not sure if that is OK maybe check if one is set ?
2976 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_SRCBLT)) return DDERR_WRONGPARAM;?
2977
2978 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
2979 }
2980
2981 // ToDo : We currently indicate that we don't support
2982 // DDBLT_KEYDEST but HEL does change that!
2983 // also add this key in the get/setColorKey functions
2984
2985 if( (dwFlags & DDBLT_KEYDEST) |
2986 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
2987 {
2988 // Source and dest color keying SLOW!!!
2989 if(dwFlags & DDBLT_KEYDESTOVERRIDE)
2990 {
2991 if( NULL==lpDDBltFx)
2992 return DDERR_INVALIDPARAMS;
2993
2994 dwFlags &= ~DDBLT_KEYDESTOVERRIDE;
2995
2996 // We work like the HEL and test only the low value
2997 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
2998
2999 }
3000 else
3001 {
3002
3003 dwFlags &= ~DDBLT_KEYDEST;
3004
3005 // Not sure if that is OK maybe check if one is set ?
3006 // if(!(Dest->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
3007
3008 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3009 }
3010
3011 // This will be be slow maybe move to ASM ?
3012 // using MMX should be much faster
3013 switch(dest->dwBytesPPDive)
3014 {
3015 case 1:
3016 while(BlitHeight--)
3017 {
3018 x = 0;
3019 while(x<BlitWidth)
3020 {
3021 if(pSrcPos[x] != (char) dwSrcColor)
3022 {
3023 if(pBltPos[x] != (char) dwDestColor)
3024 pBltPos[x] = pSrcPos[x];
3025 }
3026 x++;
3027 }
3028 pBltPos += dwPitch;
3029 pSrcPos += src->dwPitchDB;
3030 }
3031 break;
3032 case 2:
3033 while(BlitHeight--)
3034 {
3035 x = 0;
3036 while(x<BlitWidth)
3037 {
3038 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3039 {
3040 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3041 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3042 }
3043 x++;
3044 }
3045 pBltPos += dwPitch;
3046 pSrcPos += src->dwPitchDB;
3047 }
3048 break;
3049 case 3:
3050 {
3051 char *pSC, *pDC;
3052 pSC = (char*)&dwSrcColor;
3053 pDC = (char*)&dwDestColor;
3054 BlitWidth *=3;
3055
3056 while(BlitHeight--)
3057 {
3058 x = 0;
3059
3060 while(x<BlitWidth)
3061 {
3062 if( (pSrcPos[x] != pSC[1]) &&
3063 (pSrcPos[x+1] != pSC[2]) &&
3064 (pSrcPos[x+2] != pSC[3])
3065 )
3066 {
3067 if( (pBltPos[x] != pDC[1]) &&
3068 (pBltPos[x+1] != pDC[2]) &&
3069 (pBltPos[x+2] != pDC[3])
3070 )
3071 {
3072 pBltPos[x] = pSrcPos[x];
3073 pBltPos[x+1] = pSrcPos[x+2];
3074 pBltPos[x+1] = pSrcPos[x+2];
3075 }
3076 }
3077 x +=3;
3078 }
3079 pBltPos += dwPitch;
3080 pSrcPos += src->dwPitchDB;
3081 }
3082 break;
3083 }
3084 case 4:
3085 while(BlitHeight--)
3086 {
3087 x = 0;
3088 while(x<BlitWidth)
3089 {
3090 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3091 {
3092 if(((DWORD*)pBltPos)[x] != dwDestColor)
3093 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3094 }
3095 x++;
3096 }
3097 pBltPos += dwPitch;
3098 pSrcPos += src->dwPitchDB;
3099 }
3100 break;
3101 } // End switch
3102 }
3103 else
3104 {
3105 // Only Source colorkey
3106 }
3107 // if(dest->lpVtbl == dest->Vtbl4)
3108 // dest->Vtbl4->ChangeUniquenessValue(dest);
3109 return DD_OK;
3110 }
3111
3112 if( (dwFlags & DDBLT_KEYDEST) |
3113 (dwFlags & DDBLT_KEYDESTOVERRIDE) )
3114 {
3115 // Dest color keying SLOW!!!
3116 if(dwFlags & DDBLT_KEYSRCOVERRIDE)
3117 {
3118 if( NULL==lpDDBltFx)
3119 return DDERR_INVALIDPARAMS;
3120
3121 dwFlags &= ~DDBLT_KEYSRCOVERRIDE;
3122
3123 // We work like the HEL and test only the low value
3124 dwDestColor = lpDDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
3125
3126 }
3127 else
3128 {
3129
3130 dwFlags &= ~DDBLT_KEYDEST;
3131
3132 // Not sure if that is OK maybe check if one is set ?
3133 // if(!(src->DDSurfaceDesc.dwFlags & DDCKEY_DESTBLT)) return DDERR_WRONGPARAM;?
3134
3135 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3136 }
3137
3138 // This will be be slow maybe move to ASM ?
3139 // using MMX should be much faster
3140 switch(dest->dwBytesPPDive)
3141 {
3142 case 1:
3143 while(BlitHeight--)
3144 {
3145 x = 0;
3146 while(x<BlitWidth)
3147 {
3148 if(pBltPos[x] != (char) dwDestColor)
3149 pBltPos[x] = pSrcPos[x];
3150 x++;
3151 }
3152 pBltPos += dwPitch;
3153 pSrcPos += src->dwPitchDB;
3154 }
3155 break;
3156 case 2:
3157 while(BlitHeight--)
3158 {
3159 x = 0;
3160 while(x<BlitWidth)
3161 {
3162 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3163 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3164 x++;
3165 }
3166 pBltPos += dwPitch;
3167 pSrcPos += src->dwPitchDB;
3168 }
3169 break;
3170 case 3:
3171 {
3172 char *pSC, *pDC;
3173 pSC = (char*)&dwSrcColor;
3174 pDC = (char*)&dwDestColor;
3175 BlitWidth *=3;
3176
3177 while(BlitHeight--)
3178 {
3179 x = 0;
3180
3181 while(x<BlitWidth)
3182 {
3183 if( (pBltPos[x] != pDC[1]) &&
3184 (pBltPos[x+1] != pDC[2]) &&
3185 (pBltPos[x+2] != pDC[3])
3186 )
3187 {
3188 pBltPos[x] = pSrcPos[x];
3189 pBltPos[x+1] = pSrcPos[x+2];
3190 pBltPos[x+1] = pSrcPos[x+2];
3191 }
3192 x +=3;
3193 }
3194 pBltPos += dwPitch;
3195 pSrcPos += src->dwPitchDB;
3196 }
3197 break;
3198 }
3199 case 4:
3200 while(BlitHeight--)
3201 {
3202 x = 0;
3203 while(x<BlitWidth)
3204 {
3205 if( ((DWORD*)pBltPos)[x] != dwDestColor)
3206 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3207 x++;
3208 }
3209 pBltPos += dwPitch;
3210 pSrcPos += src->dwPitchDB;
3211 }
3212 break;
3213 } // End switch
3214 } // End of Dest ColorKey
3215
3216
3217 }// end handling dwFlags
3218 } // End handling source not Framebuffer
3219
3220 }// end handling destination not framebuffer
3221
3222 // if(dest->lpVtbl == dest->Vtbl4)
3223 // dest->Vtbl4->ChangeUniquenessValue(dest);
3224 return(DD_OK);
3225}
3226//******************************************************************************
3227//******************************************************************************
3228HRESULT __stdcall SurfBltBatch(THIS, LPDDBLTBATCH, DWORD, DWORD )
3229{
3230 #ifdef DEBUG
3231 dprintf(("SurfBltBatch Not implemented by M$\n"));
3232 #endif
3233
3234 return(DD_OK);
3235}
3236//******************************************************************************
3237//******************************************************************************
3238HRESULT __stdcall SurfBltFast( THIS This ,
3239 DWORD dwX,
3240 DWORD dwY,
3241 LPDIRECTDRAWSURFACE2 lpDDSrcSurface,
3242 LPRECT lpSrcRect,
3243 DWORD dwTrans)
3244{
3245 dprintf(("SurfBltFast=>"));
3246 return SurfBltFast4( This,
3247 dwX,
3248 dwY,
3249 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
3250 lpSrcRect,
3251 dwTrans);
3252}
3253//******************************************************************************
3254//******************************************************************************
3255HRESULT __stdcall SurfBltFast3(THIS This ,
3256 DWORD dwX,
3257 DWORD dwY,
3258 LPDIRECTDRAWSURFACE3 lpDDSrcSurface,
3259 LPRECT lpSrcRect,
3260 DWORD dwTrans)
3261{
3262 dprintf(("SurfBltFast3=>"));
3263 return SurfBltFast4( This,
3264 dwX,
3265 dwY,
3266 (LPDIRECTDRAWSURFACE4) lpDDSrcSurface,
3267 lpSrcRect,
3268 dwTrans);
3269}
3270//******************************************************************************
3271//******************************************************************************
3272HRESULT __stdcall SurfBltFast4( THIS This,
3273 DWORD dwX,
3274 DWORD dwY,
3275 LPDIRECTDRAWSURFACE4 lpDDSrcSurface,
3276 LPRECT lpSrcRect,
3277 DWORD dwTrans)
3278{
3279 OS2IDirectDrawSurface *dest = (OS2IDirectDrawSurface *)This;
3280 OS2IDirectDrawSurface *src = (OS2IDirectDrawSurface *)lpDDSrcSurface;
3281 RECTL SrcRect;
3282 char *pBltPos, *pSrcPos;
3283 DWORD dwDestColor, dwSrcColor, BlitWidth, BlitHeight,x,y;
3284
3285 #ifdef DEBUG
3286 dprintf(("SurfBltFast4 %08X at(%d/%d) onto %08X with flags %08X\n",src, dwX,dwY, dest, dwTrans));
3287 #endif
3288
3289 if( (NULL==lpDDSrcSurface) ||
3290 (dwX<0) || (dwY<0) ||
3291 (dwX>dest->width) ||
3292 (dwY>dest->height))
3293 {
3294 dprintf(("Invalid Parameters %08X, %d %d", lpDDSrcSurface ,dest->width , dest->height));
3295 return DDERR_INVALIDPARAMS;
3296 }
3297
3298 if (NULL!=lpSrcRect)
3299 {
3300 memcpy(&SrcRect,lpSrcRect,sizeof(RECTL) );
3301 }
3302 else
3303 {
3304 SrcRect.top = 0;
3305 SrcRect.left = 0;
3306 SrcRect.bottom = src->height;
3307 SrcRect.right = src->width;
3308 }
3309
3310 // Todo: Test for locked src/dest
3311
3312 pBltPos = (char*) dest->pDiveBuffer + (dwY * dest->dwPitchDB) +
3313 (dwX * dest->dwBytesPPDive);
3314
3315 pSrcPos = (char*) src->pDiveBuffer + (SrcRect.top * src->dwPitchDB) +
3316 (SrcRect.left * src->dwBytesPPDive);
3317
3318 BlitHeight = SrcRect.bottom - SrcRect.top;
3319 BlitWidth = (SrcRect.right - SrcRect.left) * src->dwBytesPPDive;
3320
3321 // Remove unsupported wait flag
3322 dwTrans &= ~DDBLTFAST_WAIT;
3323
3324 if(DDBLTFAST_NOCOLORKEY == dwTrans )
3325 {
3326 dprintf(( "Solid Blit, %d bits => %d bytes per line\n",
3327 (SrcRect.right - SrcRect.left),
3328 BlitWidth) );
3329 #ifdef USE_ASM
3330 BltRec(pBltPos, pSrcPos, BlitWidth, BlitHeight,
3331 dest->dwPitchDB,
3332 src->dwPitchDB);
3333 #else
3334 // Solid Blit
3335 while(1)
3336 {
3337 memcpy(pBltPos,pSrcPos,BlitWidth);
3338 pBltPos += dest->dwPitchDB;
3339 pSrcPos += src->dwPitchDB;
3340 if(! (--BlitHeight))
3341 break;
3342 }
3343 #endif
3344
3345 }
3346 else
3347 {
3348 dprintf(("TransBlit\n"));
3349
3350 if(dwTrans & DDBLTFAST_SRCCOLORKEY)
3351 {
3352 dprintf(("Trans SRC\n"));
3353 // transparent source
3354 dwSrcColor = src->DDSurfaceDesc.ddckCKSrcBlt.dwColorSpaceLowValue;
3355 if(dwTrans & DDBLTFAST_DESTCOLORKEY)
3356 {
3357 dprintf(("And Dest Colorkey"));
3358 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3359 // Source and dest colorkeying
3360 switch(dest->dwBytesPPDive)
3361 {
3362 case 1:
3363 while(BlitHeight--)
3364 {
3365 x = 0;
3366 while(x<BlitWidth)
3367 {
3368 if(pSrcPos[x] != (char) dwSrcColor)
3369 {
3370 if(pBltPos[x] != (char) dwDestColor)
3371 pBltPos[x] = pSrcPos[x];
3372 }
3373 x++;
3374 }
3375 pBltPos += dest->dwPitchDB;
3376 pSrcPos += src->dwPitchDB;
3377 }
3378 break;
3379 case 2:
3380 while(BlitHeight--)
3381 {
3382 x = 0;
3383 while(x<BlitWidth)
3384 {
3385 if(((USHORT*)pSrcPos)[x] != (USHORT) dwSrcColor)
3386 {
3387 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3388 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3389 }
3390 x++;
3391 }
3392 pBltPos += dest->dwPitchDB;
3393 pSrcPos += src->dwPitchDB;
3394 }
3395 break;
3396 case 3:
3397 {
3398 char *pSC, *pDC;
3399 pSC = (char*)&dwSrcColor;
3400 pDC = (char*)&dwDestColor;
3401 BlitWidth *=3;
3402
3403 while(BlitHeight--)
3404 {
3405 x = 0;
3406
3407 while(x<BlitWidth)
3408 {
3409 if( (pSrcPos[x] != pSC[1]) &&
3410 (pSrcPos[x+1] != pSC[2]) &&
3411 (pSrcPos[x+2] != pSC[3])
3412 )
3413 {
3414 if( (pBltPos[x] != pDC[1]) &&
3415 (pBltPos[x+1] != pDC[2]) &&
3416 (pBltPos[x+2] != pDC[3])
3417 )
3418 {
3419 pBltPos[x] = pSrcPos[x];
3420 pBltPos[x+1] = pSrcPos[x+2];
3421 pBltPos[x+1] = pSrcPos[x+2];
3422 }
3423 }
3424 x +=3;
3425 }
3426 pBltPos += dest->dwPitchDB;
3427 pSrcPos += src->dwPitchDB;
3428 }
3429 break;
3430 }
3431 case 4:
3432 while(BlitHeight--)
3433 {
3434 x = 0;
3435 while(x<BlitWidth)
3436 {
3437 if(((DWORD*)pSrcPos)[x] != dwSrcColor)
3438 {
3439 if(((DWORD*)pBltPos)[x] != dwDestColor)
3440 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3441 }
3442 x++;
3443 }
3444 pBltPos += dest->dwPitchDB;
3445 pSrcPos += src->dwPitchDB;
3446 }
3447 break;
3448 } // End switch
3449 }
3450 else
3451 {
3452 // This MMX detection should be moved into OS2Draw
3453 // and into the surface constructor a setup for blitting pointers
3454 dprintf(("Only Src ColorKey"));
3455 switch(dest->dwBytesPPDive)
3456 {
3457 case 1:
3458 if(CPUHasMMX())
3459 while(BlitHeight--)
3460 {
3461 BlitColorKey8MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3462 pBltPos += dest->dwPitchDB;
3463 pSrcPos += src->dwPitchDB;
3464 }
3465 else
3466 while(BlitHeight--)
3467 {
3468 BlitColorKey8((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3469 pBltPos += dest->dwPitchDB;
3470 pSrcPos += src->dwPitchDB;
3471 }
3472 break;
3473 case 2:
3474
3475 if(CPUHasMMX())
3476 while(BlitHeight--)
3477 {
3478 BlitColorKey16MMX((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3479 pBltPos += dest->dwPitchDB;
3480 pSrcPos += src->dwPitchDB;
3481 }
3482 else
3483 while(BlitHeight--)
3484 {
3485 BlitColorKey16((PBYTE)pBltPos,(PBYTE)pSrcPos,dwSrcColor,BlitWidth);
3486 pBltPos += dest->dwPitchDB;
3487 pSrcPos += src->dwPitchDB;
3488 }
3489 break;
3490 case 3:
3491 char *pSC;
3492 pSC = (char*)&dwSrcColor;
3493 BlitWidth *=3;
3494
3495 while(BlitHeight--)
3496 {
3497 x = 0;
3498
3499 while(x<BlitWidth)
3500 {
3501 if( (pSrcPos[x] != pSC[1]) &&
3502 (pSrcPos[x+1] != pSC[2]) &&
3503 (pSrcPos[x+2] != pSC[3])
3504 )
3505 {
3506 pBltPos[x] = pSrcPos[x];
3507 pBltPos[x+1] = pSrcPos[x+1];
3508 pBltPos[x+1] = pSrcPos[x+2];
3509 }
3510 x +=3;
3511 }
3512 pBltPos += dest->dwPitchDB;
3513 pSrcPos += src->dwPitchDB;
3514 }
3515 break;
3516 case 4:
3517 break;
3518 }
3519 }
3520 }
3521 else
3522 {
3523 if(dwTrans & DDBLTFAST_DESTCOLORKEY)
3524 {
3525 dprintf(("DestColorKey\n"));
3526
3527 dwDestColor = dest->DDSurfaceDesc.ddckCKDestBlt.dwColorSpaceLowValue;
3528 switch(dest->dwBytesPPDive)
3529 {
3530 case 1:
3531 while(BlitHeight--)
3532 {
3533 x = 0;
3534 while(x<BlitWidth)
3535 {
3536 if(pBltPos[x] != (char) dwDestColor)
3537 pBltPos[x] = pSrcPos[x];
3538 x++;
3539 }
3540 pBltPos += dest->dwPitchDB;
3541 pSrcPos += src->dwPitchDB;
3542 }
3543 break;
3544 case 2:
3545 while(BlitHeight--)
3546 {
3547 x = 0;
3548 while(x<BlitWidth)
3549 {
3550 if(((USHORT*)pBltPos)[x] != (USHORT) dwDestColor)
3551 ((USHORT*)pBltPos)[x] = ((USHORT*)pSrcPos)[x];
3552 x++;
3553 }
3554 pBltPos += dest->dwPitchDB;
3555 pSrcPos += src->dwPitchDB;
3556 }
3557 break;
3558 case 3:
3559 {
3560 char *pSC, *pDC;
3561 pSC = (char*)&dwSrcColor;
3562 pDC = (char*)&dwDestColor;
3563 BlitWidth *=3;
3564
3565 while(BlitHeight--)
3566 {
3567 x = 0;
3568
3569 while(x<BlitWidth)
3570 {
3571 if( (pBltPos[x] != pDC[1]) &&
3572 (pBltPos[x+1] != pDC[2]) &&
3573 (pBltPos[x+2] != pDC[3])
3574 )
3575 {
3576 pBltPos[x] = pSrcPos[x];
3577 pBltPos[x+1] = pSrcPos[x+2];
3578 pBltPos[x+1] = pSrcPos[x+2];
3579 }
3580 x +=3;
3581 }
3582 pBltPos += dest->dwPitchDB;
3583 pSrcPos += src->dwPitchDB;
3584 }
3585 break;
3586 }
3587 case 4:
3588 while(BlitHeight--)
3589 {
3590 x = 0;
3591 while(x<BlitWidth)
3592 {
3593 if(((DWORD*)pBltPos)[x] != dwDestColor)
3594 ((DWORD*)pBltPos)[x] = ((DWORD*)pSrcPos)[x];
3595 x++;
3596 }
3597 pBltPos += dest->dwPitchDB;
3598 pSrcPos += src->dwPitchDB;
3599 }
3600 break;
3601 } // End switch
3602 }
3603 else
3604 {
3605 dprintf(("Unexpected Flags"));
3606 }
3607 }
3608 }
3609
3610 // if(dest->lpVtbl == dest->Vtbl4)
3611 // dest->Vtbl4->ChangeUniquenessValue(dest);
3612
3613 return(DD_OK);
3614}
3615//******************************************************************************
3616//******************************************************************************
3617HRESULT __stdcall SurfDeleteAttachedSurface(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSurface)
3618{
3619 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3620 #ifdef DEBUG
3621 dprintf(("SurfDeleteAttachedSurface\n"));
3622 #endif
3623
3624 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3625}
3626//******************************************************************************
3627//******************************************************************************
3628HRESULT __stdcall SurfDeleteAttachedSurface3(THIS This, DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSurface)
3629{
3630 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3631 #ifdef DEBUG
3632 dprintf(("SurfDeleteAttachedSurface\n"));
3633 #endif
3634
3635 return(SurfDeleteAttachedSurface4(me, dwFlags, (LPDIRECTDRAWSURFACE4)lpDDSurface));
3636}
3637//******************************************************************************
3638//******************************************************************************
3639HRESULT __stdcall SurfDeleteAttachedSurface4(THIS This, DWORD dwFlags , LPDIRECTDRAWSURFACE4 lpDDSurface)
3640{
3641
3642 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3643 OS2IDirectDrawSurface *AttachedSurface;
3644 OS2IDirectDrawSurface *SurfaceCursor;
3645 int i;
3646
3647 BOOL Found = FALSE;
3648 #ifdef DEBUG
3649 dprintf(("SurfDeleteAttachedSurface\n"));
3650 #endif
3651
3652 if((0!=dwFlags)||(NULL==lpDDSurface))
3653 return(DDERR_INVALIDPARAMS);
3654
3655 AttachedSurface = (OS2IDirectDrawSurface*) lpDDSurface;
3656 if (AttachedSurface->IsImplicitSurface())
3657 return (DDERR_CANNOTDETACHSURFACE);
3658
3659 if ( (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP | DDSCAPS_BACKBUFFER)) &&
3660 !(AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) )
3661 {
3662 // Surface seams to be a backbuffer in a flipchain search it
3663
3664 // Goto top of list
3665 if(me->FrontBuffer!=NULL)
3666 {
3667 SurfaceCursor = me->FrontBuffer;
3668 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3669 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3670 }
3671 else
3672 SurfaceCursor = me;
3673
3674 // now iterrate through the list skip first in list as we don't remove the frontbuffer
3675
3676 SurfaceCursor = SurfaceCursor->BackBuffer;
3677 while((SurfaceCursor!= AttachedSurface)&&(SurfaceCursor!=NULL))
3678 SurfaceCursor = SurfaceCursor->BackBuffer;
3679
3680 if(SurfaceCursor!=NULL)
3681 {
3682 Found = TRUE;
3683 // remove the Surface from the list
3684 SurfaceCursor->FrontBuffer->BackBuffer = SurfaceCursor->BackBuffer;
3685 if(SurfaceCursor->BackBuffer!=NULL)
3686 {
3687 SurfaceCursor->BackBuffer->SetFrontBuffer(SurfaceCursor->FrontBuffer);
3688
3689 }
3690 else
3691 {
3692 // we were the last buffer in the list have we been the only backbuffer?
3693 if(SurfaceCursor->FrontBuffer->FrontBuffer == NULL)
3694 {
3695 // Yepp so "destroy" the flipchain
3696 SurfaceCursor->FrontBuffer->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3697 SurfaceCursor->FrontBuffer->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3698 }
3699 }
3700 // decrement the backbuffer count of all buffers in the chain in front of us
3701 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3702 {
3703 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3704 SurfaceCursor->DDSurfaceDesc.dwBackBufferCount-- ;
3705 }
3706
3707 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3708 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3709 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3710 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; // Set this flag as adding to the chain removed it
3711 AttachedSurface->lpVtbl->Release(AttachedSurface);
3712
3713 }
3714 } //endif delete back/frontbuffers
3715
3716 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & ( DDSCAPS_FLIP & DDSCAPS_FRONTBUFFER)) )
3717 {
3718 // seams like someone wants a new frontbuffer
3719
3720 // Goto top of list
3721
3722 if(me->FrontBuffer!=NULL)
3723 {
3724 SurfaceCursor = me->FrontBuffer;
3725 while(SurfaceCursor->GetFrontBuffer()!=NULL)
3726 SurfaceCursor = SurfaceCursor->GetFrontBuffer();
3727 }
3728 else
3729 SurfaceCursor = me;
3730
3731 if(SurfaceCursor == AttachedSurface)
3732 {
3733 Found = TRUE;
3734 SurfaceCursor->BackBuffer->SetFrontBuffer(NULL);
3735 AttachedSurface->DDSurfaceDesc.dwBackBufferCount = 0;
3736 AttachedSurface->DDSurfaceDesc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3737 AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_FLIP;
3738 AttachedSurface->lpVtbl->Release(AttachedSurface);
3739 }
3740
3741 }
3742
3743
3744 if ( (!Found) && (AttachedSurface->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_MIPMAP ) )
3745 {
3746 // Surface seams to be a mipmap
3747 i = 0;
3748 while((DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>i ) && !Found)
3749 {
3750 if (DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i) == AttachedSurface)
3751 {
3752 Found = TRUE;
3753 DPA_DeletePtr(me->DPA_SurfaceMipMaps,i);
3754 AttachedSurface->lpVtbl->Release(AttachedSurface);
3755 // adjust our info
3756 me->DDSurfaceDesc.dwMipMapCount-- ;
3757 if (!me->DDSurfaceDesc.dwMipMapCount)
3758 {
3759 me->DDSurfaceDesc.dwFlags &= ~DDSD_MIPMAPCOUNT;
3760 }
3761 }
3762 i++;
3763 }
3764 }
3765
3766 if(!Found)
3767 {
3768 // Surface seams to be an attached one
3769 i = 0;
3770 while((DPA_GetPtrCount(me->DPA_SurfaceAttached)>i ) && !Found)
3771 {
3772 if (DPA_FastGetPtr(me->DPA_SurfaceAttached,i) == AttachedSurface)
3773 {
3774 Found = TRUE;
3775 DPA_DeletePtr(me->DPA_SurfaceAttached,i);
3776 AttachedSurface->lpVtbl->Release(AttachedSurface);
3777 }
3778 i++;
3779 }
3780 }
3781
3782
3783 return(Found?DD_OK:DDERR_SURFACENOTATTACHED);
3784}
3785//******************************************************************************
3786//******************************************************************************
3787HRESULT __stdcall SurfEnumAttachedSurfaces(THIS This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpCallBack)
3788{
3789 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3790 #ifdef DEBUG
3791 dprintf(("SurfEnumAttachedSurfaces\n"));
3792 #endif
3793
3794 return(SurfEnumAttachedSurfaces4(me,lpContext, (LPDDENUMSURFACESCALLBACK2) lpCallBack));
3795}
3796//******************************************************************************
3797//******************************************************************************
3798HRESULT __stdcall SurfEnumAttachedSurfaces4(THIS This, LPVOID lpContext ,LPDDENUMSURFACESCALLBACK2 lpCallBack)
3799{
3800 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3801 OS2IDirectDrawSurface *EnumSurface;
3802 DDSURFACEDESC2 EnumDesc;
3803 int i,count;
3804 HRESULT rc;
3805
3806 #ifdef DEBUG
3807 dprintf(("SurfEnumAttachedSurfaces\n"));
3808 #endif
3809 if (NULL==lpCallBack)
3810 return (DDERR_INVALIDPARAMS);
3811
3812 rc = DDENUMRET_OK;
3813
3814
3815 if(me->BackBuffer != NULL)
3816 {
3817 memcpy(&EnumDesc,&(me->DDSurfaceDesc),sizeof(DDSURFACEDESC2));
3818 rc = lpCallBack((LPDIRECTDRAWSURFACE4)me->BackBuffer,&EnumDesc,lpContext);
3819 }
3820
3821 count = DPA_GetPtrCount(me->DPA_SurfaceMipMaps);
3822
3823 if(count>0)
3824 {
3825 i=0;
3826 while( (DDENUMRET_OK == rc) && i<count )
3827 {
3828 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
3829 memcpy( &EnumDesc,
3830 &(EnumSurface->DDSurfaceDesc),
3831 sizeof(DDSURFACEDESC2));
3832 // Calling back into WIN32 app so we had to reset FS
3833 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
3834 i++;
3835 }
3836 }
3837
3838 count = DPA_GetPtrCount(me->DPA_SurfaceAttached);
3839
3840 if(count>0)
3841 {
3842 i=0;
3843 while( (DDENUMRET_OK == rc) && i<count )
3844 {
3845 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
3846 memcpy( &EnumDesc,
3847 &(EnumSurface->DDSurfaceDesc),
3848 sizeof(DDSURFACEDESC2));
3849 rc = lpCallBack((LPDIRECTDRAWSURFACE4)EnumSurface,&EnumDesc,lpContext);
3850 i++;
3851 }
3852 }
3853
3854 return(DD_OK);
3855}
3856//******************************************************************************
3857//******************************************************************************
3858HRESULT __stdcall SurfEnumOverlayZOrders(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK)
3859{
3860 dprintf(("SurfEnumOverlayZOrders\n"));
3861
3862 return(DD_OK);
3863}
3864//******************************************************************************
3865//******************************************************************************
3866HRESULT __stdcall SurfEnumOverlayZOrders4(THIS, DWORD,LPVOID,LPDDENUMSURFACESCALLBACK2)
3867{
3868 dprintf(("SurfEnumOverlayZOrders\n"));
3869
3870 return(DD_OK);
3871}
3872//******************************************************************************
3873//******************************************************************************
3874HRESULT __stdcall SurfFlip(THIS This, LPDIRECTDRAWSURFACE2 lpDDSurf, DWORD dwFlags)
3875{
3876 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3877
3878 dprintf(("SurfFlip\n"));
3879
3880 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
3881}
3882//******************************************************************************
3883//******************************************************************************
3884HRESULT __stdcall SurfFlip3(THIS This, LPDIRECTDRAWSURFACE3 lpDDSurf, DWORD dwFlags)
3885{
3886 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3887
3888 dprintf(("SurfFlip\n"));
3889
3890 return(SurfFlip4(me, (LPDIRECTDRAWSURFACE4) lpDDSurf, dwFlags));
3891}
3892//******************************************************************************
3893//******************************************************************************
3894HRESULT __stdcall SurfFlip4(THIS This, LPDIRECTDRAWSURFACE4 lpDDSurf, DWORD dwFlags)
3895{
3896 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
3897 OS2IDirectDrawSurface *FlipSurface;
3898 OS2IDirectDrawSurface *FlipCursor;
3899 LPVOID Data;
3900 char *pcrFB,*pcFB,*pcrDB,*pcDB;
3901 ULONG rc;
3902
3903 dprintf(("SurfFlip4\n"));
3904
3905 if(!((me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) &&
3906 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_FLIP))
3907 )
3908 {
3909 #ifdef DEBUG
3910 dprintf(("Flip called on none Frontbuffer/Flip surface\n Flags:\n"));
3911 _dump_DDSCAPS(me->DDSurfaceDesc.ddsCaps.dwCaps);
3912 dprintf(("\n"));
3913 #endif
3914 return(DDERR_NOTFLIPPABLE);
3915 }
3916
3917 if(NULL!=lpDDSurf)
3918 {
3919 dprintf(("Check if Surface is in Flipchain!\n"));
3920
3921 // We got an override surface check if it is in the flipchain
3922 FlipSurface = (OS2IDirectDrawSurface*) lpDDSurf;
3923 FlipCursor = me->BackBuffer;
3924 while((NULL!=FlipCursor)&&(FlipCursor!=FlipSurface))
3925 {
3926 FlipCursor = FlipCursor->BackBuffer;
3927 }
3928
3929 if(FlipCursor!=FlipSurface)
3930 {
3931 dprintf(("Surface not in Flipchain!\n"));
3932
3933 return (DDERR_INVALIDPARAMS); // Not sure if the returnvalue is right
3934 }
3935 }
3936 else
3937 {
3938 FlipSurface = me->NextFlip; // Take the next Surface in the Flipchain
3939 dprintf(("Next Surface @ 0x%08X\n",FlipSurface));
3940 }
3941
3942 if((me->fLocked)||(FlipSurface->fLocked))
3943 {
3944 dprintf(("Locked surface(s) Dest %d Src %d\n",me->fLocked,FlipSurface->fLocked));
3945
3946 return(DDERR_SURFACEBUSY);
3947 }
3948
3949 if(-1 != me->diveBufNr)
3950 {
3951 dprintf(("DIVE Flipchain"));
3952
3953 // we got some DIVE surfaces
3954 // On Dive Buffers More then Double buffering won't get any perf. gain
3955 // as we have to move all the data to the Frontbuffer and can't simply exchange the pointers
3956 // Doulebuffering should work best.
3957
3958 rc = DiveBlitImage(me->hDive, FlipSurface->diveBufNr, me->diveBufNr);
3959
3960 #ifdef DEBUG
3961 dprintf(("DiveBlitImage rc = 0x%08X\n"));
3962 #endif
3963
3964 if(NULL==lpDDSurf)
3965 {
3966 // advance in the flipchain if no valid override surface was passed in
3967 me->NextFlip = FlipSurface->BackBuffer!=NULL?FlipSurface->BackBuffer:me->BackBuffer;
3968 }
3969 }
3970 else
3971 {
3972 #ifdef DEBUG
3973 dprintf(("Memory Flipchain"));
3974 #endif
3975 // Memory Flipchain
3976 //
3977 // ToDo : Check what happens to src/dest colorkeys etc do the move also ?
3978 //
3979 // We only change the memory pointer to the buffers no need to copy all the data
3980 // So the NextFlip is here allways the Backbuffer so we won't advance this
3981 //
3982 // Sample (triple buffering) : Before Flip After Flip
3983 // Buffer: FB BB TB FB BB TB
3984 // Memory: 11 22 33 22 33 11
3985 //
3986
3987 Data = me->DDSurfaceDesc.lpSurface;
3988 pcrFB = me->pFBreal;
3989 pcFB = me->pFrameBuffer;
3990 pcrDB = me->pDBreal;
3991 pcDB = me->pDiveBuffer;
3992 me->DDSurfaceDesc.lpSurface = FlipSurface->DDSurfaceDesc.lpSurface;
3993 me->pFBreal = FlipSurface->pFBreal;
3994 me->pFrameBuffer = FlipSurface->pFrameBuffer;
3995 me->pDBreal = FlipSurface->pDBreal;
3996 me->pDiveBuffer = FlipSurface->pDiveBuffer;
3997
3998 if(NULL==lpDDSurf)
3999 {
4000 while(NULL!=FlipSurface->BackBuffer)
4001 {
4002 FlipSurface->DDSurfaceDesc.lpSurface = FlipSurface->BackBuffer->DDSurfaceDesc.lpSurface;
4003 FlipSurface->pFBreal = FlipSurface->BackBuffer->pFBreal;
4004 FlipSurface->pFrameBuffer = FlipSurface->BackBuffer->pFrameBuffer;
4005 FlipSurface->pDBreal = FlipSurface->BackBuffer->pDBreal;
4006 FlipSurface->pDiveBuffer = FlipSurface->BackBuffer->pDiveBuffer;
4007 FlipSurface = FlipSurface->BackBuffer;
4008 }
4009 }
4010 FlipSurface->DDSurfaceDesc.lpSurface = Data;
4011 FlipSurface->pFBreal = pcrFB;
4012 FlipSurface->pFrameBuffer = pcFB;
4013 FlipSurface->pDBreal = pcrDB;
4014 FlipSurface->pDiveBuffer = pcDB;
4015 }
4016
4017 return(DD_OK);
4018}
4019//******************************************************************************
4020//******************************************************************************
4021HRESULT __stdcall SurfGetAttachedSurface(THIS This, LPDDSCAPS lpDDCaps,
4022 LPDIRECTDRAWSURFACE2 FAR * lpDDSurf)
4023{
4024 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4025 #ifdef DEBUG
4026 dprintf(("SurfGetAttachedSurface\n"));
4027 #endif
4028
4029 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
4030}
4031//******************************************************************************
4032//******************************************************************************
4033HRESULT __stdcall SurfGetAttachedSurface3(THIS This, LPDDSCAPS lpDDCaps,
4034 LPDIRECTDRAWSURFACE3 FAR * lpDDSurf)
4035{
4036 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4037 #ifdef DEBUG
4038 dprintf(("SurfGetAttachedSurface3\n"));
4039 #endif
4040
4041 return(SurfGetAttachedSurface4(me, (LPDDSCAPS2)lpDDCaps , (LPDIRECTDRAWSURFACE4*)lpDDSurf));
4042}
4043//******************************************************************************
4044//******************************************************************************
4045HRESULT __stdcall SurfGetAttachedSurface4(THIS This, LPDDSCAPS2 lpDDCaps,
4046 LPDIRECTDRAWSURFACE4 FAR * lpDDSurf)
4047{
4048 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4049 OS2IDirectDrawSurface *EnumSurface = NULL;
4050 OS2IDirectDrawSurface *AttachedSurface = NULL;
4051 HRESULT rc;
4052 int i;
4053
4054 #ifdef DEBUG
4055 dprintf(("SurfGetAttachedSurface4\n>Requested Caps: "));
4056 _dump_DDSCAPS(lpDDCaps->dwCaps);
4057 dprintf(("\n"));
4058 #endif
4059
4060 if( (NULL==lpDDCaps)||(NULL==lpDDSurf))
4061 {
4062 dprintf(("Invalid params\n\n"));
4063 return (DDERR_INVALIDPARAMS);
4064 }
4065
4066
4067 rc = DD_OK;
4068
4069 if( (me->BackBuffer!=NULL) &&
4070 (me->BackBuffer->DDSurfaceDesc.ddsCaps.dwCaps & lpDDCaps->dwCaps) )
4071 {
4072 dprintf(("Return Backbuffer\n"));
4073 AttachedSurface = me->BackBuffer;
4074 }
4075
4076 if(DPA_GetPtrCount(me->DPA_SurfaceMipMaps)>0)
4077 {
4078 i=0;
4079 while( i<DPA_GetPtrCount(me->DPA_SurfaceMipMaps) )
4080 {
4081 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceMipMaps,i);
4082 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
4083 {
4084 if(NULL==AttachedSurface)
4085 AttachedSurface = EnumSurface;
4086 else
4087 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
4088 // but function must fail if more then one surface fits
4089
4090 }
4091 i++;
4092 }
4093 }
4094
4095 if(DPA_GetPtrCount(me->DPA_SurfaceAttached)>0)
4096 {
4097 i=0;
4098 while( i<DPA_GetPtrCount(me->DPA_SurfaceAttached) )
4099 {
4100 EnumSurface = (OS2IDirectDrawSurface*) DPA_FastGetPtr(me->DPA_SurfaceAttached,i);
4101 if(EnumSurface->DDSurfaceDesc.ddsCaps.dwCaps == lpDDCaps->dwCaps)
4102 {
4103 if(NULL==AttachedSurface)
4104 AttachedSurface = EnumSurface;
4105 else
4106 rc = DDERR_NOTFOUND; // Not sure if this is the right return value,
4107 // but function must fail if more then one surface fits
4108
4109 }
4110 i++;
4111 }
4112 }
4113
4114 if( (DD_OK==rc) &&
4115 (NULL!=AttachedSurface) )
4116 {
4117 *lpDDSurf = (IDirectDrawSurface4*)AttachedSurface;
4118 // not sure but as we returned an reference rains usage count
4119 AttachedSurface->lpVtbl->AddRef(AttachedSurface);
4120 }
4121 else
4122 {
4123 *lpDDSurf = NULL;
4124 rc = DDERR_NOTFOUND;
4125 }
4126
4127
4128 return rc;
4129}
4130//******************************************************************************
4131//******************************************************************************
4132HRESULT __stdcall SurfGetBltStatus(THIS This, DWORD)
4133{
4134 #ifdef DEBUG
4135 dprintf(("SurfGetBltStatus\n"));
4136 #endif
4137
4138 return(DD_OK);
4139}
4140//******************************************************************************
4141//******************************************************************************
4142HRESULT __stdcall SurfGetCaps(THIS This, LPDDSCAPS lpDDCaps)
4143{
4144 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4145
4146 #ifdef DEBUG
4147 dprintf(("SurfGetCaps\n"));
4148 #endif
4149
4150 if(NULL==lpDDCaps)
4151 return(DDERR_INVALIDPARAMS);
4152
4153 lpDDCaps->dwCaps = me->DDSurfaceDesc.ddsCaps.dwCaps;
4154 #ifdef DEBUG
4155 _dump_DDSCAPS(lpDDCaps->dwCaps);
4156 #endif
4157 return(DD_OK);
4158}
4159//******************************************************************************
4160//******************************************************************************
4161HRESULT __stdcall SurfGetCaps4(THIS This, LPDDSCAPS2 lpDDCaps)
4162{
4163 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4164 #ifdef DEBUG
4165 dprintf(("SurfGetCaps4\n"));
4166 #endif
4167
4168 if(NULL==lpDDCaps)
4169 return(DDERR_INVALIDPARAMS);
4170
4171 memcpy(lpDDCaps, &(me->DDSurfaceDesc.ddsCaps), sizeof(DDSCAPS2) );
4172 #ifdef DEBUG
4173 _dump_DDSCAPS(lpDDCaps->dwCaps);
4174 _dump_DDSCAPS2(lpDDCaps->dwCaps2);
4175
4176 #endif
4177
4178 return(DD_OK);
4179}
4180//******************************************************************************
4181//******************************************************************************
4182HRESULT __stdcall SurfGetClipper(THIS This, LPDIRECTDRAWCLIPPER FAR *lplpClipper)
4183{
4184 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4185
4186 #ifdef DEBUG
4187 dprintf(("SurfGetClipper\n"));
4188 #endif
4189
4190 if(me->lpClipper)
4191 {
4192 *lplpClipper = (LPDIRECTDRAWCLIPPER) me->lpClipper;
4193 return(DD_OK);
4194 }
4195 else
4196 return(DDERR_NOCLIPPERATTACHED);
4197}
4198//******************************************************************************
4199//******************************************************************************
4200HRESULT __stdcall SurfGetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
4201{
4202 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4203
4204#ifdef DEBUG
4205 dprintf(("SurfGetColorKey\n"));
4206#endif
4207
4208 if ((0==dwFlags) || (NULL==lpDDColKey))
4209 return (DDERR_INVALIDPARAMS);
4210
4211 // as we report only src colorkey in the caps return error on all others flags
4212 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY) & dwFlags)
4213 return(DDERR_UNSUPPORTED);
4214
4215 if(me->DDSurfaceDesc.dwFlags & dwFlags)
4216 {
4217 if(DDCKEY_SRCBLT & dwFlags)
4218 {
4219 memcpy(lpDDColKey,&(me->DDSurfaceDesc.ddckCKSrcBlt),sizeof(DDCOLORKEY) );
4220 }
4221 else
4222 return (DDERR_INVALIDPARAMS); // some other flags where set => error
4223 }
4224 else
4225 return(DDERR_NOCOLORKEY); // surface doesn't have a color key set
4226
4227 return (DD_OK);
4228}
4229//******************************************************************************
4230//******************************************************************************
4231HRESULT __stdcall SurfGetDC(THIS This, HDC FAR *hdc)
4232{
4233 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4234 DDSURFACEDESC2 LockedSurfaceDesc;
4235 HRESULT rc;
4236 BITMAP bmpSurface;
4237 struct
4238 {
4239 BITMAPINFOHEADER bmiHead;
4240 RGBQUAD bmiCols[256];
4241 } BitmapInfo;
4242
4243 #ifdef DEBUG
4244 dprintf(("SurfGetDC\n"));
4245 #endif
4246
4247 if (NULL==hdc)
4248 return(DDERR_INVALIDPARAMS);
4249
4250 LockedSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
4251
4252 if(DD_OK != me->Vtbl.Lock(me,NULL,&LockedSurfaceDesc,0,0))
4253 {
4254 return(DDERR_DCALREADYCREATED);
4255 }
4256
4257 rc = DD_OK;
4258
4259 if(me->hdcImage == NULL)
4260 {
4261 // Create a Device context
4262 me->hdcImage = CreateCompatibleDC(NULL);
4263 if(me->hdcImage == NULL)
4264 {
4265 #ifdef DEBUG
4266 dprintf(("Can't create compatible DC!\n"));
4267 #endif
4268 me->Vtbl.Unlock(me,NULL);
4269 rc = DDERR_GENERIC;
4270 }
4271 }
4272
4273 if( (DD_OK==rc) &&
4274 (me->hbmImage == NULL) )
4275 {
4276 dprintf( ("Trying to create Bitmap (%d/%d) at %d Bit\n",
4277 LockedSurfaceDesc.lPitch/ (LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3),
4278 LockedSurfaceDesc.dwHeight,
4279 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount
4280 ));
4281 #if 0
4282 memset(&BitmapInfo, 0, sizeof(BitmapInfo));
4283 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4284 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.lPitch/ (LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4285 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
4286 BitmapInfo.bmiHead.biPlanes = 1;
4287 BitmapInfo.bmiHead.biBitCount = LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4288 #else
4289 bmpSurface.bmType = 0;
4290 bmpSurface.bmWidth = LockedSurfaceDesc.dwWidth;
4291 bmpSurface.bmHeight = LockedSurfaceDesc.dwHeight;
4292 bmpSurface.bmWidthBytes = LockedSurfaceDesc.lPitch;
4293 bmpSurface.bmPlanes = 1;
4294 bmpSurface.bmBits = LockedSurfaceDesc.lpSurface;
4295 #endif
4296 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4297 {
4298 case 1:
4299 case 4:
4300 dprintf(("1/4 Bit Not yet supported\n"));
4301 break;
4302 case 8:
4303 #if 0
4304 BitmapInfo.bmiHead.biCompression = BI_RGB;
4305 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4306 me->hbmImage = CreateDIBitmap( me->hdcImage,
4307 NULL,
4308 CBM_CREATEDIB,
4309 LockedSurfaceDesc.lpSurface,
4310 (PBITMAPINFO)&BitmapInfo,
4311 DIB_RGB_COLORS);
4312 #else
4313 bmpSurface.bmBitsPixel = 8;
4314 me->hbmImage = CreateBitmapIndirect( &bmpSurface);
4315 #endif
4316 break;
4317 case 16:
4318 case 32:
4319 dprintf(("16/32 Bit not supported by OS/2"));
4320 break;
4321 case 24:
4322 #if 0
4323 BitmapInfo.bmiHead.biCompression = BI_RGB;
4324 me->hbmImage = CreateDIBitmap( me->hdcImage,
4325 NULL,
4326 CBM_CREATEDIB,
4327 LockedSurfaceDesc.lpSurface,
4328 (PBITMAPINFO)&BitmapInfo,
4329 DIB_RGB_COLORS);
4330 #else
4331 bmpSurface.bmBitsPixel = 24;
4332 me->hbmImage = CreateBitmapIndirect( &bmpSurface);
4333 #endif
4334 break;
4335 default:
4336 #ifdef DEBUG
4337 dprintf( ("Unexptected BitCount %d \n",
4338 LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4339 #endif
4340 me->hbmImage=NULL;
4341 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4342
4343 if(me->hbmImage == NULL)
4344 {
4345 #ifdef DEBUG
4346 dprintf(("Can't create bitmap!\n"));
4347 #endif
4348 DeleteDC(me->hdcImage);
4349 me->hdcImage = NULL;
4350 me->Vtbl.Unlock(me,NULL);
4351 rc = DDERR_GENERIC;
4352 }
4353 }
4354 else
4355 {
4356 if( (DD_OK==rc) &&
4357 (me->dwLastDCUnique != me->dwUniqueValue) )
4358 {
4359 #ifdef DEBUG
4360 dprintf(("The Surface was locked/unlocked after the last DC was created =>Update Bitmap!\n"));
4361 #endif
4362
4363 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4364 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4365 BitmapInfo.bmiHead.biWidth = LockedSurfaceDesc.lPitch/ (LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4366 BitmapInfo.bmiHead.biHeight = LockedSurfaceDesc.dwHeight;
4367 BitmapInfo.bmiHead.biPlanes = 1;
4368 BitmapInfo.bmiHead.biBitCount = LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4369
4370 switch(LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4371 {
4372 case 1:
4373 case 4:
4374 case 8:
4375 BitmapInfo.bmiHead.biCompression = BI_RGB;
4376 GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4377 SetDIBits(me->hdcImage, me->hbmImage, 0, LockedSurfaceDesc.dwHeight,
4378 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4379 break;
4380 case 16:
4381 case 32:
4382 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4383 BitmapInfo.bmiHead.biClrUsed = 3;
4384 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4385 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4386 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4387 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4388 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4389 break;
4390 case 24:
4391 BitmapInfo.bmiHead.biCompression = BI_RGB;
4392 SetDIBits(me->hdcImage, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4393 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4394 break;
4395 default:
4396 #ifdef DEBUG
4397 dprintf(("Unexptected BitCount %d => Bitmap not updated!\n",LockedSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4398 #endif
4399 break;
4400 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4401
4402 }
4403 }
4404
4405 // Allways select the bitmap into the DC! No matter if the old or a new one
4406
4407 if(DD_OK==rc)
4408 {
4409 if((me->hgdiOld = SelectObject(me->hdcImage, me->hbmImage)) == NULL)
4410 {
4411 #ifdef DEBUG
4412 dprintf(("Can't select bitmap into dc!\n"));
4413 #endif
4414 DeleteDC(me->hdcImage);
4415 me->hdcImage = NULL;
4416 DeleteObject(me->hbmImage);
4417 me->hbmImage = NULL;
4418 me->Vtbl.Unlock(me,NULL);
4419 rc = DDERR_GENERIC;
4420 }
4421 else
4422 {
4423 *hdc = me->hdcImage;
4424 }
4425 }
4426
4427 return rc;
4428}
4429//******************************************************************************
4430//******************************************************************************
4431HRESULT __stdcall SurfGetFlipStatus(THIS This, DWORD dwFlags)
4432{
4433 #ifdef DEBUG
4434 dprintf(("SurfGetFlipStatus\n"));
4435 #endif
4436
4437 if( (DDGFS_CANFLIP!=dwFlags) && (DDGFS_ISFLIPDONE!=dwFlags) )
4438 return DDERR_INVALIDPARAMS;
4439
4440 return(DD_OK);
4441}
4442//******************************************************************************
4443//******************************************************************************
4444HRESULT __stdcall SurfGetOverlayPosition(THIS This, LPLONG lplX, LPLONG lplY)
4445{
4446 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4447 #ifdef DEBUG
4448 dprintf(("SurfGetOverlayPosition\n"));
4449 #endif
4450
4451 // Maybe simply return dderr_notsupported as we retun a max overlay value of 0 in the caps ?
4452
4453 if( (NULL==lplX) || (NULL==lplY))
4454 return DDERR_INVALIDPARAMS;
4455
4456 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
4457 return DDERR_NOTAOVERLAYSURFACE;
4458
4459 if(!(me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_VISIBLE))
4460 return DDERR_OVERLAYNOTVISIBLE;
4461
4462 if(!me->fOverlayValid)
4463 return DDERR_NOOVERLAYDEST;
4464
4465 *lplX = me->lOverlayX;
4466 *lplY = me->lOverlayY;
4467
4468 return(DD_OK);
4469}
4470//******************************************************************************
4471//******************************************************************************
4472HRESULT __stdcall SurfGetPalette(THIS This, LPDIRECTDRAWPALETTE FAR *lplpPalette)
4473{
4474 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4475
4476 #ifdef DEBUG
4477 dprintf(("SurfGetPalette\n"));
4478 #endif
4479
4480 if(me->lpPalette)
4481 {
4482 *lplpPalette = (LPDIRECTDRAWPALETTE)me->lpPalette;
4483 return(DD_OK);
4484 }
4485 else
4486 return(DDERR_NOPALETTEATTACHED);
4487}
4488//******************************************************************************
4489//******************************************************************************
4490HRESULT __stdcall SurfGetPixelFormat(THIS This, LPDDPIXELFORMAT lpPixelFormat)
4491{
4492 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4493
4494 #ifdef DEBUG
4495 dprintf(("SurfGetPixelFormat\n"));
4496 #endif
4497
4498 if(NULL==lpPixelFormat)
4499 return DDERR_INVALIDPARAMS;
4500
4501 memcpy( (char*)lpPixelFormat,
4502 (char*)&(me->DDSurfaceDesc.ddpfPixelFormat),
4503 sizeof(DDPIXELFORMAT));
4504
4505 return(DD_OK);
4506}
4507//******************************************************************************
4508//******************************************************************************
4509HRESULT __stdcall SurfGetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurface)
4510{
4511 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4512
4513 #ifdef DEBUG
4514 dprintf(("SurfGetSurfaceDesc\n"));
4515 #endif
4516
4517 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC)) )
4518 return(DDERR_INVALIDPARAMS);
4519
4520 memcpy( (char *)lpSurface,
4521 (char *)&me->DDSurfaceDesc,
4522 sizeof(DDSURFACEDESC));
4523
4524 return(DD_OK);
4525}
4526//******************************************************************************
4527//******************************************************************************
4528HRESULT __stdcall SurfGetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurface)
4529{
4530 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4531
4532 #ifdef DEBUG
4533 dprintf(("SurfGetSurfaceDesc4\n"));
4534 #endif
4535
4536 if((lpSurface == NULL)||(lpSurface->dwSize != sizeof(DDSURFACEDESC2)) )
4537 return(DDERR_INVALIDPARAMS);
4538
4539 memcpy( (char *)lpSurface,
4540 (char *)&me->DDSurfaceDesc,
4541 sizeof(DDSURFACEDESC2));
4542
4543 return(DD_OK);
4544}
4545//******************************************************************************
4546//******************************************************************************
4547HRESULT __stdcall SurfInitialize(THIS, LPDIRECTDRAW, LPDDSURFACEDESC)
4548{
4549 #ifdef DEBUG
4550 dprintf(("SurfInitialize\n"));
4551 #endif
4552
4553 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4554}
4555//******************************************************************************
4556//******************************************************************************
4557HRESULT __stdcall SurfInitialize4(THIS, LPDIRECTDRAW, LPDDSURFACEDESC2)
4558{
4559 #ifdef DEBUG
4560 dprintf(("SurfInitialize\n"));
4561 #endif
4562
4563 return(DDERR_ALREADYINITIALIZED); // Init is done during creation see M$ Doc
4564}
4565//******************************************************************************
4566//******************************************************************************
4567HRESULT __stdcall SurfIsLost(THIS)
4568{
4569 // We don't loose any surface ;)
4570 // But we might shoud check for primary and/or Dive Buffers as I don't know
4571 // if they are preserved if switching to a FS DOS/OS2 session
4572 //
4573 #ifdef DEBUG
4574 dprintf(("SurfIsLost\n"));
4575 #endif
4576
4577 return(DD_OK);
4578}
4579//******************************************************************************
4580//******************************************************************************
4581HRESULT __stdcall SurfLock( THIS This,
4582 LPRECT lpRect,
4583 LPDDSURFACEDESC lpSurfaceDesc,
4584 DWORD dwFlags,
4585 HANDLE hEvent)
4586{
4587 DDSURFACEDESC2 SurfaceDesc4;
4588 HRESULT rc;
4589
4590 #ifdef DEBUG
4591 dprintf(("SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent));
4592 #endif
4593
4594 if((NULL==lpSurfaceDesc)||(NULL!=hEvent))
4595 return DDERR_INVALIDPARAMS;
4596
4597 if(lpSurfaceDesc->dwSize != sizeof(DDSURFACEDESC))
4598 return DDERR_INVALIDPARAMS;
4599
4600 SurfaceDesc4.dwSize = sizeof(DDSURFACEDESC2);
4601
4602 rc = SurfLock4( This,
4603 lpRect,
4604 &SurfaceDesc4,
4605 dwFlags,
4606 hEvent);
4607 if (DD_OK==rc)
4608 {
4609 memcpy( (char*)lpSurfaceDesc,
4610 (char*)&SurfaceDesc4,
4611 sizeof(DDSURFACEDESC) );
4612 }
4613
4614 return(rc);
4615}
4616//******************************************************************************
4617//******************************************************************************
4618HRESULT __stdcall SurfLock4( THIS This,
4619 LPRECT lpRect,
4620 LPDDSURFACEDESC2 lpSurfaceDesc,
4621 DWORD dwFlags,
4622 HANDLE hEvent)
4623{
4624
4625 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4626 int i;
4627
4628 BOOL Found;
4629 ULONG nrScanLines;
4630 char *pBuffer;
4631 DDRectangle *pIRectCurrent,*pIRectNew;
4632 static int times = 0;
4633 HRESULT rc;
4634
4635 #ifdef DEBUG
4636 dprintf( ("SurfLock4 %08X %08X %08X %d %d\n",
4637 me,
4638 (int)lpRect,
4639 (int)lpSurfaceDesc,
4640 dwFlags,
4641 hEvent) );
4642 #endif
4643
4644 if( (NULL==lpSurfaceDesc) ||
4645 (NULL!=hEvent)
4646 )
4647 return DDERR_INVALIDPARAMS;
4648
4649
4650 if (NULL!=lpRect)
4651 pIRectNew = new DDRectangle( lpRect->left, lpRect->top, lpRect->bottom, lpRect->right );
4652 else
4653 pIRectNew = new DDRectangle( 0, 0, me->height, me->width);
4654
4655 // ToDo : the lockchecking should be done in a critcal seq.
4656 dprintf( ("Lock Rectangle (%d/%d) x (%d/%d)\n",
4657 pIRectNew->Top(),
4658 pIRectNew->Left(),
4659 pIRectNew->Bottom(),
4660 pIRectNew->Right() ));
4661
4662 rc = DD_OK;
4663
4664 if(me->fLocked)
4665 {
4666 if (NULL==lpRect)
4667 {
4668 // If anything is locked we can't locke the complete surface
4669 dprintf(("Surface has locked Rectangles, and we want to complete lock it\n"));
4670 Found = TRUE;
4671 }
4672 else
4673 {
4674 // If the new Rectangle intersects with any of the already locked rectangles it can't
4675 // be locked so check for this
4676
4677 dprintf(("Surface has locked Rectangles, check if the overlap\n"));
4678
4679 i=0;
4680 Found = FALSE;
4681
4682 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
4683 {
4684 pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
4685 dprintf( ("Test with Rectangle (%d/%d) x (%d/%d)\n",
4686 pIRectCurrent->Top(),
4687 pIRectCurrent->Left(),
4688 pIRectCurrent->Bottom(),
4689 pIRectCurrent->Right() ));
4690 Found = pIRectCurrent->intersects(*pIRectNew);
4691 i++;
4692 }
4693
4694 }
4695
4696 if (Found)
4697 {
4698 delete pIRectNew;
4699 #ifdef DEBUG
4700 dprintf(("SurfLock4: Surface already locked\n\n"));
4701 #endif
4702 rc = DDERR_SURFACEBUSY;
4703 }
4704
4705 }
4706
4707 if(DD_OK == rc)
4708 {
4709 memcpy((char *)lpSurfaceDesc, (char *)&me->DDSurfaceDesc, sizeof(DDSURFACEDESC2));
4710
4711 if(lpRect != NULL)
4712 {
4713 lpSurfaceDesc->lpSurface = (LPVOID)((char*)me->pFrameBuffer +
4714 (lpRect->top * me->dwPitchFB) +
4715 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
4716 #ifdef DEBUG
4717 dprintf(("SurfLock4 %08X (x,y) = (%d,%d)\n\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left));
4718 #endif
4719 }
4720 else
4721 {
4722 #ifdef DEBUG
4723 dprintf(("SurfLock4 %08X \n\n", lpSurfaceDesc->lpSurface));
4724 #endif
4725 }
4726 // Add the rectangle to the list of locked rectangles
4727
4728 pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
4729
4730 DPA_InsertPtr( me->DPA_LockedRects,
4731 DPA_GetPtrCount(me->DPA_LockedRects),
4732 pIRectNew);
4733
4734 me->fLocked = TRUE;
4735 }
4736
4737
4738 return rc;
4739}
4740//******************************************************************************
4741//******************************************************************************
4742HRESULT __stdcall SurfReleaseDC(THIS This, HDC hdc)
4743{
4744 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4745 struct
4746 {
4747 BITMAPINFOHEADER bmiHead;
4748 RGBQUAD bmiCols[256];
4749 } BitmapInfo;
4750 BITMAP bmpData;
4751 char szError[256];
4752 int i,rc;
4753
4754 #ifdef DEBUG
4755 dprintf(("SurfReleaseDC\n"));
4756 #endif
4757
4758 if(hdc != me->hdcImage)
4759 return(DDERR_INVALIDOBJECT);
4760
4761 #if 1
4762 //unselect our bitmap
4763 SelectObject(me->hdcImage, me->hgdiOld);
4764 memset(&BitmapInfo,0, sizeof(BitmapInfo));
4765 BitmapInfo.bmiHead.biSize = sizeof(BITMAPINFOHEADER);
4766 /*
4767 BitmapInfo.bmiHead.biWidth = me->DDSurfaceDesc.lPitch/ (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount>>3);
4768 BitmapInfo.bmiHead.biHeight = me->DDSurfaceDesc.dwHeight;
4769 BitmapInfo.bmiHead.biPlanes = 1;
4770 BitmapInfo.bmiHead.biBitCount = 0; // me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount;
4771 */
4772 switch(me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4773 {
4774 case 1:
4775 case 4:
4776 case 8:
4777 BitmapInfo.bmiHead.biCompression = BI_RGB;
4778 //GetSystemPaletteEntries(me->hdcImage,0,255,(PPALETTEENTRY)&BitmapInfo.bmiCols[0]);
4779 rc = GetDIBits( hdc,
4780 me->hbmImage,
4781 0,
4782 me->DDSurfaceDesc.dwHeight,
4783 NULL,
4784 (PBITMAPINFO)&BitmapInfo,
4785 DIB_RGB_COLORS);
4786 dprintf( ("GetDIBits rc=%d\n Size :%d\n Width :%d\n Height :%d\n"
4787 " Planes :%d\n BitCount :%d\nLastEror = %d\nPixel[0,0] = 0x%02X\n",
4788 rc,
4789 BitmapInfo.bmiHead.biSize,
4790 BitmapInfo.bmiHead.biWidth,
4791 BitmapInfo.bmiHead.biHeight,
4792 BitmapInfo.bmiHead.biPlanes,
4793 BitmapInfo.bmiHead.biBitCount,
4794 GetLastError(),
4795 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4796 rc = GetDIBits( hdc,
4797 me->hbmImage,
4798 0,
4799 me->DDSurfaceDesc.dwHeight,
4800 me->DDSurfaceDesc.lpSurface,
4801 (PBITMAPINFO)&BitmapInfo,
4802 DIB_RGB_COLORS);
4803 dprintf( ("GetDIBits rc=%d\n LastEror = %d\nPixel[0,0] = 0x%02X\n",
4804 rc,
4805 GetLastError(),
4806 ((char*)me->DDSurfaceDesc.lpSurface)[0]));
4807 break;
4808 case 16:
4809 case 32:
4810 BitmapInfo.bmiHead.biCompression = BI_BITFIELDS;
4811 BitmapInfo.bmiHead.biClrUsed = 3;
4812 *((DWORD *) &(BitmapInfo.bmiCols[0])) = me->DDSurfaceDesc.ddpfPixelFormat.dwRBitMask;
4813 *((DWORD *) &(BitmapInfo.bmiCols[1])) = me->DDSurfaceDesc.ddpfPixelFormat.dwGBitMask;
4814 *((DWORD *) &(BitmapInfo.bmiCols[2])) = me->DDSurfaceDesc.ddpfPixelFormat.dwBBitMask;
4815 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4816 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4817 break;
4818 case 24:
4819 BitmapInfo.bmiHead.biCompression = BI_RGB;
4820 GetDIBits(hdc, me->hbmImage, 0, me->DDSurfaceDesc.dwHeight,
4821 me->DDSurfaceDesc.lpSurface,(PBITMAPINFO)&BitmapInfo,DIB_RGB_COLORS);
4822 break;
4823 default:
4824 #ifdef DEBUG
4825 dprintf(("Unexptected BitCount %d => Surface unlocked but no data copied back\n",me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount));
4826 #endif
4827 // we might could keep the surface locked and return an error but this is more "safe"
4828 break;
4829 } // end switch (me->DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
4830 #else
4831
4832 rc = GetObjectA( me->hbmImage,
4833 sizeof(BITMAP),
4834 &bmpData);
4835 dprintf( ("GetObject returned rc=%d\n BitmapInfo:\n Size:(%dx%d)\n Pitch: %d\n Bits %d\n @mem %08X",
4836 rc,
4837 bmpData.bmWidth, bmpData.bmHeight,
4838 bmpData.bmWidthBytes,
4839 bmpData.bmBitsPixel,
4840 bmpData.bmBits));
4841 #endif
4842 me->Vtbl.Unlock(me,NULL);
4843 me->dwLastDCUnique = me->dwUniqueValue; // Store this to see if the surface was locked after we released the DC
4844
4845 return(DD_OK);
4846}
4847//******************************************************************************
4848//******************************************************************************
4849HRESULT __stdcall SurfRestore(THIS)
4850{
4851 #ifdef DEBUG
4852 dprintf(("SurfRestore\n"));
4853 #endif
4854
4855 return(DD_OK);
4856}
4857//******************************************************************************
4858//******************************************************************************
4859HRESULT __stdcall SurfSetClipper(THIS This, LPDIRECTDRAWCLIPPER lpClipper)
4860{
4861 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4862
4863 #ifdef DEBUG
4864 dprintf(("SurfSetClipper\n"));
4865 #endif
4866
4867 if(lpClipper == NULL)
4868 {
4869 //deattach surface
4870 if(me->lpClipper)
4871 {
4872 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper);
4873 me->lpClipper = NULL;
4874 return(DD_OK);
4875 }
4876 else
4877 return(DDERR_NOCLIPPERATTACHED);
4878 }
4879
4880 if(lpClipper == (LPDIRECTDRAWCLIPPER)me->lpClipper)
4881 return(DD_OK); //already attached
4882
4883 if(me->lpClipper != NULL)
4884 {
4885 me->lpClipper->Vtbl.Release((IDirectDrawClipper*)me->lpClipper); //attach other surface
4886 return(DD_OK);
4887 }
4888
4889 me->lpClipper = (OS2IDirectDrawClipper *)lpClipper;
4890 me->lpClipper->Vtbl.AddRef((IDirectDrawClipper*)me->lpClipper);
4891
4892 return(DD_OK);
4893}
4894//******************************************************************************
4895//******************************************************************************
4896HRESULT __stdcall SurfSetColorKey(THIS This, DWORD dwFlags, LPDDCOLORKEY lpDDColKey)
4897{
4898 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4899 HRESULT rc;
4900 #ifdef DEBUG
4901 dprintf(("SurfSetColorKey\n"));
4902 #endif
4903
4904 if (0==dwFlags)
4905 return (DDERR_INVALIDPARAMS);
4906
4907 // as we report only src colorkey in the caps return error on all others flags
4908 if( (DDCKEY_DESTBLT|DDCKEY_DESTOVERLAY|DDCKEY_SRCOVERLAY|DDCKEY_COLORSPACE) & dwFlags)
4909 return(DDERR_UNSUPPORTED);
4910
4911 if(DDCKEY_SRCBLT & dwFlags)
4912 {
4913 //(me->lpVtbl == me->Vtbl4)
4914 // me->Vtbl4->ChangeUniquenessValue(me); // we changed somethin so change this value
4915 if(NULL!=lpDDColKey)
4916 {
4917 memcpy(&(me->DDSurfaceDesc.ddckCKSrcBlt), lpDDColKey, sizeof(DDCOLORKEY) );
4918 me->DDSurfaceDesc.dwFlags |= DDCKEY_SRCBLT;
4919
4920 // ToDo: Generate a maskbitmap for transparent blitting here
4921 }
4922 else
4923 {
4924 memset(&(me->DDSurfaceDesc.ddckCKSrcBlt), 0, sizeof(DDCOLORKEY) );
4925 me->DDSurfaceDesc.dwFlags &= ~DDCKEY_SRCBLT;
4926 }
4927 rc = DD_OK;
4928 }
4929 else
4930 rc = DDERR_INVALIDPARAMS; // some other flags where set => error
4931
4932 return rc;
4933}
4934//******************************************************************************
4935//******************************************************************************
4936HRESULT __stdcall SurfSetOverlayPosition(THIS This, LONG lX, LONG lY)
4937{
4938 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4939
4940 #ifdef DEBUG
4941 dprintf(("SurfSetOverlayPosition\n"));
4942 #endif
4943
4944 if( (me->DDSurfaceDesc.dwFlags & DDSD_CAPS) &&
4945 (me->DDSurfaceDesc.ddsCaps.dwCaps & DDSCAPS_OVERLAY) )
4946 {
4947 if(me->fOverlayValid)
4948 return(DDERR_NOOVERLAYDEST);
4949
4950 if(!(me->DDSurfaceDesc.dwFlags & DDSCAPS_VISIBLE))
4951 return(DDERR_OVERLAYNOTVISIBLE);
4952
4953 // ToDo: If we implement alignment restricions to the Overlay position
4954 // check if the new values are OK otherwiese return DDERR_INVALIDPOSITION
4955
4956 me->lOverlayX = lX;
4957 me->lOverlayY = lY;
4958 return(DD_OK);
4959 }
4960
4961 return(DDERR_NOTAOVERLAYSURFACE);
4962}
4963//******************************************************************************
4964//******************************************************************************
4965HRESULT __stdcall SurfSetPalette(THIS This, LPDIRECTDRAWPALETTE lpPalette)
4966{
4967 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
4968
4969 #ifdef DEBUG
4970 dprintf(("SurfSetPalette\n"));
4971 #endif
4972
4973 if(lpPalette == NULL)
4974 {
4975 //deattach palette
4976 if(me->lpPalette)
4977 {
4978 // If removed from a primary surface notify
4979 // palette that it is no longer attached to the
4980 // primary surface => doesn't modify physical palette
4981 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
4982 {
4983 me->lpPalette->SetIsPrimary(FALSE);
4984 }
4985 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette);
4986 me->lpPalette = NULL;
4987 return(DD_OK);
4988 }
4989 else
4990 return(DDERR_NOPALETTEATTACHED);
4991 }
4992
4993 if(lpPalette == (LPDIRECTDRAWPALETTE)me->lpPalette)
4994 return(DD_OK); //already attached
4995
4996 if(me->lpPalette != NULL)
4997 {
4998 me->lpPalette->Vtbl.Release((IDirectDrawPalette*)me->lpPalette); //attach other palette
4999 return(DD_OK);
5000 }
5001 me->lpPalette = (OS2IDirectDrawPalette *)lpPalette;
5002 me->lpPalette->Vtbl.AddRef((IDirectDrawPalette*)me->lpPalette);
5003
5004 // If Attached to a primary surface notify
5005 // palette that it is attached to the primary surface
5006 // => It does modify physical palette.
5007 // This is important as an palette can be attached to
5008 // multiple surfaces. If one is the primary surface
5009 // changes done to it via any surface must result in
5010 // changes in the phys pal.
5011
5012 if(me->surfaceType & DDSCAPS_PRIMARYSURFACE)
5013 {
5014 me->lpPalette->SetIsPrimary(TRUE);
5015 }
5016 // me->lpVtbl->ChangeUniquenessValue(me);
5017
5018 return(DD_OK);
5019}
5020//******************************************************************************
5021//******************************************************************************
5022HRESULT __stdcall SurfUnlock(THIS This, LPVOID lpSurfaceData)
5023{
5024
5025 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5026 int i;
5027 DDRectangle *pIRectUnlock, *pIRectEnum;
5028 BOOL Found = FALSE;
5029 OS2RECTL CCRect;
5030 HRESULT rc;
5031
5032 #ifdef DEBUG
5033 dprintf(("SurfUnlock at %08X\n",lpSurfaceData));
5034 #endif
5035
5036 if(me->fLocked == FALSE)
5037 {
5038 #ifdef DEBUG
5039 dprintf(("Surface not locked!\n"));
5040 #endif
5041 return(DDERR_NOTLOCKED);
5042 }
5043
5044 #ifdef DEBUG
5045 dprintf(("Start Emuneration of Locked Rects\n"));
5046 #endif
5047
5048 i=0;
5049 if(NULL!=lpSurfaceData)
5050 {
5051 dprintf(("Buffer Pointer Compare"));
5052
5053 // We got a pinter to the surface memory so we must search for
5054 // this pointer in the locked rects DPA to unlock the right rect.
5055
5056 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5057 {
5058 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5059 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5060 i,
5061 pIRectEnum->Top(),
5062 pIRectEnum->Left(),
5063 pIRectEnum->Bottom(),
5064 pIRectEnum->Right(),
5065 pIRectEnum->GetMemPtr() ));
5066
5067 Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
5068 if(!Found)
5069 {
5070 #ifdef DEBUG
5071 dprintf(("Not Found, try Next rect\n"));
5072 #endif
5073 i++;
5074 }
5075 #ifdef DEBUG
5076 else
5077 {
5078 dprintf(("Found Rect\n"));
5079 }
5080 #endif
5081 }
5082 }
5083 else
5084 {
5085 // If a NULL pointer was passed in the SW tries to unlock the
5086 // complete surface so we must compare the rects.
5087 dprintf(("Rectangle compare"));
5088
5089 pIRectUnlock = new DDRectangle( 0, 0, me->height, me->width);
5090
5091 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5092 {
5093 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5094 dprintf(( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
5095 i,
5096 pIRectEnum->Top(),
5097 pIRectEnum->Left(),
5098 pIRectEnum->Bottom(),
5099 pIRectEnum->Right(),
5100 pIRectEnum->GetMemPtr() ));
5101
5102 Found = (*pIRectEnum == *pIRectUnlock);
5103 if(!Found)
5104 {
5105 #ifdef DEBUG
5106 dprintf(("Not Found, try Next rect\n"));
5107 #endif
5108 i++;
5109 }
5110 #ifdef DEBUG
5111 else
5112 {
5113 dprintf(("Found Rect\n"));
5114 }
5115 #endif
5116 }
5117 delete pIRectUnlock;
5118 }
5119
5120 if(!Found)
5121 {
5122 #ifdef DEBUG
5123 dprintf(("Rectangle not locked, wrong Rect!\n\n"));
5124 #endif
5125 rc = DDERR_INVALIDRECT;
5126 }
5127 else
5128 {
5129 #ifdef DEBUG
5130 dprintf(("Remove Rect %d from Seq.\n",i));
5131 #endif
5132
5133 DPA_DeletePtr(me->DPA_LockedRects,i);
5134
5135 #ifdef DEBUG
5136 dprintf(("Test if locked Rects main\n"));
5137 #endif
5138
5139 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5140 {
5141 #ifdef DEBUG
5142 dprintf(("No Locked Rects left for surface\n"));
5143 #endif
5144 me->fLocked = FALSE;
5145 }
5146 #ifdef DEBUG
5147 else
5148 dprintf(( "%d Rects in Seq\n",
5149 DPA_GetPtrCount(me->DPA_LockedRects)));
5150 #endif
5151
5152 if(me->pFrameBuffer != me->pDiveBuffer)
5153 {
5154 #ifdef DEBUG
5155 dprintf(( "ColorConversion Needed %08X != %08X\n",
5156 me->pFrameBuffer,
5157 me->pDiveBuffer));
5158 #endif
5159 if(NULL!=lpSurfaceData)
5160 {
5161 CCRect.yTop = pIRectEnum->Top();
5162 CCRect.xLeft = pIRectEnum->Left();
5163 CCRect.xRight = pIRectEnum->Right();
5164 CCRect.yBottom = pIRectEnum->Bottom();
5165
5166 me->ColorConversion( (LPRECT)&CCRect);
5167 }
5168 else
5169 {
5170 me->ColorConversion(NULL);
5171 }
5172 }
5173 #ifdef DEBUG
5174 else
5175 dprintf( ("No ColorConversion Needed"));
5176 #endif
5177
5178 // delete tne DDRectobject of the found rectangle
5179 delete pIRectEnum;
5180
5181 // me->lpVtbl->ChangeUniquenessValue(me);
5182
5183 dprintf(("Unlock OK\n\n"));
5184
5185 rc = DD_OK;
5186 }
5187
5188 return rc;
5189}
5190//******************************************************************************
5191//******************************************************************************
5192HRESULT __stdcall SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
5193{
5194 // MS changed the parameter from LPVOID to LPRECT with DX6
5195 // as DX-6 allways returns a DDSurface4 on create surface this
5196 // is a problem i not NULL is passed in.
5197 // Solution We first test with the pointer ns assuming a rectangle
5198 // if we don't find a rect Which is very likely if we get a pointer
5199 // SurfaceMemory we call SurfUnlock and test for the pointer there.
5200
5201
5202 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5203 int i;
5204 DDRectangle *pIRectUnlock, *pIRectEnum;
5205 BOOL Found = FALSE;
5206 HRESULT rc;
5207
5208 #ifdef DEBUG
5209 dprintf(("SurfUnlock4\n"));
5210 #endif
5211
5212 if(me->fLocked == FALSE)
5213 {
5214 #ifdef DEBUG
5215 dprintf(("Surface not locked!\n"));
5216 #endif
5217 return(DDERR_NOTLOCKED);
5218 }
5219
5220 if(NULL!=lpSurfaceRect)
5221 {
5222 dprintf(("Unlock rectangle\n"));
5223 pIRectUnlock = new DDRectangle( lpSurfaceRect->top,
5224 lpSurfaceRect->left,
5225 lpSurfaceRect->bottom,
5226 lpSurfaceRect->right);
5227 }
5228 else
5229 {
5230 dprintf(("Unlock complete surface\n"));
5231 pIRectUnlock = new DDRectangle( 0, 0, me->height, me->width);
5232 }
5233
5234 dprintf(( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
5235 pIRectUnlock->Top(),
5236 pIRectUnlock->Left(),
5237 pIRectUnlock->Bottom(),
5238 pIRectUnlock->Right() ));
5239
5240 #ifdef DEBUG
5241 dprintf(("Start Emuneration of Locked Rects\n"));
5242 #endif
5243
5244 i=0;
5245 while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
5246 {
5247 pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
5248 dprintf(( "Test with Rectangle (%d/%d) x (%d/%d)\n",
5249 pIRectEnum->Top(),
5250 pIRectEnum->Left(),
5251 pIRectEnum->Bottom(),
5252 pIRectEnum->Right() ));
5253
5254 Found = (*pIRectEnum == *pIRectUnlock);
5255 if(!Found)
5256 {
5257 #ifdef DEBUG
5258 dprintf(("Not Found, try Next rect\n"));
5259 #endif
5260 i++;
5261 }
5262 #ifdef DEBUG
5263 else
5264 {
5265 dprintf(("Found Rect\n"));
5266 }
5267 #endif
5268 }
5269
5270 if(!Found)
5271 {
5272
5273 if(NULL==lpSurfaceRect)
5274 {
5275 #ifdef DEBUG
5276 dprintf(("Rectangle not locked, wrong Rect!\n\n"));
5277 #endif
5278 return(DDERR_INVALIDRECT);
5279 }
5280 else
5281 rc = SurfUnlock(This, (LPVOID)lpSurfaceRect);
5282 }
5283 else
5284 {
5285 #ifdef DEBUG
5286 dprintf(("Remove Rect from Seq.\n"));
5287 #endif
5288
5289 DPA_DeletePtr(me->DPA_LockedRects,i);
5290
5291 if(0==DPA_GetPtrCount(me->DPA_LockedRects)) // Do we have unlocked last rectangle
5292 {
5293 #ifdef DEBUG
5294 dprintf(("No Locked Rects left for surface\n"));
5295 #endif
5296 me->fLocked = FALSE;
5297 }
5298
5299 if(me->pFrameBuffer != me->pDiveBuffer)
5300 {
5301 #ifdef DEBUG
5302 dprintf(( "ColorConversion Needed %08X != %08X\n",
5303 me->pFrameBuffer,
5304 me->pDiveBuffer));
5305 #endif
5306 me->ColorConversion(lpSurfaceRect);
5307 }
5308
5309 // me->lpVtbl->ChangeUniquenessValue(me);
5310
5311 dprintf(("Unlock OK\n\n"));
5312 rc = DD_OK;
5313 }
5314
5315 return rc;
5316}
5317//******************************************************************************
5318//******************************************************************************
5319HRESULT __stdcall SurfUpdateOverlay(THIS This, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX)
5320{
5321 #ifdef DEBUG
5322 dprintf(("SurfUpdateOverlay\n"));
5323 #endif
5324 return(DD_OK);
5325}
5326//******************************************************************************
5327//******************************************************************************
5328HRESULT __stdcall SurfUpdateOverlay3(THIS This, LPRECT, LPDIRECTDRAWSURFACE3,LPRECT,DWORD, LPDDOVERLAYFX)
5329{
5330 #ifdef DEBUG
5331 dprintf(("SurfUpdateOverlay\n"));
5332 #endif
5333 return(DD_OK);
5334}
5335//******************************************************************************
5336//******************************************************************************
5337HRESULT __stdcall SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX)
5338{
5339 #ifdef DEBUG
5340 dprintf(("SurfUpdateOverlay\n"));
5341 #endif
5342 return(DD_OK);
5343}
5344//******************************************************************************
5345//******************************************************************************
5346HRESULT __stdcall SurfUpdateOverlayDisplay(THIS, DWORD)
5347{
5348 #ifdef DEBUG
5349 dprintf(("SurfUpdateOverlayDisplay\n"));
5350 #endif
5351 return(DD_OK);
5352}
5353//******************************************************************************
5354//******************************************************************************
5355HRESULT __stdcall SurfUpdateOverlayZOrder(THIS, DWORD, LPDIRECTDRAWSURFACE2)
5356{
5357 #ifdef DEBUG
5358 dprintf(("SurfUpdateOverlayZOrder\n"));
5359 #endif
5360 return(DD_OK);
5361}
5362//******************************************************************************
5363//******************************************************************************
5364HRESULT __stdcall SurfUpdateOverlayZOrder3(THIS, DWORD, LPDIRECTDRAWSURFACE3)
5365{
5366 #ifdef DEBUG
5367 dprintf(("SurfUpdateOverlayZOrder\n"));
5368 #endif
5369 return(DD_OK);
5370}
5371//******************************************************************************
5372//******************************************************************************
5373HRESULT __stdcall SurfUpdateOverlayZOrder4(THIS, DWORD, LPDIRECTDRAWSURFACE4)
5374{
5375 #ifdef DEBUG
5376 dprintf(("SurfUpdateOverlayZOrder4\n"));
5377 #endif
5378 return(DD_OK);
5379}
5380//******************************************************************************
5381//******************************************************************************
5382HRESULT __stdcall SurfGetDDInterface(THIS This, LPVOID FAR *lplpDirectDraw)
5383{
5384 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5385
5386 #ifdef DEBUG
5387 dprintf(("SurfGetDDInterface\n"));
5388 #endif
5389 *lplpDirectDraw = (LPVOID FAR *)me->lpDraw;
5390 return(DD_OK);
5391}
5392//******************************************************************************
5393//******************************************************************************
5394HRESULT __stdcall SurfPageLock(THIS, DWORD)
5395{
5396 // Only used for DMA memory access
5397 // If we implement this for the None dive buffers with a pdd the we must change
5398 // from malloc to DosAllocMem and use OBJ_TILE flag
5399 #ifdef DEBUG
5400 dprintf(("SurfPageLock\n"));
5401 #endif
5402 return(DD_OK);
5403}
5404//******************************************************************************
5405//******************************************************************************
5406HRESULT __stdcall SurfPageUnlock(THIS, DWORD)
5407{
5408 #ifdef DEBUG
5409 dprintf(("SurfPageUnlock\n"));
5410 #endif
5411 return(DD_OK);
5412}
5413//******************************************************************************
5414//******************************************************************************
5415// V3 Interface Functions
5416
5417HRESULT __stdcall SurfSetSurfaceDesc(THIS This, LPDDSURFACEDESC lpSurfDesc, DWORD dwFlags)
5418{
5419 #ifdef DEBUG
5420 dprintf(("SurfSetSurfaceDesc\n"));
5421 #endif
5422
5423 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5424 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5425 return DDERR_INVALIDPARAMS;
5426
5427 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5428 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5429 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5430 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5431 if(-1==me->diveBufNr)
5432 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5433
5434 if (!me->Updated)
5435 {
5436 me->Updated = TRUE;
5437 // free our allocated Memory
5438 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5439 free(me->DDSurfaceDesc.lpSurface);
5440 }
5441 // me->lpVtbl->ChangeUniquenessValue(me);
5442 memcpy((char *)&(me->DDSurfaceDesc), (char *)lpSurfDesc, sizeof(DDSURFACEDESC));
5443
5444 return DD_OK;
5445}
5446//******************************************************************************
5447//******************************************************************************
5448HRESULT __stdcall SurfSetSurfaceDesc4(THIS This, LPDDSURFACEDESC2 lpSurfDesc, DWORD dwFlags)
5449{
5450 #ifdef DEBUG
5451 dprintf(("SurfSetSurfaceDesc4\n"));
5452 #endif
5453
5454 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5455 if ( (NULL==lpSurfDesc) || (dwFlags!=0) )
5456 return DDERR_INVALIDPARAMS;
5457
5458 // Is this ok ? Not sure if Front/BackBuffer should be handled like the Primary one.
5459 // if ( ( DDSCAPS_PRIMARYSURFACE == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5460 // ( DDSCAPS_FRONTBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) ||
5461 // ( DDSCAPS_BACKBUFFER == me->DDSurfaceDesc.ddsCaps.dwCaps) )
5462 if(-1==me->diveBufNr)
5463 return DDERR_INVALIDSURFACETYPE; // only work for system alloced surfaces
5464
5465 if (!me->Updated)
5466 {
5467 me->Updated = TRUE;
5468 // free our allocated Memory
5469 if(me->DDSurfaceDesc.dwFlags & DDSD_LPSURFACE)
5470 free(me->DDSurfaceDesc.lpSurface);
5471 }
5472 // me->lpVtbl->ChangeUniquenessValue(me);
5473 memcpy((char *)&(me->DDSurfaceDesc), (char *)lpSurfDesc, sizeof(DDSURFACEDESC2));
5474
5475 return DD_OK;
5476}
5477//******************************************************************************
5478//******************************************************************************
5479// V4 Interface Functions
5480
5481HRESULT __stdcall SurfSetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData,
5482 DWORD dwDataSize, DWORD dwFlags)
5483{
5484 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5485 int i;
5486 PSURFPRIVATEDATA pSData;
5487 void *pBuffer;
5488 BOOL bFound = FALSE;
5489 HRESULT rc;
5490
5491 #ifdef DEBUG
5492 dprintf(("SurfSetPrivateData\n"));
5493 #endif
5494
5495 if(NULL==me)
5496 return(DDERR_INVALIDOBJECT);
5497
5498 if((NULL==lpData)||(0==dwDataSize)||
5499 (dwFlags & ~(DDSPD_IUNKNOWNPOINTER|DDSPD_VOLATILE)))
5500 return(DDERR_INVALIDPARAMS);
5501
5502 // first check if the refGUID is stored as then the content will be updated
5503 if( DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0 )
5504 {
5505 i=0;
5506 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5507 {
5508 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5509
5510 if (IsEqualGUID(pSData->guidTag,refGUID))
5511 bFound = TRUE;
5512
5513 i++;
5514 }
5515 }
5516
5517 if(bFound)
5518 {
5519 // update Private Data
5520
5521 if (!pSData->isValid)
5522 {
5523 // Current data is invalid we need to update/allocate
5524
5525 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5526 {
5527 pSData->pData = lpData;
5528 pSData->dwSize = 4;
5529 pSData->dwFlags = dwFlags;
5530 pSData->isValid = TRUE;
5531 ((OS2IDirectDrawSurface *) lpData)->lpVtbl->AddRef(lpData);
5532 }
5533 else
5534 {
5535 pSData->pData = malloc(dwDataSize);
5536 if(NULL!=pSData->pData)
5537 {
5538 memcpy(pSData->pData,lpData,dwDataSize);
5539 pSData->dwSize = dwDataSize;
5540 pSData->dwFlags = dwFlags;
5541 pSData->isValid = TRUE;
5542 }
5543 else
5544 {
5545 delete pSData;
5546 rc = DDERR_OUTOFMEMORY;
5547 }
5548 }
5549 }
5550 else
5551 {
5552 if(pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5553 {
5554 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5555 {
5556 if(pSData->pData != lpData)
5557 {
5558 // Change of IUNKOWNPOINTER => release old and add ref to new one
5559 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5560 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5561 pSData->pData = lpData;
5562 }
5563 pSData->dwFlags = dwFlags; // Update the flags, size is the same
5564 }
5565 else
5566 {
5567 // Replace IUNKOWN through data
5568 pBuffer = malloc(dwDataSize); // get new buffer first
5569 if(NULL!=pBuffer)
5570 {
5571 // release old ref and copy data
5572 ((OS2IDirectDrawSurface *)pSData->pData)->lpVtbl->Release(pSData->pData);
5573 memcpy(pBuffer,lpData,dwDataSize);
5574 pSData->pData = pBuffer;
5575 pSData->dwSize = dwDataSize; // Update the size
5576 pSData->dwFlags = dwFlags; // Update the flags
5577 }
5578 else
5579 rc = DDERR_OUTOFMEMORY;
5580 }
5581 }
5582 else
5583 {
5584 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5585 {
5586 // Change of data to IUNKOWNPOINTER => free old memory and add ref to new one
5587 free(pSData->pData);
5588 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5589 pSData->pData = lpData;
5590 pSData->dwSize = dwDataSize; // Update the size
5591 pSData->dwFlags = dwFlags; // Update the flags
5592 }
5593 else
5594 {
5595 // Update/Replace data
5596 if(pSData->dwSize!=dwDataSize)
5597 pBuffer = realloc(pSData->pData,dwDataSize); // update buffer to new size
5598 else
5599 pBuffer = pSData->pData;
5600
5601 if(NULL!=pBuffer)
5602 {
5603 // release old ref and copy data
5604 memcpy(pBuffer,lpData,dwDataSize);
5605 pSData->pData = pBuffer;
5606 pSData->dwSize = dwDataSize; // Update the size
5607 pSData->dwFlags = dwFlags; // Update the flags
5608 }
5609 else
5610 rc = DDERR_OUTOFMEMORY;
5611 }
5612 }
5613 }
5614 }
5615 else
5616 {
5617 // New data
5618
5619 pSData = new(SURFPRIVATEDATA);
5620 if (NULL!=pSData)
5621 {
5622 if(dwFlags & DDSPD_IUNKNOWNPOINTER)
5623 {
5624 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5625 pSData->pData = lpData;
5626 pSData->dwSize = 4;
5627 pSData->dwFlags = dwFlags;
5628 pSData->isValid = TRUE;
5629 ((OS2IDirectDrawSurface *)lpData)->lpVtbl->AddRef(lpData);
5630 }
5631 else
5632 {
5633 pSData->pData = malloc(dwDataSize);
5634 if(NULL!=pSData->pData)
5635 {
5636 memcpy(&(pSData->guidTag),&refGUID,sizeof(GUID));
5637 memcpy(pSData->pData,lpData,dwDataSize);
5638 pSData->dwSize = dwDataSize;
5639 pSData->dwFlags = dwFlags;
5640 pSData->isValid = TRUE;
5641
5642 if( DPA_InsertPtr( me->DPA_SurfacePrivateData,
5643 DPA_GetPtrCount(me->DPA_SurfacePrivateData),
5644 pSData) <0)
5645 {
5646 delete(pSData);
5647 rc = DDERR_OUTOFMEMORY;
5648 }
5649 }
5650 else
5651 {
5652 delete(pSData);
5653 rc = DDERR_OUTOFMEMORY;
5654 }
5655 }
5656
5657 }
5658 else
5659 rc = DDERR_OUTOFMEMORY;
5660 }
5661
5662 return rc;
5663}
5664//******************************************************************************
5665//******************************************************************************
5666HRESULT __stdcall SurfGetPrivateData(THIS This, REFGUID refGUID, LPVOID lpData, LPDWORD lpDataSize)
5667{
5668 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5669 int i;
5670 PSURFPRIVATEDATA pSData;
5671 HRESULT rc;
5672 BOOL bFound = FALSE;
5673
5674 #ifdef DEBUG
5675 dprintf(("SurfGetPrivateData\n"));
5676 #endif
5677
5678 if(NULL==me)
5679 return(DDERR_INVALIDOBJECT);
5680
5681 if((NULL==lpData)||(NULL==lpDataSize))
5682 return(DDERR_INVALIDPARAMS);
5683
5684 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5685 {
5686 i=0;
5687 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5688 {
5689 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5690
5691 if (IsEqualGUID(pSData->guidTag,refGUID))
5692 bFound = TRUE;
5693
5694 i++;
5695 }
5696 }
5697
5698 if(bFound)
5699 {
5700 if(!pSData->isValid)
5701 {
5702 rc =DDERR_EXPIRED;
5703 }
5704 else
5705 {
5706 if(pSData->dwSize > *lpDataSize)
5707 {
5708 // Buffer to small return needed Size
5709 *lpDataSize = pSData->dwSize;
5710 rc = DDERR_MOREDATA;
5711 }
5712 else
5713 {
5714 memcpy(lpData,pSData->pData,pSData->dwSize);
5715 rc = DD_OK;
5716 }
5717 }
5718 }
5719 else
5720 rc = DDERR_NOTFOUND;
5721
5722
5723 return rc;
5724}
5725//******************************************************************************
5726//******************************************************************************
5727HRESULT __stdcall SurfFreePrivateData(THIS This, REFGUID refGUID)
5728{
5729 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5730 int i;
5731 PSURFPRIVATEDATA pSData;
5732 BOOL bFound = FALSE;
5733
5734 #ifdef DEBUG
5735 dprintf(("SurfFreePrivateData\n"));
5736 #endif
5737
5738 if(NULL==me)
5739 return(DDERR_INVALIDOBJECT);
5740
5741 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5742 {
5743 i=0;
5744 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData) && !bFound)
5745 {
5746 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5747
5748 if (IsEqualGUID(pSData->guidTag,refGUID))
5749 {
5750 bFound = TRUE;
5751
5752 if(pSData->isValid)
5753 {
5754 // delete the data if valid
5755 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5756 {
5757 // pointer to com stored so calll its release
5758 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5759 }
5760 else
5761 {
5762 // Free allocated data
5763 free( pSData->pData);
5764 }
5765 }
5766 // Now remove the entry from the list
5767 DPA_DeletePtr(me->DPA_SurfacePrivateData,i);
5768 }
5769 i++;
5770 }
5771 }
5772
5773 return (bFound?DD_OK:DDERR_NOTFOUND);
5774}
5775//******************************************************************************
5776//******************************************************************************
5777HRESULT __stdcall SurfGetUniquenessValue(THIS This, LPDWORD lpValue)
5778{
5779 #ifdef DEBUG
5780 dprintf(("SurfGetUniquenessValue\n"));
5781 #endif
5782 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5783 if (NULL==lpValue)
5784 return DDERR_INVALIDPARAMS;
5785
5786 *lpValue = me->dwUniqueValue;
5787 return DD_OK;
5788}
5789//******************************************************************************
5790//******************************************************************************
5791HRESULT __stdcall SurfChangeUniquenessValue(THIS This)
5792{
5793 OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
5794 int i;
5795 PSURFPRIVATEDATA pSData;
5796
5797
5798 #ifdef DEBUG
5799 dprintf(("SurfChangeUniquenessValue\n"));
5800 #endif
5801 me->dwUniqueValue++;
5802
5803 if(DPA_GetPtrCount(me->DPA_SurfacePrivateData)>0)
5804 {
5805 i=0;
5806 while(i<DPA_GetPtrCount(me->DPA_SurfacePrivateData))
5807 {
5808 pSData = (PSURFPRIVATEDATA) DPA_FastGetPtr(me->DPA_SurfacePrivateData,i);
5809 if (pSData->dwFlags & DDSPD_VOLATILE)
5810 {
5811 // Data becomes unvalid after a Surface change
5812 if (pSData->dwFlags & DDSPD_IUNKNOWNPOINTER)
5813 {
5814 // pointer to com stored so call its release
5815 ((OS2IDirectDrawSurface *) pSData->pData)->lpVtbl->Release(pSData->pData);
5816 }
5817 else
5818 {
5819 // Free allocated data
5820 free( pSData->pData);
5821 }
5822 pSData->pData = NULL;
5823 pSData->isValid = FALSE; // set flag to invalid
5824 }
5825 i++;
5826 }
5827 }
5828
5829 return (DD_OK);
5830}
5831
5832//******************************************************************************
5833//
5834// Purpose function copies one part of the bitmap inside the same bitmap
5835//
5836//******************************************************************************
5837
5838void __cdecl MoveRects(char* pBuffer, LPRECT lpDestRect, LPRECT lpSrcRect, int bpp, LONG lPitch)
5839{
5840
5841 char *pBltPos, *pSrcPos;
5842 int BlitWidth,BlitHeight;
5843 static char Scanline[6400]; // sufficient for 1600 at 32 bit
5844
5845 // Bridge, we may got a problem ;)
5846 // Check for Overlapping Rects
5847
5848 pBltPos = pBuffer;
5849 pSrcPos = pBuffer;
5850
5851 if(lpDestRect->top <= lpSrcRect->top)
5852 {
5853 // +-------+ +-------+ +-------+
5854 // |S | |S | |S | +---+---+---+
5855 // | +---|---+ +-------+ +---|---+ | |S/D|D/S| |
5856 // | | D | | | D | | D | | | | | | |
5857 // +-------+ | +-------+ | +-------+ | | | |
5858 // | | | | | | +---+---+---+
5859 // +-------+ +-------+ +-------+
5860 //
5861 // We got one of the above cases (or no overlapping) so copy from bottom up
5862
5863 pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
5864 pSrcPos += (lpSrcRect->left * bpp) + lPitch * (lpSrcRect->bottom-1);
5865 BlitHeight = lpDestRect->bottom - lpDestRect->top;
5866 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
5867
5868 while(1)
5869 {
5870 memcpy(Scanline,pSrcPos,BlitWidth);
5871 memcpy(pBltPos,Scanline,BlitWidth);
5872 pBltPos += lPitch;
5873 pSrcPos -= lPitch;
5874 if(! (--BlitHeight))
5875 break;
5876 }
5877 }
5878 else
5879 {
5880 // +-------+ +-------+ +-------+
5881 // | D | | D | | D |
5882 // | +---|---+ +-------+ +---|---+ |
5883 // | |S | | |S | |S | | |
5884 // +-------+ | +-------+ | +-------+
5885 // | | | | | |
5886 // +-------+ +-------+ +-------+
5887 //
5888 // We got one of the above cases so copy top down
5889
5890 pBltPos += (lpDestRect->left * bpp) + lPitch * lpDestRect->top;
5891 pSrcPos += (lpSrcRect->left * bpp) + lPitch * lpSrcRect->top;
5892 BlitHeight = lpDestRect->bottom - lpDestRect->top;
5893 BlitWidth = (lpDestRect->right - lpDestRect->left) * bpp;
5894
5895 while(1)
5896 {
5897 memcpy(Scanline,pSrcPos,BlitWidth);
5898 memcpy(pBltPos,Scanline,BlitWidth);
5899 pBltPos += lPitch;
5900 pSrcPos += lPitch;
5901 if(! (--BlitHeight))
5902 break;
5903 }
5904 }
5905
5906}
5907
5908//******************************************************************************
5909//
5910// Purpose : Do a blit using the precalced Transbuffer
5911// That is the only way to do fast blits if a colorrange is used
5912// and we can find totally transparent lines and don't blit them
5913// and detect if the part of the line is transparent
5914//
5915// Idea for a kind of mask buffer
5916// Format of Transparentbuffer (each line):
5917// the first DWORD contains 2 WORDS with Offset of First Non transparent
5918// pixel in the low word and the last non transparent pixel in a row in
5919// the high word. => 0 = line totally transparent!
5920// This limits the max supported width to 2^16 but I thing this is enougth
5921// The size per line is 1+((Width+31) & ~31) DWORDS => each Bit represents
5922// 1 pixel
5923//
5924// TransparentBufferCreate(lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
5925//
5926// Layout of a DWORD:
5927// UUVVWWXX dword is processed LS Byte FIRST ...
5928// Each bit in a byte stands for one pixel. MS Bit First
5929//
5930// example: Bitmap (16x5) (X= opaque, . = Transparent)
5931// ...XX...XX....XX
5932// ..XXXX....XXXX..
5933// ................
5934// .........XXXXXX.
5935// ...XX...X......X
5936//
5937// Transparent buffer (2DWORDS) per line
5938//
5939// 0x00100003, 0x0000C318
5940// 0x000E0002, 0x00003C3C
5941// 0x00000000, 0x00000000
5942// 0x000F000A, 0x00007E00
5943// 0x00100003, 0x00008118
5944//******************************************************************************
5945
5946void __cdecl TransSRCBlit8(LPDDSURFACEDESC2 pDestDesc, LPDDSURFACEDESC2 pSrcDesc, char *pAlpha, LPRECT lpSrcRect)
5947{
5948 DWORD *pdwTLine; // pointer to the transparent buffer
5949 DWORD dwTLineLen; // # of DWORDS in each tBuffer line
5950 DWORD dwTLineStart; // # DWORD in which the first transinfo is
5951 DWORD dwTDWStart; // byte in which the firs transinfo is
5952 DWORD dwTrans; // current transparentvalue
5953 DWORD BlitWidth;
5954 dwTLineLen = 1 + ((pSrcDesc->dwWidth + 31) & ~31);
5955 pdwTLine = (DWORD*)pAlpha + (dwTLineLen* lpSrcRect->top);
5956 dwTLineStart = 1+(lpSrcRect->left/32);
5957 dwTDWStart = (lpSrcRect->left+8)/8;
5958}
5959
5960
Note: See TracBrowser for help on using the repository browser.