Isle
Loading...
Searching...
No Matches
mxdisplaysurface.cpp
Go to the documentation of this file.
1#include "mxdisplaysurface.h"
2
3#include "mxbitmap.h"
4#include "mxdebug.h"
5#include "mxmisc.h"
6#include "mxomni.h"
7#include "mxpalette.h"
8#include "mxutilities.h"
9#include "mxvideomanager.h"
10
11#include <assert.h>
12#include <windows.h>
13
15
16#define RGB555_CREATE(R, G, B) (((R) << 10) | (G) << 5 | (B) << 0)
17
18// GLOBAL: LEGO1 0x1010215c
20
21// FUNCTION: LEGO1 0x100ba500
23{
24 Init();
25}
26
27// FUNCTION: LEGO1 0x100ba5a0
29{
30 Destroy();
31}
32
33// FUNCTION: LEGO1 0x100ba610
34void MxDisplaySurface::Init()
35{
36 m_ddSurface1 = NULL;
37 m_ddSurface2 = NULL;
38 m_ddClipper = NULL;
39 m_16bitPal = NULL;
40 m_initialized = FALSE;
41 memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc));
42}
43
44// FUNCTION: LEGO1 0x100ba640
46{
47 MxS32 backBuffers;
48 DDSURFACEDESC desc;
49 HRESULT hr;
50
51 if (!m_videoParam.Flags().GetFlipSurfaces()) {
52 backBuffers = 1;
53 }
54 else {
55 backBuffers = m_videoParam.GetBackBuffers() + 1;
56 }
57
58 for (MxS32 i = 0; i < backBuffers; i++) {
59 memset(&desc, 0, sizeof(DDSURFACEDESC));
60
61 desc.dwSize = sizeof(DDSURFACEDESC);
62 hr = m_ddSurface2->Lock(NULL, &desc, DDLOCK_WAIT, NULL);
63 if (hr == DDERR_SURFACELOST) {
64 m_ddSurface2->Restore();
65 hr = m_ddSurface2->Lock(NULL, &desc, DDLOCK_WAIT, NULL);
66 }
67
68 if (hr != DD_OK) {
69 return;
70 }
71
72 MxU8* surface = (MxU8*) desc.lpSurface;
73 MxS32 height = m_videoParam.GetRect().GetHeight();
74
75 while (height--) {
76 memset(surface, 0, m_videoParam.GetRect().GetWidth() * desc.ddpfPixelFormat.dwRGBBitCount / 8);
77 surface += desc.lPitch;
78 }
79
80 m_ddSurface2->Unlock(desc.lpSurface);
81 if (m_videoParam.Flags().GetFlipSurfaces()) {
82 m_ddSurface1->Flip(NULL, DDFLIP_WAIT);
83 }
84 }
85}
86
87// FUNCTION: LEGO1 0x100ba750
88// FUNCTION: BETA10 0x1013f6df
89MxU8 MxDisplaySurface::CountTotalBitsSetTo1(MxU32 p_param)
90{
91 MxU8 count = 0;
92
93 for (; p_param; p_param >>= 1) {
94 count += ((MxU8) p_param & 1);
95 }
96
97 return count;
98}
99
100// FUNCTION: LEGO1 0x100ba770
101// FUNCTION: BETA10 0x1013f724
102MxU8 MxDisplaySurface::CountContiguousBitsSetTo1(MxU32 p_param)
103{
104 MxU8 count = 0;
105
106 for (; (p_param & 1) == 0; p_param >>= 1) {
107 count++;
108 }
109
110 return count;
111}
112
113// FUNCTION: LEGO1 0x100ba790
115 MxVideoParam& p_videoParam,
116 LPDIRECTDRAWSURFACE p_ddSurface1,
117 LPDIRECTDRAWSURFACE p_ddSurface2,
118 LPDIRECTDRAWCLIPPER p_ddClipper
119)
120{
121 MxResult result = SUCCESS;
122
123 m_videoParam = p_videoParam;
124 m_ddSurface1 = p_ddSurface1;
125 m_ddSurface2 = p_ddSurface2;
126 m_ddClipper = p_ddClipper;
127 m_initialized = FALSE;
128
129 memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc));
130 m_surfaceDesc.dwSize = sizeof(m_surfaceDesc);
131
132 if (m_ddSurface2->GetSurfaceDesc(&m_surfaceDesc)) {
133 result = FAILURE;
134 }
135
136 return result;
137}
138
139// FUNCTION: LEGO1 0x100ba7f0
141{
142 DDSURFACEDESC ddsd;
143 MxResult result = FAILURE;
144 LPDIRECTDRAW lpDirectDraw = MVideoManager()->GetDirectDraw();
146
147 m_initialized = TRUE;
148 m_videoParam = p_videoParam;
149
150 if (!m_videoParam.Flags().GetFullScreen()) {
151 m_videoParam.Flags().SetFlipSurfaces(FALSE);
152 }
153
154 if (!m_videoParam.Flags().GetFlipSurfaces()) {
155 m_videoParam.SetBackBuffers(1);
156 }
157 else {
158 MxU32 backBuffers = m_videoParam.GetBackBuffers();
159
160 if (backBuffers < 1) {
161 m_videoParam.SetBackBuffers(1);
162 }
163 else if (backBuffers > 2) {
164 m_videoParam.SetBackBuffers(2);
165 }
166
167 m_videoParam.Flags().SetBackBuffers(TRUE);
168 }
169
170 if (m_videoParam.Flags().GetFullScreen()) {
171 MxS32 width = m_videoParam.GetRect().GetWidth();
172 MxS32 height = m_videoParam.GetRect().GetHeight();
173
174 if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)) {
175 goto done;
176 }
177
178 memset(&ddsd, 0, sizeof(ddsd));
179 ddsd.dwSize = sizeof(ddsd);
180
181 if (lpDirectDraw->GetDisplayMode(&ddsd)) {
182 goto done;
183 }
184
185 MxS32 bitdepth = !m_videoParam.Flags().Get16Bit() ? 8 : 16;
186
187 if (ddsd.dwWidth != width || ddsd.dwHeight != height || ddsd.ddpfPixelFormat.dwRGBBitCount != bitdepth) {
188 if (lpDirectDraw->SetDisplayMode(width, height, bitdepth)) {
189 goto done;
190 }
191 }
192 }
193
194 if (m_videoParam.Flags().GetFlipSurfaces()) {
195 memset(&ddsd, 0, sizeof(ddsd));
196 ddsd.dwSize = sizeof(ddsd);
197 ddsd.dwBackBufferCount = m_videoParam.GetBackBuffers();
200
201 if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) {
202 goto done;
203 }
204
206
207 if (m_ddSurface1->GetAttachedSurface(&ddsd.ddsCaps, &m_ddSurface2)) {
208 goto done;
209 }
210 }
211 else {
212 memset(&ddsd, 0, sizeof(ddsd));
213 ddsd.dwSize = sizeof(ddsd);
214 ddsd.dwFlags = DDSD_CAPS;
216
217 if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface1, NULL)) {
218 goto done;
219 }
220
221 memset(&ddsd, 0, sizeof(ddsd));
222 ddsd.dwSize = sizeof(ddsd);
224 ddsd.dwWidth = m_videoParam.GetRect().GetWidth();
225 ddsd.dwHeight = m_videoParam.GetRect().GetHeight();
227
228 if (!m_videoParam.Flags().GetBackBuffers()) {
230 }
231
232 if (lpDirectDraw->CreateSurface(&ddsd, &m_ddSurface2, NULL)) {
233 goto done;
234 }
235 }
236
237 memset(&m_surfaceDesc, 0, sizeof(m_surfaceDesc));
238 m_surfaceDesc.dwSize = sizeof(m_surfaceDesc);
239
240 if (!m_ddSurface2->GetSurfaceDesc(&m_surfaceDesc)) {
241 if (!lpDirectDraw->CreateClipper(0, &m_ddClipper, NULL) && !m_ddClipper->SetHWnd(0, hWnd) &&
242 !m_ddSurface1->SetClipper(m_ddClipper)) {
243 result = SUCCESS;
244 }
245 }
246
247done:
248 return result;
249}
250
251// FUNCTION: LEGO1 0x100baa90
253{
254 if (m_initialized) {
255 if (m_ddSurface2) {
256 m_ddSurface2->Release();
257 }
258
259 if (m_ddSurface1) {
260 m_ddSurface1->Release();
261 }
262
263 if (m_ddClipper) {
264 m_ddClipper->Release();
265 }
266 }
267
268 if (m_16bitPal) {
269 delete[] m_16bitPal;
270 }
271
272 Init();
273}
274
275// FUNCTION: LEGO1 0x100baae0
276// FUNCTION: BETA10 0x1013fe15
278{
279 if (m_surfaceDesc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
280 m_ddSurface1->SetPalette(p_palette->CreateNativePalette());
281 m_ddSurface2->SetPalette(p_palette->CreateNativePalette());
282
283 if (!m_videoParam.Flags().GetFullScreen()) {
284 struct {
285 WORD m_palVersion;
286 WORD m_palNumEntries;
287 PALETTEENTRY m_palPalEntry[256];
288 } lpal = {0x300, 256};
289
290 p_palette->GetEntries((LPPALETTEENTRY) lpal.m_palPalEntry);
291
292 HPALETTE hpal = CreatePalette((LPLOGPALETTE) &lpal);
293 HDC hdc = ::GetDC(0);
294 SelectPalette(hdc, hpal, FALSE);
295 RealizePalette(hdc);
296 ::ReleaseDC(NULL, hdc);
297 DeleteObject(hpal);
298 }
299 }
300
301 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
302 case 8:
303 break;
304 case 16: {
305 if (!m_16bitPal) {
306 m_16bitPal = new MxU16[256];
307 }
308
309 PALETTEENTRY palette[256];
310 p_palette->GetEntries(palette);
311
312 MxU8 contiguousBitsRed = CountContiguousBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwRBitMask);
313 MxU8 totalBitsRed = CountTotalBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwRBitMask);
314 MxU8 contiguousBitsGreen = CountContiguousBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwGBitMask);
315 MxU8 totalBitsGreen = CountTotalBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwGBitMask);
316 MxU8 contiguousBitsBlue = CountContiguousBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwBBitMask);
317 MxU8 totalBitsBlue = CountTotalBitsSetTo1(m_surfaceDesc.ddpfPixelFormat.dwBBitMask);
318
319 for (MxS32 i = 0; i < 256; i++) {
320 m_16bitPal[i] = ((palette[i].peRed >> (8 - totalBitsRed)) << contiguousBitsRed) |
321 ((palette[i].peGreen >> (8 - totalBitsGreen)) << contiguousBitsGreen) |
322 ((palette[i].peBlue >> (8 - totalBitsBlue)) << contiguousBitsBlue);
323 }
324
325 break;
326 }
327 default:
328 break;
329 }
330}
331
332// FUNCTION: LEGO1 0x100bacc0
333// FUNCTION: BETA10 0x1014012b
335 MxBitmap* p_bitmap,
336 MxS32 p_left,
337 MxS32 p_top,
338 MxS32 p_right,
339 MxS32 p_bottom,
340 MxS32 p_width,
341 MxS32 p_height
342)
343{
345 p_bitmap->GetBmiWidth(),
346 p_bitmap->GetBmiHeightAbs(),
347 m_videoParam.GetRect().GetWidth(),
348 m_videoParam.GetRect().GetHeight(),
349 &p_left,
350 &p_top,
351 &p_right,
352 &p_bottom,
353 &p_width,
354 &p_height
355 )) {
356 return;
357 }
358 DDSURFACEDESC ddsd;
359 memset(&ddsd, 0, sizeof(ddsd));
360 ddsd.dwSize = sizeof(ddsd);
361
362 HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
363 if (hr == DDERR_SURFACELOST) {
364 m_ddSurface2->Restore();
365 hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
366 }
367
368 if (hr != DD_OK) {
369 return;
370 }
371
372 MxU8* data = p_bitmap->GetStart(p_left, p_top);
373
374 if (m_videoParam.Flags().GetF1bit3()) {
375 p_bottom *= 2;
376 p_right *= 2;
377
378 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
379 case 8: {
380 MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch);
381 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
382
383 MxLong length = -2 * p_width + ddsd.lPitch;
384 while (p_height--) {
385 MxU8* surfaceBefore = surface;
386
387 for (MxS32 i = 0; p_width > i; i++) {
388 *surface++ = *data;
389 *surface++ = *data++;
390 }
391
392 data += stride;
393 surface += length;
394
395 memcpy(surface, surfaceBefore, 2 * p_width);
396 surface += ddsd.lPitch;
397 }
398 break;
399 }
400 case 16: {
401 MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch);
402 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
403
404 MxS32 length = -4 * p_width + ddsd.lPitch;
405 MxS32 height = p_height;
406 MxS32 width = p_width;
407 MxS32 copyWidth = width * 4;
408 MxU16* p16bitPal = m_16bitPal;
409
410 MxS32 i;
411 if (!stride && !length) {
412 while (height--) {
413 MxU8* surfaceBefore = surface;
414
415 for (i = 0; i < width; i++) {
416 MxU16 element = p16bitPal[*data];
417 *(MxU16*) surface = element;
418 surface += 2;
419 *(MxU16*) surface = element;
420
421 data++;
422 surface += 2;
423 }
424
425 memcpy(surface, surfaceBefore, copyWidth);
426 surface += ddsd.lPitch;
427 }
428 }
429 else {
430 while (height--) {
431 MxU8* surfaceBefore = surface;
432
433 for (i = 0; i < width; i++) {
434 MxU16 element = p16bitPal[*data];
435 *(MxU16*) surface = element;
436 surface += 2;
437 *(MxU16*) surface = element;
438
439 data++;
440 surface += 2;
441 }
442
443 data += stride;
444 surface += length;
445
446 memcpy(surface, surfaceBefore, p_width * 4);
447 surface += ddsd.lPitch;
448 }
449 }
450 break;
451 }
452 default:
453 break;
454 }
455 }
456 else {
457 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
458 case 8: {
459 MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch);
460 MxLong stride = GetAdjustedStride(p_bitmap);
461
462 MxLong length = ddsd.lPitch;
463 while (p_height--) {
464 memcpy(surface, data, p_width);
465 data += stride;
466 surface += length;
467 }
468 break;
469 }
470 case 16: {
471 MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch);
472 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
473
474 MxLong length = -2 * p_width + ddsd.lPitch;
475 for (MxS32 i = 0; i < p_height; i++) {
476 for (MxS32 j = 0; j < p_width; j++) {
477 *(MxU16*) surface = m_16bitPal[*data++];
478 surface += 2;
479 }
480
481 data += stride;
482 surface += length;
483 }
484 break;
485 }
486 default:
487 break;
488 }
489 }
490
491 m_ddSurface2->Unlock(ddsd.lpSurface);
492}
493
494// FUNCTION: LEGO1 0x100bb1d0
495// FUNCTION: BETA10 0x1014088e
497 MxBitmap* p_bitmap,
498 MxS32 p_left,
499 MxS32 p_top,
500 MxS32 p_right,
501 MxS32 p_bottom,
502 MxS32 p_width,
503 MxS32 p_height,
504 MxBool p_RLE
505)
506{
508 p_bitmap->GetBmiWidth(),
509 p_bitmap->GetBmiHeightAbs(),
510 m_videoParam.GetRect().GetWidth(),
511 m_videoParam.GetRect().GetHeight(),
512 &p_left,
513 &p_top,
514 &p_right,
515 &p_bottom,
516 &p_width,
517 &p_height
518 )) {
519 return;
520 }
521 DDSURFACEDESC ddsd;
522 memset(&ddsd, 0, sizeof(ddsd));
523 ddsd.dwSize = sizeof(ddsd);
524
525 HRESULT hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
526 if (hr == DDERR_SURFACELOST) {
527 m_ddSurface2->Restore();
528 hr = m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
529 }
530
531 if (hr != DD_OK) {
532 return;
533 }
534
535 MxU8* data = p_bitmap->GetStart(p_left, p_top);
536
537 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
538 case 8: {
539 MxU8* surface = (MxU8*) ddsd.lpSurface + p_right + (p_bottom * ddsd.lPitch);
540 if (p_RLE) {
541 MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage;
542 DrawTransparentRLE(data, surface, size, p_width, p_height, ddsd.lPitch, 8);
543 }
544 else {
545 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
546
547 MxLong length = -p_width + ddsd.lPitch;
548 for (MxS32 i = 0; i < p_height; i++) {
549 for (MxS32 j = 0; j < p_width; j++) {
550 if (*data != 0) {
551 *surface = *data;
552 }
553
554 data++;
555 surface++;
556 }
557
558 data += stride;
559 surface += length;
560 }
561 }
562 break;
563 }
564 case 16: {
565 MxU8* surface = (MxU8*) ddsd.lpSurface + (2 * p_right) + (p_bottom * ddsd.lPitch);
566 if (p_RLE) {
567 MxS32 size = p_bitmap->GetBmiHeader()->biSizeImage;
568 DrawTransparentRLE(data, surface, size, p_width, p_height, ddsd.lPitch, 16);
569 }
570 else {
571 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
572
573 MxLong length = -2 * p_width + ddsd.lPitch;
574 for (MxS32 i = 0; i < p_height; i++) {
575 for (MxS32 j = 0; j < p_width; j++) {
576 if (*data != 0) {
577 *(MxU16*) surface = m_16bitPal[*data];
578 }
579
580 data++;
581 surface += 2;
582 }
583
584 data += stride;
585 surface += length;
586 }
587 }
588 break;
589 }
590 default:
591 break;
592 }
593
594 m_ddSurface2->Unlock(ddsd.lpSurface);
595}
596
597// FUNCTION: LEGO1 0x100bb500
598// FUNCTION: BETA10 0x10140cd6
600 MxU8*& p_bitmapData,
601 MxU8*& p_surfaceData,
602 MxU32 p_bitmapSize,
603 MxS32 p_width,
604 MxS32 p_height,
605 MxLong p_pitch,
606 MxU8 p_bpp
607)
608{
609 /* Assumes partial RLE for the bitmap: only the skipped pixels are compressed.
610 The drawn pixels are uncompressed. The procedure is:
611 1. Read 3 bytes from p_bitmapData. Skip this many pixels on the surface.
612 2. Read 3 bytes from p_bitmapData. Draw this many pixels on the surface.
613 3. Repeat until the end of p_bitmapData is reached. */
614
615 MxU8* end = p_bitmapData + p_bitmapSize;
616 MxU8* surfCopy = p_surfaceData; // unused?
617
618 // The total number of pixels drawn or skipped
619 MxU32 count = 0;
620
621 // Used in both 8 and 16 bit branches
622 MxU32 skipCount;
623 MxU32 drawCount;
624 MxU32 t;
625
626 if (p_bpp == 16) {
627 // DECOMP: why goto?
628 goto sixteen_bit;
629 }
630
631 while (p_bitmapData < end) {
632 skipCount = *p_bitmapData++;
633 t = *p_bitmapData++;
634 skipCount += t << 8;
635 t = *p_bitmapData++;
636 skipCount += t << 16;
637
638 MxS32 rowRemainder = p_width - count % p_width;
639 count += skipCount;
640
641 if (skipCount >= rowRemainder) {
642 p_surfaceData += rowRemainder; // skip the rest of this row
643 skipCount -= rowRemainder;
644 p_surfaceData += p_pitch - p_width; // seek to start of next row
645 p_surfaceData += p_pitch * (skipCount / p_width); // skip entire rows if any
646 }
647
648 // skip any pixels at the start of this row
649 p_surfaceData += skipCount % p_width;
650 if (p_bitmapData >= end) {
651 break;
652 }
653
654 drawCount = *p_bitmapData++;
655 t = *p_bitmapData++;
656 drawCount += t << 8;
657 t = *p_bitmapData++;
658 drawCount += t << 16;
659
660 rowRemainder = p_width - count % p_width;
661 count += drawCount;
662
663 if (drawCount >= rowRemainder) {
664 memcpy(p_surfaceData, p_bitmapData, rowRemainder);
665 p_surfaceData += rowRemainder;
666 p_bitmapData += rowRemainder;
667
668 drawCount -= rowRemainder;
669
670 // seek to start of bitmap on this screen row
671 p_surfaceData += p_pitch - p_width;
672 MxS32 rows = drawCount / p_width;
673
674 for (MxU32 i = 0; i < rows; i++) {
675 memcpy(p_surfaceData, p_bitmapData, p_width);
676 p_bitmapData += p_width;
677 p_surfaceData += p_pitch;
678 }
679 }
680
681 MxS32 tail = drawCount % p_width;
682 memcpy(p_surfaceData, p_bitmapData, tail);
683 p_surfaceData += tail;
684 p_bitmapData += tail;
685 }
686 return;
687
688sixteen_bit:
689 while (p_bitmapData < end) {
690 skipCount = *p_bitmapData++;
691 t = *p_bitmapData++;
692 skipCount += t << 8;
693 t = *p_bitmapData++;
694 skipCount += t << 16;
695
696 MxS32 rowRemainder = p_width - count % p_width;
697 count += skipCount;
698
699 if (skipCount >= rowRemainder) {
700 p_surfaceData += 2 * rowRemainder;
701 skipCount -= rowRemainder;
702 p_surfaceData += p_pitch - 2 * p_width;
703 p_surfaceData += p_pitch * (skipCount / p_width);
704 }
705
706 p_surfaceData += 2 * (skipCount % p_width);
707 if (p_bitmapData >= end) {
708 break;
709 }
710
711 drawCount = *p_bitmapData++;
712 t = *p_bitmapData++;
713 drawCount += t << 8;
714 t = *p_bitmapData++;
715 drawCount += t << 16;
716
717 rowRemainder = p_width - count % p_width;
718 count += drawCount;
719
720 if (drawCount >= rowRemainder) {
721 // memcpy
722 for (MxU32 j = 0; j < rowRemainder; j++) {
723 *((MxU16*) p_surfaceData) = m_16bitPal[*p_bitmapData++];
724 p_surfaceData += 2;
725 }
726
727 drawCount -= rowRemainder;
728
729 p_surfaceData += p_pitch - 2 * p_width;
730 MxS32 rows = drawCount / p_width;
731
732 for (MxU32 i = 0; i < rows; i++) {
733 // memcpy
734 for (MxS32 j = 0; j < p_width; j++) {
735 *((MxU16*) p_surfaceData) = m_16bitPal[*p_bitmapData++];
736 p_surfaceData += 2;
737 }
738
739 p_surfaceData += p_pitch - 2 * p_width;
740 }
741 }
742
743 MxS32 tail = drawCount % p_width;
744 // memcpy
745 for (MxS32 j = 0; j < tail; j++) {
746 *((MxU16*) p_surfaceData) = m_16bitPal[*p_bitmapData++];
747 p_surfaceData += 2;
748 }
749 }
750}
751
752// FUNCTION: LEGO1 0x100bb850
753// FUNCTION: BETA10 0x10141191
754void MxDisplaySurface::VTable0x34(MxU8* p_pixels, MxS32 p_bpp, MxS32 p_width, MxS32 p_height, MxS32 p_x, MxS32 p_y)
755{
756 DDSURFACEDESC surfaceDesc;
757 memset(&surfaceDesc, 0, sizeof(surfaceDesc));
758 surfaceDesc.dwSize = sizeof(surfaceDesc);
759
760 HRESULT result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL);
761
762 if (result == DDERR_SURFACELOST) {
763 m_ddSurface2->Restore();
764 result = m_ddSurface2->Lock(NULL, &surfaceDesc, DDLOCK_WAIT, NULL);
765 }
766
767 if (result == DD_OK) {
768 MxU8* pixels = p_pixels;
769
770 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
771 case 8: {
772 if (p_bpp == 16) {
773 MxTrace("16 bit source to 8 bit display NOT_IMPLEMENTED");
774 assert(0);
775 return;
776 }
777
778 MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x;
779 MxLong stride = p_width;
780 MxLong length = surfaceDesc.lPitch;
781
782 while (p_height--) {
783 memcpy(dst, pixels, p_width);
784 pixels += stride;
785 dst += length;
786 }
787 break;
788 }
789 case 16: {
790 if (p_bpp == 16) {
791 MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + p_x;
792 MxLong stride = p_width * 2;
793 MxLong length = surfaceDesc.lPitch;
794
795 while (p_height--) {
796 memcpy(dst, pixels, 2 * p_width);
797 pixels += stride;
798 dst += length;
799 }
800 }
801 else if (p_bpp == 8) {
802 MxU8* dst = (MxU8*) surfaceDesc.lpSurface + p_y * surfaceDesc.lPitch + 2 * p_x;
803 MxLong stride = p_width * 2;
804 MxLong length = -2 * p_width + surfaceDesc.lPitch;
805
806 for (MxS32 i = 0; i < p_height; i++) {
807 for (MxS32 j = 0; j < p_width; j++) {
808 *(MxU16*) dst = m_16bitPal[*pixels++];
809 dst += 2;
810 }
811
812 pixels += stride;
813 dst += length;
814 }
815 }
816 }
817 }
818
819 m_ddSurface2->Unlock(surfaceDesc.lpSurface);
820 }
821}
822
823// FUNCTION: LEGO1 0x100bba50
824void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height)
825{
826 if (m_videoParam.Flags().GetF2bit1()) {
827 if (m_videoParam.Flags().GetFlipSurfaces()) {
828 if (g_unk0x1010215c < 2) {
830
831 DDSURFACEDESC ddsd;
832 memset(&ddsd, 0, sizeof(ddsd));
833 ddsd.dwSize = sizeof(ddsd);
834 if (m_ddSurface2->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK) {
835 MxU8* surface = (MxU8*) ddsd.lpSurface;
836 MxS32 height = m_videoParam.GetRect().GetHeight();
837
838 for (MxU32 i = 0; i < ddsd.dwHeight; i++) {
839 memset(surface, 0, ddsd.dwWidth * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
840 surface += ddsd.lPitch;
841 }
842
843 m_ddSurface2->Unlock(ddsd.lpSurface);
844 }
845 else {
846 OutputDebugString("MxDisplaySurface::Display error\n");
847 }
848 }
849 m_ddSurface1->Flip(NULL, DDFLIP_WAIT);
850 }
851 else {
852 MxPoint32 point(0, 0);
853 ClientToScreen(MxOmni::GetInstance()->GetWindowHandle(), (LPPOINT) &point);
854
855 p_left2 += m_videoParam.GetRect().GetLeft() + point.GetX();
856 p_top2 += m_videoParam.GetRect().GetTop() + point.GetY();
857
858 MxRect32 a(MxPoint32(p_left, p_top), MxSize32(p_width + 1, p_height + 1));
859 MxRect32 b(MxPoint32(p_left2, p_top2), MxSize32(p_width + 1, p_height + 1));
860
861 DDBLTFX data;
862 memset(&data, 0, sizeof(data));
863 data.dwSize = sizeof(data);
864 data.dwDDFX = 8;
865
866 if (m_ddSurface1->Blt((LPRECT) &b, m_ddSurface2, (LPRECT) &a, 0, &data) == DDERR_SURFACELOST) {
867 m_ddSurface1->Restore();
868 m_ddSurface1->Blt((LPRECT) &b, m_ddSurface2, (LPRECT) &a, 0, &data);
869 }
870 }
871 }
872}
873
874// FUNCTION: LEGO1 0x100bbc10
876{
877 if (m_ddSurface2 && !m_ddSurface2->GetDC(p_hdc)) {
878 return;
879 }
880
881 *p_hdc = NULL;
882}
883
884// FUNCTION: LEGO1 0x100bbc40
886{
887 if (m_ddSurface2 && p_hdc) {
888 m_ddSurface2->ReleaseDC(p_hdc);
889 }
890}
891
892// FUNCTION: LEGO1 0x100bbc60
893// FUNCTION: BETA10 0x10141745
895 MxBitmap* p_bitmap,
896 undefined4* p_ret,
897 undefined4 p_doNotWriteToSurface,
898 undefined4 p_transparent
899)
900{
901 LPDIRECTDRAWSURFACE surface = NULL;
904
905 DDSURFACEDESC ddsd;
906 memset(&ddsd, 0, sizeof(ddsd));
907 ddsd.dwSize = sizeof(ddsd);
908
909 if (draw->GetDisplayMode(&ddsd)) {
910 return NULL;
911 }
912
914 ddsd.dwWidth = p_bitmap->GetBmiWidth();
915 ddsd.dwHeight = p_bitmap->GetBmiHeightAbs();
917 *p_ret = 0;
919
920 if (draw->CreateSurface(&ddsd, &surface, NULL) != DD_OK) {
921 if (*p_ret) {
922 *p_ret = 0;
923
924 // Try creating bitmap surface in vram if system ram ran out
925 ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
927
928 if (draw->CreateSurface(&ddsd, &surface, NULL) != DD_OK) {
929 surface = NULL;
930 }
931 }
932 else {
933 surface = NULL;
934 }
935 }
936
937 if (surface) {
938 memset(&ddsd, 0, sizeof(ddsd));
939 ddsd.dwSize = sizeof(ddsd);
940
941 if (surface->Lock(NULL, &ddsd, DDLOCK_WAIT, 0) != DD_OK) {
942 surface->Release();
943 surface = NULL;
944 }
945 else if (p_doNotWriteToSurface) {
946 assert(0);
947 }
948 else {
949 MxU8* bitmapSrcPtr = p_bitmap->GetStart(0, 0);
950 MxU16* surfaceData = (MxU16*) ddsd.lpSurface;
951 MxLong widthNormal = p_bitmap->GetBmiWidth();
952 MxLong heightAbs = p_bitmap->GetBmiHeightAbs();
953
954 MxLong newPitch = ddsd.lPitch;
955 MxS32 rowSeek = p_bitmap->AlignToFourByte(p_bitmap->GetBmiWidth());
956 if (!p_bitmap->IsTopDown()) {
957 rowSeek *= -1;
958 }
959
960 switch (ddsd.ddpfPixelFormat.dwRGBBitCount) {
961 case 8: {
962 for (MxS32 y = 0; y < heightAbs; y++) {
963 memcpy(surfaceData, bitmapSrcPtr, widthNormal);
964 bitmapSrcPtr += rowSeek;
965 surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
966 }
967
968 surface->Unlock(ddsd.lpSurface);
969
970 if (p_transparent && surface) {
971 DDCOLORKEY key;
973 surface->SetColorKey(DDCKEY_SRCBLT, &key);
974 }
975 break;
976 }
977 case 16: {
978 if (m_16bitPal == NULL) {
979 goto error;
980 }
981
982 rowSeek -= widthNormal;
983 newPitch -= 2 * widthNormal;
984
985 if (p_transparent) {
986 for (MxS32 y = 0; y < heightAbs; y++) {
987 for (MxS32 x = 0; x < widthNormal; x++) {
988 if (*bitmapSrcPtr == 0) {
989 *surfaceData = RGB555_CREATE(0x1f, 0, 0x1f);
990 }
991 else {
992 *surfaceData = m_16bitPal[*bitmapSrcPtr];
993 }
994
995 bitmapSrcPtr++;
996 surfaceData++;
997 }
998
999 bitmapSrcPtr += rowSeek;
1000 surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
1001 }
1002
1003 DDCOLORKEY key;
1004 key.dwColorSpaceLowValue = key.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f);
1005 surface->SetColorKey(DDCKEY_SRCBLT, &key);
1006 }
1007 else {
1008 for (MxS32 y = 0; y < heightAbs; y++) {
1009 for (MxS32 x = 0; x < widthNormal; x++) {
1010 *surfaceData++ = m_16bitPal[*bitmapSrcPtr++];
1011 }
1012
1013 bitmapSrcPtr += rowSeek;
1014 surfaceData = (MxU16*) ((MxU8*) surfaceData + newPitch);
1015 }
1016 }
1017
1018 surface->Unlock(ddsd.lpSurface);
1019 break;
1020 }
1021 }
1022 }
1023 }
1024
1025 return surface;
1026
1027error:
1028 if (surface) {
1029 surface->Release();
1030 }
1031
1032 return NULL;
1033}
1034
1035// FUNCTION: LEGO1 0x100bbfb0
1037{
1038 LPDIRECTDRAWSURFACE newSurface = NULL;
1039 IDirectDraw* draw = MVideoManager()->GetDirectDraw();
1040
1041 DDSURFACEDESC ddsd;
1042 memset(&ddsd, 0, sizeof(ddsd));
1043 ddsd.dwSize = sizeof(ddsd);
1044
1045 p_src->GetSurfaceDesc(&ddsd);
1046
1047 if (draw->CreateSurface(&ddsd, &newSurface, NULL) != DD_OK) {
1048 return NULL;
1049 }
1050
1051 RECT rect = {0, 0, (LONG) ddsd.dwWidth, (LONG) ddsd.dwHeight};
1052
1053 if (newSurface->BltFast(0, 0, p_src, &rect, 16) != DD_OK) {
1054 newSurface->Release();
1055 return NULL;
1056 }
1057
1058 return newSurface;
1059}
1060
1061// FUNCTION: LEGO1 0x100bc070
1063{
1064 LPDIRECTDRAWSURFACE newSurface = NULL;
1065 IDirectDraw* draw = MVideoManager()->GetDirectDraw();
1066 MVideoManager();
1067
1068 DDSURFACEDESC ddsd;
1069 memset(&ddsd, 0, sizeof(ddsd));
1070 ddsd.dwSize = sizeof(ddsd);
1071
1072 if (draw->GetDisplayMode(&ddsd) != DD_OK) {
1073 return NULL;
1074 }
1075
1076 if (ddsd.ddpfPixelFormat.dwRGBBitCount != 16) {
1077 return NULL;
1078 }
1079
1080 ddsd.dwWidth = 16;
1081 ddsd.dwHeight = 16;
1084
1085 if (draw->CreateSurface(&ddsd, &newSurface, NULL) != DD_OK) {
1086 ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
1088
1089 if (draw->CreateSurface(&ddsd, &newSurface, NULL) != DD_OK) {
1090 goto done;
1091 }
1092 }
1093
1094 memset(&ddsd, 0, sizeof(ddsd));
1095 ddsd.dwSize = sizeof(ddsd);
1096
1097 if (newSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK) {
1098 goto done;
1099 }
1100 else {
1101 MxU16* surface = (MxU16*) ddsd.lpSurface;
1102 MxLong pitch = ddsd.lPitch;
1103
1104 // draw a simple cursor to the surface
1105 for (MxS32 x = 0; x < 16; x++) {
1106 MxU16* surface2 = surface;
1107 for (MxS32 y = 0; y < 16; y++) {
1108 if ((y > 10 || x) && (x > 10 || y) && x + y != 10) {
1109 if (x + y > 10) {
1110 *surface2 = RGB555_CREATE(0x1f, 0, 0x1f);
1111 }
1112 else {
1113 *surface2 = -1;
1114 }
1115 }
1116 else {
1117 *surface2 = 0;
1118 }
1119 surface2++;
1120 }
1121 surface = (MxU16*) ((MxU8*) surface + pitch);
1122 }
1123
1124 newSurface->Unlock(ddsd.lpSurface);
1125 DDCOLORKEY colorkey;
1126 colorkey.dwColorSpaceHighValue = RGB555_CREATE(0x1f, 0, 0x1f);
1127 colorkey.dwColorSpaceLowValue = RGB555_CREATE(0x1f, 0, 0x1f);
1128 newSurface->SetColorKey(DDCKEY_SRCBLT, &colorkey);
1129
1130 return newSurface;
1131 }
1132
1133done:
1134 if (newSurface) {
1135 newSurface->Release();
1136 }
1137
1138 return NULL;
1139}
1140
1141// FUNCTION: LEGO1 0x100bc200
1143 LPDDSURFACEDESC p_desc,
1144 MxBitmap* p_bitmap,
1145 MxS32 p_left,
1146 MxS32 p_top,
1147 MxS32 p_right,
1148 MxS32 p_bottom,
1149 MxS32 p_width,
1150 MxS32 p_height
1151)
1152{
1153 // DECOMP: Almost an exact copy of VTable0x28, except that it uses the argument DDSURFACEDESC
1154 // instead of getting one from GetDisplayMode.
1156 p_bitmap->GetBmiWidth(),
1157 p_bitmap->GetBmiHeightAbs(),
1158 m_videoParam.GetRect().GetWidth(),
1159 m_videoParam.GetRect().GetHeight(),
1160 &p_left,
1161 &p_top,
1162 &p_right,
1163 &p_bottom,
1164 &p_width,
1165 &p_height
1166 )) {
1167 return;
1168 }
1169
1170 MxU8* data = p_bitmap->GetStart(p_left, p_top);
1171
1172 if (m_videoParam.Flags().GetF1bit3()) {
1173 p_bottom *= 2;
1174 p_right *= 2;
1175
1176 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
1177 case 8: {
1178 MxU8* surface = (MxU8*) p_desc->lpSurface + p_right + (p_bottom * p_desc->lPitch);
1179 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
1180
1181 MxLong length = -2 * p_width + p_desc->lPitch;
1182 while (p_height--) {
1183 MxU8* surfaceBefore = surface;
1184
1185 for (MxS32 i = 0; p_width > i; i++) {
1186 *surface++ = *data;
1187 *surface++ = *data++;
1188 }
1189
1190 data += stride;
1191 surface += length;
1192
1193 memcpy(surface, surfaceBefore, 2 * p_width);
1194 surface += p_desc->lPitch;
1195 }
1196 break;
1197 }
1198 case 16: {
1199 MxU8* surface = (MxU8*) p_desc->lpSurface + (2 * p_right) + (p_bottom * p_desc->lPitch);
1200 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
1201
1202 MxS32 length = -4 * p_width + p_desc->lPitch;
1203 MxS32 height = p_height;
1204 MxS32 width = p_width;
1205 MxS32 copyWidth = width * 4;
1206 MxU16* p16bitPal = m_16bitPal;
1207
1208 MxS32 i;
1209 if (!stride && !length) {
1210 while (height--) {
1211 MxU8* surfaceBefore = surface;
1212
1213 for (i = 0; i < width; i++) {
1214 MxU16 element = p16bitPal[*data];
1215 *(MxU16*) surface = element;
1216 surface += 2;
1217 *(MxU16*) surface = element;
1218
1219 data++;
1220 surface += 2;
1221 }
1222
1223 memcpy(surface, surfaceBefore, copyWidth);
1224 surface += p_desc->lPitch;
1225 }
1226 }
1227 else {
1228 while (height--) {
1229 MxU8* surfaceBefore = surface;
1230
1231 for (i = 0; i < width; i++) {
1232 MxU16 element = p16bitPal[*data];
1233 *(MxU16*) surface = element;
1234 surface += 2;
1235 *(MxU16*) surface = element;
1236
1237 data++;
1238 surface += 2;
1239 }
1240
1241 data += stride;
1242 surface += length;
1243
1244 memcpy(surface, surfaceBefore, p_width * 4);
1245 surface += p_desc->lPitch;
1246 }
1247 }
1248 break;
1249 }
1250 default:
1251 break;
1252 }
1253 }
1254 else {
1255 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
1256 case 8: {
1257 MxU8* surface = (MxU8*) p_desc->lpSurface + p_right + (p_bottom * p_desc->lPitch);
1258 MxLong stride = GetAdjustedStride(p_bitmap);
1259
1260 MxLong length = p_desc->lPitch;
1261 while (p_height--) {
1262 memcpy(surface, data, p_width);
1263 data += stride;
1264 surface += length;
1265 }
1266 break;
1267 }
1268 case 16: {
1269 MxU8* surface = (MxU8*) p_desc->lpSurface + (2 * p_right) + (p_bottom * p_desc->lPitch);
1270 MxLong stride = -p_width + GetAdjustedStride(p_bitmap);
1271
1272 MxLong length = -2 * p_width + p_desc->lPitch;
1273 for (MxS32 i = 0; i < p_height; i++) {
1274 for (MxS32 j = 0; j < p_width; j++) {
1275 *(MxU16*) surface = m_16bitPal[*data++];
1276 surface += 2;
1277 }
1278
1279 data += stride;
1280 surface += length;
1281 }
1282 break;
1283 }
1284 default:
1285 break;
1286 }
1287 }
1288}
1289
1290// FUNCTION: LEGO1 0x100bc630
1292 LPDDSURFACEDESC p_desc,
1293 MxBitmap* p_bitmap,
1294 MxS32 p_left,
1295 MxS32 p_top,
1296 MxS32 p_right,
1297 MxS32 p_bottom,
1298 MxS32 p_width,
1299 MxS32 p_height,
1300 MxBool p_RLE
1301)
1302{
1303 // DECOMP: Almost an exact copy of VTable0x28, except that it uses the argument DDSURFACEDESC
1304 // instead of getting one from GetDisplayMode.
1306 p_bitmap->GetBmiWidth(),
1307 p_bitmap->GetBmiHeightAbs(),
1308 m_videoParam.GetRect().GetWidth(),
1309 m_videoParam.GetRect().GetHeight(),
1310 &p_left,
1311 &p_top,
1312 &p_right,
1313 &p_bottom,
1314 &p_width,
1315 &p_height
1316 )) {
1317 return;
1318 }
1319
1320 MxU8* src = p_bitmap->GetStart(p_left, p_top);
1321
1322 switch (m_surfaceDesc.ddpfPixelFormat.dwRGBBitCount) {
1323 case 8: {
1324 MxLong destStride = p_desc->lPitch;
1325 MxU8* dest = (MxU8*) p_desc->lpSurface + p_right + (p_bottom * p_desc->lPitch);
1326
1327 if (p_RLE) {
1328 DrawTransparentRLE(src, dest, p_bitmap->GetBmiHeader()->biSizeImage, p_width, p_height, p_desc->lPitch, 8);
1329 }
1330 else {
1331 MxLong srcSkip = GetAdjustedStride(p_bitmap) - p_width;
1332 MxLong destSkip = destStride - p_width;
1333
1334 for (MxS32 i = 0; i < p_height; i++, src += srcSkip, dest += destSkip) {
1335 for (MxS32 j = 0; j < p_width; j++, src++, dest++) {
1336 if (*src) {
1337 *dest = *src;
1338 }
1339 }
1340 }
1341 }
1342 break;
1343 }
1344 case 16: {
1345 MxLong destStride = p_desc->lPitch;
1346 MxU8* dest = (MxU8*) p_desc->lpSurface + (2 * p_right) + (p_bottom * p_desc->lPitch);
1347
1348 if (p_RLE) {
1349 DrawTransparentRLE(src, dest, p_bitmap->GetBmiHeader()->biSizeImage, p_width, p_height, p_desc->lPitch, 16);
1350 }
1351 else {
1352 MxLong srcStride = GetAdjustedStride(p_bitmap);
1353 MxLong srcSkip = srcStride - p_width;
1354 MxLong destSkip = destStride - 2 * p_width;
1355
1356 for (MxS32 i = 0; i < p_height; i++, src += srcSkip, dest += destSkip) {
1357 for (MxS32 j = 0; j < p_width; j++, src++, dest += 2) {
1358 if (*src != 0) {
1359 *(MxU16*) dest = m_16bitPal[*src];
1360 }
1361 }
1362 }
1363 }
1364 break;
1365 }
1366 default:
1367 break;
1368 }
1369}
1370
1371// FUNCTION: LEGO1 0x100bc8b0
1373{
1374 LPDIRECTDRAWSURFACE surface = NULL;
1375
1378
1379 DDSURFACEDESC surfaceDesc;
1380 memset(&surfaceDesc, 0, sizeof(surfaceDesc));
1381 surfaceDesc.dwSize = sizeof(surfaceDesc);
1382
1383 if (ddraw->GetDisplayMode(&surfaceDesc) != DD_OK) {
1384 return NULL;
1385 }
1386
1387 if (surfaceDesc.ddpfPixelFormat.dwRGBBitCount != 16) {
1388 return NULL;
1389 }
1390
1391 surfaceDesc.dwWidth = width;
1392 surfaceDesc.dwHeight = height;
1395
1396 if (ddraw->CreateSurface(&surfaceDesc, &surface, NULL) != DD_OK) {
1397 surfaceDesc.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY;
1398 surfaceDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
1399 if (ddraw->CreateSurface(&surfaceDesc, &surface, NULL) != DD_OK) {
1400 return NULL;
1401 }
1402 }
1403
1404 return surface;
1405}
[AI] Represents an 8bpp or high color device-independent bitmap (DIB) and provides operations for bit...
Definition: mxbitmap.h:55
MxBool IsTopDown() const
[AI] Checks if the bitmap is stored in top-down scanline order.
Definition: mxbitmap.h:267
MxLong AlignToFourByte(MxLong p_value) const
[AI] Aligns a value up to the nearest multiple of four (stride alignment for DIBs).
Definition: mxbitmap.h:204
MxLong GetBmiHeightAbs() const
[AI] Returns the absolute value of the bitmap's height.
Definition: mxbitmap.h:242
MxU8 * GetStart(MxS32 p_left, MxS32 p_top) const
[AI] Returns a pointer to the starting address of the pixel data at the specified coordinates.
Definition: mxbitmap.h:288
BITMAPINFOHEADER * GetBmiHeader() const
[AI] Returns a pointer to the underlying BITMAPINFOHEADER.
Definition: mxbitmap.h:218
MxLong GetBmiWidth() const
[AI] Fetches the width (in pixels) encoded in this bitmap's header.
Definition: mxbitmap.h:224
Provides a DirectDraw-based drawing surface for blitting bitmaps, managing palette,...
LPDIRECTDRAWSURFACE FUN_100bc8b0(MxS32 width, MxS32 height)
[AI] Creates a 16-bit DirectDraw surface of specified size, either in video or system memory.
static LPDIRECTDRAWSURFACE CopySurface(LPDIRECTDRAWSURFACE p_src)
[AI] Creates a deep copy of the provided surface (new DirectDraw surface with same content).
~MxDisplaySurface() override
[AI] Destroys the display surface and releases DirectDraw objects and resources.
virtual MxResult Create(MxVideoParam &p_videoParam)
[AI] Creates DirectDraw surfaces and initializes based on the desired video mode.
virtual void SetPalette(MxPalette *p_palette)
[AI] Sets the palette used for the primary and secondary DirectDraw surfaces.
void ClearScreen()
[AI] Fills the current back buffer with black (clears the display area). [AI]
virtual void GetDC(HDC *p_hdc)
[AI] Acquires a Win32 device context (DC) for the back buffer surface, for GDI drawing.
virtual void VTable0x34(MxU8 *p_pixels, MxS32 p_bpp, MxS32 p_width, MxS32 p_height, MxS32 p_x, MxS32 p_y)
[AI] Directly writes an array of pixel data into the back surface at the given rectangle.
MxDisplaySurface()
[AI] Constructs the display surface and initializes all members.
virtual void Destroy()
[AI] Releases all DirectDraw surfaces and resources held by this object.
virtual void VTable0x24(LPDDSURFACEDESC p_desc, MxBitmap *p_bitmap, MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom, MxS32 p_width, MxS32 p_height)
[AI] Draws a bitmap onto a surface described by p_desc, scaling to the specified rectangle.
virtual MxResult Init(MxVideoParam &p_videoParam, LPDIRECTDRAWSURFACE p_ddSurface1, LPDIRECTDRAWSURFACE p_ddSurface2, LPDIRECTDRAWCLIPPER p_ddClipper)
[AI] Initializes the surface object with given video parameters, DirectDraw surfaces,...
static LPDIRECTDRAWSURFACE CreateCursorSurface()
[AI] Creates and draws a 16x16 cursor DirectDraw surface.
virtual void VTable0x30(MxBitmap *p_bitmap, MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom, MxS32 p_width, MxS32 p_height, MxBool p_RLE)
[AI] Draws a bitmap with optional transparency (RLE), outputting to active back surface.
virtual void VTable0x28(MxBitmap *p_bitmap, MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom, MxS32 p_width, MxS32 p_height)
[AI] Draws a bitmap onto the back surface, specified by coordinates and output size.
virtual void VTable0x2c(LPDDSURFACEDESC p_desc, MxBitmap *p_bitmap, MxS32 p_left, MxS32 p_top, MxS32 p_right, MxS32 p_bottom, MxS32 p_width, MxS32 p_height, MxBool p_RLE)
[AI] Draws a bitmap with optional transparency (RLE) onto the output surface.
virtual void ReleaseDC(HDC p_hdc)
[AI] Releases a device context (DC) previously acquired for the back surface.
virtual void Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height)
[AI] Presents the back buffer contents to the front buffer or window.
void DrawTransparentRLE(MxU8 *&p_bitmapData, MxU8 *&p_surfaceData, MxU32 p_bitmapSize, MxS32 p_width, MxS32 p_height, MxLong p_pitch, MxU8 p_bpp)
[AI] Performs RLE-based transparent drawing from an RLE-compressed bitmap into the given surface.
virtual LPDIRECTDRAWSURFACE VTable0x44(MxBitmap *p_bitmap, undefined4 *p_ret, undefined4 p_doNotWriteToSurface, undefined4 p_transparent)
[AI] Allocates a DirectDraw surface for a bitmap to allow hardware blitting/transparency.
static MxOmni * GetInstance()
[AI] Returns the singleton instance of the MxOmni subsystem coordinator.
Definition: mxomni.cpp:289
HWND GetWindowHandle() const
[AI] Gets the window handle (HWND) associated with the engine (ownership not transferred).
Definition: mxomni.h:192
[AI] Encapsulates a DirectDraw 8-bit (256 color) palette for use with DirectX rendering.
Definition: mxpalette.h:17
LPDIRECTDRAWPALETTE CreateNativePalette()
[AI] Creates the internal DirectDraw palette object and populates it with the current palette entries...
Definition: mxpalette.cpp:114
MxResult GetEntries(LPPALETTEENTRY p_entries)
[AI] Copies all palette entries to external buffer.
Definition: mxpalette.cpp:170
[AI] 2D point with 32-bit signed integer coordinates.
Definition: mxgeometry.h:487
T GetY() const
[AI] Get Y coordinate.
Definition: mxgeometry.h:53
T GetX() const
[AI] Get X coordinate.
Definition: mxgeometry.h:48
[AI] Rectangle using 32-bit signed integer coordinates.
Definition: mxgeometry.h:706
T GetTop() const
[AI] Get the top edge.
Definition: mxgeometry.h:231
T GetWidth() const
[AI] Get the rectangle's width.
Definition: mxgeometry.h:262
T GetHeight() const
[AI] Get the rectangle's height.
Definition: mxgeometry.h:268
T GetLeft() const
[AI] Get the left edge.
Definition: mxgeometry.h:221
[AI] Size with 32-bit signed integer width and height.
Definition: mxgeometry.h:593
LPDIRECTDRAW GetDirectDraw()
[AI] Returns the current DirectDraw COM interface managed by this class (may be owned or external).
MxVideoParam & GetVideoParam()
[AI] Retrieves the current video parameter configuration used by this manager.
[AI] Manages video parameter flags, providing an abstraction for various video settings such as fulls...
MxBool GetFullScreen()
[AI] Get whether fullscreen mode is enabled.
MxBool Get16Bit()
[AI] Get whether 16-bit rendering mode is selected.
void SetBackBuffers(MxBool p_e)
[AI] Toggle the use of a back buffer (double-buffered rendering).
MxBool GetF2bit1()
[AI] Get the value of secondary flag 1.
MxBool GetFlipSurfaces()
[AI] Get whether page flipping of surfaces is enabled.
MxBool GetF1bit3()
[AI] Get the value of primary flag 3.
void SetFlipSurfaces(MxBool p_e)
[AI] Toggle the use of flip (page flipping) for surfaces.
MxBool GetBackBuffers()
[AI] Get whether back buffering (double buffering) is enabled.
[AI] Video parameter configuration for display and rendering, encapsulates resolution,...
Definition: mxvideoparam.h:14
void SetBackBuffers(MxU32 p_backBuffers)
[AI] Set the desired number of backbuffers (triple/double buffering).
Definition: mxvideoparam.h:68
MxU32 GetBackBuffers()
[AI] Get the number of backbuffers requested for this display mode.
Definition: mxvideoparam.h:64
MxVideoParamFlags & Flags()
[AI] Access the video parameter flags (windowed/fullscreen, rendering mode, etc).
Definition: mxvideoparam.h:45
MxRect32 & GetRect()
[AI] Get the rectangle specifying the display dimensions and screen area.
Definition: mxvideoparam.h:49
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DDSD_WIDTH
Definition: ddraw.h:1174
#define DDSD_PIXELFORMAT
Definition: ddraw.h:1205
struct _DDSURFACEDESC FAR * LPDDSURFACEDESC
Definition: ddraw.h:83
struct IDirectDrawClipper FAR * LPDIRECTDRAWCLIPPER
Definition: ddraw.h:79
struct IDirectDrawSurface FAR * LPDIRECTDRAWSURFACE
Definition: ddraw.h:74
#define DDSD_HEIGHT
Definition: ddraw.h:1169
#define DDSCAPS_PRIMARYSURFACE
Definition: ddraw.h:1405
#define DDERR_SURFACELOST
Definition: ddraw.h:3489
#define DDSCL_EXCLUSIVE
Definition: ddraw.h:2551
struct _DDSURFACEDESC DDSURFACEDESC
#define DDSCAPS_OFFSCREENPLAIN
Definition: ddraw.h:1385
HWND hWnd
Definition: ddraw.h:425
#define DD_OK
Definition: ddraw.h:3166
#define DDSCAPS_FLIP
Definition: ddraw.h:1366
#define DDPF_PALETTEINDEXED8
Definition: ddraw.h:2399
#define DDSCAPS_BACKBUFFER
Definition: ddraw.h:1346
long HRESULT
Definition: ddraw.h:115
#define DDSCAPS_3DDEVICE
Definition: ddraw.h:1432
#define DDFLIP_WAIT
Definition: ddraw.h:2745
#define DDCKEY_SRCBLT
Definition: ddraw.h:2237
struct IDirectDraw FAR * LPDIRECTDRAW
Definition: ddraw.h:72
#define DDSCAPS_VIDEOMEMORY
Definition: ddraw.h:1437
#define DDSD_CAPS
Definition: ddraw.h:1164
#define DDLOCK_WAIT
Definition: ddraw.h:2916
#define DDSCAPS_SYSTEMMEMORY
Definition: ddraw.h:1419
#define DDSD_BACKBUFFERCOUNT
Definition: ddraw.h:1184
#define DDSCAPS_COMPLEX
Definition: ddraw.h:1355
#define DDSCL_FULLSCREEN
Definition: ddraw.h:2530
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
unsigned int undefined4
Definition: decomp.h:28
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
#define GetAdjustedStride(p_bitmap)
Definition: mxbitmap.h:277
#define MxTrace(args)
[AI] Macro for trace logging (non-variadic version, MSVC compatibility), expands to nothing.
Definition: mxdebug.h:55
#define RGB555_CREATE(R, G, B)
MxU32 g_unk0x1010215c
void DeleteObject(MxDSAction &p_dsAction)
[AI] Deletes the specified action object, removing it from the global action list.
Definition: mxmisc.cpp:105
MxVideoManager * MVideoManager()
[AI] Returns the video manager used for video/cutscene presenter management.
Definition: mxmisc.cpp:65
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
int MxLong
[AI]
Definition: mxtypes.h:83
unsigned char MxU8
[AI]
Definition: mxtypes.h:8
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned short MxU16
[AI]
Definition: mxtypes.h:20
unsigned int MxU32
[AI]
Definition: mxtypes.h:32
MxBool GetRectIntersection(MxS32 p_rect1Width, MxS32 p_rect1Height, MxS32 p_rect2Width, MxS32 p_rect2Height, MxS32 *p_rect1Left, MxS32 *p_rect1Top, MxS32 *p_rect2Left, MxS32 *p_rect2Top, MxS32 *p_width, MxS32 *p_height)
Computes intersection of two rectangles and modifies their positions and dimensions to the intersecti...
Definition: mxutilities.cpp:19
DWORD dwSize
Definition: ddraw.h:141
DWORD dwDDFX
Definition: ddraw.h:142
DWORD dwColorSpaceHighValue
Definition: ddraw.h:129
DWORD dwColorSpaceLowValue
Definition: ddraw.h:127
DWORD dwBBitMask
Definition: ddraw.h:365
DWORD dwRGBBitCount
Definition: ddraw.h:348
DWORD dwRBitMask
Definition: ddraw.h:355
DWORD dwGBitMask
Definition: ddraw.h:360
DWORD dwFlags
Definition: ddraw.h:344
DWORD dwCaps
Definition: ddraw.h:196
DDSCAPS ddsCaps
Definition: ddraw.h:1158
LPVOID lpSurface
Definition: ddraw.h:1152
DDPIXELFORMAT ddpfPixelFormat
Definition: ddraw.h:1157
LONG lPitch
Definition: ddraw.h:1140
DWORD dwSize
Definition: ddraw.h:1134
DWORD dwFlags
Definition: ddraw.h:1135
DWORD dwWidth
Definition: ddraw.h:1137
DWORD dwBackBufferCount
Definition: ddraw.h:1143
DWORD dwHeight
Definition: ddraw.h:1136