diff --git a/Source/appfat.cpp b/Source/appfat.cpp index 1f52367a7..8bff1201b 100644 --- a/Source/appfat.cpp +++ b/Source/appfat.cpp @@ -142,6 +142,11 @@ void MsgBox(const char *pszFmt, va_list va) void FreeDlg() { + // Diablo calls this method before calling the dialog, which wouldn't work + // for DevilutionX. + puts("FreeDlg(): skipping"); + return; + if (terminating && cleanup_thread_id != GetCurrentThreadId()) Sleep(20000); diff --git a/Source/init.cpp b/Source/init.cpp index 7cc7be979..a3b365375 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -13,7 +13,7 @@ char diablo_exe_path[MAX_PATH]; HANDLE hellfire_mpq; char patch_rt_mpq_path[MAX_PATH]; WNDPROC CurrentProc; -HANDLE diabdat_mpq; +HANDLE diabdat_mpq = NULL; char diabdat_mpq_path[MAX_PATH]; HANDLE patch_rt_mpq; diff --git a/SourceS/sdl2_to_1_2_backports.h b/SourceS/sdl2_to_1_2_backports.h index 52aff1afe..d7a2ea10e 100644 --- a/SourceS/sdl2_to_1_2_backports.h +++ b/SourceS/sdl2_to_1_2_backports.h @@ -79,23 +79,6 @@ inline void SDL_DisableScreenSaver() DUMMY(); } -//= Messagebox (simply logged to stderr for now) - -typedef enum { - SDL_MESSAGEBOX_ERROR = 0x00000010, /**< error dialog */ - SDL_MESSAGEBOX_WARNING = 0x00000020, /**< warning dialog */ - SDL_MESSAGEBOX_INFORMATION = 0x00000040 /**< informational dialog */ -} SDL_MessageBoxFlags; - -inline int SDL_ShowSimpleMessageBox(Uint32 flags, - const char *title, - const char *message, - SDL_Surface *window) -{ - fprintf(stderr, "MSGBOX: %s\n%s\n", title, message); - return 0; -} - //= Window handling #define SDL_Window SDL_Surface diff --git a/SourceX/DiabloUI/art.cpp b/SourceX/DiabloUI/art.cpp index 8f078d17e..81bb23cad 100644 --- a/SourceX/DiabloUI/art.cpp +++ b/SourceX/DiabloUI/art.cpp @@ -7,6 +7,8 @@ void LoadArt(const char *pszFile, Art *art, int frames, PALETTEENTRY *pPalette) if (art == NULL || art->surface != NULL) return; + art->frames = frames; + DWORD width, height, bpp; if (!SBmpLoadImage(pszFile, 0, 0, 0, &width, &height, &bpp)) return; @@ -37,7 +39,6 @@ void LoadArt(const char *pszFile, Art *art, int frames, PALETTEENTRY *pPalette) } art->surface = art_surface; - art->frames = frames; art->frame_height = height / frames; } diff --git a/SourceX/DiabloUI/diabloui.cpp b/SourceX/DiabloUI/diabloui.cpp index d8fc5ccc6..6b135513c 100644 --- a/SourceX/DiabloUI/diabloui.cpp +++ b/SourceX/DiabloUI/diabloui.cpp @@ -66,7 +66,7 @@ const char *const errorTitle[] = { const char *const errorMessages[] = { "Diablo was unable to properly initialize SDL.\nPlease try the following solutions to correct the problem:\n\n Install the most recent SDL provided for your distribution.\n\nIf you continue to have problems with SDL, create an issue on GitHub:\n https://github.com/diasurgical/devilutionX/issues\n\n\nThe error encountered while trying to initialize was:\n\n %s", "Diablo has exhausted all the memory on your system.\nMake sure you have at least 512MB of free system memory\n\nThe error encountered was:\n\n %s", - "Diablo was unable to open a required file.\nPlease ensure that the diabdat.mpq is in the same folder as Devilution.\nIf this problem persists, try checking that the md5 of diabdat.mpq is either 011bc6518e6166206231080a4440b373 or 68f049866b44688a7af65ba766bef75a.\n\n\nThe problem occurred while trying to load a file.\n\n %s", + "Diablo was unable to open a required file.\nPlease ensure that the diabdat.mpq is in the same folder as Devilution.\nIf this problem persists, try checking that the md5 of diabdat.mpq is either 011bc6518e6166206231080a4440b373 or 68f049866b44688a7af65ba766bef75a.\n\nThe problem occurred while trying to load %s", "Diablo was unable to find the file \"ddraw.dll\", which is a component of Microsoft DirectX.\nPlease run the program \"SETUP.EXE\" on the Diablo CD-ROM and install Microsoft DirectX.\n\nIf you continue to have problems with DirectX, please contact Microsoft's Technical Support at:\n\n USA telephone: 1-800-426-9400\n International telephone: 206-882-8080\n http://www.microsoft.com\n\n\nThe error encountered while trying to initialize DirectX was:\n\n %s", "Diablo was unable to find the file \"dsound.dll\", which is a component of Microsoft DirectX.\nPlease run the program \"SETUP.EXE\" on the Diablo CD-ROM and install Microsoft DirectX.\n\nIf you continue to have problems with DirectX, please contact Microsoft's Technical Support at:\n\n USA telephone: 1-800-426-9400\n International telephone: 206-882-8080\n http://www.microsoft.com\n\n\nThe error encountered while trying to initialize DirectX was:\n\n %s", "Diablo requires at least 10 megabytes of free disk space to run properly.\nThe disk:\n\n%s\n\nhas less than 10 megabytes of free space left.\n\nPlease free some space on your drive and run Diablo again.", @@ -123,12 +123,7 @@ int DialogBoxParam(HINSTANCE hInstance, LPCSTR msgId, HWND hWndParent, DLGPROC l { char text[1024]; snprintf(text, 1024, errorMessages[(intptr_t)msgId], dwInitParam); - - if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, errorTitle[(intptr_t)msgId], text, window) <= -1) { - SDL_Log(SDL_GetError()); - return -1; - } - + UiErrorOkDialog(errorTitle[(intptr_t)msgId], text, nullptr, 0); return 0; } @@ -585,16 +580,6 @@ int GetCenterOffset(int w, int bw) return (bw - w) / 2; } -void LoadPalInMem(PALETTEENTRY *pPal) -{ - for (int i = 0; i < 256; i++) { - orig_palette[i].peFlags = 0; - orig_palette[i].peRed = pPal[i].peRed; - orig_palette[i].peGreen = pPal[i].peGreen; - orig_palette[i].peBlue = pPal[i].peBlue; - } -} - void LoadBackgroundArt(char *pszFile) { PALETTEENTRY pPal[256]; @@ -838,6 +823,16 @@ bool HandleMouseEvent(const SDL_Event &event, UiItem *item) } // namespace +void LoadPalInMem(const PALETTEENTRY *pPal) +{ + for (int i = 0; i < 256; i++) { + orig_palette[i].peFlags = 0; + orig_palette[i].peRed = pPal[i].peRed; + orig_palette[i].peGreen = pPal[i].peGreen; + orig_palette[i].peBlue = pPal[i].peBlue; + } +} + void UiRenderItems(UiItem *items, std::size_t size) { for (std::size_t i = 0; i < size; i++) diff --git a/SourceX/DiabloUI/diabloui.h b/SourceX/DiabloUI/diabloui.h index 59dbf1e9b..1555c3ab0 100644 --- a/SourceX/DiabloUI/diabloui.h +++ b/SourceX/DiabloUI/diabloui.h @@ -40,6 +40,7 @@ void UiFadeIn(int steps = 16); bool UiFocusNavigation(SDL_Event *event); bool UiItemMouseEvents(SDL_Event *event, UiItem *items, std::size_t size); int GetCenterOffset(int w, int bw = 0); +void LoadPalInMem(const PALETTEENTRY *pPal); void DrawLogo(int t = 0, int size = LOGO_MED); void DrawMouse(); void LoadBackgroundArt(char *pszFile); diff --git a/SourceX/DiabloUI/dialogs.cpp b/SourceX/DiabloUI/dialogs.cpp index a8800550e..b680ed7b8 100644 --- a/SourceX/DiabloUI/dialogs.cpp +++ b/SourceX/DiabloUI/dialogs.cpp @@ -1,12 +1,14 @@ #include "DiabloUI/dialogs.h" #include "devilution.h" +#include "dx.h" #include "DiabloUI/diabloui.h" #include "DiabloUI/button.h" #include "DiabloUI/fonts.h" namespace dvl { +extern HANDLE diabdat_mpq; extern SDL_Surface *pal_surface; namespace { @@ -57,7 +59,7 @@ UiItem OK_DIALOG[] = { UiItem OK_DIALOG_WITH_CAPTION[] = { DIALOG_ART_L, - UiText(dialogText, SDL_Color { 255, 255, 0, 0 }, { 147, 110, 345, 20 }, UIS_CENTER), + UiText(dialogText, SDL_Color{ 255, 255, 0, 0 }, { 147, 110, 345, 20 }, UIS_CENTER), UiText(dialogCaption, { 147, 141, 345, 190 }, UIS_CENTER), MakeSmlButton("OK", &DialogActionOK, 264, 335), }; @@ -82,6 +84,28 @@ UiItem SPAWNERR_DIALOG[] = { UiArtTextButton("OK", &DialogActionOK, { 230, 407, 180, 43 }), }; +const std::uint_fast8_t DEFAULT_BG_DIALOG_IDX = 4; +const std::uint_fast8_t DEFAULT_BG_BUTTON_IDX = 5; + +void LoadFallbackPalette() +{ + PALETTEENTRY fallback_palette[256] = { 0 }; + fallback_palette[1] = { 255, 255, 255, 0 }; + fallback_palette[2] = { 255, 255, 0, 0 }; + fallback_palette[3] = { 243, 243, 243, 0 }; + fallback_palette[DEFAULT_BG_DIALOG_IDX] = { 100, 20, 20, 0 }; + fallback_palette[DEFAULT_BG_BUTTON_IDX] = { 130, 110, 80, 0 }; + LoadPalInMem(fallback_palette); + ApplyGamma(logical_palette, orig_palette, 256); +} + +void StubArt(Art *art, int w, int h, std::uint_fast8_t color_idx) +{ + art->surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h * art->frames, 8, 0, 0, 0, 0); + SDL_FillRect(art->surface, nullptr, color_idx); + art->frame_height = h; +} + void Init(const char *text, const char *caption, bool error) { strcpy(dialogText, text); @@ -97,6 +121,15 @@ void Init(const char *text, const char *caption, bool error) } LoadSmlButtonArt(); + if (diabdat_mpq == nullptr) { + ShowCursor(true); + LoadFallbackPalette(); + const auto dlg_rect = (caption == nullptr ? DIALOG_ART_S.rect : DIALOG_ART_L.rect); + StubArt(&dialogArt, dlg_rect.w, dlg_rect.h, DEFAULT_BG_DIALOG_IDX); + const auto &btn = dialogItems[dialogItemsSize - 1].button; + StubArt(btn.art, btn.rect.w, btn.rect.h, DEFAULT_BG_BUTTON_IDX); + } + fontWasLoaded = font != nullptr; if (!fontWasLoaded) LoadTtfFont(); diff --git a/SourceX/miniwin/misc.cpp b/SourceX/miniwin/misc.cpp index 97a72252a..4b4e0bf9b 100644 --- a/SourceX/miniwin/misc.cpp +++ b/SourceX/miniwin/misc.cpp @@ -5,6 +5,7 @@ #include #include "DiabloUI/diabloui.h" +#include "DiabloUI/dialogs.h" #ifdef _MSC_VER #define strcasecmp _stricmp @@ -329,18 +330,7 @@ void lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength) int MessageBoxA(HWND hWnd, const char *Text, const char *Title, UINT Flags) { - Uint32 SDLFlags = 0; - if (Flags & DVL_MB_ICONHAND) { - SDLFlags |= SDL_MESSAGEBOX_ERROR; - } else if (Flags & DVL_MB_ICONEXCLAMATION) { - SDLFlags |= SDL_MESSAGEBOX_WARNING; - } - - if (SDL_ShowSimpleMessageBox(SDLFlags, Title, Text, window) <= -1) { - SDL_Log(SDL_GetError()); - return -1; - } - + UiOkDialog(Title, Text, /*error=*/!!(Flags & (DVL_MB_ICONHAND | DVL_MB_ICONEXCLAMATION)), nullptr, 0); return 0; }