You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
8.5 KiB

/**
* @file interfac.cpp
*
* Implementation of load screens.
*/
#include <cstdint>
#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_t 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]) {
6 years ago
case DTYPE_TOWN:
return CutTown;
6 years ago
case DTYPE_CATHEDRAL:
if (lvl > 16)
return CutLevel5;
return CutLevel1;
6 years ago
case DTYPE_CATACOMBS:
return CutLevel2;
6 years ago
case DTYPE_CAVES:
if (lvl > 16)
return CutLevel6;
return CutLevel3;
6 years ago
case DTYPE_HELL:
return CutLevel4;
7 years ago
default:
return CutLevel1;
7 years ago
}
};
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;
7 years ago
break;
case CutTown:
celPath = "Gendata\\Cuttt.cel";
palPath = "Gendata\\Cuttt.pal";
progress_id = 1;
7 years ago
break;
case CutLevel1:
celPath = "Gendata\\Cutl1d.cel";
palPath = "Gendata\\Cutl1d.pal";
progress_id = 0;
7 years ago
break;
case CutLevel2:
celPath = "Gendata\\Cut2.cel";
palPath = "Gendata\\Cut2.pal";
progress_id = 2;
7 years ago
break;
case CutLevel3:
celPath = "Gendata\\Cut3.cel";
palPath = "Gendata\\Cut3.pal";
7 years ago
progress_id = 1;
break;
case CutLevel4:
celPath = "Gendata\\Cut4.cel";
palPath = "Gendata\\Cut4.pal";
7 years ago
progress_id = 1;
break;
case CutLevel5:
celPath = "Nlevels\\Cutl5.cel";
palPath = "Nlevels\\Cutl5.pal";
7 years ago
progress_id = 1;
break;
case CutLevel6:
celPath = "Nlevels\\Cutl6.cel";
palPath = "Nlevels\\Cutl6.pal";
progress_id = 1;
7 years ago
break;
case CutPortal:
LoadArt("Gendata\\Cutportlw.pcx", &ArtCutsceneWidescreen);
celPath = "Gendata\\Cutportl.cel";
palPath = "Gendata\\Cutportl.pal";
7 years ago
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;
7 years ago
break;
}
7 years ago
assert(!sgpBackCel);
sgpBackCel = LoadFileInMem(celPath, nullptr);
LoadPalette(palPath);
7 years ago
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 (unsigned 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 != nullptr)
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].position.tile.x, plr[myplr].position.tile.y, plr[myplr].plrlevel);
plrmsg_delay(false);
ResetPal();
if (gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16) {
PrepDoEnding();
}
gbSomebodyWonGameKludge = false;
}
} // namespace devilution