Browse Source

Split up menu code

pull/25/head
Anders Jenbo 7 years ago
parent
commit
c75d50a82c
  1. 33
      CMakeLists.txt
  2. 885
      Stub/DiabloUI/credits.cpp
  3. 228
      Stub/DiabloUI/diabloui.cpp
  4. 180
      Stub/DiabloUI/mainmenu.cpp
  5. 502
      Stub/DiabloUI/sdlrender.cpp
  6. 93
      Stub/DiabloUI/sdlrender.h
  7. 594
      Stub/DiabloUI/selhero.cpp
  8. 53
      Stub/DiabloUI/title.cpp
  9. 1032
      Stub/diabloui.cpp
  10. 81
      Stub/sdlrender.h
  11. 6
      enums.h
  12. 2
      types.h

33
CMakeLists.txt

@ -59,6 +59,7 @@ set(SOURCES
Source/drlg_l2.cpp
Source/drlg_l3.cpp
Source/drlg_l4.cpp
Source/dthread.cpp
Source/effects.cpp
Source/encrypt.cpp
Source/engine.cpp
@ -80,6 +81,7 @@ set(SOURCES
Source/msgcmd.cpp
Source/msg.cpp
Source/multi.cpp
Source/nthread.cpp
Source/objects.cpp
Source/pack.cpp
Source/palette.cpp
@ -104,8 +106,6 @@ set(SOURCES
Source/track.cpp
Source/trigs.cpp
Source/wave.cpp
Source/dthread.cpp
Source/nthread.cpp
3rdParty/PKWare/explode.cpp
3rdParty/PKWare/implode.cpp
@ -113,36 +113,41 @@ set(SOURCES
# Stubbed out sources, for reference
set(ORIGINAL_SOURCES
Source/capture.cpp
Source/appfat.cpp
Source/capture.cpp
Source/dx.cpp
Source/fault.cpp
Source/init.cpp
Source/logging.cpp
Source/movie.cpp
Source/restrict.cpp
Source/sound.cpp
Source/sound.cpp
)
set(STUB_SOURCES
Stub/miniwin.cpp
Stub/miniwin_rand.cpp
Stub/appfat.cpp
Stub/capture.cpp
Stub/dx.cpp
Stub/fault.cpp
Stub/init.cpp
Stub/miniwin.cpp
Stub/miniwin_io.cpp
Stub/miniwin_msg_sdl.cpp
Stub/miniwin_rand.cpp
Stub/miniwin_thread.cpp
Stub/movie.cpp
Stub/restrict.cpp
Stub/sound.cpp
Stub/storm.cpp
Stub/diabloui.cpp
Stub/miniwin_io.cpp
Stub/miniwin_msg_sdl.cpp
Stub/miniwin_thread.cpp
Stub/storm_net.cpp
# Stub/validate.cpp
Stub/sdlrender.cpp
Stub/storm_net.cpp
Stub/DiabloUI/credits.cpp
Stub/DiabloUI/diabloui.cpp
Stub/DiabloUI/mainmenu.cpp
Stub/DiabloUI/sdlrender.cpp
Stub/DiabloUI/selconn.cpp
Stub/DiabloUI/selhero.cpp
Stub/DiabloUI/title.cpp
3rdParty/StormLib/src/FileStream.cpp
3rdParty/StormLib/src/SBaseCommon.cpp
@ -154,7 +159,7 @@ set(STUB_SOURCES
3rdParty/StormLib/src/SFileGetFileInfo.cpp
3rdParty/StormLib/src/SFileOpenArchive.cpp
3rdParty/StormLib/src/SFileOpenFileEx.cpp
3rdParty/StormLib/src/SFileReadFile.cpp
3rdParty/StormLib/src/SFileReadFile.cpp
)
include_directories(${SDL2_INCLUDE_DIR}

885
Stub/sdlrender.cpp → Stub/DiabloUI/credits.cpp

@ -1,77 +1,13 @@
#include "../types.h"
#include "../../types.h"
int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;
#define CREDIT_LINES 13
int LogoWidth;
int LogoHeight;
bool TitleImageLoaded = false;
int SelectedItem = 1;
int TotalPlayers = 0;
void *pPcxLogoImage;
int gdwLogoWidth;
int gdwLogoHeight;
void *pPcxLogoSmImage;
int gdwLogoSmWidth;
int gdwLogoSmHeight;
int gdwTitleWidth;
int gdwTitleHeight;
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 HeroUndecidedName[17];
_uiheroinfo heroarray[10];
//////////////////////////////////////
// things I need to unload...
int bloaded = 0;
////////////////
// new vars
int gb_Lfont_str_len;
int gb_Lfont_pix_width;
int the_pcx_frame;
TTF_Font *font;
int creditLine;
int ybase;
int lastYbase;
int lineCount;
bool creditEnd;
char *the_long_credits[] = {
"Game Design",
@ -532,414 +468,52 @@ char *the_long_credits[] = {
NULL
};
int creditline = 0;
int ybase = 0;
int lastYbase = 0;
int lineCount = 13;
BOOL nottheend = TRUE;
/////////////////////////////////////////
PALETTEENTRY pcxPal[256];
void LoadPalInMem(PALETTEENTRY *pPal)
void credts_Loade()
{
int i;
for (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;
}
}
LoadTitelArt("ui_art\\credits.pcx");
BOOL LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data)
{
DWORD width;
DWORD height;
*pBuffer = NULL;
if (!SBmpLoadImage(pszFile, 0, 0, 0, &width, &height, 0))
return 0;
*pBuffer = SMemAlloc(height * width, "U:\\DiabloUI\\Ui\\local.cpp", 88, 0);
if (!SBmpLoadImage(pszFile, pcxPal, *pBuffer, height * width, 0, 0, 0))
return 0;
if (pBuffer && data) {
data[0] = width;
data[1] = height / frames;
}
return 1;
}
BOOL __stdcall SBmpLoadImage(const char *pszFileName, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp)
{
char *v7; // ebx
unsigned char *v8; // edi
PALETTEENTRY *v9; // esi
int v10; // esi
signed int v11; // ebx
int v12; // ebp
size_t v13; // ebp
unsigned char *v14; // eax
unsigned char *v15; // edx
int v16; // ebp
unsigned char v17; // cl
unsigned char v18; // al
int v19; // ecx
bool v20; // zf
bool v21; // sf
unsigned char(*v22)[3]; // eax
BYTE v23; // cl
unsigned char *Memory; // [esp+14h] [ebp-38Ch]
HANDLE hFile; // [esp+18h] [ebp-388h] MAPDST
DWORD v28; // [esp+1Ch] [ebp-384h]
PCXHeader pcxhdr; // [esp+20h] [ebp-380h]
unsigned char paldata[256][3]; // [esp+A0h] [ebp-300h]
int z;
if (pdwWidth)
*pdwWidth = 0;
if (dwHeight)
*dwHeight = 0;
if (pdwBpp)
*pdwBpp = 0;
v7 = (char *)pszFileName;
if (pszFileName) {
if (*pszFileName) {
v8 = (unsigned char *)pBuffer;
if (!pBuffer || dwBuffersize) {
v9 = pPalette;
if (pPalette || pBuffer || pdwWidth || dwHeight) {
if (SFileOpenFile(pszFileName, &hFile)) {
if (strchr(pszFileName, 92)) {
do
v7 = strchr(v7, 92) + 1;
while (strchr(v7, 92));
}
for (; strchr(v7 + 1, 46); v7 = strchr(v7, 46))
;
if (!v7 || _strcmpi(v7, ".pcx")) // omit all types except PCX
{
return 0;
//v10 = sub_15001C70(hFile, pPalette, pBuffer, dwBuffersize, pdwWidth, dwHeight, pdwBpp);
//goto LABEL_51;
}
if (!SFileReadFile(hFile, &pcxhdr, 128u, 0, 0)) {
v10 = 0;
LABEL_51:
SFileCloseFile(hFile);
return v10;
}
*(_DWORD *)&paldata[0][0] = pcxhdr.xmax - pcxhdr.xmin + 1;
v11 = pcxhdr.ymax - pcxhdr.ymin + 1;
v28 = pcxhdr.bitsPerPixel;
if (pdwWidth)
*pdwWidth = *(_DWORD *)&paldata[0][0];
if (dwHeight)
*dwHeight = v11;
if (pdwBpp)
*pdwBpp = v28;
if (!pBuffer) {
SFileSetFilePointer(hFile, 0, 0, 2);
goto LABEL_45;
}
v12 = SFileGetFileSize(hFile, 0);
v13 = v12 - SFileSetFilePointer(hFile, 0, 0, 1);
v14 = (unsigned char *)SMemAlloc(v13, "SBMP.CPP", 171, 0);
Memory = v14;
if (!v14) {
LABEL_45:
if (pPalette && v28 == 8) {
SFileSetFilePointer(hFile, -768, 0, 1);
SFileReadFile(hFile, paldata, 768u, 0, 0);
v22 = paldata;
for (z = 0; z < 256; z++) {
v23 = *(_BYTE *)v22;
++v9;
++v22;
v9[-1].peRed = v23;
v9[-1].peGreen = (*v22)[-2];
v9[-1].peBlue = (*v22)[-1];
v9[-1].peFlags = 0;
}
}
v10 = 1;
goto LABEL_51;
}
SFileReadFile(hFile, v14, v13, 0, 0);
v15 = Memory;
if (v11 <= 0)
goto LABEL_43;
LABEL_33:
v16 = *(_DWORD *)&paldata[0][0];
while (1) {
v17 = *v15++;
if (v17 < 0xC0u) {
*v8++ = v17;
--v16;
} else {
v18 = *v15;
v19 = v17 & 0x3F;
++v15;
for (; v19; --v16) {
v20 = v16 == 0;
v21 = v16 < 0;
if (!v16)
goto LABEL_41;
*v8++ = v18;
--v19;
}
}
v20 = v16 == 0;
v21 = v16 < 0;
LABEL_41:
if (v21 || v20) {
if (!--v11) {
LABEL_43:
SMemFree(Memory, "SBMP.CPP", 178, 0);
goto LABEL_45;
}
goto LABEL_33;
}
}
}
}
}
}
}
return 0;
}
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);
window = SDL_CreateWindow("Diablo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
printf("Window And Renderer Created!\n");
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, 640, 480);
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 = NULL)
{
BYTE *src = (BYTE *)pBuffer + (SW * SH * nFrame);
BYTE *dst = (BYTE *)&gpBuffer->row[SY].pixels[SX];
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 (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;
if (!TTF_WasInit() && TTF_Init() == -1) {
printf("TTF_Init: %s\n", TTF_GetError());
exit(1);
}
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 LoadTitelArt(char *pszFile)
{
DWORD dwData[2];
if (TitleImageLoaded) {
// TODO locate font dynamically, and use fallback font if missing
font = TTF_OpenFont("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf", 17);
if (font == NULL) {
printf("TTF_OpenFont: %s\n", TTF_GetError());
return;
}
LoadArtImage(pszFile, &pPcxTitleImage, 1, dwData);
LoadPalInMem(pcxPal);
ApplyGamma(logical_palette, orig_palette, 256);
gdwTitleWidth = dwData[0];
gdwTitleHeight = dwData[1];
TitleImageLoaded = true;
TTF_SetFontKerning(font, FALSE);
TTF_SetFontHinting(font, TTF_HINTING_MONO);
}
int GetAnimationFrame(int frames, int fps = 60)
void credts_Free()
{
int frame = (SDL_GetTicks() / fps) % frames;
return frame > frames ? 0 : frame;
mem_free_dbg(pPcxTitleImage);
pPcxTitleImage = NULL;
mem_free_dbg(font);
font = NULL;
}
int fadeValue = 0;
void UiFadeIn(int steps = 10)
void credts_Render()
{
if (fadeValue < 256) {
fadeValue += steps;
if (fadeValue > 256) {
fadeValue = 256;
}
}
SetFadeLevel(fadeValue);
}
void UiFadeOut(int steps = 20)
{
if (fadeValue > 0) {
fadeValue -= steps;
if (fadeValue < 0) {
fadeValue = 0;
}
}
SetFadeLevel(fadeValue);
}
TTF_Font *font;
BOOL ShowCredts()
{
if (!TitleImageLoaded) {
// TODO locate font dynamically, and use fallback font if missing
font = TTF_OpenFont("/usr/share/fonts/truetype/msttcorefonts/Times_New_Roman_Bold.ttf", 17);
if (font == NULL) {
printf("TTF_OpenFont: %s\n", TTF_GetError());
} else {
TTF_SetFontKerning(font, FALSE);
TTF_SetFontHinting(font, TTF_HINTING_MONO);
}
LoadTitelArt("ui_art\\credits.pcx");
}
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
int lineHeight = 22;
ybase = GetAnimationFrame(lineHeight, 40);
if (lastYbase != ybase && ybase == 0) {
if (!nottheend) {
if (creditEnd) {
lineCount--;
creditline++;
} else if (the_long_credits[creditline + 13] == NULL) {
nottheend = FALSE;
} else
creditline++;
creditLine++;
} else {
if (the_long_credits[creditLine + CREDIT_LINES + 1] == NULL) {
creditEnd = true;
}
creditLine++;
}
}
lastYbase = ybase;
@ -947,19 +521,19 @@ BOOL ShowCredts()
SDL_Color color = palette->colors[224];
SDL_Surface *text_surface;
for (int i = 0; i < lineCount; i++) {
if (creditline + i < 0) {
if (creditLine + i < 0) {
continue;
}
int offset = 0;
int x = 31;
int y = (i * lineHeight) - ybase - lineHeight;
if (*the_long_credits[creditline + i] == ' ') {
if (*the_long_credits[creditLine + i] == ' ') {
offset = 1;
x += 40;
}
if (text_surface = TTF_RenderUTF8_Solid(font, the_long_credits[creditline + i] + offset, color)) {
if (text_surface = TTF_RenderUTF8_Solid(font, the_long_credits[creditLine + i] + offset, color)) {
SDL_Rect src_rect = { 0, -y, 640, 251 };
SDL_Rect dsc_rect = { 64 + x, 160 + 114, 640, 480 };
SDL_BlitSurface(text_surface, &src_rect, pal_surface, &dsc_rect);
@ -967,376 +541,41 @@ BOOL ShowCredts()
}
}
}
if (lineCount <= 0) {
UiFadeOut();
} else {
UiFadeIn();
}
if (lineCount <= 0 && !fadeValue) {
return false;
}
return true;
}
///////////////////////////Renders
void AnimateDiabloLogo(int t, int w, int h, void *pBuffer)
BOOL __stdcall UiCreditsDialog(int a1)
{
BYTE mask = 250;
int frame = GetAnimationFrame(15);
credts_Loade();
DrawArtImage(GetCenterOffset(w), t, w, h, frame, pBuffer, &mask);
}
creditEnd = false;
lineCount = CREDIT_LINES;
creditLine = -lineCount;
lastYbase = 0;
bool endMenu = false;
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);
}
void RenderDiabloSplashPage()
{
LoadTitelArt("ui_art\\title.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
PrintText24Silver(-1, 410, "Copyright \xA9 1996-2001 Blizzard Entertainment", JustCentre);
RenderDiabloLogo();
UiFadeIn();
}
void RenderDiabloMainPage(char *name)
{
char *pszFile = "ui_art\\mainmenu.pcx";
if (false) //DiabloUI_GetSpawned()
pszFile = "ui_art\\swmmenu.pcx";
LoadTitelArt(pszFile);
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
// scrollrt_draw_cursor_back_buffer(); // Doesn't work?
RenderDiabloLogoSm();
int menuTop = 192;
char *MENIITEMS[5] = { "Single Player", "Multi Player", "Replay Intro", "Show Credits", "Exit Diablo" };
for (int i = 0; i < 5; i++) {
int y = menuTop + i * 43;
if (i > 1) {
y -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items
}
PrintText42Gold(-1, y, MENIITEMS[i], 1);
}
int selectorTop = menuTop;
if (SelectedItem > 2) {
selectorTop -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items
}
DrawSelector42(0, selectorTop, 0, 85, 43);
PrintText16Silver(17, 444, name);
DrawMouse();
UiFadeIn();
}
void RenderStats(char *lvl, char *str, char *mag, char *dex, char *vit)
{
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);
}
void RenderDiabloSinglePlayerPage()
{
LoadTitelArt("ui_art\\selhero.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 3, pPcxHeroImage);
PrintText30Silver(-1, 161, "Single Player Characters", JustCentre);
int w = 369;
int x = 241;
PrintText30Silver(x - 1, 211, "Select Hero", JustCentre, w);
int selectorTop = 256;
int y = selectorTop;
for (int i = 0; i < 0; i++) {
PrintText24Gold(x - 1, y, "Hero name", JustCentre, w);
y += 26;
}
PrintText24Gold(x - 1, y, "New Hero", JustCentre, w);
DrawSelector16(x, selectorTop + 3, w, 32, 26);
RenderStats("-", "-", "-", "-", "-");
PrintText30Gold(279, 429, "OK");
PrintText30Gold(378, 429, "Delete");
PrintText30Gold(501, 429, "Cancel");
DrawMouse();
UiFadeIn();
}
void RenderDefaultStats(int HeroClass)
{
switch (HeroClass) {
case UI_WARRIOR:
RenderStats("1", "30", "10", "20", "25");
break;
case UI_ROGUE:
RenderStats("1", "20", "15", "30", "20");
break;
case UI_SORCERER:
RenderStats("1", "15", "35", "15", "20");
break;
}
}
void SetHeroStats(_uiheroinfo *a1)
{
memcpy(&heroarray[TotalPlayers], a1, sizeof(_uiheroinfo));
}
void LoadHeroStats()
{
pfile_ui_set_hero_infos(SetHeroStats);
}
// Have this load the function above and then render it in the main menu.
// Cnacel box is also needed.
void CreateHeroMenu()
{
LoadTitelArt("ui_art\\selhero.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, SelectedItem - 1, pPcxHeroImage);
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 285;
PrintText30Silver(x - 1, 211, "Choose Class", JustCentre, w);
RenderDefaultStats(SelectedItem - 1);
char *heroclasses[3] = { "Warrior", "Rogue", "Sorcerer" };
int selectorTop = y;
for (int i = 0; i < 3; i++) {
if (i > 1) {
y += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
PrintText24Gold(x - 1, y, heroclasses[i], JustCentre, w);
y += 33;
}
if (SelectedItem > 1) {
selectorTop += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
DrawSelector(x, selectorTop - 2, w, 39, 33);
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "Cancel");
DrawMouse();
UiFadeIn();
}
void RenderUndecidedHeroName(int HeroClass)
{
LoadTitelArt("ui_art\\selhero.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage);
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 318;
PrintText30Silver(x - 1, 211, "Enter Name", JustCentre, w);
RenderDefaultStats(HeroClass);
DrawSelector(x, y - 2, w, 39, 26);
PrintText24Gold(x + 67, y, (char *)HeroUndecidedName); // todo add blinking "|"
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "Cancel");
DrawMouse();
UiFadeIn();
}
void DrawPreGameOptions(int HeroClass, int ShowClasses)
{
LoadTitelArt("ui_art\\selhero.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage);
char *GameOptions[2] = { "New Game", "Load Game" };
SDL_Event event;
while (1) {
credts_Render();
// this should not be hard coded.
int x = 280;
int y = 256;
if (ShowClasses == 1) {
for (int i = 0; i < 2; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN:
endMenu = true;
break;
case SDL_QUIT:
exit(0);
}
}
}
RenderDefaultStats(HeroClass);
DrawMouse();
UiFadeIn();
}
void DrawPreGameDifficultySelection(int HeroClass, int ShowClasses)
{
LoadTitelArt("ui_art\\selhero.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage);
RenderStats("1", "30", "10", "20", "25");
char *GameOptions[3] = { "Normal", "Nightmare", "Hell" };
// this should not be hard coded.
int x = 280;
int y = 256;
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage);
if (ShowClasses == 1) {
for (int i = 0; i < 3; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
if (!endMenu && lineCount > 0) {
UiFadeIn();
} else if (UiFadeOut()) {
break;
}
}
RenderDefaultStats(HeroClass);
DrawMouse();
UiFadeIn();
}
void DrawSelMultiConnection()
{
LoadTitelArt("ui_art\\selgame.pcx");
DrawArtImage(0, 0, gdwTitleWidth, gdwTitleHeight, 0, pPcxTitleImage);
RenderDiabloLogoSm();
PrintText30Silver(-1, 161, "Multi Player Game", JustCentre);
int w = 334;
int x = 280;
int y = 261;
PrintText30Silver(x, 211, "Select Connection", JustCentre, w);
char *connections[3] = { "Local Area Network (IPC)", "Modem", "Direct Cable Connection" };
int selectorTop = y;
for (int i = 0; i < 3; i++) {
PrintText16Gold(x - 1, y, connections[i], JustCentre, w);
y += 26;
}
DrawSelector16(x, selectorTop - 2, w, 35, 26);
PrintText16Silver(35, 218, "Players Supported: 4");
PrintText16Silver(35, 256, "Requirements:");
// TODO need a word wrap function
PrintText16Silver(35, 275, "All computers must be");
PrintText16Silver(35, 291, "connected to an");
PrintText16Silver(35, 307, "IPX-compatible network.");
PrintText24Silver(26, 356, "no gateway needed", JustCentre, 226);
PrintText30Gold(349, 429, "OK");
PrintText30Gold(476, 429, "Cancel");
credts_Free();
DrawMouse();
UiFadeIn();
return TRUE;
}

228
Stub/DiabloUI/diabloui.cpp

@ -0,0 +1,228 @@
#include "../../types.h"
char hero_names[MAX_CHARACTERS][PLR_NAME_LEN];
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;
void __cdecl UiDestroy()
{
DUMMY();
FreeMenuItems();
}
void LoadCharNamesintoMemory()
{
PkPlayerStruct pkplr;
HANDLE CharFile;
char *p_hero_names = *hero_names; // Not sure if this is correct
memset(hero_names, 0, 0x140u);
for (int i = 0; i < MAX_CHARACTERS; i++) {
CharFile = pfile_open_save_archive(NULL, i);
if (CharFile) {
if (pfile_read_hero(CharFile, &pkplr)) {
strcpy(p_hero_names, pkplr.pName);
UnPackPlayer(&pkplr, 0, 0);
pfile_archive_contains_game(CharFile, 0); // FIXME: what is the second argument?
}
pfile_SFileCloseArchive(CharFile);
}
p_hero_names += PLR_NAME_LEN;
}
// memcpy(shero_names, hero_names, sizeof(hero_names));
}
void SetMenu(int MenuId)
{
effects_play_sound("sfx\\items\\titlslct.wav");
submenu = MenuId;
SelectedItem = 1;
SelectedItemMax = MenuItem[MenuId];
}
bool IsInsideRect(const SDL_Event *event, const SDL_Rect *rect)
{
const SDL_Point point = { event->button.x, event->button.y };
return SDL_PointInRect(&point, rect);
}
void InitHiracy()
{
MenuItem[SINGLEPLAYER_CLASSES] = 3;
MenuItem[MULTIPLAYER_CONNECTIONS] = 3;
MenuItem[MULTIPLAYER_LOBBY] = 2;
MenuItem[MULTIPLAYER_DIFFICULTY] = 3;
MenuItem[MULTIPLAYER_BNET_GATEWAYS] = 3;
PreviousItem[SINGLEPLAYER_CLASSES] = SINGLEPLAYER_LOAD;
PreviousItem[SINGLEPLAYER_NAME] = SINGLEPLAYER_CLASSES;
PreviousItem[MULTIPLAYER_CONNECTIONS] = MAINMENU;
PreviousItem[MULTIPLAYER_DIFFICULTY] = MULTIPLAYER_LOBBY;
PreviousItem[MULTIPLAYER_BNET_GATEWAYS] = MULTIPLAYER_CONNECTIONS;
PreviousItem[MULTIPLAYER_ERROR] = MAINMENU;
}
void LoadUiGFX()
{
DWORD dwData[2];
LoadArtImage("ui_art\\focus16.pcx", &MenuPentegram16, 8, NULL);
LoadArtImage("ui_art\\focus.pcx", &MenuPentegram, 8, NULL);
LoadArtImage("ui_art\\focus42.pcx", &MenuPentegram42, 8, NULL);
LoadArtImage("ui_art\\cursor.pcx", &pPcxCursorImage, 1, dwData);
gdwCursorWidth = dwData[0];
gdwCursorHeight = dwData[1];
LoadArtImage("ui_art\\logo.pcx", &pPcxLogoImage, 15, dwData);
gdwLogoWidth = dwData[0];
gdwLogoHeight = dwData[1];
LoadArtImage("ui_art\\smlogo.pcx", &pPcxLogoSmImage, 15, dwData);
gdwLogoSmWidth = dwData[0];
gdwLogoSmHeight = dwData[1];
LoadArtImage("ui_art\\heros.pcx", &pPcxHeroImage, 4, dwData);
gdwHeroWidth = dwData[0];
gdwHeroHeight = dwData[1];
pFont16 = LoadFileInMem("ui_art\\font16.bin", 0);
LoadArtImage("ui_art\\font16s.pcx", &pPcxFont16sImage, 256, NULL);
LoadArtImage("ui_art\\font16g.pcx", &pPcxFont16gImage, 256, dwData);
gdwFont16Width = dwData[0];
gdwFont16Height = dwData[1];
pFont24 = LoadFileInMem("ui_art\\font24.bin", 0);
LoadArtImage("ui_art\\font24s.pcx", &pPcxFont24sImage, 256, NULL);
LoadArtImage("ui_art\\font24g.pcx", &pPcxFont24gImage, 256, dwData);
gdwFont24Width = dwData[0];
gdwFont24Height = dwData[1];
pFont30 = LoadFileInMem("ui_art\\font30.bin", 0);
LoadArtImage("ui_art\\font30s.pcx", &pPcxFont30sImage, 256, NULL);
LoadArtImage("ui_art\\font30g.pcx", &pPcxFont30gImage, 256, dwData);
gdwFont30Width = dwData[0];
gdwFont30Height = dwData[1];
pFont42 = LoadFileInMem("ui_art\\font42.bin", 0);
LoadArtImage("ui_art\\font42g.pcx", &pPcxFont42gImage, 256, dwData);
gdwFont42Width = dwData[0];
gdwFont42Height = dwData[1];
}
void UiInitialize()
{
InitHiracy();
LoadUiGFX();
if (!window) {
SdlDiabloMainWindow();
}
ShowCursor(FALSE);
LoadHeroStats();
LoadCharNamesintoMemory();
}
int __cdecl UiProfileGetString()
{
DUMMY();
return 0;
}
void __stdcall UiSetupPlayerInfo(char *infostr, _uiheroinfo *pInfo, int type)
{
DUMMY_PRINT("chr: %s", infostr);
}
BOOL __stdcall UiCopyProtError(int *pdwResult)
{
UNIMPLEMENTED();
}
void __stdcall UiAppActivate(BOOL bActive)
{
UNIMPLEMENTED();
}
BOOL __fastcall UiValidPlayerName(char *name)
{
UNIMPLEMENTED();
}
int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5)
{
UNIMPLEMENTED();
}
void __cdecl UiProfileCallback()
{
UNIMPLEMENTED();
}
void __cdecl UiProfileDraw()
{
UNIMPLEMENTED();
}
BOOL __stdcall UiCategoryCallback(int a1, int a2, int a3, int a4, int a5, _DWORD *a6, _DWORD *a7)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiGetDataCallback(int game_type, int data_code, void *a3, int a4, int a5)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiAuthCallback(int a1, char *a2, char *a3, char a4, char *a5, LPSTR lpBuffer, int cchBufferMax)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiSoundCallback(int a1, int type, int a3)
{
UNIMPLEMENTED();
}
void __stdcall UiMessageBoxCallback(HWND hWnd, char *lpText, LPCSTR lpCaption, UINT uType)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiDrawDescCallback(int arg0, COLORREF color, LPCSTR lpString, char *a4, int a5, UINT align, time_t a7,
HDC *a8)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiCreateGameCallback(int a1, int a2, int a3, int a4, int a5, int a6)
{
UNIMPLEMENTED();
}
BOOL __stdcall UiArtCallback(int game_type, unsigned int art_code, PALETTEENTRY *pPalette, void *pBuffer,
DWORD dwBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp)
{
UNIMPLEMENTED();
}
int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info,
_SNETVERSIONDATA *file_info, int *playerId)
{
DUMMY();
*playerId = 0;
return 1;
}
int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc)
{
UNIMPLEMENTED();
}

180
Stub/DiabloUI/mainmenu.cpp

@ -0,0 +1,180 @@
#include "../../types.h"
void mainmenu_Render(char *name)
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
// scrollrt_draw_cursor_back_buffer(); // Doesn't work?
RenderDiabloLogoSm();
int menuTop = 192;
char *MENIITEMS[5] = { "Single Player", "Multi Player", "Replay Intro", "Show Credits", "Exit Diablo" };
for (int i = 0; i < 5; i++) {
int y = menuTop + i * 43;
if (i > 1) {
y -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items
}
PrintText42Gold(-1, y, MENIITEMS[i], 1);
}
int selectorTop = menuTop;
if (SelectedItem > 2) {
selectorTop -= 1; // "Multi Player" and "Replay Intro" has a smaller gap then other items
}
DrawSelector42(0, selectorTop, 0, 85, 43);
PrintText16Silver(17, 444, name);
DrawMouse();
UiFadeIn();
}
void mainmenu_Loade()
{
char *pszFile = "ui_art\\mainmenu.pcx";
if (false) //DiabloUI_GetSpawned()
pszFile = "ui_art\\swmmenu.pcx";
LoadTitelArt(pszFile);
}
void mainmenu_Free()
{
mem_free_dbg(pPcxTitleImage);
pPcxTitleImage = NULL;
}
BOOL __stdcall UiMainMenuDialog(char *name, int *pdwResult, void(__stdcall *fnSound)(char *file), int a4)
{
mainmenu_Loade();
SelectedItem = 1;
SelectedItemMax = 5;
SDL_Event event;
int ItemHeight = 42;
SDL_Rect SinglePlayer = { 0, 191, 515, ItemHeight };
SinglePlayer.x = GetCenterOffset(SinglePlayer.w);
SDL_Rect MultiPlayer = SinglePlayer;
MultiPlayer.y += ItemHeight * 1 + 1;
SDL_Rect ReplayIntro = MultiPlayer;
ReplayIntro.y += ItemHeight * 2 + 0;
SDL_Rect ShowCredits = ReplayIntro;
ShowCredits.y += ItemHeight * 3 + 1;
SDL_Rect ExitDiablo = ShowCredits;
ExitDiablo.y += ItemHeight * 4 + 1;
bool endMenu = false;
while (1) {
mainmenu_Render(name);
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_UP:
SelectedItem--;
if (SelectedItem < MAINMENU_SINGLE_PLAYER) {
SelectedItem = SelectedItemMax;
}
fnSound("sfx\\items\\titlemov.wav");
break;
case SDLK_DOWN:
SelectedItem++;
if (SelectedItem > SelectedItemMax) {
SelectedItem = MAINMENU_SINGLE_PLAYER;
}
fnSound("sfx\\items\\titlemov.wav");
break;
case SDLK_ESCAPE:
*pdwResult = MAINMENU_EXIT_DIABLO;
fnSound("sfx\\items\\titlslct.wav");
Sleep(250); // Wait for soudn to play
endMenu = true;
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
case SDLK_SPACE:
switch (SelectedItem) {
case MAINMENU_SINGLE_PLAYER:
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_SINGLE_PLAYER;
endMenu = true;
break;
case MAINMENU_MULTIPLAYER:
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_MULTIPLAYER;
endMenu = true;
break;
case MAINMENU_REPLAY_INTRO:
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_REPLAY_INTRO;
endMenu = true;
break;
case MAINMENU_SHOW_CREDITS:
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_SHOW_CREDITS;
endMenu = true;
break;
case MAINMENU_EXIT_DIABLO:
fnSound("sfx\\items\\titlslct.wav");
Sleep(250); // Wait for sound to play
*pdwResult = MAINMENU_EXIT_DIABLO;
endMenu = true;
break;
}
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
if (IsInsideRect(&event, &SinglePlayer)) {
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_SINGLE_PLAYER;
endMenu = true;
break;
} else if (IsInsideRect(&event, &MultiPlayer)) {
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_MULTIPLAYER;
endMenu = true;
break;
} else if (IsInsideRect(&event, &ReplayIntro)) {
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_REPLAY_INTRO;
endMenu = true;
break;
} else if (IsInsideRect(&event, &ShowCredits)) {
fnSound("sfx\\items\\titlslct.wav");
*pdwResult = MAINMENU_SHOW_CREDITS;
endMenu = true;
break;
} else if (IsInsideRect(&event, &ExitDiablo)) {
fnSound("sfx\\items\\titlslct.wav");
Sleep(250); // Wait for soudn to play
*pdwResult = MAINMENU_EXIT_DIABLO;
endMenu = true;
break;
}
}
break;
case SDL_QUIT:
*pdwResult = MAINMENU_EXIT_DIABLO;
endMenu = true;
break;
}
}
if (!endMenu) {
UiFadeIn();
} else if (UiFadeOut()) {
break;
}
}
mainmenu_Free();
return TRUE;
}

502
Stub/DiabloUI/sdlrender.cpp

@ -0,0 +1,502 @@
#include "../../types.h"
int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;
int LogoWidth;
int LogoHeight;
int fadeValue = 0;
int SelectedItem = 1;
int TotalPlayers = 0;
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 HeroUndecidedName[17];
_uiheroinfo heroarray[10];
bool LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data, PALETTEENTRY *pPalette = NULL)
{
DWORD width;
DWORD height;
*pBuffer = NULL;
if (!SBmpLoadImage(pszFile, 0, 0, 0, &width, &height, 0))
return 0;
*pBuffer = SMemAlloc(height * width, "U:\\DiabloUI\\Ui\\local.cpp", 88, 0);
if (!SBmpLoadImage(pszFile, pPalette, *pBuffer, height * width, 0, 0, 0))
return 0;
if (pBuffer && data) {
data[0] = width;
data[1] = height / frames;
}
return 1;
}
BOOL __stdcall SBmpLoadImage(const char *pszFileName, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp)
{
char *v7; // ebx
unsigned char *v8; // edi
PALETTEENTRY *v9; // esi
int v10; // esi
signed int v11; // ebx
int v12; // ebp
size_t v13; // ebp
unsigned char *v14; // eax
unsigned char *v15; // edx
int v16; // ebp
unsigned char v17; // cl
unsigned char v18; // al
int v19; // ecx
bool v20; // zf
bool v21; // sf
unsigned char(*v22)[3]; // eax
BYTE v23; // cl
unsigned char *Memory; // [esp+14h] [ebp-38Ch]
HANDLE hFile; // [esp+18h] [ebp-388h] MAPDST
DWORD v28; // [esp+1Ch] [ebp-384h]
PCXHeader pcxhdr; // [esp+20h] [ebp-380h]
unsigned char paldata[256][3]; // [esp+A0h] [ebp-300h]
int z;
if (pdwWidth)
*pdwWidth = 0;
if (dwHeight)
*dwHeight = 0;
if (pdwBpp)
*pdwBpp = 0;
v7 = (char *)pszFileName;
if (pszFileName) {
if (*pszFileName) {
v8 = (unsigned char *)pBuffer;
if (!pBuffer || dwBuffersize) {
v9 = pPalette;
if (pPalette || pBuffer || pdwWidth || dwHeight) {
if (SFileOpenFile(pszFileName, &hFile)) {
if (strchr(pszFileName, 92)) {
do
v7 = strchr(v7, 92) + 1;
while (strchr(v7, 92));
}
for (; strchr(v7 + 1, 46); v7 = strchr(v7, 46))
;
if (!v7 || _strcmpi(v7, ".pcx")) // omit all types except PCX
{
return 0;
//v10 = sub_15001C70(hFile, pPalette, pBuffer, dwBuffersize, pdwWidth, dwHeight, pdwBpp);
//goto LABEL_51;
}
if (!SFileReadFile(hFile, &pcxhdr, 128u, 0, 0)) {
v10 = 0;
LABEL_51:
SFileCloseFile(hFile);
return v10;
}
*(_DWORD *)&paldata[0][0] = pcxhdr.xmax - pcxhdr.xmin + 1;
v11 = pcxhdr.ymax - pcxhdr.ymin + 1;
v28 = pcxhdr.bitsPerPixel;
if (pdwWidth)
*pdwWidth = *(_DWORD *)&paldata[0][0];
if (dwHeight)
*dwHeight = v11;
if (pdwBpp)
*pdwBpp = v28;
if (!pBuffer) {
SFileSetFilePointer(hFile, 0, 0, 2);
goto LABEL_45;
}
v12 = SFileGetFileSize(hFile, 0);
v13 = v12 - SFileSetFilePointer(hFile, 0, 0, 1);
v14 = (unsigned char *)SMemAlloc(v13, "SBMP.CPP", 171, 0);
Memory = v14;
if (!v14) {
LABEL_45:
if (pPalette && v28 == 8) {
SFileSetFilePointer(hFile, -768, 0, 1);
SFileReadFile(hFile, paldata, 768u, 0, 0);
v22 = paldata;
for (z = 0; z < 256; z++) {
v23 = *(_BYTE *)v22;
++v9;
++v22;
v9[-1].peRed = v23;
v9[-1].peGreen = (*v22)[-2];
v9[-1].peBlue = (*v22)[-1];
v9[-1].peFlags = 0;
}
}
v10 = 1;
goto LABEL_51;
}
SFileReadFile(hFile, v14, v13, 0, 0);
v15 = Memory;
if (v11 <= 0)
goto LABEL_43;
LABEL_33:
v16 = *(_DWORD *)&paldata[0][0];
while (1) {
v17 = *v15++;
if (v17 < 0xC0u) {
*v8++ = v17;
--v16;
} else {
v18 = *v15;
v19 = v17 & 0x3F;
++v15;
for (; v19; --v16) {
v20 = v16 == 0;
v21 = v16 < 0;
if (!v16)
goto LABEL_41;
*v8++ = v18;
--v19;
}
}
v20 = v16 == 0;
v21 = v16 < 0;
LABEL_41:
if (v21 || v20) {
if (!--v11) {
LABEL_43:
SMemFree(Memory, "SBMP.CPP", 178, 0);
goto LABEL_45;
}
goto LABEL_33;
}
}
}
}
}
}
}
return 0;
}
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);
window = SDL_CreateWindow("Diablo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
printf("Window And Renderer Created!\n");
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, 640, 480);
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 = NULL)
{
BYTE *src = (BYTE *)pBuffer + (SW * SH * nFrame);
BYTE *dst = (BYTE *)&gpBuffer->row[SY].pixels[SX];
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 (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;
}
void UiFadeIn(int steps)
{
if (fadeValue < 256) {
fadeValue += steps;
if (fadeValue > 256) {
fadeValue = 256;
}
}
SetFadeLevel(fadeValue);
return fadeValue == 256;
}
bool UiFadeOut(int steps)
{
if (fadeValue > 0) {
fadeValue -= 256 / steps;
if (fadeValue < 0) {
fadeValue = 0;
}
}
SetFadeLevel(fadeValue);
return fadeValue == 0;
}
///////////////////////////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);
}
void SetHeroStats(_uiheroinfo *a1)
{
memcpy(&heroarray[TotalPlayers], a1, sizeof(_uiheroinfo));
}
void LoadHeroStats()
{
pfile_ui_set_hero_infos(SetHeroStats);
}

93
Stub/DiabloUI/sdlrender.h

@ -0,0 +1,93 @@
#pragma once
#include "../../types.h"
extern unsigned char *pFont16;
extern int gdwFont16Width;
extern int gdwFont16Height;
extern void *pPcxFont16sImage;
extern void *pPcxFont16gImage;
extern unsigned char *pFont24;
extern int gdwFont24Width;
extern int gdwFont24Height;
extern void *pPcxFont24sImage;
extern void *pPcxFont24gImage;
extern unsigned char *pFont30;
extern int gdwFont30Width;
extern int gdwFont30Height;
extern void *pPcxFont30sImage;
extern void *pPcxFont30gImage;
extern unsigned char *pFont42;
extern int gdwFont42Width;
extern int gdwFont42Height;
extern void *pPcxFont42gImage;
extern void *pPcxLogoImage;
extern int gdwLogoWidth;
extern int gdwLogoHeight;
extern void *pPcxLogoSmImage;
extern int gdwLogoSmWidth;
extern int gdwLogoSmHeight;
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 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;
typedef enum TXT_JUST {
JustLeft = 0,
JustCentre = 1,
JustRight = 2,
} TXT_JUST;
bool IsInsideRect(const SDL_Event *event, const SDL_Rect *rect);
bool LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data, PALETTEENTRY *pPalette = NULL);
bool UiFadeOut(int steps = 5);
int GetAnimationFrame(int frames, int fps = 60);
int GetCenterOffset(int w, int bw = 0);
void DrawArtImage(int SX, int SY, int SW, int SH, int nFrame, void *pBuffer, BYTE *bMask = NULL);
void DrawMouse();
void DrawSelector16(int x, int y, int width, int padding, int spacing);
void DrawSelector42(int x, int y, int width, int padding, int spacing);
void DrawSelector(int x, int y, int width, int padding, int spacing);
void FreeMenuItems();
void LoadHeroStats();
void LoadTitelArt(char *pszFile);
void PrintText16Silver(int x, int y, char *text, TXT_JUST align = JustLeft, int bw = 0);
void PrintText16Gold(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 SetMenu(int MenuId);
void UiFadeIn(int steps = 10);

594
Stub/DiabloUI/selhero.cpp

@ -0,0 +1,594 @@
#include "../../types.h"
int HeroChosen = 0;
bool StartNewGame = false;
bool timestart = false;
bool CreateSinglePlayerChar = false;
char chr_name_str[16];
int NewHeroNameIndex = 0;
static std::vector<_uiheroinfo> hero_infos;
static BOOL __stdcall ui_add_hero_info(_uiheroinfo *info)
{
hero_infos.emplace_back(*info);
return TRUE;
}
void RenderStats(char *lvl, char *str, char *mag, char *dex, char *vit)
{
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);
}
void RenderDefaultStats(int HeroClass)
{
switch (HeroClass) {
case UI_WARRIOR:
RenderStats("1", "30", "10", "20", "25");
break;
case UI_ROGUE:
RenderStats("1", "20", "15", "30", "20");
break;
case UI_SORCERER:
RenderStats("1", "15", "35", "15", "20");
break;
}
}
void selhero_Render()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 3, pPcxHeroImage);
PrintText30Silver(-1, 161, "Single Player Characters", JustCentre);
int w = 369;
int x = 241;
PrintText30Silver(x - 1, 211, "Select Hero", JustCentre, w);
int selectorTop = 256;
int y = selectorTop;
for (int i = 0; i < 0; i++) {
PrintText24Gold(x - 1, y, "Hero name", JustCentre, w);
y += 26;
}
PrintText24Gold(x - 1, y, "New Hero", JustCentre, w);
DrawSelector16(x, selectorTop + 3, w, 32, 26);
RenderStats("-", "-", "-", "-", "-");
PrintText30Gold(279, 429, "OK");
PrintText30Gold(378, 429, "Delete");
PrintText30Gold(501, 429, "Cancel");
}
void selhero_Render_DifficultySelection(int HeroClass, int ShowClasses)
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage);
RenderStats("1", "30", "10", "20", "25");
char *GameOptions[3] = { "Normal", "Nightmare", "Hell" };
// this should not be hard coded.
int x = 280;
int y = 256;
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage);
if (ShowClasses == 1) {
for (int i = 0; i < 3; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
}
}
RenderDefaultStats(HeroClass);
}
void DrawPreGameOptions(int HeroClass, int ShowClasses)
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, 0, pPcxHeroImage);
char *GameOptions[2] = { "New Game", "Load Game" };
// this should not be hard coded.
int x = 280;
int y = 256;
if (ShowClasses == 1) {
for (int i = 0; i < 2; i++) {
y += 40;
PrintText16Silver(x, y, GameOptions[i]);
}
}
RenderDefaultStats(HeroClass);
}
void selhero_Render_Name(int HeroClass)
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
RenderDiabloLogoSm();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, HeroClass, pPcxHeroImage);
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 318;
PrintText30Silver(x - 1, 211, "Enter Name", JustCentre, w);
RenderDefaultStats(HeroClass);
DrawSelector(x, y - 2, w, 39, 26);
PrintText24Gold(x + 67, y, (char *)HeroUndecidedName); // todo add blinking "|"
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "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();
DrawArtImage(30, 211, gdwHeroWidth, gdwHeroHeight, SelectedItem - 1, pPcxHeroImage);
PrintText30Silver(-1, 161, "New Single Player Hero", JustCentre);
int w = 369;
int x = 241;
int y = 285;
PrintText30Silver(x - 1, 211, "Choose Class", JustCentre, w);
RenderDefaultStats(SelectedItem - 1);
char *heroclasses[3] = { "Warrior", "Rogue", "Sorcerer" };
int selectorTop = y;
for (int i = 0; i < 3; i++) {
if (i > 1) {
y += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
PrintText24Gold(x - 1, y, heroclasses[i], JustCentre, w);
y += 33;
}
if (SelectedItem > 1) {
selectorTop += 1; // "Rouge" and "Sorcerer" has a smaller gap then other items
}
DrawSelector(x, selectorTop - 2, w, 39, 33);
PrintText30Gold(329, 429, "OK");
PrintText30Gold(451, 429, "Cancel");
}
void selhero_Loade()
{
LoadTitelArt("ui_art\\selhero.pcx");
}
void selhero_Free()
{
mem_free_dbg(pPcxTitleImage);
pPcxTitleImage = NULL;
}
BOOL __stdcall UiSelHeroSingDialog(
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)),
BOOL(__stdcall *fncreate)(_uiheroinfo *),
BOOL(__stdcall *fnremove)(_uiheroinfo *),
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult,
char *name,
int *difficulty)
{
selhero_Loade();
bool endMenu = false;
submenu = SINGLEPLAYER_LOAD;
if (!TotalPlayers) {
PreviousItem[SINGLEPLAYER_CLASSES] = 0;
submenu = SINGLEPLAYER_CLASSES;
}
SelectedItem = 1;
SelectedItemMax = MenuItem[submenu];
SDL_Event event;
int x, y;
bool done = false;
while (done == false) {
switch (submenu) {
case SINGLEPLAYER_LOAD:
selhero_Render();
break;
case SINGLEPLAYER_CLASSES:
selhero_Render_ClassSelector();
break;
case SINGLEPLAYER_NAME:
selhero_Render_Name(HeroChosen);
break;
}
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
if (PreviousItem[submenu]) {
SetMenu(PreviousItem[submenu]);
break;
}
*dlgresult = 4;
endMenu = true;
break;
case SDLK_BACKSPACE:
if (NewHeroNameIndex > 0) {
HeroUndecidedName[NewHeroNameIndex - 1] = 0;
NewHeroNameIndex--;
}
break;
case SDLK_UP:
SelectedItem--;
if (SelectedItem < 1) {
SelectedItem = SelectedItemMax ? SelectedItemMax : 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_DOWN:
SelectedItem++;
if (SelectedItem > SelectedItemMax) {
SelectedItem = 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
case SDLK_SPACE:
switch (submenu) {
case SINGLEPLAYER_LOAD:
if (SelectedItem == SelectedItemMax) {
SetMenu(SINGLEPLAYER_CLASSES);
}
break;
case SINGLEPLAYER_CLASSES:
HeroChosen = SelectedItem - 1;
for (int i = 0; i < 17; i++)
HeroUndecidedName[i] = 0;
NewHeroNameIndex = 0;
SetMenu(SINGLEPLAYER_NAME);
break;
case SINGLEPLAYER_NAME:
CreateSinglePlayerChar = 1;
const char *test_name = HeroUndecidedName;
done = true;
break;
}
break;
default:
if (submenu != SINGLEPLAYER_NAME) {
break;
}
char letter = event.key.keysym.sym;
if (int(letter) > 96 && int(letter) < 123 || int(letter) == 32)
if (NewHeroNameIndex < 17) {
HeroUndecidedName[NewHeroNameIndex] = letter;
NewHeroNameIndex++;
}
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
x = event.button.x;
y = event.button.y;
printf("X %d , Y %d\n", x, y);
SDL_Rect CreateHeroCancelBox;
CreateHeroCancelBox.y = 550;
CreateHeroCancelBox.x = 675;
CreateHeroCancelBox.w = 100;
CreateHeroCancelBox.h = 30;
clock_t start, end;
double cpu_time_used;
switch (submenu) {
case SINGLEPLAYER_NAME:
if (IsInsideRect(&event, &CreateHeroCancelBox)) {
memset(HeroUndecidedName, 0, 17);
NewHeroNameIndex = 0;
SetMenu(SINGLEPLAYER_CLASSES);
}
break;
}
}
break;
case SDL_QUIT:
exit(0);
}
}
DrawMouse();
if (!endMenu) {
UiFadeIn();
} else if (UiFadeOut()) {
break;
}
}
if (*dlgresult != 4) {
hero_infos.clear();
fninfo(&ui_add_hero_info);
if (CreateSinglePlayerChar) {
const char *test_name = HeroUndecidedName;
DUMMY_PRINT("create hero: %s", test_name);
strcpy(name, test_name);
_uiheroinfo hero_info = { 1 };
strcpy(hero_info.name, test_name);
hero_info.heroclass = HeroChosen;
fncreate(&hero_info);
} else {
*difficulty = gnDifficulty; // BUGFIX this replicates a bug that allowed setting deficulity in SP
printf("Difficulty : %d \n", *difficulty);
const char *test_name = chr_name_str;
if (!StartNewGame) {
*dlgresult = 2; // This means load game
}
strcpy(name, test_name);
}
}
selhero_Free();
return TRUE;
}
BOOL __stdcall UiSelHeroMultDialog(
BOOL(__stdcall *fninfo)(BOOL(__stdcall *fninfofunc)(_uiheroinfo *)),
BOOL(__stdcall *fncreate)(_uiheroinfo *),
BOOL(__stdcall *fnremove)(_uiheroinfo *),
BOOL(__stdcall *fnstats)(unsigned int, _uidefaultstats *),
int *dlgresult,
int *hero_is_created,
char *name)
{
selhero_Loade();
DUMMY();
submenu = MULTIPLAYER_LOBBY;
SelectedItem = 1;
SelectedItemMax = MenuItem[submenu];
SDL_Event event;
bool endMenu = false;
int done = false;
while (done == false) {
switch (submenu) {
case MULTIPLAYER_LOBBY:
DrawPreGameOptions(HeroChosen, 1);
break;
case MULTIPLAYER_DIFFICULTY:
selhero_Render_DifficultySelection(HeroChosen, 1);
break;
}
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
if (PreviousItem[submenu]) {
SetMenu(PreviousItem[submenu]);
break;
}
*dlgresult = 4;
return TRUE;
case SDLK_UP:
SelectedItem--;
if (SelectedItem < 1) {
SelectedItem = SelectedItemMax ? SelectedItemMax : 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_DOWN:
SelectedItem++;
if (SelectedItem > SelectedItemMax) {
SelectedItem = 1;
}
effects_play_sound("sfx\\items\\titlemov.wav");
break;
case SDLK_RETURN:
case SDLK_KP_ENTER:
case SDLK_SPACE:
switch (submenu) {
case MULTIPLAYER_LOBBY:
SetMenu(MULTIPLAYER_DIFFICULTY);
break;
case MULTIPLAYER_DIFFICULTY:
CreateSinglePlayerChar = 1;
done = true;
break;
}
break;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
SDL_Rect CreateHeroCancelBox;
CreateHeroCancelBox.y = 550;
CreateHeroCancelBox.x = 675;
CreateHeroCancelBox.w = 100;
CreateHeroCancelBox.h = 30;
clock_t start, end;
double cpu_time_used;
switch (submenu) {
case 5:
if (timestart == 0) {
start = clock();
timestart = 1;
}
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
printf("TIEM DELAY %f\n", cpu_time_used);
SDL_Rect NewGameBox;
NewGameBox.y = 350;
NewGameBox.x = 280;
NewGameBox.w = 300;
NewGameBox.h = 30;
SDL_Rect LoadGameBox;
LoadGameBox.y = 392;
LoadGameBox.x = 280;
LoadGameBox.w = 300;
LoadGameBox.h = 30;
if (cpu_time_used > 0.5 && IsInsideRect(&event, &NewGameBox)) {
printf(" New Game I was hit\n\n\n");
SetMenu(MULTIPLAYER_DIFFICULTY);
cpu_time_used = 0;
timestart = 0;
start = 0;
} else if (cpu_time_used > 0.5 && IsInsideRect(&event, &LoadGameBox)) {
printf(" Load Game I was hit\n\n\n");
break;
} else if (IsInsideRect(&event, &CreateHeroCancelBox)) {
timestart = 0;
cpu_time_used = 0;
start = 0;
end = 0;
cpu_time_used = 0;
SetMenu(SINGLEPLAYER_CLASSES); // TODO skip to main menu if no valid saves
}
break;
case MULTIPLAYER_DIFFICULTY:
if (timestart == 0) {
start = clock();
timestart = 1;
}
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
SDL_Rect NormalSelectBox;
NormalSelectBox.x = 280;
NormalSelectBox.y = 350;
NormalSelectBox.w = 300;
NormalSelectBox.h = 30;
SDL_Rect NightmareSelectBox;
NightmareSelectBox.x = 280;
NightmareSelectBox.y = 392;
NightmareSelectBox.w = 300;
NightmareSelectBox.h = 30;
SDL_Rect HellSelectBox;
HellSelectBox.x = 280;
HellSelectBox.y = 428;
HellSelectBox.w = 300;
HellSelectBox.h = 30;
if (cpu_time_used > 0.5 && IsInsideRect(&event, &NormalSelectBox)) {
StartNewGame = 1;
gnDifficulty = DIFF_NORMAL;
break;
} else if (cpu_time_used > 0.5 && IsInsideRect(&event, &NightmareSelectBox)) {
StartNewGame = 1;
gnDifficulty = DIFF_NIGHTMARE;
break;
} else if (cpu_time_used > 1 && IsInsideRect(&event, &HellSelectBox)) {
gnDifficulty = DIFF_HELL;
StartNewGame = 1;
break;
} else if (IsInsideRect(&event, &CreateHeroCancelBox)) {
timestart = 0;
cpu_time_used = 0;
start = 0;
end = 0;
cpu_time_used = 0;
printf("Cancel\n\n\n");
SetMenu(MULTIPLAYER_LOBBY);
}
break;
}
}
break;
case SDL_QUIT:
exit(0);
}
}
DrawMouse();
if (!endMenu) {
UiFadeIn();
} else if (UiFadeOut()) {
break;
}
}
hero_infos.clear();
fninfo(&ui_add_hero_info);
if (CreateSinglePlayerChar) {
strcpy(name, "testname");
DUMMY_PRINT("create hero: %s", name);
_uiheroinfo hero_info = { 1 };
strcpy(hero_info.name, name);
hero_info.heroclass = HeroChosen;
fncreate(&hero_info);
}
selhero_Free();
return TRUE;
}

