2019-09-19 22:42:45 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
|
|
Copyright (C) 2019 Nuke.YKT
|
|
|
|
|
|
|
|
This file is part of NBlood.
|
|
|
|
|
|
|
|
NBlood is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License version 2
|
|
|
|
as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-09-21 18:59:54 +00:00
|
|
|
|
|
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
#include "build.h"
|
|
|
|
#include "compat.h"
|
|
|
|
#include "SmackerDecoder.h"
|
|
|
|
#include "common_game.h"
|
|
|
|
#include "blood.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "controls.h"
|
|
|
|
#include "globals.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "screen.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "view.h"
|
2019-12-25 13:13:15 +00:00
|
|
|
#include "../glbackend/glbackend.h"
|
2019-12-18 21:24:50 +00:00
|
|
|
#include "sound/s_soundinternal.h"
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-09-22 06:39:22 +00:00
|
|
|
BEGIN_BLD_NS
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
char exitCredits = 0;
|
|
|
|
|
|
|
|
char Wait(int nTicks)
|
|
|
|
{
|
2019-09-07 13:15:39 +00:00
|
|
|
totalclock = 0;
|
|
|
|
while (totalclock < nTicks)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-10-24 14:51:55 +00:00
|
|
|
gameHandleEvents();
|
2019-12-24 11:59:26 +00:00
|
|
|
auto key = inputState.keyGetScan();
|
2019-09-19 22:42:45 +00:00
|
|
|
if (key)
|
|
|
|
{
|
|
|
|
if (key == sc_Escape) // sc_Escape
|
|
|
|
exitCredits = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char DoFade(char r, char g, char b, int nTicks)
|
|
|
|
{
|
2019-09-22 21:55:45 +00:00
|
|
|
#if 0
|
2019-09-19 22:42:45 +00:00
|
|
|
dassert(nTicks > 0);
|
|
|
|
scrSetupFade(r, g, b);
|
2019-09-07 13:15:39 +00:00
|
|
|
totalclock = gFrameClock = 0;
|
2019-09-19 22:42:45 +00:00
|
|
|
do
|
|
|
|
{
|
2019-10-24 14:51:55 +00:00
|
|
|
while (totalclock < gFrameClock) { gameHandleEvents();};
|
2019-09-19 22:42:45 +00:00
|
|
|
gFrameClock += 2;
|
|
|
|
scrNextPage();
|
2019-09-07 13:15:39 +00:00
|
|
|
scrFadeAmount(divscale16(ClipHigh((int)totalclock, nTicks), nTicks));
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.keyGetScan())
|
2019-09-19 22:42:45 +00:00
|
|
|
return 0;
|
2019-09-07 13:15:39 +00:00
|
|
|
} while (totalclock <= nTicks);
|
2019-09-22 21:55:45 +00:00
|
|
|
#endif
|
2019-09-19 22:42:45 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char DoUnFade(int nTicks)
|
|
|
|
{
|
2019-09-22 21:55:45 +00:00
|
|
|
#if 0
|
2019-09-19 22:42:45 +00:00
|
|
|
dassert(nTicks > 0);
|
|
|
|
scrSetupUnfade();
|
2019-09-07 13:15:39 +00:00
|
|
|
totalclock = gFrameClock = 0;
|
2019-09-19 22:42:45 +00:00
|
|
|
do
|
|
|
|
{
|
2019-10-24 14:51:55 +00:00
|
|
|
while (totalclock < gFrameClock) { gameHandleEvents(); };
|
|
|
|
gFrameClock += 2;
|
2019-09-19 22:42:45 +00:00
|
|
|
scrNextPage();
|
2019-09-07 13:15:39 +00:00
|
|
|
scrFadeAmount(0x10000-divscale16(ClipHigh((int)totalclock, nTicks), nTicks));
|
2019-11-03 23:53:55 +00:00
|
|
|
if (inputState.keyGetScan())
|
2019-09-19 22:42:45 +00:00
|
|
|
return 0;
|
2019-09-07 13:15:39 +00:00
|
|
|
} while (totalclock <= nTicks);
|
2019-09-22 21:55:45 +00:00
|
|
|
#endif
|
2019-09-19 22:42:45 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-12-25 00:10:13 +00:00
|
|
|
void credPlaySmk(const char* _pzSMK, const char* _pzWAV, int nWav);
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
void credLogosDos(void)
|
|
|
|
{
|
2019-10-28 00:12:31 +00:00
|
|
|
char bShift = inputState.ShiftPressed();
|
2019-09-19 22:42:45 +00:00
|
|
|
videoSetViewableArea(0, 0, xdim-1, ydim-1);
|
|
|
|
DoUnFade(1);
|
|
|
|
videoClearScreen(0);
|
|
|
|
if (bShift)
|
|
|
|
return;
|
|
|
|
{
|
2019-12-25 00:10:13 +00:00
|
|
|
if (fileSystem.FindFile("logo.smk"))
|
|
|
|
{
|
|
|
|
credPlaySmk("logo.smk", "logo.wav", -1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-19 22:42:45 +00:00
|
|
|
rotatesprite(160<<16, 100<<16, 65536, 0, 2050, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
|
|
|
sndStartSample("THUNDER2", 128, -1);
|
|
|
|
scrNextPage();
|
|
|
|
if (!Wait(360))
|
|
|
|
return;
|
|
|
|
if (!DoFade(0, 0, 0, 60))
|
|
|
|
return;
|
2019-12-25 00:10:13 +00:00
|
|
|
}
|
|
|
|
if (fileSystem.FindFile("gti.smk"))
|
|
|
|
{
|
|
|
|
credPlaySmk("gti.smk", "gt.wav", -1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-09-19 22:42:45 +00:00
|
|
|
videoClearScreen(0);
|
|
|
|
rotatesprite(160<<16, 100<<16, 65536, 0, 2052, 0, 0, 0x0a, 0, 0, xdim-1, ydim-1);
|
|
|
|
scrNextPage();
|
|
|
|
DoUnFade(1);
|
|
|
|
sndStartSample("THUNDER2", 128, -1);
|
|
|
|
if (!Wait(360))
|
|
|
|
return;
|
2019-12-25 00:10:13 +00:00
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
sndPlaySpecialMusicOrNothing(MUS_INTRO);
|
|
|
|
sndStartSample("THUNDER2", 128, -1);
|
|
|
|
if (!DoFade(0, 0, 0, 60))
|
|
|
|
return;
|
|
|
|
videoClearScreen(0);
|
|
|
|
scrNextPage();
|
|
|
|
if (!DoUnFade(1))
|
|
|
|
return;
|
|
|
|
videoClearScreen(0);
|
|
|
|
rotatesprite(160<<16, 100<<16, 65536, 0, 2518, 0, 0, 0x4a, 0, 0, xdim-1, ydim-1);
|
|
|
|
scrNextPage();
|
|
|
|
Wait(360);
|
2019-12-25 00:10:13 +00:00
|
|
|
//Mus_Fade(4000);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void credReset(void)
|
|
|
|
{
|
|
|
|
videoClearScreen(0);
|
|
|
|
scrNextPage();
|
|
|
|
DoFade(0,0,0,1);
|
|
|
|
scrSetupUnfade();
|
|
|
|
DoUnFade(1);
|
|
|
|
}
|
|
|
|
|
2020-01-26 10:42:02 +00:00
|
|
|
bool credKOpen4Load(FString &pzFile)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
int nLen = strlen(pzFile);
|
2019-12-26 13:43:44 +00:00
|
|
|
FixPathSeperator(pzFile);
|
2020-01-26 10:42:02 +00:00
|
|
|
auto nHandle = fileSystem.FindFile(pzFile);
|
|
|
|
if (nHandle < 0)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2020-01-26 10:42:02 +00:00
|
|
|
// Strip the drive letter and retry.
|
2019-09-19 22:42:45 +00:00
|
|
|
if (nLen >= 3 && isalpha(pzFile[0]) && pzFile[1] == ':' && pzFile[2] == '/')
|
|
|
|
{
|
2020-01-26 10:42:02 +00:00
|
|
|
pzFile = pzFile.Mid(3);
|
|
|
|
nHandle = fileSystem.FindFile(pzFile);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define kSMKPal 5
|
|
|
|
#define kSMKTile (MAXTILES-1)
|
|
|
|
|
|
|
|
void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
CSMKPlayer smkPlayer;
|
|
|
|
if (dword_148E14 >= 0)
|
|
|
|
{
|
|
|
|
if (toupper(*pzSMK) == 'A'+dword_148E14)
|
|
|
|
{
|
|
|
|
if (Redbook.sub_82258() == 0 || Redbook.sub_82258() > 20)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Redbook.sub_82554();
|
|
|
|
}
|
|
|
|
smkPlayer.sub_82E6C(pzSMK, pzWAV);
|
|
|
|
#endif
|
2019-12-26 13:43:44 +00:00
|
|
|
if (!_pzSMK || !*_pzSMK)
|
2019-09-19 22:42:45 +00:00
|
|
|
return;
|
2019-12-26 13:43:44 +00:00
|
|
|
FString pzSMK = _pzSMK;
|
|
|
|
FString pzWAV = _pzWAV;
|
2019-10-21 15:16:08 +00:00
|
|
|
auto nHandleSMK = credKOpen4Load(pzSMK);
|
2020-01-26 10:42:02 +00:00
|
|
|
if (!nHandleSMK)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SmackerHandle hSMK = Smacker_Open(pzSMK);
|
|
|
|
if (!hSMK.isValid)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t nWidth, nHeight;
|
|
|
|
Smacker_GetFrameSize(hSMK, nWidth, nHeight);
|
|
|
|
uint8_t palette[768];
|
2019-10-11 19:04:31 +00:00
|
|
|
tileDelete(kSMKTile);
|
2019-12-25 00:10:13 +00:00
|
|
|
auto pFrame = TileFiles.tileCreate(kSMKTile, nHeight, nWidth);
|
2019-09-19 22:42:45 +00:00
|
|
|
if (!pFrame)
|
|
|
|
{
|
|
|
|
Smacker_Close(hSMK);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int nFrameRate = Smacker_GetFrameRate(hSMK);
|
|
|
|
int nFrames = Smacker_GetNumFrames(hSMK);
|
|
|
|
|
|
|
|
Smacker_GetPalette(hSMK, palette);
|
2019-10-06 17:32:35 +00:00
|
|
|
paletteSetColorTable(kSMKPal, palette, true);
|
2020-01-26 09:58:00 +00:00
|
|
|
videoSetPalette(0, kSMKPal, Pal_Fullscreen);
|
2020-02-19 17:34:17 +00:00
|
|
|
Mus_Stop();
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
int nScale;
|
2020-02-12 16:59:22 +00:00
|
|
|
int nStat;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-02-12 16:59:22 +00:00
|
|
|
if (nWidth <= 320 && nHeight <= 200)
|
|
|
|
{
|
|
|
|
if ((nWidth / (nHeight * 1.2f)) > (1.f * xdim / ydim))
|
|
|
|
nScale = divscale16(320 * xdim * 3, nWidth * ydim * 4);
|
|
|
|
else
|
|
|
|
nScale = divscale16(200, nHeight);
|
|
|
|
nStat = 2 | 4 | 8 | 64;
|
|
|
|
}
|
2019-09-19 22:42:45 +00:00
|
|
|
else
|
2020-02-12 16:59:22 +00:00
|
|
|
{
|
|
|
|
// DOS Blood v1.11: 320x240, 320x320, 640x400, and 640x480 SMKs all display 1:1 and centered in a 640x480 viewport
|
|
|
|
nScale = tabledivide32(scale(65536, ydim << 2, xdim * 3), ((max(nHeight, 240 + 1u) + 239) / 240));
|
|
|
|
nStat = 2 | 4 | 8 | 64 | 1024;
|
|
|
|
renderSetAspect(viewingrange, 65536);
|
|
|
|
}
|
|
|
|
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2020-01-03 23:07:20 +00:00
|
|
|
if (nWav > 0)
|
2019-12-17 18:37:05 +00:00
|
|
|
sndStartWavID(nWav, 255);
|
2019-09-19 22:42:45 +00:00
|
|
|
else
|
|
|
|
{
|
2019-10-21 15:16:08 +00:00
|
|
|
auto nHandleWAV = credKOpen4Load(pzWAV);
|
2020-01-26 10:42:02 +00:00
|
|
|
if (nHandleWAV)
|
2019-09-19 22:42:45 +00:00
|
|
|
{
|
2019-12-17 18:37:05 +00:00
|
|
|
sndStartWavDisk(pzWAV, 255);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDacs(0, true);
|
|
|
|
|
2019-10-24 14:51:55 +00:00
|
|
|
gameHandleEvents();
|
2019-09-07 13:15:39 +00:00
|
|
|
ClockTicks nStartTime = totalclock;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
inputState.ClearAllInput();
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
int nFrame = 0;
|
2020-02-04 19:40:10 +00:00
|
|
|
hw_int_useindexedcolortextures = false;
|
2019-09-19 22:42:45 +00:00
|
|
|
do
|
|
|
|
{
|
2019-10-24 13:25:34 +00:00
|
|
|
gameHandleEvents();
|
2019-09-07 13:15:39 +00:00
|
|
|
if (scale((int)(totalclock-nStartTime), nFrameRate, kTicRate) < nFrame)
|
2019-09-19 22:42:45 +00:00
|
|
|
continue;
|
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
if (inputState.CheckAllInput())
|
2019-09-19 22:42:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
videoClearScreen(0);
|
|
|
|
Smacker_GetPalette(hSMK, palette);
|
2019-10-06 17:32:35 +00:00
|
|
|
paletteSetColorTable(kSMKPal, palette, true);
|
2020-01-26 11:10:23 +00:00
|
|
|
videoSetPalette(0, kSMKPal, Pal_Fullscreen);
|
2019-09-19 22:42:45 +00:00
|
|
|
tileInvalidate(kSMKTile, 0, 1 << 4); // JBF 20031228
|
|
|
|
Smacker_GetFrame(hSMK, pFrame);
|
2020-02-12 16:59:22 +00:00
|
|
|
rotatesprite_fs(160<<16, 100<<16, nScale, 512, kSMKTile, 0, 0, nStat);
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
videoNextPage();
|
|
|
|
|
|
|
|
nFrame++;
|
|
|
|
Smacker_GetNextFrame(hSMK);
|
|
|
|
} while(nFrame < nFrames);
|
2020-02-04 19:40:10 +00:00
|
|
|
hw_int_useindexedcolortextures = hw_useindexedcolortextures;
|
2019-09-19 22:42:45 +00:00
|
|
|
|
|
|
|
Smacker_Close(hSMK);
|
2019-12-24 11:59:26 +00:00
|
|
|
inputState.ClearAllInput();
|
2019-12-18 21:24:50 +00:00
|
|
|
soundEngine->StopAllChannels();
|
2020-01-26 09:58:00 +00:00
|
|
|
videoSetPalette(0, 0, 0);
|
2019-10-11 19:04:31 +00:00
|
|
|
tileDelete(kSMKTile);
|
2019-09-19 22:42:45 +00:00
|
|
|
}
|
2019-09-22 06:39:22 +00:00
|
|
|
|
|
|
|
END_BLD_NS
|