- transitioned the text intermission screen to use DScreenJob and interpolate the scrolling text display.

This commit is contained in:
Christoph Oelckers 2020-08-22 11:56:54 +02:00
parent 8e34288a1c
commit 7e7f9670c1
6 changed files with 220 additions and 274 deletions

View file

@ -879,5 +879,193 @@ public:
RunScreenJob(&job, 1, mycompletion);
}
//---------------------------------------------------------------------------
//
// text overlay
//
//---------------------------------------------------------------------------
void TextOverlay::Start(int starttime)
{
lastclock = starttime;
}
void TextOverlay::ComputeCinemaText(int nLine)
{
linecount = 0;
while (1)
{
if (!strcmp(gString[linecount + nLine], "END")) {
break;
}
int nWidth = SmallFont->StringWidth(gString[linecount + nLine]);
nLeft[linecount] = 160 - nWidth / 2;
linecount++;
}
nCrawlY = 199;
nHeight = linecount * 10;
}
void TextOverlay::ReadyCinemaText(uint16_t nVal)
{
line = FindGString("CINEMAS");
if (line < 0) {
return;
}
while (nVal)
{
while (strcmp(gString[line], "END")) {
line++;
}
line++;
nVal--;
}
ComputeCinemaText(line);
}
void TextOverlay::DisplayText()
{
if (nHeight + nCrawlY > 0)
{
double y = nCrawlY;
int i = 0;
while (i < linecount && y <= 199)
{
if (y >= -10) {
DrawText(twod, SmallFont, CR_UNDEFINED, nLeft[i], y, gString[line + i], DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, TAG_DONE);
}
i++;
y += 10;
}
}
}
bool TextOverlay::AdvanceCinemaText(int totalclock)
{
if (nHeight + nCrawlY > 0 || CDplaying())
{
nCrawlY-= (totalclock - lastclock) / 15.; // do proper interpolation.
lastclock = totalclock;
return true;
}
return false;
}
//---------------------------------------------------------------------------
//
// cinema
//
//---------------------------------------------------------------------------
static const char * const cinpalfname[] = {
"3454.pal",
"3452.pal",
"3449.pal",
"3445.pal",
"set.pal",
"3448.pal",
"3446.pal",
"hsc1.pal",
"2972.pal",
"2973.pal",
"2974.pal",
"2975.pal",
"2976.pal",
"heli.pal",
"2978.pal",
"terror.pal"
};
extern short nCinemaSeen[30];
void uploadCinemaPalettes()
{
for (int i = 0; i < countof(cinpalfname); i++)
{
uint8_t palette[768] = {};
auto hFile = fileSystem.OpenFileReader(cinpalfname[i]);
if (hFile.isOpen())
hFile.Read(palette, 768);
for (auto& c : palette)
c <<= 2;
paletteSetColorTable(ANIMPAL+i, palette, false, true);
}
}
//---------------------------------------------------------------------------
//
// cinema
//
//---------------------------------------------------------------------------
class DCinema : public DScreenJob
{
TextOverlay text;
short cinematile;
int currentCinemaPalette;
int edx;
public:
DCinema(int nVal) : DScreenJob(fadein|fadeout)
{
static const short cinematiles[] = { 3454, 3452, 3449, 3445, 3451, 3448, 3446};
static const int8_t bxvals[] = { 4, 0, 2, 7, 3, 8, 6 };
static const int8_t dxvals[] = { 4, -1, 2, -1, 3, 8, 6 };
if (nVal < 1 || nVal >7) return;
cinematile = cinematiles[nVal-1];
currentCinemaPalette = nVal;
edx = dxvals[nVal - 1];
text.Start(0);
text.ReadyCinemaText(bxvals[nVal - 1]);
}
int Frame(uint64_t clock, bool skiprequest) override
{
if (clock == 0)
{
StopAllSounds();
if (edx != -1)
{
playCDtrack(edx + 2, false);
}
}
twod->ClearScreen();
DrawTexture(twod, tileGetTexture(cinematile), 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_TranslationIndex, TRANSLATION(Translation_BasePalettes, currentCinemaPalette), TAG_DONE);
text.DisplayText();
auto cont = text.AdvanceCinemaText(clock * 129 / 1'000'000'000);
int ret = skiprequest ? -1 : cont ? 1 : 0;
// quit the game if we've finished level 4 and displayed the advert text
if (ISDEMOVER && currentCinemaPalette == 3 && ret != 1)
{
ExitGame();
}
return ret;
}
};
// temporary.
void RunCinemaScene(int num)
{
JobDesc job = { Create<DCinema>(num) };
RunScreenJob(&job, 1, [](bool) { gamestate = GS_LEVEL; });
SyncScreenJob();
}
END_PS_NS

View file

@ -2059,7 +2059,6 @@ void DoGameOverScene()
NoClip();
overwritesprite(0, 0, kTile3591, 0, 2, kPalNormal, 16);
videoNextPage();
CinemaFadeIn();
PlayGameOverSound();
//WaitAnyKey(3);
FadeOut(0);

View file

@ -261,6 +261,26 @@ enum {
kPalBrite2
};
class TextOverlay
{
double nCrawlY;
short nLeft[50];
int nHeight;
int linecount;
int line;
int lastclock;
public:
void Start(int starttime);
void ComputeCinemaText(int nLine);
void ReadyCinemaText(uint16_t nVal);
void DisplayText();
bool AdvanceCinemaText(int totalclock);
};
extern char g_modDir[BMAX_PATH];
void G_LoadGroupsInDir(const char* dirname);

View file

@ -58,9 +58,6 @@ short nCinemaSeen[30];
uint8_t energytile[66 * 66] = {0};
short nLeft[50] = {0};
int line;
short SavePosition = -1;
uint8_t *cur;
@ -87,6 +84,8 @@ enum {
kMenuMaxItems
};
void RunCinemaScene(int num);
void ClearCinemaSeen()
{
@ -382,270 +381,10 @@ const char *cinpalfname[kMaxCinemaPals] = {
"terror.pal"
};
int linecount;
int nextclock;
short nHeight;
short nCrawlY;
short cinematile;
int currentCinemaPalette;
void uploadCinemaPalettes()
{
for (int i = 0; i < countof(cinpalfname); i++)
{
uint8_t palette[768] = {};
auto hFile = fileSystem.OpenFileReader(cinpalfname[i]);
if (hFile.isOpen())
hFile.Read(palette, 768);
for (auto& c : palette)
c <<= 2;
paletteSetColorTable(ANIMPAL+i, palette, false, true);
}
}
void CinemaFadeIn()
{
}
void ComputeCinemaText(int nLine)
{
linecount = 0;
while (1)
{
if (!strcmp(gString[linecount + nLine], "END")) {
break;
}
int nWidth = SmallFont->StringWidth(gString[linecount + nLine]);
nLeft[linecount] = 160 - nWidth / 2;
linecount++;
}
nCrawlY = 199;
nHeight = linecount * 10;
inputState.ClearAllInput();
}
void ReadyCinemaText(uint16_t nVal)
{
line = FindGString("CINEMAS");
if (line < 0) {
return;
}
while (nVal)
{
while (strcmp(gString[line], "END")) {
line++;
}
line++;
nVal--;
}
ComputeCinemaText(line);
}
bool AdvanceCinemaText()
{
bool bDoText = nHeight + nCrawlY > 0;
if (bDoText || CDplaying())
{
nextclock = (int)totalclock + 15; // NOTE: Value was 14 in original code but seems a touch too fast now
if (bDoText)
{
short y = nCrawlY;
int i = 0;
while (i < linecount && y <= 199)
{
if (y >= -10) {
DrawText(twod, SmallFont, CR_UNDEFINED, nLeft[i], y, gString[line + i], DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, TAG_DONE);
}
i++;
y += 10;
}
nCrawlY--;
}
while (1)
{
HandleAsync();
if (inputState.CheckAllInput())
{
break;
}
if (nextclock <= (int)totalclock) {
return true;
}
}
}
return false;
}
void DoCinemaText(short nVal)
{
ReadyCinemaText(nVal);
bool bContinue = true;
while (bContinue)
{
overwritesprite(0, 0, cinematile, 0, 2, kPalNormal, currentCinemaPalette);
bContinue = AdvanceCinemaText();
WaitVBL();
videoNextPage();
}
}
void GoToTheCinema(int nVal)
{
switch (nVal - 1)
{
default:
return;
case 0:
{
cinematile = 3454;
break;
}
case 1:
{
cinematile = 3452;
break;
}
case 2:
{
cinematile = 3449;
break;
}
case 3:
{
cinematile = 3445;
break;
}
case 4:
{
cinematile = 3451;
break;
}
case 5:
{
cinematile = 3448;
break;
}
case 6:
{
cinematile = 3446;
break;
}
}
currentCinemaPalette = nVal;
FadeOut(false);
StopAllSounds();
NoClip();
overwritesprite(0, 0, kMovieTile, 100, 2, kPalNormal, currentCinemaPalette);
videoNextPage();
// int386(16, (const union REGS *)&val, (union REGS *)&val)
overwritesprite(0, 0, cinematile, 0, 2, kPalNormal, currentCinemaPalette);
videoNextPage();
CinemaFadeIn();
inputState.ClearAllInput();
int ebx = -1;
int edx = -1;
switch (nVal - 1)
{
default:
//WaitAnyKey(10);
break;
case 0:
ebx = 4;
edx = ebx;
break;
case 1:
ebx = 0;
break;
case 2:
ebx = 2;
edx = ebx;
break;
case 3:
ebx = 7;
break;
case 4:
ebx = 3;
edx = ebx;
break;
case 5:
ebx = 8;
edx = ebx;
break;
case 6:
ebx = 6;
edx = ebx;
break;
}
if (ebx != -1)
{
if (edx != -1)
{
if (CDplaying()) {
fadecdaudio();
}
playCDtrack(edx + 2, false);
}
DoCinemaText(ebx);
}
FadeOut(true);
overwritesprite(0, 0, kMovieTile, 100, 2, kPalNormal, currentCinemaPalette);
videoNextPage();
GrabPalette();
// quit the game if we've finished level 4 and displayed the advert text
if (ISDEMOVER && nVal == 3) {
ExitGame();
}
}
short nBeforeScene[] = { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
@ -665,7 +404,7 @@ void CheckBeforeScene(int nLevel)
{
if (!nCinemaSeen[nScene])
{
GoToTheCinema(nScene);
RunCinemaScene(nScene);
nCinemaSeen[nScene] = 1;
}
}
@ -703,7 +442,7 @@ void DoAfterCinemaScene(int nLevel)
short nAfterScene[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 7, 0, 0, 0, 0, 6 };
if (nAfterScene[nLevel]) {
GoToTheCinema(nAfterScene[nLevel]);
RunCinemaScene(nAfterScene[nLevel]);
}
}
@ -718,7 +457,7 @@ void DoFailedFinalScene()
playCDtrack(9, false);
FadeToWhite();
GoToTheCinema(4);
RunCinemaScene(4);
}
int FindGString(const char *str)

View file

@ -62,9 +62,6 @@ void DoEnergyTile();
void CinemaFadeIn();
void ReadyCinemaText(uint16_t nVal);
bool AdvanceCinemaText();
void DoFailedFinalScene();
void DoLastLevelCinema();

View file

@ -240,6 +240,8 @@ static inline int interpolate16(int a, int b, int smooth)
return a + mulscale16(b - a, smooth);
}
static TextOverlay subtitleOverlay;
void DrawView(int smoothRatio, bool sceneonly)
{
int playerX;
@ -435,15 +437,16 @@ void DrawView(int smoothRatio, bool sceneonly)
if (bSubTitles)
{
subtitleOverlay.Start(totalclock);
if (levelnum == 1)
ReadyCinemaText(1);
subtitleOverlay.ReadyCinemaText(1);
else
ReadyCinemaText(5);
subtitleOverlay.ReadyCinemaText(5);
}
}
else
else if (nHeadStage == 6)
{
if ((bSubTitles && !AdvanceCinemaText()) || inputState.CheckAllInput())
if ((bSubTitles && !subtitleOverlay.AdvanceCinemaText(totalclock)) || inputState.CheckAllInput())
{
inputState.ClearAllInput();
levelnew = levelnum + 1;