From d86ceb14cbbaea38dcf2094f2299b6f6e7b88cdf Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sun, 3 Feb 2019 05:17:35 +0100 Subject: [PATCH] Refactor ui code --- CMakeLists.txt | 3 +- Stub/DiabloUI/credits.cpp | 8 +- Stub/DiabloUI/diabloui.cpp | 340 +++++++++++++++++++++++---- Stub/DiabloUI/mainmenu.cpp | 16 +- Stub/DiabloUI/progress.cpp | 62 +++-- Stub/DiabloUI/sdlrender.cpp | 446 ------------------------------------ Stub/DiabloUI/sdlrender.h | 102 ++++----- Stub/DiabloUI/selconn.cpp | 53 +++-- Stub/DiabloUI/selhero.cpp | 104 ++++----- Stub/DiabloUI/title.cpp | 12 +- Stub/dx.cpp | 4 +- Stub/init.cpp | 25 ++ 12 files changed, 494 insertions(+), 681 deletions(-) delete mode 100644 Stub/DiabloUI/sdlrender.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 32df4bc9c..8e9e631d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,7 +148,6 @@ set(STUB_SOURCES Stub/DiabloUI/diabloui.cpp Stub/DiabloUI/mainmenu.cpp Stub/DiabloUI/progress.cpp - Stub/DiabloUI/sdlrender.cpp Stub/DiabloUI/selconn.cpp Stub/DiabloUI/selhero.cpp Stub/DiabloUI/title.cpp @@ -169,7 +168,7 @@ set(STUB_SOURCES include_directories(${SDL2_INCLUDE_DIR} ${SDL2_TTF_INCLUDE_DIR} ${SDL2_MIXER_INCLUDE_DIR} - ${sodium_INCLUDE_DIR}) + ${sodium_INCLUDE_DIR}) include_directories(. Stub 3rdParty/asio/include) diff --git a/Stub/DiabloUI/credits.cpp b/Stub/DiabloUI/credits.cpp index c182f012e..dd05a6dac 100644 --- a/Stub/DiabloUI/credits.cpp +++ b/Stub/DiabloUI/credits.cpp @@ -469,18 +469,18 @@ char *the_long_credits[] = { void credts_Loade() { - LoadTitelArt("ui_art\\credits.pcx"); + LoadBackgroundArt("ui_art\\credits.pcx"); } void credts_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; } void credts_Render() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); + DrawArt(0, 0, &ArtBackground); int lineHeight = 22; diff --git a/Stub/DiabloUI/diabloui.cpp b/Stub/DiabloUI/diabloui.cpp index 439defdb7..bd694ff91 100644 --- a/Stub/DiabloUI/diabloui.cpp +++ b/Stub/DiabloUI/diabloui.cpp @@ -5,11 +5,115 @@ int SelectedItemMax = 0; int MenuItem[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int PreviousItem[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int submenu = 0; +BYTE *FontTables[4]; +Art ArtFonts[4][2]; +Art ArtLogos[3]; +Art ArtFocus[3]; +Art ArtBackground; +Art ArtCursor; +Art ArtHero; + +int SCREEN_WIDTH = 640; +int SCREEN_HEIGHT = 480; + +int fadeValue = 0; +int SelectedItem = 1; + +char *errorTitle[] = { + "Direct Draw Error", + "Out of Memory Error", + "Direct Draw Error", + "Data File Error", + "Direct Sound Error", + "Out of Disk Space", + "Direct Draw Error", + "Data File Error", + "Windows 2000 Restricted User Advisory", + "Read-Only Directory Error", +}; +char *errorMessages[] = { + "Diablo was unable to properly initialize your video card using DirectX.\nPlease try the following solutions to correct the problem:\n\n Use the Diablo setup program \"SETUP.EXE\" provided on the Diablo CD-ROM to install DirectX 3.0.\n\n Install the most recent DirectX video drivers provided by the manufacturer of your video card.\nA list of video card manufactuers can be found at: http://www.blizzard.com/support/vendors.htm\n\nIf you continue to have problems with DirectX, please contact Microsoft's Technical Support at:\n\n\nIf you continue to have problems, we have also included Microsoft DirectX 2.0 drivers on the Diablo CD-ROM.\nThis older version of DirectX may work in cases where DirectX 3.0 does not.\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 the video card was:\n\n %s", + "Diablo has exhausted all the memory on your system.\nThis problem can likely be corrected by changing the virtual memory settings for Windows.\nEnsure that your system has at least 10 megabytes of free disk space, then check your virtual memory settings:\n\nFor Windows 95:\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"System\" control panel applet\n Select the \"Performance\" tab, and press \"Virtual Memory\"\n Use the \"Let Windows manage my virtual memory...\" option\n\nFor Windows NT:\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"System\" control panel applet\n Select the \"Performance\" tab\n Press \"Change\" in \"Virtual Memory\" settings\n Ensure that the virtual memory file is at least 32 megabytes\n\nThe error encountered was:\n\n %s", + "Diablo was unable to open a required file.\nPlease ensure that the Diablo disc is in the CDROM drive.\nIf this problem persists, try uninstalling and reinstalling Diablo using the program \"SETUP.EXE\" on the Diablo CD-ROM.\n\n\nThe problem occurred while trying to load a file\n\n %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.", + "Diablo was unable to switch video modes.\nThis is a common problem for computers with more than one video card.\nTo correct this problem, please set your video resolution to 640 x 480 and try running Diablo again.\n\nFor Windows 95 and Windows NT\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"Display\" control panel applet\n Select the \"Settings\" tab\n Set the \"Desktop Area\" to \"640 x 480 pixels\"\n\n\nThe error encountered while trying to switch video modes was:\n\n %s", + "Diablo cannot read a required data file.\nYour Diablo CD may not be in the CDROM drive.\nPlease ensure that the Diablo disc is in the CDROM drive and press OK.\nTo leave the program, press Exit.\n %s", + "In order to install, play or patch Diablo using the Windows 2000 operating system,\nyou will need to log in as either an Administrator or as a Power User.\n\nUsers, also known as Restricted Users, do not have sufficient access to install or play the game properly.\n\nIf you have further questions regarding User Rights in Windows 2000, please refer to your Windows 2000 documentation or contact your system administrator.", + "Diablo is being run from:\n\n %s\n\n\nDiablo or the current user does not seem to have write privilages in this directory. Contact your system administrator.\n\nNote that Windows 2000 Restricted Users can not write to the Windows or Program Files directory hierarchies.", +}; + +DWORD FormatMessage( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + char *lpBuffer, + DWORD nSize, + va_list *Arguments) +{ + DUMMY(); + return 0; +} + +int MAKEINTRESOURCE(int i) +{ + switch (i) { + case IDD_DIALOG1: + return 0; + case IDD_DIALOG2: + return 1; + case IDD_DIALOG3: + return 2; + case IDD_DIALOG4: + return 3; + case IDD_DIALOG5: + return 4; + case IDD_DIALOG7: + return 5; + case IDD_DIALOG8: + return 6; + case IDD_DIALOG9: + return 7; + case IDD_DIALOG10: + return 8; + case IDD_DIALOG11: + return 9; + } +} + +int DialogBoxParam(HINSTANCE hInstance, int msgId, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) +{ + char text[1024]; + snprintf(text, 1024, errorMessages[msgId], dwInitParam); + + return SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, errorTitle[msgId], text, window) < 0 ? -1 : 0; +} + +BOOL SetDlgItemText(HWND hDlg, int nIDDlgItem, LPCSTR lpString) +{ + return FALSE; +} + +BOOL EndDialog(HWND hDlg, INT_PTR nResult) +{ + return FALSE; +} + +BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) +{ + SDL_SetWindowPosition(window, X, Y); + + return TRUE; +} void __cdecl UiDestroy() { DUMMY(); - FreeMenuItems(); + mem_free_dbg(ArtHero.data); + ArtHero.data = NULL; + mem_free_dbg(font); font = NULL; } @@ -46,52 +150,59 @@ void InitHiracy() PreviousItem[MULTIPLAYER_ERROR] = MAINMENU; } -void LoadUiGFX() +void LoadArt(char *pszFile, Art *art, int frames, PALETTEENTRY *pPalette) { - DWORD dwData[2]; - - LoadArtImage("ui_art\\focus16.pcx", &MenuPentegram16, 8); - LoadArtImage("ui_art\\focus.pcx", &MenuPentegram, 8); - LoadArtImage("ui_art\\focus42.pcx", &MenuPentegram42, 8); + if (art == NULL || art->data != NULL) + return; - LoadArtImage("ui_art\\cursor.pcx", &pPcxCursorImage, 1, dwData); - gdwCursorWidth = dwData[0]; - gdwCursorHeight = dwData[1]; + if (!SBmpLoadImage(pszFile, 0, 0, 0, &art->width, &art->height, 0)) + return; - LoadArtImage("ui_art\\logo.pcx", &pPcxLogoImage, 15, dwData); - gdwLogoWidth = dwData[0]; - gdwLogoHeight = dwData[1]; + art->data = malloc(art->width * art->height); + if (!SBmpLoadImage(pszFile, pPalette, art->data, art->width * art->height, 0, 0, 0)) + return; - LoadArtImage("ui_art\\smlogo.pcx", &pPcxLogoSmImage, 15, dwData); - gdwLogoSmWidth = dwData[0]; - gdwLogoSmHeight = dwData[1]; + if (art->data == NULL) + return; - LoadArtImage("ui_art\\heros.pcx", &pPcxHeroImage, 4, dwData); - gdwHeroWidth = dwData[0]; - gdwHeroHeight = dwData[1]; + art->height /= frames; - pFont16 = LoadFileInMem("ui_art\\font16.bin", 0); - LoadArtImage("ui_art\\font16s.pcx", &pPcxFont16sImage, 256); - LoadArtImage("ui_art\\font16g.pcx", &pPcxFont16gImage, 256, dwData); - gdwFont16Width = dwData[0]; - gdwFont16Height = dwData[1]; + return art; +} - pFont24 = LoadFileInMem("ui_art\\font24.bin", 0); - LoadArtImage("ui_art\\font24s.pcx", &pPcxFont24sImage, 256); - LoadArtImage("ui_art\\font24g.pcx", &pPcxFont24gImage, 256, dwData); - gdwFont24Width = dwData[0]; - gdwFont24Height = dwData[1]; +void LoadMaskedArtFont(char *pszFile, Art *art, int frames, int mask = 250) +{ + LoadArt(pszFile, art, frames); + art->masked = true; + art->mask = mask; +} - pFont30 = LoadFileInMem("ui_art\\font30.bin", 0); - LoadArtImage("ui_art\\font30s.pcx", &pPcxFont30sImage, 256); - LoadArtImage("ui_art\\font30g.pcx", &pPcxFont30gImage, 256, dwData); - gdwFont30Width = dwData[0]; - gdwFont30Height = dwData[1]; +void LoadArtFont(char *pszFile, int size, int color) +{ + LoadMaskedArtFont(pszFile, &ArtFonts[size][color], 256, 32); +} - pFont42 = LoadFileInMem("ui_art\\font42.bin", 0); - LoadArtImage("ui_art\\font42g.pcx", &pPcxFont42gImage, 256, dwData); - gdwFont42Width = dwData[0]; - gdwFont42Height = dwData[1]; +void LoadUiGFX() +{ + FontTables[AFT_SMALL] = LoadFileInMem("ui_art\\font16.bin", 0); + FontTables[AFT_MED] = LoadFileInMem("ui_art\\font24.bin", 0); + FontTables[AFT_BIG] = LoadFileInMem("ui_art\\font30.bin", 0); + FontTables[AFT_HUGE] = LoadFileInMem("ui_art\\font42.bin", 0); + LoadArtFont("ui_art\\font16s.pcx", AFT_SMALL, AFC_SILVER); + LoadArtFont("ui_art\\font16g.pcx", AFT_SMALL, AFC_GOLD); + LoadArtFont("ui_art\\font24s.pcx", AFT_MED, AFC_SILVER); + LoadArtFont("ui_art\\font24g.pcx", AFT_MED, AFC_GOLD); + LoadArtFont("ui_art\\font30s.pcx", AFT_BIG, AFC_SILVER); + LoadArtFont("ui_art\\font30g.pcx", AFT_BIG, AFC_GOLD); + LoadArtFont("ui_art\\font42g.pcx", AFT_HUGE, AFC_GOLD); + + LoadMaskedArtFont("ui_art\\logo.pcx", &ArtLogos[LOGO_BIG], 15); + LoadMaskedArtFont("ui_art\\smlogo.pcx", &ArtLogos[LOGO_MED], 15); + LoadMaskedArtFont("ui_art\\focus16.pcx", &ArtFocus[FOCUS_SMALL], 8); + LoadMaskedArtFont("ui_art\\focus.pcx", &ArtFocus[FOCUS_MED], 8); + LoadMaskedArtFont("ui_art\\focus42.pcx", &ArtFocus[FOCUS_BIG], 8); + LoadMaskedArtFont("ui_art\\cursor.pcx", &ArtCursor, 1, 0); + LoadArt("ui_art\\heros.pcx", &ArtHero, 4); } void InitFont() @@ -116,10 +227,6 @@ void UiInitialize() { InitHiracy(); LoadUiGFX(); - - if (!window) { - SdlDiabloMainWindow(); - } ShowCursor(FALSE); InitFont(); } @@ -213,3 +320,152 @@ int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc) { UNIMPLEMENTED(); } + +void DrawArt(int screenX, int screenY, Art *art, int nFrame, int drawW) +{ + BYTE *src = (BYTE *)art->data + (art->width * art->height * nFrame); + BYTE *dst = (BYTE *)&gpBuffer->row[screenY].pixels[screenX]; + drawW = drawW ?: art->width; + + for (int i = 0; i < art->height && i + screenY < SCREEN_HEIGHT; i++, src += art->width, dst += 768) { + for (int j = 0; j < art->width && j + screenX < SCREEN_WIDTH; j++) { + if (j < drawW && (!art->masked || src[j] != art->mask)) + dst[j] = src[j]; + } + } +} + +int GetCenterOffset(int w, int bw = 0) +{ + if (bw == 0) { + bw = SCREEN_WIDTH; + } + + return bw / 2 - w / 2; +} + +int GetStrWidth(BYTE *str, int size) +{ + int strWidth = 0; + + for (int i = 0; i < strlen(str); i++) { + BYTE w = FontTables[size][str[i] + 2]; + if (w) + strWidth += w; + else + strWidth += FontTables[size][0]; + } + + return strWidth; +} + +int TextAlignment(char *text, TXT_JUST align, int bw, int size) +{ + if (align != JustLeft) { + int w = GetStrWidth(text, size); + if (align == JustCentre) { + return GetCenterOffset(w, bw); + } else if (align == JustRight) { + return bw - w; + } + } + + return 0; +} + +void DrawArtStr(int x, int y, int size, int color, BYTE *str, TXT_JUST align, int bw) +{ + x += TextAlignment(str, align, bw, size); + + for (int i = 0; i < strlen(str); i++) { + BYTE w = FontTables[size][str[i] + 2]; + if (!w) + w = FontTables[size][0]; + DrawArt(x, y, &ArtFonts[size][color], str[i], w); + x += w; + } +} + +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]; + + fadeValue = 0; + LoadArt(pszFile, &ArtBackground, 1, pPal); + LoadPalInMem(pPal); + ApplyGamma(logical_palette, orig_palette, 256); +} + +int GetAnimationFrame(int frames, int fps = 60) +{ + int frame = (SDL_GetTicks() / fps) % frames; + + return frame > frames ? 0 : frame; +} + +int frameEnd = 0; +void CapFPS() +{ + int now = SDL_GetTicks(); + frameEnd += 1000 / 60; + if (now < frameEnd) { + SDL_Delay(frameEnd - now); + } +} + +bool UiFadeIn(int steps) +{ + if (fadeValue < 256) { + fadeValue += steps; + if (fadeValue > 256) { + fadeValue = 256; + } + } + + SetFadeLevel(fadeValue); + + return fadeValue == 256; +} + +void DrawLogo(int t, int size) +{ + DrawArt(GetCenterOffset(ArtLogos[size].width), t, &ArtLogos[size], GetAnimationFrame(15)); +} + +void DrawMouse() +{ + SDL_GetMouseState(&MouseX, &MouseY); + + float scaleX; + SDL_RenderGetScale(renderer, &scaleX, NULL); + MouseX /= scaleX; + MouseY /= scaleX; + + SDL_Rect view; + SDL_RenderGetViewport(renderer, &view); + MouseX -= view.x; + MouseY -= view.y; + + DrawArt(MouseX, MouseY, &ArtCursor); +} + +void DrawSelector(int x, int y, int width, int padding, int spacing, int size) +{ + width = width ? width : SCREEN_WIDTH; + x += GetCenterOffset(ArtFocus[size].width, width); + y += (SelectedItem - 1) * spacing; + + int frame = GetAnimationFrame(8); + DrawArt(x - width / 2 + padding, y, &ArtFocus[size], frame); + DrawArt(x + width / 2 - padding, y, &ArtFocus[size], frame); +} diff --git a/Stub/DiabloUI/mainmenu.cpp b/Stub/DiabloUI/mainmenu.cpp index b41fd3493..ff191941c 100644 --- a/Stub/DiabloUI/mainmenu.cpp +++ b/Stub/DiabloUI/mainmenu.cpp @@ -2,11 +2,11 @@ void mainmenu_Render(char *name) { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); + DrawArt(0, 0, &ArtBackground); // scrollrt_draw_cursor_back_buffer(); // Doesn't work? - RenderDiabloLogoSm(); + DrawLogo(); int menuTop = 192; char *MENIITEMS[5] = { "Single Player", "Multi Player", "Replay Intro", "Show Credits", "Exit Diablo" }; @@ -16,7 +16,7 @@ void mainmenu_Render(char *name) if (i > 1) { y -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items } - PrintText42Gold(-1, y, MENIITEMS[i], 1); + DrawArtStr(-1, y, AFT_HUGE, AFC_GOLD, MENIITEMS[i], 1); } int selectorTop = menuTop; @@ -24,9 +24,9 @@ void mainmenu_Render(char *name) selectorTop -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items } - DrawSelector42(0, selectorTop, 0, 85, 43); + DrawSelector(0, selectorTop, 0, 85, 43, FOCUS_BIG); - PrintText16Silver(17, 444, name); + DrawArtStr(17, 444, AFT_SMALL, AFC_SILVER, name); } void mainmenu_Loade() @@ -34,13 +34,13 @@ void mainmenu_Loade() char *pszFile = "ui_art\\mainmenu.pcx"; if (false) //DiabloUI_GetSpawned() pszFile = "ui_art\\swmmenu.pcx"; - LoadTitelArt(pszFile); + LoadBackgroundArt(pszFile); } void mainmenu_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; } BOOL __stdcall UiMainMenuDialog(char *name, int *pdwResult, void(__stdcall *fnSound)(char *file), int a4) diff --git a/Stub/DiabloUI/progress.cpp b/Stub/DiabloUI/progress.cpp index 9ee00305b..5aa68c09a 100644 --- a/Stub/DiabloUI/progress.cpp +++ b/Stub/DiabloUI/progress.cpp @@ -1,72 +1,66 @@ #include "../../types.h" -void *pPcxSPopupImage; -void *pPcxProgBGImage; -void *pPcxProgFillImage; -void *pPcxSmlButImage; -int dwSmlButWidth, dwSmlButHeight; +Art ArtPopupSm; +Art ArtProgBG; +Art ProgFil; +Art ButImage; SDL_Surface *msgSurface; SDL_Surface *cancleSurface; -int w; +int textWidth; void progress_Loade(char *msg) { - DWORD dwData[2]; - - LoadTitelArt("ui_art\\black.pcx"); - LoadArtImage("ui_art\\spopup.pcx", &pPcxSPopupImage, 1); - LoadArtImage("ui_art\\prog_bg.pcx", &pPcxProgBGImage, 1); - LoadArtImage("ui_art\\prog_fil.pcx", &pPcxProgFillImage, 1); - LoadArtImage("ui_art\\but_sml.pcx", &pPcxSmlButImage, 15, dwData); - dwSmlButWidth = dwData[0]; - dwSmlButHeight = dwData[1]; + LoadBackgroundArt("ui_art\\black.pcx"); + LoadArt("ui_art\\spopup.pcx", &ArtPopupSm); + LoadArt("ui_art\\prog_bg.pcx", &ArtProgBG); + LoadArt("ui_art\\prog_fil.pcx", &ProgFil); + LoadArt("ui_art\\but_sml.pcx", &ButImage, 15); if (font != NULL) { SDL_Color color = { 243, 243, 243 }; msgSurface = TTF_RenderUTF8_Solid(font, msg, color); cancleSurface = TTF_RenderUTF8_Solid(font, "Cancel", color); - TTF_SizeUTF8(font, "Cancel", &w, NULL); + TTF_SizeUTF8(font, "Cancel", &textWidth, NULL); } } void progress_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; - mem_free_dbg(pPcxSPopupImage); - pPcxSPopupImage = NULL; - mem_free_dbg(pPcxProgBGImage); - pPcxProgBGImage = NULL; - mem_free_dbg(pPcxProgFillImage); - pPcxProgFillImage = NULL; - mem_free_dbg(pPcxSmlButImage); - pPcxSmlButImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; + mem_free_dbg(ArtPopupSm.data); + ArtPopupSm.data = NULL; + mem_free_dbg(ArtProgBG.data); + ArtProgBG.data = NULL; + mem_free_dbg(ProgFil.data); + ProgFil.data = NULL; + mem_free_dbg(ButImage.data); + ButImage.data = NULL; SDL_FreeSurface(msgSurface); msgSurface = NULL; SDL_FreeSurface(cancleSurface); cancleSurface = NULL; } -void progress_Render(int progress) +void progress_Render(BYTE progress) { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); + DrawArt(0, 0, &ArtBackground); int x = GetCenterOffset(280); int y = GetCenterOffset(144, SCREEN_HEIGHT); - DrawArtImage(x, y, 284, 148, 0, pPcxSPopupImage); - DrawArtImage(GetCenterOffset(228), y + 52, 232, 38, 0, pPcxProgBGImage, NULL, 228); + DrawArt(x, y, &ArtPopupSm); + DrawArt(GetCenterOffset(228), y + 52, &ArtProgBG, 0, 228); if (progress) { - DrawArtImage(GetCenterOffset(228), y + 52, 232, 38, 0, pPcxProgFillImage, NULL, 228 * progress / 100); + DrawArt(GetCenterOffset(228), y + 52, &ProgFil, 0, 228 * progress / 100); } - DrawArtImage(GetCenterOffset(dwSmlButWidth - 2), y + 99, dwSmlButWidth, dwSmlButHeight, 2, pPcxSmlButImage, NULL, dwSmlButWidth - 2); + DrawArt(GetCenterOffset(110), y + 99, &ButImage, 2, 110); if (msgSurface) { - SDL_Rect src_rect = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }; SDL_Rect dsc_rect = { 64 + x + 50, 160 + y + 8, SCREEN_WIDTH, SCREEN_HEIGHT }; SDL_BlitSurface(msgSurface, NULL, pal_surface, &dsc_rect); - dsc_rect.x = 64 + GetCenterOffset(w) - 1; + dsc_rect.x = 64 + GetCenterOffset(textWidth) - 1; dsc_rect.y = 160 + y + 99 + 4; SDL_BlitSurface(cancleSurface, NULL, pal_surface, &dsc_rect); } diff --git a/Stub/DiabloUI/sdlrender.cpp b/Stub/DiabloUI/sdlrender.cpp deleted file mode 100644 index 7e849b8c8..000000000 --- a/Stub/DiabloUI/sdlrender.cpp +++ /dev/null @@ -1,446 +0,0 @@ -#include "../../types.h" - -int SCREEN_WIDTH = 640; -int SCREEN_HEIGHT = 480; - -int LogoWidth; -int LogoHeight; - -int fadeValue = 0; -int SelectedItem = 1; - -void *pPcxLogoImage; -int gdwLogoWidth; -int gdwLogoHeight; -void *pPcxLogoSmImage; -int gdwLogoSmWidth; -int gdwLogoSmHeight; - -void *pPcxTitleImage; - -int gdwCursorWidth; -int gdwCursorHeight; -void *pPcxCursorImage; - -int gdwHeroHeight; -int gdwHeroWidth; -void *pPcxHeroImage; - -int gdwFont16Width; -int gdwFont16Height; -void *pPcxFont16sImage; -void *pPcxFont16gImage; -unsigned char *pFont16; - -int gdwFont24Width; -int gdwFont24Height; -void *pPcxFont24sImage; -void *pPcxFont24gImage; -unsigned char *pFont24; - -int gdwFont30Width; -int gdwFont30Height; -void *pPcxFont30sImage; -void *pPcxFont30gImage; -unsigned char *pFont30; - -int gdwFont42Width; -int gdwFont42Height; -void *pPcxFont42gImage; -void *pPcxFont42yImage; -unsigned char *pFont42; - -void *MenuPentegram16; -void *MenuPentegram; -void *MenuPentegram42; - -char *errorTitle[] = { - "Direct Draw Error", - "Out of Memory Error", - "Direct Draw Error", - "Data File Error", - "Direct Sound Error", - "Out of Disk Space", - "Direct Draw Error", - "Data File Error", - "Windows 2000 Restricted User Advisory", - "Read-Only Directory Error", -}; -char *errorMessages[] = { - "Diablo was unable to properly initialize your video card using DirectX.\nPlease try the following solutions to correct the problem:\n\n Use the Diablo setup program \"SETUP.EXE\" provided on the Diablo CD-ROM to install DirectX 3.0.\n\n Install the most recent DirectX video drivers provided by the manufacturer of your video card.\nA list of video card manufactuers can be found at: http://www.blizzard.com/support/vendors.htm\n\nIf you continue to have problems with DirectX, please contact Microsoft's Technical Support at:\n\n\nIf you continue to have problems, we have also included Microsoft DirectX 2.0 drivers on the Diablo CD-ROM.\nThis older version of DirectX may work in cases where DirectX 3.0 does not.\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 the video card was:\n\n %s", - "Diablo has exhausted all the memory on your system.\nThis problem can likely be corrected by changing the virtual memory settings for Windows.\nEnsure that your system has at least 10 megabytes of free disk space, then check your virtual memory settings:\n\nFor Windows 95:\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"System\" control panel applet\n Select the \"Performance\" tab, and press \"Virtual Memory\"\n Use the \"Let Windows manage my virtual memory...\" option\n\nFor Windows NT:\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"System\" control panel applet\n Select the \"Performance\" tab\n Press \"Change\" in \"Virtual Memory\" settings\n Ensure that the virtual memory file is at least 32 megabytes\n\nThe error encountered was:\n\n %s", - "Diablo was unable to open a required file.\nPlease ensure that the Diablo disc is in the CDROM drive.\nIf this problem persists, try uninstalling and reinstalling Diablo using the program \"SETUP.EXE\" on the Diablo CD-ROM.\n\n\nThe problem occurred while trying to load a file\n\n %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.", - "Diablo was unable to switch video modes.\nThis is a common problem for computers with more than one video card.\nTo correct this problem, please set your video resolution to 640 x 480 and try running Diablo again.\n\nFor Windows 95 and Windows NT\n Select \"Settings - Control Panel\" from the \"Start\" menu\n Run the \"Display\" control panel applet\n Select the \"Settings\" tab\n Set the \"Desktop Area\" to \"640 x 480 pixels\"\n\n\nThe error encountered while trying to switch video modes was:\n\n %s", - "Diablo cannot read a required data file.\nYour Diablo CD may not be in the CDROM drive.\nPlease ensure that the Diablo disc is in the CDROM drive and press OK.\nTo leave the program, press Exit.\n %s", - "In order to install, play or patch Diablo using the Windows 2000 operating system,\nyou will need to log in as either an Administrator or as a Power User.\n\nUsers, also known as Restricted Users, do not have sufficient access to install or play the game properly.\n\nIf you have further questions regarding User Rights in Windows 2000, please refer to your Windows 2000 documentation or contact your system administrator.", - "Diablo is being run from:\n\n %s\n\n\nDiablo or the current user does not seem to have write privilages in this directory. Contact your system administrator.\n\nNote that Windows 2000 Restricted Users can not write to the Windows or Program Files directory hierarchies.", -}; - -DWORD FormatMessage( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - char *lpBuffer, - DWORD nSize, - va_list *Arguments) -{ - DUMMY(); - return 0; -} - -int MAKEINTRESOURCE(int i) -{ - switch (i) { - case IDD_DIALOG1: - return 0; - case IDD_DIALOG2: - return 1; - case IDD_DIALOG3: - return 2; - case IDD_DIALOG4: - return 3; - case IDD_DIALOG5: - return 4; - case IDD_DIALOG7: - return 5; - case IDD_DIALOG8: - return 6; - case IDD_DIALOG9: - return 7; - case IDD_DIALOG10: - return 8; - case IDD_DIALOG11: - return 9; - } -} - -int DialogBoxParam(HINSTANCE hInstance, int msgId, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) -{ - char text[1024]; - snprintf(text, 1024, errorMessages[msgId], dwInitParam); - - return SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, errorTitle[msgId], text, window) < 0 ? -1 : 0; -} - -BOOL SetDlgItemText(HWND hDlg, int nIDDlgItem, LPCSTR lpString) -{ - return FALSE; -} - -BOOL EndDialog(HWND hDlg, INT_PTR nResult) -{ - return FALSE; -} - -BOOL SetWindowPos( - HWND hWnd, - HWND hWndInsertAfter, - int X, - int Y, - int cx, - int cy, - UINT uFlags) -{ - SDL_SetWindowPosition(window, X, Y); - - return TRUE; -} - -bool LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data, PALETTEENTRY *pPalette) -{ - DWORD width; - DWORD height; - - *pBuffer = NULL; - - if (!SBmpLoadImage(pszFile, 0, 0, 0, &width, &height, 0)) - return 0; - *pBuffer = malloc(height * width); - if (!SBmpLoadImage(pszFile, pPalette, *pBuffer, height * width, 0, 0, 0)) - return 0; - if (pBuffer && data) { - data[0] = width; - data[1] = height / frames; - } - - return 1; -} - -void FreeMenuItems() -{ - void *tmp; - - tmp = pPcxFont42yImage; - pPcxFont42yImage = NULL; - mem_free_dbg(tmp); -} - -void SdlDiabloMainWindow() -{ - atexit(SDL_Quit); - atexit(TTF_Quit); - SDL_Init(SDL_INIT_EVERYTHING); - - int flags = SDL_WINDOW_FULLSCREEN_DESKTOP; - if (!fullscreen) { - flags = SDL_WINDOW_RESIZABLE; - } - window = SDL_CreateWindow("Diablo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, flags); - - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC); - printf("Window And Renderer Created!\n"); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); - SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); - - surface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); - assert(surface); - - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - assert(texture); - - palette = SDL_AllocPalette(256); - - j_lock_buf_priv(0); //FIXME 0? -} - -void DrawArtImage(int SX, int SY, int SW, int SH, int nFrame, void *pBuffer, BYTE *bMask, int RW) -{ - BYTE *src = (BYTE *)pBuffer + (SW * SH * nFrame); - BYTE *dst = (BYTE *)&gpBuffer->row[SY].pixels[SX]; - RW = RW ?: SW; - - for (int i = 0; i < SH && i + SY < SCREEN_HEIGHT; i++, src += SW, dst += 768) { - for (int j = 0; j < SW && j + SX < SCREEN_WIDTH; j++) { - if (j < RW && (bMask == NULL || src[j] != *bMask)) - dst[j] = src[j]; - } - } -} - -int GetCenterOffset(int w, int bw = 0) -{ - if (bw == 0) { - bw = SCREEN_WIDTH; - } - - return bw / 2 - w / 2; -} - -void DrawPCXString(int x, int y, int w, int h, BYTE *str, BYTE *font, void *pBuff) -{ - int len = 0; - BYTE mask = 32; - BYTE chr; - int i; - - for (i = 0; i < strlen(str); i++) { - DrawArtImage(x + len, y, w, h, str[i], pBuff, &mask); - chr = font[str[i] + 2]; - if (chr) - len += chr; - else - len += *font; - } -} - -int GetPCXFontWidth(unsigned char *str, BYTE *font) -{ - int i; - int len = 0; - BYTE chr; - for (i = 0; i < strlen(str); i++) { - chr = font[str[i] + 2]; - if (chr) - len += chr; - else - len += *font; - } - - return len; -} - -int TextAlignment(char *text, TXT_JUST align, int bw, BYTE *pFont) -{ - if (align != JustLeft) { - int w = GetPCXFontWidth(text, pFont); - if (align == JustCentre) { - return GetCenterOffset(w, bw); - } else if (align == JustRight) { - return bw - w; - } - } - - return 0; -} - -void PrintText16Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont16); - - DrawPCXString(x, y, gdwFont16Width, gdwFont16Height, text, pFont16, pPcxFont16gImage); -} - -void PrintText16Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont16); - - DrawPCXString(x, y, gdwFont16Width, gdwFont16Height, text, pFont16, pPcxFont16sImage); -} - -void PrintText24Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont24); - - DrawPCXString(x, y, gdwFont24Width, gdwFont24Height, text, pFont24, pPcxFont24gImage); -} - -void PrintText24Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont24); - - DrawPCXString(x, y, gdwFont24Width, gdwFont24Height, text, pFont24, pPcxFont24sImage); -} - -void PrintText30Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont30); - - DrawPCXString(x, y, gdwFont30Width, gdwFont30Height, text, pFont30, pPcxFont30gImage); -} - -void PrintText30Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont30); - - DrawPCXString(x, y, gdwFont30Width, gdwFont30Height, text, pFont30, pPcxFont30sImage); -} - -void PrintText42Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0) -{ - x += TextAlignment(text, align, bw, pFont42); - - DrawPCXString(x, y, gdwFont42Width, gdwFont42Height, text, pFont42, pPcxFont42gImage); -} - -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 LoadTitelArt(char *pszFile) -{ - PALETTEENTRY pPal[256]; - - fadeValue = 0; - LoadArtImage(pszFile, &pPcxTitleImage, 1, NULL, pPal); - LoadPalInMem(pPal); - ApplyGamma(logical_palette, orig_palette, 256); -} - -int GetAnimationFrame(int frames, int fps = 60) -{ - int frame = (SDL_GetTicks() / fps) % frames; - - return frame > frames ? 0 : frame; -} - -int frameEnd = 0; -void CapFPS() -{ - int now = SDL_GetTicks(); - frameEnd += 1000 / 60; - if (now < frameEnd) { - SDL_Delay(frameEnd - now); - } -} - -bool UiFadeIn(int steps) -{ - if (fadeValue < 256) { - fadeValue += steps; - if (fadeValue > 256) { - fadeValue = 256; - } - } - - SetFadeLevel(fadeValue); - - return fadeValue == 256; -} - -///////////////////////////Renders - -void AnimateDiabloLogo(int t, int w, int h, void *pBuffer) -{ - BYTE mask = 250; - int frame = GetAnimationFrame(15); - - DrawArtImage(GetCenterOffset(w), t, w, h, frame, pBuffer, &mask); -} - -void RenderDiabloLogo() -{ - AnimateDiabloLogo(182, gdwLogoWidth, gdwLogoHeight, pPcxLogoImage); -} - -void RenderDiabloLogoSm() -{ - AnimateDiabloLogo(0, gdwLogoSmWidth, gdwLogoSmHeight, pPcxLogoSmImage); -} - -void DrawMouse() -{ - BYTE mask = 0; - - SDL_GetMouseState(&MouseX, &MouseY); - - float scaleX; - SDL_RenderGetScale(renderer, &scaleX, NULL); - MouseX /= scaleX; - MouseY /= scaleX; - - SDL_Rect view; - SDL_RenderGetViewport(renderer, &view); - MouseX -= view.x; - MouseY -= view.y; - - DrawArtImage(MouseX, MouseY, gdwCursorWidth, gdwCursorHeight, 0, pPcxCursorImage, &mask); -} - -void AnimateSelector(int x, int y, int width, int padding, int spacing, int swidth, void *pBuffer) -{ - BYTE mask = 250; - - width = width ? width : SCREEN_WIDTH; - x += GetCenterOffset(swidth, width); - y += (SelectedItem - 1) * spacing; - - int frame = GetAnimationFrame(8); - DrawArtImage(x - width / 2 + padding, y, swidth, swidth, frame, pBuffer, &mask); - DrawArtImage(x + width / 2 - padding, y, swidth, swidth, frame, pBuffer, &mask); -} - -void DrawSelector16(int x, int y, int width, int padding, int spacing) -{ - AnimateSelector(x, y, width, padding, spacing, 20, MenuPentegram16); -} - -void DrawSelector(int x, int y, int width, int padding, int spacing) -{ - AnimateSelector(x, y, width, padding, spacing, 30, MenuPentegram); -} - -void DrawSelector42(int x, int y, int width, int padding, int spacing) -{ - AnimateSelector(x, y, width, padding, spacing, 42, MenuPentegram42); -} diff --git a/Stub/DiabloUI/sdlrender.h b/Stub/DiabloUI/sdlrender.h index c9d4ad8e5..b96fca894 100644 --- a/Stub/DiabloUI/sdlrender.h +++ b/Stub/DiabloUI/sdlrender.h @@ -2,62 +2,54 @@ #include "../../types.h" -extern TTF_Font *font; +typedef enum _artFocus { + FOCUS_SMALL, + FOCUS_MED, + FOCUS_BIG, +} _artFocus; -extern unsigned char *pFont16; -extern int gdwFont16Width; -extern int gdwFont16Height; -extern void *pPcxFont16sImage; -extern void *pPcxFont16gImage; +typedef enum _artLogo { + LOGO_SMALL, + LOGO_MED, + LOGO_BIG, +} _artLogo; -extern unsigned char *pFont24; -extern int gdwFont24Width; -extern int gdwFont24Height; -extern void *pPcxFont24sImage; -extern void *pPcxFont24gImage; +typedef enum _artFontTables { + AFT_SMALL, + AFT_MED, + AFT_BIG, + AFT_HUGE, +} _artFontTables; -extern unsigned char *pFont30; -extern int gdwFont30Width; -extern int gdwFont30Height; -extern void *pPcxFont30sImage; -extern void *pPcxFont30gImage; +typedef enum _artFontColors { + AFC_SILVER, + AFC_GOLD, +} _artFontColors; -extern unsigned char *pFont42; -extern int gdwFont42Width; -extern int gdwFont42Height; -extern void *pPcxFont42gImage; +typedef struct Art { + BYTE *data; + DWORD width; + DWORD height; + bool masked = false; + BYTE mask; +} Art; -extern void *pPcxLogoImage; -extern int gdwLogoWidth; -extern int gdwLogoHeight; -extern void *pPcxLogoSmImage; -extern int gdwLogoSmWidth; -extern int gdwLogoSmHeight; +extern TTF_Font *font; -extern void *pPcxTitleImage; -extern int gdwCursorHeight; -extern int gdwCursorWidth; -extern void *pPcxCursorImage; -extern int gdwHeroHeight; -extern int gdwHeroWidth; -extern void *pPcxHeroImage; -extern int gdwSHeroHeight; -extern int gdwSHeroWidth; -extern void *pPcxSHeroImage; -extern void *pMedTextCels; +extern BYTE *FontTables[4]; +extern Art ArtFonts[4][2]; +extern Art ArtLogos[3]; +extern Art ArtFocus[3]; +extern Art ArtBackground; +extern Art ArtCursor; +extern Art ArtHero; extern int SelectedItem; extern int SelectedItemMax; extern int SCREEN_WIDTH; extern int SCREEN_HEIGHT; -extern int TotalPlayers; - -extern void *MenuPentegram16; -extern void *MenuPentegram; -extern void *MenuPentegram42; -extern char HeroUndecidedName[17]; extern int MenuItem[10]; extern int PreviousItem[10]; extern int submenu; @@ -76,27 +68,15 @@ BOOL EndDialog(HWND hDlg, INT_PTR nResult); BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); bool IsInsideRect(const SDL_Event *event, const SDL_Rect *rect); -bool LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data = NULL, PALETTEENTRY *pPalette = NULL); bool UiFadeIn(int steps = 16); int GetAnimationFrame(int frames, int fps = 60); int GetCenterOffset(int w, int bw = 0); void CapFPS(); -void DrawArtImage(int SX, int SY, int SW, int SH, int nFrame, void *pBuffer, BYTE *bMask = NULL, int RW = 0); +void DrawArt(int screenX, int screenY, Art *art, int nFrame = 0, int drawW = 0); +void DrawArtStr(int x, int y, int size, int color, BYTE *str, TXT_JUST align = JustLeft, int bw = 0); +void DrawLogo(int t = 0, int size = LOGO_MED); void DrawMouse(); -void DrawSelector16(int x, int y, int width, int padding, int spacing); -void DrawSelector(int x, int y, int width, int padding, int spacing); -void DrawSelector42(int x, int y, int width, int padding, int spacing); -void FreeMenuItems(); -void LoadHeroStats(); -void LoadTitelArt(char *pszFile); -void PrintText16Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText16Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText24Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText24Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText30Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText30Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void PrintText42Gold(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0); -void RenderDiabloLogo(); -void RenderDiabloLogoSm(); -void SdlDiabloMainWindow(); +void DrawSelector(int x, int y, int width, int padding, int spacing, int size = FOCUS_MED); +void LoadArt(char *pszFile, Art *art, int frames = 1, PALETTEENTRY *pPalette = NULL); +void LoadBackgroundArt(char *pszFile); void SetMenu(int MenuId); diff --git a/Stub/DiabloUI/selconn.cpp b/Stub/DiabloUI/selconn.cpp index 6f5f85670..133fabc43 100644 --- a/Stub/DiabloUI/selconn.cpp +++ b/Stub/DiabloUI/selconn.cpp @@ -2,63 +2,63 @@ void selconn_Render() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - PrintText30Silver(-1, 161, "Multi Player Game", JustCentre); + DrawArtStr(-1, 161, AFT_BIG, AFC_SILVER, "Multi Player Game", JustCentre); int w = 334; int x = 280; int y = 261; - PrintText30Silver(x, 211, "Select Connection", JustCentre, w); + DrawArtStr(x, 211, AFT_BIG, AFC_SILVER, "Select Connection", JustCentre, w); char *connections[2] = { //"Battle.net", //"Local Area Network (IPC)", //"Modem", //"Direct Cable Connection", - "Local Area Network (UDP)" - ,"Solo" + "Local Area Network (UDP)", + "Solo", }; int selectorTop = y; for (int i = 0; i < 2; i++) { - PrintText16Gold(x - 1, y, connections[i], JustCentre, w); + DrawArtStr(x - 1, y, AFT_SMALL, AFC_GOLD, connections[i], JustCentre, w); y += 26; } - DrawSelector16(x, selectorTop - 2, w, 35, 26); + DrawSelector(x, selectorTop - 2, w, 35, 26, FOCUS_SMALL); if (SelectedItem == 1) { - PrintText16Silver(35, 218, "Players Supported: 4"); - PrintText16Silver(35, 256, "Requirements:"); + DrawArtStr(35, 218, AFT_SMALL, AFC_SILVER, "Players Supported: 4"); + DrawArtStr(35, 256, AFT_SMALL, AFC_SILVER, "Requirements:"); // TODO need a word wrap function - PrintText16Silver(35, 275, "All computers must be"); - PrintText16Silver(35, 291, "connected to an"); - PrintText16Silver(35, 307, "UDP-compatible network."); + DrawArtStr(35, 275, AFT_SMALL, AFC_SILVER, "All computers must be"); + DrawArtStr(35, 291, AFT_SMALL, AFC_SILVER, "connected to an"); + DrawArtStr(35, 307, AFT_SMALL, AFC_SILVER, "UDP-compatible network."); } else { - PrintText16Silver(35, 218, "Players Supported: 1"); - PrintText16Silver(35, 256, "Play by your self with"); - PrintText16Silver(35, 275, "no network exposure."); + DrawArtStr(35, 218, AFT_SMALL, AFC_SILVER, "Players Supported: 1"); + DrawArtStr(35, 256, AFT_SMALL, AFC_SILVER, "Play by your self with"); + DrawArtStr(35, 275, AFT_SMALL, AFC_SILVER, "no network exposure."); } - PrintText24Silver(26, 356, "no gateway needed", JustCentre, 226); + DrawArtStr(26, 356, AFT_MED, AFC_SILVER, "no gateway needed", JustCentre, 226); - PrintText30Gold(349, 429, "OK"); - PrintText30Gold(476, 429, "Cancel"); + DrawArtStr(349, 429, AFT_BIG, AFC_GOLD, "OK"); + DrawArtStr(476, 429, AFT_BIG, AFC_GOLD, "Cancel"); } void selconn_Loade() { - LoadTitelArt("ui_art\\selconn.pcx"); + LoadBackgroundArt("ui_art\\selconn.pcx"); } void selconn_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; } int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, @@ -70,6 +70,7 @@ int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYE SelectedItemMax = 2; SDL_Event event; + bool rv = true; bool endMenu = false; while (!endMenu) { CapFPS(); @@ -100,11 +101,14 @@ int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYE SetMenu(PreviousItem[submenu]); break; } - return FALSE; + rv = false; + endMenu = true; + break; case SDLK_RETURN: case SDLK_KP_ENTER: case SDLK_SPACE: effects_play_sound("sfx\\items\\titlslct.wav"); + selconn_Free(); switch (SelectedItem) { /* case 1: @@ -127,6 +131,7 @@ int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYE endMenu = SNetInitializeProvider('SCBL', client_info, user_info, ui_info, file_info); break; } + selconn_Loade(); SelectedItem = 1; SelectedItemMax = 3; break; @@ -141,5 +146,5 @@ int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYE selconn_Free(); - return TRUE; + return rv; } diff --git a/Stub/DiabloUI/selhero.cpp b/Stub/DiabloUI/selhero.cpp index a2c992021..0d4e45593 100644 --- a/Stub/DiabloUI/selhero.cpp +++ b/Stub/DiabloUI/selhero.cpp @@ -28,16 +28,16 @@ void RenderStats() sprintf(vit, "%d", heroInfo.vitality); } - PrintText16Silver(31, 323, "Level:", JustRight, 118); - PrintText16Silver(149, 323, lvl, JustCentre, 61); - PrintText16Silver(31, 358, "Strength:", JustRight, 118); - PrintText16Silver(149, 358, str, JustCentre, 61); - PrintText16Silver(31, 380, "Magic:", JustRight, 118); - PrintText16Silver(149, 380, mag, JustCentre, 61); - PrintText16Silver(31, 401, "Dexterity:", JustRight, 118); - PrintText16Silver(149, 401, dex, JustCentre, 61); - PrintText16Silver(31, 422, "Vitality:", JustRight, 118); - PrintText16Silver(149, 422, vit, JustCentre, 61); + DrawArtStr(31, 323, AFT_SMALL, AFC_SILVER, "Level:", JustRight, 118); + DrawArtStr(149, 323, AFT_SMALL, AFC_SILVER, lvl, JustCentre, 61); + DrawArtStr(31, 358, AFT_SMALL, AFC_SILVER, "Strength:", JustRight, 118); + DrawArtStr(149, 358, AFT_SMALL, AFC_SILVER, str, JustCentre, 61); + DrawArtStr(31, 380, AFT_SMALL, AFC_SILVER, "Magic:", JustRight, 118); + DrawArtStr(149, 380, AFT_SMALL, AFC_SILVER, mag, JustCentre, 61); + DrawArtStr(31, 401, AFT_SMALL, AFC_SILVER, "Dexterity:", JustRight, 118); + DrawArtStr(149, 401, AFT_SMALL, AFC_SILVER, dex, JustCentre, 61); + DrawArtStr(31, 422, AFT_SMALL, AFC_SILVER, "Vitality:", JustRight, 118); + DrawArtStr(149, 422, AFT_SMALL, AFC_SILVER, vit, JustCentre, 61); } void selhero_Render() @@ -47,40 +47,40 @@ void selhero_Render() memcpy(&heroInfo, &heros[SelectedItem - 1], sizeof(heroInfo)); } - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - PrintText30Silver(-1, 161, "Single Player Characters", JustCentre); + DrawArtStr(-1, 161, AFT_BIG, AFC_SILVER, "Single Player Characters", JustCentre); - DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); + DrawArt(30, 211, &ArtHero, heroInfo.heroclass); RenderStats(); int w = 369; int x = 241; - PrintText30Silver(x - 1, 211, "Select Hero", JustCentre, w); + DrawArtStr(x - 1, 211, AFT_BIG, AFC_SILVER, "Select Hero", JustCentre, w); int selectorTop = 256; int y = selectorTop; for (int i = 0; i < selhero_SaveCount; i++) { - PrintText24Gold(x - 1, y, heros[i].name, JustCentre, w); + DrawArtStr(x - 1, y, AFT_MED, AFC_GOLD, heros[i].name, JustCentre, w); y += 26; } - PrintText24Gold(x - 1, y, "New Hero", JustCentre, w); + DrawArtStr(x - 1, y, AFT_MED, AFC_GOLD, "New Hero", JustCentre, w); - DrawSelector16(x, selectorTop + 3, w, 32, 26); + DrawSelector(x, selectorTop + 3, w, 32, 26, FOCUS_SMALL); - PrintText30Gold(279, 429, "OK"); - PrintText30Gold(378, 429, "Delete"); - PrintText30Gold(501, 429, "Cancel"); + DrawArtStr(279, 429, AFT_BIG, AFC_GOLD, "OK"); + DrawArtStr(378, 429, AFT_BIG, AFC_GOLD, "Delete"); + DrawArtStr(501, 429, AFT_BIG, AFC_GOLD, "Cancel"); } void selhero_Render_DifficultySelection() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); + DrawArt(30, 211, &ArtHero, heroInfo.heroclass); RenderStats(); char *GameOptions[3] = { "Normal", "Nightmare", "Hell" }; @@ -91,16 +91,16 @@ void selhero_Render_DifficultySelection() for (int i = 0; i < 3; i++) { y += 40; - PrintText16Silver(x, y, GameOptions[i]); + DrawArtStr(x, y, AFT_SMALL, AFC_SILVER, GameOptions[i]); } } void selhero_Render_GameType() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); + DrawArt(30, 211, &ArtHero, heroInfo.heroclass); RenderStats(); char *GameOptions[2] = { "New Game", "Load Game" }; @@ -111,25 +111,25 @@ void selhero_Render_GameType() for (int i = 0; i < 2; i++) { y += 40; - PrintText16Silver(x, y, GameOptions[i]); + DrawArtStr(x, y, AFT_SMALL, AFC_SILVER, GameOptions[i]); } } void selhero_Render_Name() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); + DrawArt(30, 211, &ArtHero, heroInfo.heroclass); RenderStats(); - PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre); + DrawArtStr(-1, 161, AFT_BIG, AFC_SILVER, "New Single Player Hero", JustCentre); int w = 369; int x = 241; int y = 318; - PrintText30Silver(x - 1, 211, "Enter Name", JustCentre, w); + DrawArtStr(x - 1, 211, AFT_BIG, AFC_SILVER, "Enter Name", JustCentre, w); DrawSelector(x, y - 2, w, 39, 26); @@ -137,31 +137,32 @@ void selhero_Render_Name() strcpy(lable, heroInfo.name); if (GetAnimationFrame(2, 500)) { lable[strlen(lable)] = '|'; + lable[strlen(lable) + 1] = '\0'; } - PrintText24Gold(x + 67, y, lable); // todo add blinking "|" + DrawArtStr(x + 67, y, AFT_MED, AFC_GOLD, lable); // todo add blinking "|" - PrintText30Gold(329, 429, "OK"); - PrintText30Gold(451, 429, "Cancel"); + DrawArtStr(329, 429, AFT_BIG, AFC_GOLD, "OK"); + DrawArtStr(451, 429, AFT_BIG, AFC_GOLD, "Cancel"); } // Have this load the function above and then render it in the main menu. // Cnacel box is also needed. void selhero_Render_ClassSelector() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); - RenderDiabloLogoSm(); + DrawArt(0, 0, &ArtBackground); + DrawLogo(); - DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, heroInfo.heroclass, pPcxHeroImage); + DrawArt(30, 211, &ArtHero, heroInfo.heroclass); RenderStats(); - PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre); + DrawArtStr(-1, 161, AFT_BIG, AFC_SILVER, "New Single Player Hero", JustCentre); int w = 369; int x = 241; int y = 285; - PrintText30Silver(x - 1, 211, "Choose Class", JustCentre, w); + DrawArtStr(x - 1, 211, AFT_BIG, AFC_SILVER, "Choose Class", JustCentre, w); char *heroclasses[3] = { "Warrior", "Rogue", "Sorcerer" }; @@ -171,7 +172,7 @@ void selhero_Render_ClassSelector() if (i > 1) { y += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items } - PrintText24Gold(x - 1, y, heroclasses[i], JustCentre, w); + DrawArtStr(x - 1, y, AFT_MED, AFC_GOLD, heroclasses[i], JustCentre, w); y += 33; } @@ -181,8 +182,8 @@ void selhero_Render_ClassSelector() DrawSelector(x, selectorTop - 2, w, 39, 33); - PrintText30Gold(329, 429, "OK"); - PrintText30Gold(451, 429, "Cancel"); + DrawArtStr(329, 429, AFT_BIG, AFC_GOLD, "OK"); + DrawArtStr(451, 429, AFT_BIG, AFC_GOLD, "Cancel"); } BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo) @@ -195,7 +196,7 @@ BOOL __stdcall SelHero_GetHeroInfo(_uiheroinfo *pInfo) void selhero_Loade(BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *))) { - LoadTitelArt("ui_art\\selhero.pcx"); + LoadBackgroundArt("ui_art\\selhero.pcx"); hero_infos.clear(); fninfo(ui_add_hero_info); @@ -209,8 +210,8 @@ void selhero_Loade(BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroin void selhero_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; } void selhero_setDefaultStats(BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *)) @@ -288,7 +289,7 @@ BOOL __stdcall UiSelHeroSingDialog( case SDLK_BACKSPACE: nameLen = strlen(heroInfo.name); if (nameLen > 0) { - heroInfo.name[nameLen-1] = '\0'; + heroInfo.name[nameLen - 1] = '\0'; } break; case SDLK_UP: @@ -338,11 +339,12 @@ BOOL __stdcall UiSelHeroSingDialog( } char letter = event.key.keysym.sym; - if (int(letter) > 96 && int(letter) < 123 || int(letter) == 32) + if (int(letter) > 96 && int(letter) < 123 || int(letter) == 32) { nameLen = strlen(heroInfo.name); if (nameLen < 15) { heroInfo.name[nameLen] = letter; } + } break; } break; @@ -403,7 +405,7 @@ BOOL __stdcall UiSelHeroMultDialog( } *dlgresult = EXIT_MENU; - return TRUE; + endMenu = true; case SDLK_UP: SelectedItem--; if (SelectedItem < 1) { diff --git a/Stub/DiabloUI/title.cpp b/Stub/DiabloUI/title.cpp index 7a64690a8..b22457959 100644 --- a/Stub/DiabloUI/title.cpp +++ b/Stub/DiabloUI/title.cpp @@ -2,21 +2,21 @@ void title_Render() { - DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage); + DrawArt(0, 0, &ArtBackground); - PrintText24Silver(-1, 410, "Copyright \xA9 1996-2001 Blizzard Entertainment", JustCentre); - RenderDiabloLogo(); + DrawArtStr(-1, 410, AFT_MED, AFC_SILVER, "Copyright \xA9 1996-2001 Blizzard Entertainment", JustCentre); + DrawLogo(182, LOGO_BIG); } void title_Loade() { - LoadTitelArt("ui_art\\title.pcx"); + LoadBackgroundArt("ui_art\\title.pcx"); } void title_Free() { - mem_free_dbg(pPcxTitleImage); - pPcxTitleImage = NULL; + mem_free_dbg(ArtBackground.data); + ArtBackground.data = NULL; } BOOL __stdcall UiTitleDialog(int a1) diff --git a/Stub/dx.cpp b/Stub/dx.cpp index 508c295e5..a2e6dada1 100644 --- a/Stub/dx.cpp +++ b/Stub/dx.cpp @@ -479,9 +479,7 @@ WINBOOL WINAPI SetCursorPos(int X, int Y) int WINAPI ShowCursor(WINBOOL bShow) { - if (window) { - SDL_ShowCursor(bShow ? SDL_ENABLE : SDL_DISABLE); - } + SDL_ShowCursor(bShow ? SDL_ENABLE : SDL_DISABLE); return bShow; } diff --git a/Stub/init.cpp b/Stub/init.cpp index b1b70113d..e9cae8b5f 100644 --- a/Stub/init.cpp +++ b/Stub/init.cpp @@ -91,6 +91,31 @@ void __fastcall init_create_window(int nCmdShow) DUMMY(); pfile_init_save_directory(); + atexit(SDL_Quit); + atexit(TTF_Quit); + SDL_Init(SDL_INIT_EVERYTHING); + + int flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + if (!fullscreen) { + flags = SDL_WINDOW_RESIZABLE; + } + window = SDL_CreateWindow("Diablo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, flags); + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC); + printf("Window And Renderer Created!\n"); + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); + SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); + + surface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); + assert(surface); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); + assert(texture); + + palette = SDL_AllocPalette(256); + + j_lock_buf_priv(0); //FIXME 0? dx_init(NULL); snd_init(NULL);