|
|
|
|
/**
|
|
|
|
|
* @file interfac.cpp
|
|
|
|
|
*
|
|
|
|
|
* Implementation of load screens.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "control.h"
|
|
|
|
|
#include "DiabloUI/art_draw.h"
|
|
|
|
|
#include "dx.h"
|
|
|
|
|
#include "init.h"
|
|
|
|
|
#include "loadsave.h"
|
|
|
|
|
#include "palette.h"
|
|
|
|
|
#include "pfile.h"
|
|
|
|
|
#include "plrmsg.h"
|
|
|
|
|
|
|
|
|
|
namespace devilution {
|
|
|
|
|
|
|
|
|
|
BYTE *sgpBackCel;
|
|
|
|
|
Uint32 sgdwProgress;
|
|
|
|
|
int progress_id;
|
|
|
|
|
|
|
|
|
|
/** The color used for the progress bar as an index into the palette. */
|
|
|
|
|
const BYTE BarColor[3] = { 138, 43, 254 };
|
|
|
|
|
/** The screen position of the top left corner of the progress bar. */
|
|
|
|
|
const int BarPos[3][2] = { { 53, 37 }, { 53, 421 }, { 53, 37 } };
|
|
|
|
|
|
|
|
|
|
Art ArtCutsceneWidescreen;
|
|
|
|
|
|
|
|
|
|
static void FreeInterface()
|
|
|
|
|
{
|
|
|
|
|
MemFreeDbg(sgpBackCel);
|
|
|
|
|
ArtCutsceneWidescreen.Unload();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Cutscenes PickCutscene(interface_mode uMsg)
|
|
|
|
|
{
|
|
|
|
|
switch (uMsg) {
|
|
|
|
|
case WM_DIABLOADGAME:
|
|
|
|
|
case WM_DIABNEWGAME:
|
|
|
|
|
return CutStart;
|
|
|
|
|
case WM_DIABRETOWN:
|
|
|
|
|
return CutTown;
|
|
|
|
|
case WM_DIABNEXTLVL:
|
|
|
|
|
case WM_DIABPREVLVL:
|
|
|
|
|
case WM_DIABTOWNWARP:
|
|
|
|
|
case WM_DIABTWARPUP: {
|
|
|
|
|
int lvl = currlevel;
|
|
|
|
|
if (uMsg == WM_DIABTWARPUP)
|
|
|
|
|
lvl = plr[myplr].plrlevel;
|
|
|
|
|
|
|
|
|
|
if (lvl == 1 && uMsg == WM_DIABPREVLVL)
|
|
|
|
|
return CutTown;
|
|
|
|
|
if (lvl == 16 && uMsg == WM_DIABNEXTLVL)
|
|
|
|
|
return CutGate;
|
|
|
|
|
|
|
|
|
|
switch (gnLevelTypeTbl[lvl]) {
|
|
|
|
|
case DTYPE_TOWN:
|
|
|
|
|
return CutTown;
|
|
|
|
|
case DTYPE_CATHEDRAL:
|
|
|
|
|
if (lvl > 16)
|
|
|
|
|
return CutLevel5;
|
|
|
|
|
return CutLevel1;
|
|
|
|
|
case DTYPE_CATACOMBS:
|
|
|
|
|
return CutLevel2;
|
|
|
|
|
case DTYPE_CAVES:
|
|
|
|
|
if (lvl > 16)
|
|
|
|
|
return CutLevel6;
|
|
|
|
|
return CutLevel3;
|
|
|
|
|
case DTYPE_HELL:
|
|
|
|
|
return CutLevel4;
|
|
|
|
|
default:
|
|
|
|
|
return CutLevel1;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
case WM_DIABWARPLVL:
|
|
|
|
|
return CutPortal;
|
|
|
|
|
case WM_DIABSETLVL:
|
|
|
|
|
case WM_DIABRTNLVL:
|
|
|
|
|
if (setlvlnum == SL_BONECHAMB)
|
|
|
|
|
return CutLevel2;
|
|
|
|
|
if (setlvlnum == SL_VILEBETRAYER)
|
|
|
|
|
return CutPortalRed;
|
|
|
|
|
return CutLevel1;
|
|
|
|
|
default:
|
|
|
|
|
app_fatal("Unknown progress mode");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void InitCutscene(interface_mode uMsg)
|
|
|
|
|
{
|
|
|
|
|
const char *celPath;
|
|
|
|
|
const char *palPath;
|
|
|
|
|
|
|
|
|
|
switch (PickCutscene(uMsg)) {
|
|
|
|
|
case CutStart:
|
|
|
|
|
celPath = "Gendata\\Cutstart.cel";
|
|
|
|
|
palPath = "Gendata\\Cutstart.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutTown:
|
|
|
|
|
celPath = "Gendata\\Cuttt.cel";
|
|
|
|
|
palPath = "Gendata\\Cuttt.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel1:
|
|
|
|
|
celPath = "Gendata\\Cutl1d.cel";
|
|
|
|
|
palPath = "Gendata\\Cutl1d.pal";
|
|
|
|
|
progress_id = 0;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel2:
|
|
|
|
|
celPath = "Gendata\\Cut2.cel";
|
|
|
|
|
palPath = "Gendata\\Cut2.pal";
|
|
|
|
|
progress_id = 2;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel3:
|
|
|
|
|
celPath = "Gendata\\Cut3.cel";
|
|
|
|
|
palPath = "Gendata\\Cut3.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel4:
|
|
|
|
|
celPath = "Gendata\\Cut4.cel";
|
|
|
|
|
palPath = "Gendata\\Cut4.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel5:
|
|
|
|
|
celPath = "Nlevels\\Cutl5.cel";
|
|
|
|
|
palPath = "Nlevels\\Cutl5.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutLevel6:
|
|
|
|
|
celPath = "Nlevels\\Cutl6.cel";
|
|
|
|
|
palPath = "Nlevels\\Cutl6.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutPortal:
|
|
|
|
|
LoadArt("Gendata\\Cutportlw.pcx", &ArtCutsceneWidescreen);
|
|
|
|
|
celPath = "Gendata\\Cutportl.cel";
|
|
|
|
|
palPath = "Gendata\\Cutportl.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutPortalRed:
|
|
|
|
|
LoadArt("Gendata\\Cutportrw.pcx", &ArtCutsceneWidescreen);
|
|
|
|
|
celPath = "Gendata\\Cutportr.cel";
|
|
|
|
|
palPath = "Gendata\\Cutportr.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
case CutGate:
|
|
|
|
|
celPath = "Gendata\\Cutgate.cel";
|
|
|
|
|
palPath = "Gendata\\Cutgate.pal";
|
|
|
|
|
progress_id = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(!sgpBackCel);
|
|
|
|
|
sgpBackCel = LoadFileInMem(celPath, nullptr);
|
|
|
|
|
LoadPalette(palPath);
|
|
|
|
|
|
|
|
|
|
sgdwProgress = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void DrawProgress(CelOutputBuffer out, int x, int y, int progress_id)
|
|
|
|
|
{
|
|
|
|
|
BYTE *dst = out.at(x, y);
|
|
|
|
|
for (int i = 0; i < 22; ++i, dst += out.pitch()) {
|
|
|
|
|
*dst = BarColor[progress_id];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void DrawCutscene()
|
|
|
|
|
{
|
|
|
|
|
lock_buf(1);
|
|
|
|
|
CelOutputBuffer out = GlobalBackBuffer();
|
|
|
|
|
DrawArt(out, PANEL_X - (ArtCutsceneWidescreen.w() - PANEL_WIDTH) / 2, UI_OFFSET_Y, &ArtCutsceneWidescreen);
|
|
|
|
|
CelDrawTo(out, PANEL_X, 480 - 1 + UI_OFFSET_Y, sgpBackCel, 1, 640);
|
|
|
|
|
|
|
|
|
|
for (Uint32 i = 0; i < sgdwProgress; i++) {
|
|
|
|
|
DrawProgress(
|
|
|
|
|
out,
|
|
|
|
|
BarPos[progress_id][0] + i + PANEL_X,
|
|
|
|
|
BarPos[progress_id][1] + UI_OFFSET_Y,
|
|
|
|
|
progress_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unlock_buf(1);
|
|
|
|
|
force_redraw = 255;
|
|
|
|
|
scrollrt_draw_game_screen(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void interface_msg_pump()
|
|
|
|
|
{
|
|
|
|
|
MSG Msg;
|
|
|
|
|
|
|
|
|
|
while (FetchMessage(&Msg)) {
|
|
|
|
|
if (Msg.message != DVL_WM_QUIT) {
|
|
|
|
|
TranslateMessage(&Msg);
|
|
|
|
|
PushMessage(&Msg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IncProgress()
|
|
|
|
|
{
|
|
|
|
|
interface_msg_pump();
|
|
|
|
|
sgdwProgress += 23;
|
|
|
|
|
if (sgdwProgress > 534)
|
|
|
|
|
sgdwProgress = 534;
|
|
|
|
|
if (sgpBackCel)
|
|
|
|
|
DrawCutscene();
|
|
|
|
|
return sgdwProgress >= 534;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ShowProgress(interface_mode uMsg)
|
|
|
|
|
{
|
|
|
|
|
WNDPROC saveProc;
|
|
|
|
|
|
|
|
|
|
gbSomebodyWonGameKludge = false;
|
|
|
|
|
plrmsg_delay(true);
|
|
|
|
|
|
|
|
|
|
assert(ghMainWnd);
|
|
|
|
|
saveProc = SetWindowProc(DisableInputWndProc);
|
|
|
|
|
|
|
|
|
|
interface_msg_pump();
|
|
|
|
|
ClearScreenBuffer();
|
|
|
|
|
scrollrt_draw_game_screen(true);
|
|
|
|
|
InitCutscene(uMsg);
|
|
|
|
|
BlackPalette();
|
|
|
|
|
DrawCutscene();
|
|
|
|
|
PaletteFadeIn(8);
|
|
|
|
|
IncProgress();
|
|
|
|
|
sound_init();
|
|
|
|
|
IncProgress();
|
|
|
|
|
|
|
|
|
|
switch (uMsg) {
|
|
|
|
|
case WM_DIABLOADGAME:
|
|
|
|
|
IncProgress();
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGame(true);
|
|
|
|
|
IncProgress();
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABNEWGAME:
|
|
|
|
|
plr[myplr].pOriginalCathedral = !gbIsHellfire;
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
IncProgress();
|
|
|
|
|
pfile_remove_temp_files();
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(true, ENTRY_MAIN);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABNEXTLVL:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
currlevel++;
|
|
|
|
|
leveltype = gnLevelTypeTbl[currlevel];
|
|
|
|
|
assert(plr[myplr].plrlevel == currlevel);
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_MAIN);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABPREVLVL:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
currlevel--;
|
|
|
|
|
leveltype = gnLevelTypeTbl[currlevel];
|
|
|
|
|
assert(plr[myplr].plrlevel == currlevel);
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_PREV);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABSETLVL:
|
|
|
|
|
SetReturnLvlPos();
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
setlevel = true;
|
|
|
|
|
leveltype = setlvltype;
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_SETLVL);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABRTNLVL:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
setlevel = false;
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
IncProgress();
|
|
|
|
|
GetReturnLvlPos();
|
|
|
|
|
LoadGameLevel(false, ENTRY_RTNLVL);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABWARPLVL:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
GetPortalLevel();
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_WARPLVL);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABTOWNWARP:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
currlevel = plr[myplr].plrlevel;
|
|
|
|
|
leveltype = gnLevelTypeTbl[currlevel];
|
|
|
|
|
assert(plr[myplr].plrlevel == currlevel);
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_TWARPDN);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABTWARPUP:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
currlevel = plr[myplr].plrlevel;
|
|
|
|
|
leveltype = gnLevelTypeTbl[currlevel];
|
|
|
|
|
assert(plr[myplr].plrlevel == currlevel);
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_TWARPUP);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
case WM_DIABRETOWN:
|
|
|
|
|
IncProgress();
|
|
|
|
|
if (!gbIsMultiplayer) {
|
|
|
|
|
SaveLevel();
|
|
|
|
|
} else {
|
|
|
|
|
DeltaSaveLevel();
|
|
|
|
|
}
|
|
|
|
|
IncProgress();
|
|
|
|
|
FreeGameMem();
|
|
|
|
|
currlevel = plr[myplr].plrlevel;
|
|
|
|
|
leveltype = gnLevelTypeTbl[currlevel];
|
|
|
|
|
assert(plr[myplr].plrlevel == currlevel);
|
|
|
|
|
IncProgress();
|
|
|
|
|
LoadGameLevel(false, ENTRY_MAIN);
|
|
|
|
|
IncProgress();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(ghMainWnd);
|
|
|
|
|
|
|
|
|
|
PaletteFadeOut(8);
|
|
|
|
|
FreeInterface();
|
|
|
|
|
|
|
|
|
|
saveProc = SetWindowProc(saveProc);
|
|
|
|
|
assert(saveProc == DisableInputWndProc);
|
|
|
|
|
|
|
|
|
|
NetSendCmdLocParam1(true, CMD_PLAYER_JOINLEVEL, plr[myplr]._px, plr[myplr]._py, plr[myplr].plrlevel);
|
|
|
|
|
plrmsg_delay(false);
|
|
|
|
|
ResetPal();
|
|
|
|
|
|
|
|
|
|
if (gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16) {
|
|
|
|
|
PrepDoEnding();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gbSomebodyWonGameKludge = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace devilution
|