53
Stub/DiabloUI/title.cpp

@ -0,0 +1,53 @@
#include "../../types.h"
void title_Render()
{
DrawArtImage(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, pPcxTitleImage);
PrintText24Silver(-1, 410, "Copyright \xA9 1996-2001 Blizzard Entertainment", JustCentre);
RenderDiabloLogo();
}
void title_Loade()
{
LoadTitelArt("ui_art\\title.pcx");
}
void title_Free()
{
mem_free_dbg(pPcxTitleImage);
pPcxTitleImage = NULL;
}
BOOL __stdcall UiTitleDialog(int a1)
{
title_Loade();
bool endMenu = false;
SDL_Event event;
while (1) {
title_Render();
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN:
endMenu = true;
break;
case SDL_QUIT:
exit(0);
}
}
if (!endMenu) {
UiFadeIn();
} else if (UiFadeOut()) {
break;
}
}
title_Free();
return TRUE;
}

1032
Stub/diabloui.cpp

File diff suppressed because it is too large Load Diff

81
Stub/sdlrender.h

@ -1,81 +0,0 @@
#pragma once
#include "miniwin.h"
extern unsigned char *pFont16;
extern int gdwFont16Width;
extern int gdwFont16Height;
extern void *pPcxFont16sImage;
extern void *pPcxFont16gImage;
extern unsigned char *pFont24;
extern int gdwFont24Width;
extern int gdwFont24Height;
extern void *pPcxFont24sImage;
extern void *pPcxFont24gImage;
extern unsigned char *pFont30;
extern int gdwFont30Width;
extern int gdwFont30Height;
extern void *pPcxFont30sImage;
extern void *pPcxFont30gImage;
extern unsigned char *pFont42;
extern int gdwFont42Width;
extern int gdwFont42Height;
extern void *pPcxFont42gImage;
extern void *pPcxLogoImage;
extern int gdwLogoWidth;
extern int gdwLogoHeight;
extern void *pPcxLogoSmImage;
extern int gdwLogoSmWidth;
extern int gdwLogoSmHeight;
extern int gdwTitleWidth;
extern int gdwTitleHeight;
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 int fadeValue;
extern int lineCount;
extern int creditline;
extern BOOL nottheend;
extern int lastYbase;
extern bool TitleImageLoaded;
extern int SelectedItem;
extern int SCREEN_WIDTH;
extern int SCREEN_HEIGHT;
extern int TotalPlayers;
extern void *MenuPentegram16;
extern void *MenuPentegram;
extern void *MenuPentegram42;
extern char HeroUndecidedName[17];
void SdlDiabloMainWindow();
void RenderDiabloSplashPage();
void RenderDiabloMainPage(char *name);
void RenderDiabloSinglePlayerPage();
BOOL ShowCredts();
void FreeMenuItems();
BOOL LoadArtImage(char *pszFile, void **pBuffer, int frames, DWORD *data);
void CreateHeroMenu();
void RenderUndecidedHeroName(int HeroClass);
void LoadHeroStats();
void DrawPreGameOptions(int HeroClass, int ShowClasses);
void DrawPreGameDifficultySelection(int HeroClass, int ShowClasses);
void DrawSelMultiConnection();
int GetCenterOffset(int w, int bw = 0);

6
enums.h

@ -2267,12 +2267,6 @@ typedef enum menus
CREDIT,
} menus;
enum TXT_JUST {
JustLeft = 0,
JustCentre = 1,
JustRight = 2,
};
typedef enum panel_button_id {
PANBTN_CHARINFO = 0,
PANBTN_QLOG = 1,

2
types.h

@ -9,7 +9,7 @@
#include "miniwin.h"
#include "miniwin_sdl.h"
#include "stubs.h"
#include "sdlrender.h"
#include "DiabloUI/sdlrender.h"
#include "sound.h"
#endif

Loading…
Cancel
Save