Mercurial > vba-linux
view src/win32/DirectDraw.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 #include "stdafx.h"3 #define DIRECTDRAW_VERSION 0x07004 #include "ddraw.h"6 #include "resource.h"7 #include "MainWnd.h"8 #include "Reg.h"9 #include "VBA.h"11 #include "../common/System.h"12 #include "../gba/GBAGlobals.h"13 #include "../gb/gbGlobals.h"14 #include "../common/Text.h"15 #include "../version.h"17 extern u32 RGB_LOW_BITS_MASK;18 extern int systemSpeed;19 extern int Init_2xSaI(u32);20 extern void directXMessage(const char *);21 extern void winlog(const char *, ...);22 extern int winVideoModeSelect(CWnd *, GUID * *);24 class DirectDrawDisplay : public IDisplay25 {26 private:27 HINSTANCE ddrawDLL;28 LPDIRECTDRAW7 pDirectDraw;29 LPDIRECTDRAWSURFACE7 ddsPrimary;30 LPDIRECTDRAWSURFACE7 ddsOffscreen;31 LPDIRECTDRAWSURFACE7 ddsFlip;32 LPDIRECTDRAWCLIPPER ddsClipper;33 int width;34 int height;35 bool failed;37 bool initializeOffscreen(int w, int h);38 public:39 DirectDrawDisplay();40 virtual ~DirectDrawDisplay();42 virtual bool initialize();43 virtual void cleanup();44 virtual void render();45 virtual void checkFullScreen();46 virtual void renderMenu();47 virtual void clear();48 virtual bool changeRenderSize(int w, int h);49 virtual DISPLAY_TYPE getType() { return DIRECT_DRAW; };50 virtual void setOption(const char *, int) {}51 virtual int selectFullScreenMode(GUID * *);52 };54 static HRESULT WINAPI checkModesAvailable(LPDDSURFACEDESC2 surf, LPVOID lpContext)55 {56 if (surf->dwWidth == 320 &&57 surf->dwHeight == 240 &&58 surf->ddpfPixelFormat.dwRGBBitCount == 16)59 {60 theApp.mode320Available = TRUE;61 }62 if (surf->dwWidth == 640 &&63 surf->dwHeight == 480 &&64 surf->ddpfPixelFormat.dwRGBBitCount == 16)65 {66 theApp.mode640Available = TRUE;67 }68 if (surf->dwWidth == 800 &&69 surf->dwHeight == 600 &&70 surf->ddpfPixelFormat.dwRGBBitCount == 16)71 {72 theApp.mode800Available = TRUE;73 }74 return DDENUMRET_OK;75 }77 static int ffs(UINT mask)78 {79 int m = 0;80 if (mask)81 {82 while (!(mask & (1 << m)))83 m++;85 return (m);86 }88 return (0);89 }91 DirectDrawDisplay::DirectDrawDisplay()92 {93 pDirectDraw = NULL;94 ddsPrimary = NULL;95 ddsOffscreen = NULL;96 ddsFlip = NULL;97 ddsClipper = NULL;98 ddrawDLL = NULL;99 width = 0;100 height = 0;101 failed = false;102 }104 DirectDrawDisplay::~DirectDrawDisplay()105 {106 cleanup();107 }109 void DirectDrawDisplay::cleanup()110 {111 if (pDirectDraw != NULL)112 {113 if (ddsClipper != NULL)114 {115 ddsClipper->Release();116 ddsClipper = NULL;117 }119 if (ddsFlip != NULL)120 {121 ddsFlip->Release();122 ddsFlip = NULL;123 }125 if (ddsOffscreen != NULL)126 {127 ddsOffscreen->Release();128 ddsOffscreen = NULL;129 }131 if (ddsPrimary != NULL)132 {133 ddsPrimary->Release();134 ddsPrimary = NULL;135 }137 pDirectDraw->Release();138 pDirectDraw = NULL;139 }141 if (ddrawDLL != NULL)142 {143 /**/ ::FreeLibrary(ddrawDLL);144 ddrawDLL = NULL;145 }146 width = 0;147 height = 0;148 }150 bool DirectDrawDisplay::initialize()151 {152 CWnd *pWnd = theApp.m_pMainWnd;154 GUID *guid = NULL;155 if (theApp.ddrawEmulationOnly)156 guid = (GUID *)DDCREATE_EMULATIONONLY;158 if (theApp.pVideoDriverGUID)159 guid = theApp.pVideoDriverGUID;161 ddrawDLL = /**/ ::LoadLibrary("DDRAW.DLL");162 HRESULT (WINAPI *DDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown *);163 if (ddrawDLL != NULL)164 {165 DDrawCreateEx = (HRESULT (WINAPI *)(GUID *, LPVOID *, REFIID, IUnknown *))166 GetProcAddress(ddrawDLL, "DirectDrawCreateEx");168 if (DDrawCreateEx == NULL)169 {170 directXMessage("DirectDrawCreateEx");171 return FALSE;172 }173 }174 else175 {176 directXMessage("DDRAW.DLL");177 return FALSE;178 }180 theApp.ddrawUsingEmulationOnly = theApp.ddrawEmulationOnly;182 HRESULT hret = DDrawCreateEx(guid,183 (void * *)&pDirectDraw,184 IID_IDirectDraw7,185 NULL);187 if (hret != DD_OK)188 {189 winlog("Error creating DirectDraw object %08x\n", hret);190 if (theApp.ddrawEmulationOnly)191 {192 // disable emulation only setting in case of failure193 regSetDwordValue("ddrawEmulationOnly", 0);194 }195 // errorMessage(myLoadString(IDS_ERROR_DISP_DRAWCREATE), hret);196 return FALSE;197 }199 if (theApp.ddrawDebug)200 {201 DDCAPS driver;202 DDCAPS hel;203 ZeroMemory(&driver, sizeof(driver));204 ZeroMemory(&hel, sizeof(hel));205 driver.dwSize = sizeof(driver);206 hel.dwSize = sizeof(hel);207 pDirectDraw->GetCaps(&driver, &hel);208 int i;209 DWORD *p = (DWORD *)&driver;210 for (i = 0; i < (int)driver.dwSize; i += 4)211 winlog("Driver CAPS %2d: %08x\n", i>>2, *p++);212 p = (DWORD *)&hel;213 for (i = 0; i < (int)hel.dwSize; i += 4)214 winlog("HEL CAPS %2d: %08x\n", i>>2, *p++);215 }217 theApp.mode320Available = false;218 theApp.mode640Available = false;219 theApp.mode800Available = false;221 // check for available fullscreen modes222 pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, NULL, checkModesAvailable);224 DWORD flags = DDSCL_NORMAL;226 if (theApp.videoOption >= VIDEO_320x240)227 flags = DDSCL_ALLOWMODEX |228 DDSCL_ALLOWREBOOT |229 DDSCL_EXCLUSIVE |230 DDSCL_FULLSCREEN;232 hret = pDirectDraw->SetCooperativeLevel(pWnd->m_hWnd, flags);234 if (hret != DD_OK)235 {236 winlog("Error SetCooperativeLevel %08x\n", hret);237 // errorMessage(myLoadString(IDS_ERROR_DISP_DRAWLEVEL), hret);238 return FALSE;239 }241 if (theApp.videoOption > VIDEO_4X)242 {243 hret = pDirectDraw->SetDisplayMode(theApp.fsWidth,244 theApp.fsHeight,245 theApp.fsColorDepth,246 0,247 0);248 if (hret != DD_OK)249 {250 winlog("Error SetDisplayMode %08x\n", hret);251 // errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSET), hret);252 return FALSE;253 }254 }256 DDSURFACEDESC2 ddsd;257 ZeroMemory(&ddsd, sizeof(ddsd));258 ddsd.dwSize = sizeof(ddsd);259 ddsd.dwFlags = DDSD_CAPS;260 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;262 if (theApp.videoOption > VIDEO_4X && theApp.tripleBuffering)263 {264 // setup triple buffering265 ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;266 ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP;267 ddsd.dwBackBufferCount = 2;268 }270 hret = pDirectDraw->CreateSurface(&ddsd, &ddsPrimary, NULL);271 if (hret != DD_OK)272 {273 winlog("Error primary CreateSurface %08x\n", hret);274 // errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSURFACE), hret);275 return FALSE;276 }278 if (theApp.ddrawDebug)279 {280 DDSCAPS2 caps;281 ZeroMemory(&caps, sizeof(caps));282 ddsPrimary->GetCaps(&caps);284 winlog("Primary CAPS 1: %08x\n", caps.dwCaps);285 winlog("Primary CAPS 2: %08x\n", caps.dwCaps2);286 winlog("Primary CAPS 3: %08x\n", caps.dwCaps3);287 winlog("Primary CAPS 4: %08x\n", caps.dwCaps4);288 }290 if (theApp.videoOption > VIDEO_4X && theApp.tripleBuffering)291 {292 DDSCAPS2 caps;293 ZeroMemory(&caps, sizeof(caps));294 // this gets the third surface. The front one is the primary,295 // the second is the backbuffer and the third is the flip296 // surface297 caps.dwCaps = DDSCAPS_BACKBUFFER;299 hret = ddsPrimary->GetAttachedSurface(&caps, &ddsFlip);300 if (hret != DD_OK)301 {302 winlog("Failed to get attached surface %08x", hret);303 return FALSE;304 }305 ddsFlip->AddRef();306 clear();307 }309 // create clipper in all modes to avoid paint problems310 // if(videoOption <= VIDEO_4X) {311 hret = pDirectDraw->CreateClipper(0, &ddsClipper, NULL);312 if (hret == DD_OK)313 {314 ddsClipper->SetHWnd(0, pWnd->m_hWnd);315 if (theApp.videoOption > VIDEO_4X)316 {317 if (theApp.tripleBuffering)318 ddsFlip->SetClipper(ddsClipper);319 else320 ddsPrimary->SetClipper(ddsClipper);321 }322 else323 ddsPrimary->SetClipper(ddsClipper);324 }325 // }327 DDPIXELFORMAT px;329 px.dwSize = sizeof(px);331 hret = ddsPrimary->GetPixelFormat(&px);333 switch (px.dwRGBBitCount)334 {335 case 15:336 case 16:337 systemColorDepth = 16;338 break;339 case 24:340 systemColorDepth = 24;341 theApp.filterFunction = NULL;342 break;343 case 32:344 systemColorDepth = 32;345 break;346 default:347 systemMessage(348 IDS_ERROR_DISP_COLOR,349 "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode.",350 px.dwRGBBitCount);351 return FALSE;352 }353 theApp.updateFilter();354 theApp.updateIFB();356 if (failed)357 return false;359 pWnd->DragAcceptFiles(TRUE);361 return true;362 }364 bool DirectDrawDisplay::changeRenderSize(int w, int h)365 {366 if (w != width || h != height)367 {368 if (ddsOffscreen)369 {370 ddsOffscreen->Release();371 ddsOffscreen = NULL;372 }373 if (!initializeOffscreen(w, h))374 {375 failed = true;376 return false;377 }378 }379 return true;380 }382 bool DirectDrawDisplay::initializeOffscreen(int w, int h)383 {384 DDSURFACEDESC2 ddsd;386 ZeroMemory(&ddsd, sizeof(ddsd));387 ddsd.dwSize = sizeof(ddsd);388 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;389 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;390 if (theApp.ddrawUseVideoMemory)391 ddsd.ddsCaps.dwCaps |= (DDSCAPS_LOCALVIDMEM|DDSCAPS_VIDEOMEMORY);392 ddsd.dwWidth = w;393 ddsd.dwHeight = h;395 HRESULT hret = pDirectDraw->CreateSurface(&ddsd, &ddsOffscreen, NULL);397 if (hret != DD_OK)398 {399 winlog("Error offscreen CreateSurface %08x\n", hret);400 if (theApp.ddrawUseVideoMemory)401 {402 regSetDwordValue("ddrawUseVideoMemory", 0);403 }404 // errorMessage(myLoadString(IDS_ERROR_DISP_DRAWSURFACE2), hret);405 return false;406 }408 if (theApp.ddrawDebug)409 {410 DDSCAPS2 caps;411 ZeroMemory(&caps, sizeof(caps));412 ddsOffscreen->GetCaps(&caps);414 winlog("Offscreen CAPS 1: %08x\n", caps.dwCaps);415 winlog("Offscreen CAPS 2: %08x\n", caps.dwCaps2);416 winlog("Offscreen CAPS 3: %08x\n", caps.dwCaps3);417 winlog("Offscreen CAPS 4: %08x\n", caps.dwCaps4);418 }420 DDPIXELFORMAT px;422 px.dwSize = sizeof(px);424 hret = ddsOffscreen->GetPixelFormat(&px);426 if (theApp.ddrawDebug)427 {428 DWORD *pdword = (DWORD *)&px;429 for (int ii = 0; ii < 8; ii++)430 {431 winlog("Pixel format %d %08x\n", ii, pdword[ii]);432 }433 }435 switch (px.dwRGBBitCount)436 {437 case 15:438 case 16:439 systemColorDepth = 16;440 break;441 case 24:442 systemColorDepth = 24;443 theApp.filterFunction = NULL;444 break;445 case 32:446 systemColorDepth = 32;447 break;448 default:449 systemMessage(450 IDS_ERROR_DISP_COLOR,451 "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode.",452 px.dwRGBBitCount);453 return FALSE;454 }455 if (theApp.ddrawDebug)456 {457 winlog("R Mask: %08x\n", px.dwRBitMask);458 winlog("G Mask: %08x\n", px.dwGBitMask);459 winlog("B Mask: %08x\n", px.dwBBitMask);460 }462 systemRedShift = ffs(px.dwRBitMask);463 systemGreenShift = ffs(px.dwGBitMask);464 systemBlueShift = ffs(px.dwBBitMask);466 #ifdef MMX467 if (!theApp.disableMMX)468 cpu_mmx = theApp.detectMMX();469 else470 cpu_mmx = 0;471 #endif473 if ((px.dwFlags&DDPF_RGB) != 0 &&474 px.dwRBitMask == 0xF800 &&475 px.dwGBitMask == 0x07E0 &&476 px.dwBBitMask == 0x001F)477 {478 systemGreenShift++;479 Init_2xSaI(565);480 RGB_LOW_BITS_MASK = 0x821;481 }482 else if ((px.dwFlags&DDPF_RGB) != 0 &&483 px.dwRBitMask == 0x7C00 &&484 px.dwGBitMask == 0x03E0 &&485 px.dwBBitMask == 0x001F)486 {487 Init_2xSaI(555);488 RGB_LOW_BITS_MASK = 0x421;489 }490 else if ((px.dwFlags&DDPF_RGB) != 0 &&491 px.dwRBitMask == 0x001F &&492 px.dwGBitMask == 0x07E0 &&493 px.dwBBitMask == 0xF800)494 {495 systemGreenShift++;496 Init_2xSaI(565);497 RGB_LOW_BITS_MASK = 0x821;498 }499 else if ((px.dwFlags&DDPF_RGB) != 0 &&500 px.dwRBitMask == 0x001F &&501 px.dwGBitMask == 0x03E0 &&502 px.dwBBitMask == 0x7C00)503 {504 Init_2xSaI(555);505 RGB_LOW_BITS_MASK = 0x421;506 }507 else508 {509 // 32-bit or 24-bit510 if (systemColorDepth == 32 || systemColorDepth == 24)511 {512 systemRedShift += 3;513 systemGreenShift += 3;514 systemBlueShift += 3;515 if (systemColorDepth == 32)516 Init_2xSaI(32);517 }518 }520 if (theApp.ddrawDebug)521 {522 winlog("R shift: %d\n", systemRedShift);523 winlog("G shift: %d\n", systemGreenShift);524 winlog("B shift: %d\n", systemBlueShift);525 }527 switch (systemColorDepth)528 {529 case 16:530 {531 for (int i = 0; i < 0x10000; i++)532 {533 systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |534 (((i & 0x3e0) >> 5) << systemGreenShift) |535 (((i & 0x7c00) >> 10) << systemBlueShift);536 }537 break;538 }539 case 24:540 case 32:541 {542 for (int i = 0; i < 0x10000; i++)543 {544 systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |545 (((i & 0x3e0) >> 5) << systemGreenShift) |546 (((i & 0x7c00) >> 10) << systemBlueShift);547 }548 break;549 }550 }551 width = w;552 height = h;553 return true;554 }556 void DirectDrawDisplay::clear()557 {558 if (theApp.videoOption <= VIDEO_4X || !theApp.tripleBuffering || ddsFlip == NULL)559 return;561 DDBLTFX fx;562 ZeroMemory(&fx, sizeof(fx));563 fx.dwSize = sizeof(fx);564 fx.dwFillColor = 0;565 ddsFlip->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);566 ddsPrimary->Flip(NULL, 0);567 ddsFlip->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);568 ddsPrimary->Flip(NULL, 0);569 ddsFlip->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);570 ddsPrimary->Flip(NULL, 0);571 }573 void DirectDrawDisplay::renderMenu()574 {575 checkFullScreen();576 theApp.m_pMainWnd->DrawMenuBar();577 }579 void DirectDrawDisplay::checkFullScreen()580 {581 if (theApp.tripleBuffering)582 pDirectDraw->FlipToGDISurface();583 }585 void DirectDrawDisplay::render()586 {587 HRESULT hret;589 if (pDirectDraw == NULL ||590 ddsOffscreen == NULL ||591 ddsPrimary == NULL)592 return;594 bool fastForward = speedup;595 #if (defined(WIN32) && !defined(SDL))596 if (theApp.frameSearchSkipping)597 {598 if (theApp.frameSearchFirstStep)599 fastForward = true;600 else601 return; // don't render skipped frame search frames602 }603 #endif605 DDSURFACEDESC2 ddsDesc;607 ZeroMemory(&ddsDesc, sizeof(ddsDesc));609 ddsDesc.dwSize = sizeof(ddsDesc);611 hret = ddsOffscreen->Lock(NULL,612 &ddsDesc,613 #ifndef FINAL_VERSION614 DDLOCK_NOSYSLOCK |615 #endif616 DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,617 NULL);619 if (hret == DDERR_SURFACELOST)620 {621 hret = ddsPrimary->Restore();622 if (hret == DD_OK)623 {624 hret = ddsOffscreen->Restore();626 if (hret == DD_OK)627 {628 hret = ddsOffscreen->Lock(NULL,629 &ddsDesc,630 #ifndef FINAL_VERSION631 DDLOCK_NOSYSLOCK |632 #endif633 DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,634 NULL);635 }636 }637 }639 if (hret == DD_OK)640 {641 if (theApp.filterFunction)642 {643 if (systemColorDepth == 16)644 (*theApp.filterFunction)(pix + theApp.filterWidth * 2 + 4,645 theApp.filterWidth * 2 + 4,646 (u8 *)theApp.delta,647 (u8 *)ddsDesc.lpSurface,648 ddsDesc.lPitch,649 theApp.filterWidth,650 theApp.filterHeight);651 else652 (*theApp.filterFunction)(pix + theApp.filterWidth * 4 + 4,653 theApp.filterWidth * 4 + 4,654 (u8 *)theApp.delta,655 (u8 *)ddsDesc.lpSurface,656 ddsDesc.lPitch,657 theApp.filterWidth,658 theApp.filterHeight);659 }660 else661 {662 int copyX = 240;663 int copyY = 160;665 if (systemCartridgeType == 1)666 {667 if (gbBorderOn)668 {669 copyX = 256;670 copyY = 224;671 }672 else673 {674 copyX = 160;675 copyY = 144;676 }677 }678 // MMX doesn't seem to be faster to copy the data679 __asm {680 mov eax, copyX;681 mov ebx, copyY;683 mov esi, pix;684 mov edi, ddsDesc.lpSurface;685 mov edx, ddsDesc.lPitch;686 cmp systemColorDepth, 16;687 jnz gbaOtherColor;688 sub edx, eax;689 sub edx, eax;690 lea esi, [esi+2*eax+4];691 shr eax, 1;692 gbaLoop16bit:693 mov ecx, eax;694 repz movsd;695 inc esi;696 inc esi;697 inc esi;698 inc esi;699 add edi, edx;700 dec ebx;701 jnz gbaLoop16bit;702 jmp gbaLoopEnd;703 gbaOtherColor:704 cmp systemColorDepth, 32;705 jnz gbaOtherColor2;707 sub edx, eax;708 sub edx, eax;709 sub edx, eax;710 sub edx, eax;711 lea esi, [esi+4*eax+4];712 gbaLoop32bit:713 mov ecx, eax;714 repz movsd;715 add esi, 4;716 add edi, edx;717 dec ebx;718 jnz gbaLoop32bit;719 jmp gbaLoopEnd;720 gbaOtherColor2:721 lea eax, [eax+2*eax];722 sub edx, eax;723 gbaLoop24bit:724 mov ecx, eax;725 shr ecx, 2;726 repz movsd;727 add edi, edx;728 dec ebx;729 jnz gbaLoop24bit;730 gbaLoopEnd:731 }732 }733 if (theApp.showSpeed && theApp.videoOption > VIDEO_4X)734 {735 char buffer[30];736 if (theApp.showSpeed == 1)737 sprintf(buffer, "%3d%%", systemSpeed);738 else739 sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed,740 systemFrameSkip,741 theApp.showRenderedFrames);742 if (theApp.showSpeedTransparent)743 drawTextTransp((u8 *)ddsDesc.lpSurface,744 ddsDesc.lPitch,745 theApp.rect.left+10,746 theApp.rect.bottom-10,747 buffer);748 else749 drawText((u8 *)ddsDesc.lpSurface,750 ddsDesc.lPitch,751 theApp.rect.left+10,752 theApp.rect.bottom-10,753 buffer);754 }756 if (textMethod == 1)757 {758 DrawTextMessages((u8 *)ddsDesc.lpSurface, ddsDesc.lPitch, theApp.rect.left, theApp.rect.bottom);759 }760 }761 else if (theApp.ddrawDebug)762 winlog("Error during lock: %08x\n", hret);764 hret = ddsOffscreen->Unlock(NULL);766 if (hret == DD_OK)767 {768 // the correct point where to wait769 if (theApp.vsync && !fastForward)770 {771 hret = pDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);772 }774 ddsOffscreen->PageLock(0);775 if (theApp.tripleBuffering && theApp.videoOption > VIDEO_4X)776 {777 hret = ddsFlip->Blt(&theApp.dest, ddsOffscreen, NULL, DDBLT_WAIT, NULL);778 if (hret == DD_OK)779 {780 if (theApp.menuToggle || !theApp.active)781 {782 pDirectDraw->FlipToGDISurface();783 ddsPrimary->SetClipper(ddsClipper);784 hret = ddsPrimary->Blt(&theApp.dest, ddsFlip, NULL, DDBLT_ASYNC, NULL);785 // if using emulation only, then we have to redraw the menu786 // everytime. It seems like a bug in DirectDraw to me as we not787 // overwritting the menu area at all.788 if (theApp.ddrawUsingEmulationOnly)789 theApp.m_pMainWnd->DrawMenuBar();790 }791 else792 hret = ddsPrimary->Flip(NULL, 0);793 }794 }795 else796 {797 hret = ddsPrimary->Blt(&theApp.dest, ddsOffscreen, NULL, DDBLT_ASYNC, NULL);799 if (hret == DDERR_SURFACELOST)800 {801 hret = ddsPrimary->Restore();803 if (hret == DD_OK)804 {805 hret = ddsPrimary->Blt(&theApp.dest, ddsOffscreen, NULL, DDBLT_ASYNC, NULL);806 }807 }808 }809 ddsOffscreen->PageUnlock(0);810 }811 else if (theApp.ddrawDebug)812 winlog("Error during unlock: %08x\n", hret);814 bool textMessageStarted = false;816 if (textMethod == 2)817 {818 HDC hdc;820 for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++)821 {822 if (theApp.screenMessage[slot])823 {824 if ((theApp.screenMessageDuration[slot] < 0 ||825 (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) &&826 (!theApp.disableStatusMessage || slot == 1 || slot == 2))827 {828 if (!textMessageStarted)829 {830 textMessageStarted = true;831 ddsPrimary->SetClipper(ddsClipper);832 ddsPrimary->GetDC(&hdc);833 SetBkMode(hdc, TRANSPARENT);834 SetTextColor(hdc, textColor != 7 ? RGB(0, 0, 0) : RGB(255, 255, 255));835 }837 if (outlinedText)838 {839 // draw black outline840 const static int xd [8] = {-1, 0, 1, 1, 1, 0, -1, -1};841 const static int yd [8] = {-1, -1, -1, 0, 1, 1, 1, 0};842 for (int i = 0; i < 8; i++)843 {844 TextOut(hdc,845 theApp.dest.left+10+xd[i],846 theApp.dest.bottom - 20*(slot+1)+yd[i],847 theApp.screenMessageBuffer[slot],848 strlen(theApp.screenMessageBuffer[slot]));849 }850 }851 }852 else853 {854 theApp.screenMessage[slot] = false;855 }856 }857 }859 if (textMessageStarted)860 {861 COLORREF color;862 switch (textColor)863 {864 case 0:865 color = RGB(255, 255, 255); break;866 case 1:867 color = RGB(255, 0, 0); break;868 case 2:869 color = RGB(255, 255, 0); break;870 case 3:871 color = RGB(0, 255, 0); break;872 case 4:873 color = RGB(0, 255, 255); break;874 case 5:875 color = RGB(0, 0, 255); break;876 case 6:877 color = RGB(255, 0, 255); break;878 case 7:879 color = RGB(0, 0, 0); break;880 }881 SetTextColor(hdc, color);883 // draw center text884 for (int slot = 0; slot < SCREEN_MESSAGE_SLOTS; slot++)885 {886 if (theApp.screenMessage[slot])887 {888 if ((theApp.screenMessageDuration[slot] < 0 ||889 (int)(GetTickCount() - theApp.screenMessageTime[slot]) < theApp.screenMessageDuration[slot]) &&890 (!theApp.disableStatusMessage || slot == 1 || slot == 2))891 {892 TextOut(hdc, theApp.dest.left+10, theApp.dest.bottom - 20*(slot+1), theApp.screenMessageBuffer[slot],893 strlen(theApp.screenMessageBuffer[slot]));894 }895 }896 }897 }899 if (textMessageStarted)900 {901 ddsPrimary->ReleaseDC(hdc);902 }903 }905 if (hret != DD_OK)906 {907 if (theApp.ddrawDebug)908 winlog("Error on update screen: %08x\n", hret);909 }910 }912 int DirectDrawDisplay::selectFullScreenMode(GUID **pGUID)913 {914 return winVideoModeSelect(theApp.m_pMainWnd, pGUID);915 }917 IDisplay *newDirectDrawDisplay()918 {919 return new DirectDrawDisplay();920 }