2020-06-25 19:51:44 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Copyright (C) 1996, 2003 - 3D Realms Entertainment
|
|
|
|
|
|
|
|
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
|
|
|
|
|
|
|
|
Duke Nukem 3D is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
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
|
2020-06-27 09:48:32 +00:00
|
|
|
aint with this program; if not, write to the Free Software
|
2020-06-25 19:51:44 +00:00
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
Original Source: 1996 - Todd Replogle
|
|
|
|
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
|
|
|
|
Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// this file collects all 2D content of the game that was scattered across multiple sources originally.
|
|
|
|
// All this should transition to a more modern, preferably localization friendly, approach later.
|
|
|
|
|
2020-06-26 20:49:56 +00:00
|
|
|
#include "ns.h"
|
|
|
|
#include "duke3d.h"
|
2020-07-03 21:56:14 +00:00
|
|
|
#include "names_d.h"
|
2020-06-26 20:49:56 +00:00
|
|
|
#include "animtexture.h"
|
|
|
|
#include "animlib.h"
|
2020-06-27 09:48:32 +00:00
|
|
|
#include "raze_music.h"
|
|
|
|
#include "mapinfo.h"
|
2020-06-27 22:32:28 +00:00
|
|
|
#include "screenjob.h"
|
2020-06-28 08:14:42 +00:00
|
|
|
#include "texturemanager.h"
|
2020-06-28 19:38:25 +00:00
|
|
|
#include "buildtiles.h"
|
2020-07-07 11:19:09 +00:00
|
|
|
#include "mapinfo.h"
|
2020-07-14 12:00:27 +00:00
|
|
|
#include "c_dispatch.h"
|
2020-07-19 10:48:31 +00:00
|
|
|
#include "gamestate.h"
|
2020-06-26 20:49:56 +00:00
|
|
|
|
|
|
|
BEGIN_DUKE_NS
|
2020-06-25 19:51:44 +00:00
|
|
|
|
2020-06-28 08:14:42 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Sets up the game fonts.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void InitFonts_d()
|
|
|
|
{
|
2020-07-20 21:21:27 +00:00
|
|
|
GlyphSet fontdata;
|
2020-06-28 08:14:42 +00:00
|
|
|
|
2020-07-20 21:21:27 +00:00
|
|
|
// Small font
|
|
|
|
for (int i = 0; i < 95; i++)
|
|
|
|
{
|
|
|
|
auto tile = tileGetTexture(STARTALPHANUM + i);
|
2020-07-02 08:59:22 +00:00
|
|
|
if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0)
|
|
|
|
{
|
2020-09-29 19:47:32 +00:00
|
|
|
if (i >= 'a' && i <= 'z' && tileEqualTo(i, i - 32)) continue;
|
2020-07-02 08:59:22 +00:00
|
|
|
fontdata.Insert('!' + i, tile);
|
|
|
|
tile->SetOffsetsNotForFont();
|
|
|
|
}
|
2020-07-20 21:21:27 +00:00
|
|
|
}
|
|
|
|
SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, 5, false, false, false, &fontdata);
|
|
|
|
fontdata.Clear();
|
|
|
|
|
|
|
|
// Big font
|
|
|
|
|
|
|
|
// This font is VERY messy...
|
|
|
|
fontdata.Insert('_', tileGetTexture(BIGALPHANUM - 11));
|
|
|
|
fontdata.Insert('-', tileGetTexture(BIGALPHANUM - 11));
|
|
|
|
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(BIGALPHANUM - 10 + i));
|
|
|
|
for (int i = 0; i < 26; i++) fontdata.Insert('A' + i, tileGetTexture(BIGALPHANUM + i));
|
|
|
|
fontdata.Insert('.', tileGetTexture(BIGPERIOD));
|
|
|
|
fontdata.Insert(',', tileGetTexture(BIGCOMMA));
|
|
|
|
fontdata.Insert('!', tileGetTexture(BIGX));
|
|
|
|
fontdata.Insert('?', tileGetTexture(BIGQ));
|
|
|
|
fontdata.Insert(';', tileGetTexture(BIGSEMI));
|
|
|
|
fontdata.Insert(':', tileGetTexture(BIGCOLIN));
|
|
|
|
fontdata.Insert('\\', tileGetTexture(BIGALPHANUM + 68));
|
|
|
|
fontdata.Insert('/', tileGetTexture(BIGALPHANUM + 68));
|
|
|
|
fontdata.Insert('%', tileGetTexture(BIGALPHANUM + 69));
|
|
|
|
fontdata.Insert('`', tileGetTexture(BIGAPPOS));
|
|
|
|
fontdata.Insert('"', tileGetTexture(BIGAPPOS));
|
|
|
|
fontdata.Insert('\'', tileGetTexture(BIGAPPOS));
|
2020-06-29 11:19:36 +00:00
|
|
|
// The texture offsets in this font are useless for font printing. This should only apply to these glyphs, not for international extensions, though.
|
|
|
|
GlyphSet::Iterator it(fontdata);
|
|
|
|
GlyphSet::Pair* pair;
|
|
|
|
while (it.NextPair(pair)) pair->Value->SetOffsetsNotForFont();
|
2020-07-20 21:21:27 +00:00
|
|
|
BigFont = new ::FFont("BigFont", nullptr, "defbigfont", 0, 0, 0, -1, 5, false, false, false, &fontdata);
|
|
|
|
fontdata.Clear();
|
|
|
|
|
|
|
|
// Tiny font
|
|
|
|
for (int i = 0; i < 95; i++)
|
|
|
|
{
|
|
|
|
auto tile = tileGetTexture(MINIFONT + i);
|
|
|
|
if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0)
|
2020-09-29 19:47:32 +00:00
|
|
|
{
|
|
|
|
if (i >= 'a' && i <= 'z' && tileEqualTo(i, i - 32)) continue;
|
2020-07-20 21:21:27 +00:00
|
|
|
fontdata.Insert('!' + i, tile);
|
2020-09-29 19:47:32 +00:00
|
|
|
tile->SetOffsetsNotForFont();
|
|
|
|
}
|
2020-07-20 21:21:27 +00:00
|
|
|
}
|
|
|
|
fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
|
|
|
|
SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, 3, false, false, false, &fontdata);
|
2020-06-29 18:50:18 +00:00
|
|
|
SmallFont2->SetKerning(1);
|
|
|
|
fontdata.Clear();
|
2020-06-28 08:14:42 +00:00
|
|
|
|
2020-07-20 21:21:27 +00:00
|
|
|
// SBAR index font
|
|
|
|
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(THREEBYFIVE + i));
|
|
|
|
fontdata.Insert(':', tileGetTexture(THREEBYFIVE + 10));
|
|
|
|
fontdata.Insert('/', tileGetTexture(THREEBYFIVE + 11));
|
|
|
|
fontdata.Insert('%', tileGetTexture(MINIFONT + '%' - '!'));
|
|
|
|
fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
|
2020-07-25 13:41:11 +00:00
|
|
|
GlyphSet::Iterator iti(fontdata);
|
|
|
|
while (iti.NextPair(pair)) pair->Value->SetOffsetsNotForFont();
|
2020-07-20 21:21:27 +00:00
|
|
|
IndexFont = new ::FFont("IndexFont", nullptr, nullptr, 0, 0, 0, -1, -1, false, false, false, &fontdata);
|
2020-06-28 08:14:42 +00:00
|
|
|
|
2020-07-20 21:21:27 +00:00
|
|
|
fontdata.Clear();
|
2020-06-28 08:14:42 +00:00
|
|
|
|
2020-07-20 21:21:27 +00:00
|
|
|
// digital font
|
|
|
|
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(DIGITALNUM + i));
|
|
|
|
fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation.
|
2020-07-25 13:41:11 +00:00
|
|
|
GlyphSet::Iterator itd(fontdata);
|
|
|
|
while (itd.NextPair(pair)) pair->Value->SetOffsetsNotForFont();
|
2020-07-20 21:21:27 +00:00
|
|
|
DigiFont = new ::FFont("DigiFont", nullptr, nullptr, 0, 0, 0, -1, -1, false, false, false, &fontdata);
|
2020-06-28 08:14:42 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-06-29 18:50:18 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// wrappers around DrawText to allow easier reuse of the old code.
|
|
|
|
// The vertical displacements are to have the same positioning as with the original code.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2020-06-25 19:51:44 +00:00
|
|
|
|
2021-04-23 08:07:02 +00:00
|
|
|
static void BigText(double x, double y, const char* text, int align = -1, double alpha = 1.)
|
2020-06-25 19:51:44 +00:00
|
|
|
{
|
2021-04-23 08:07:02 +00:00
|
|
|
if (align != -1)
|
|
|
|
x -= BigFont->StringWidth(text) * (align == 0 ? 0.5 : 1);
|
|
|
|
DrawText(twod, BigFont, CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Alpha, alpha, TAG_DONE);
|
2020-06-25 19:51:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-27 22:32:28 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2020-07-19 09:57:00 +00:00
|
|
|
void Logo_d(const CompletionFunc &completion)
|
2020-06-25 19:51:44 +00:00
|
|
|
{
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2020-06-27 22:32:28 +00:00
|
|
|
Mus_Stop();
|
|
|
|
FX_StopAllSounds(); // JBF 20031228
|
|
|
|
|
|
|
|
static const AnimSound logosound[] =
|
|
|
|
{
|
|
|
|
{ 1, FLY_BY+1 },
|
|
|
|
{ 19, PIPEBOMB_EXPLODE+1 },
|
|
|
|
{ -1, -1 }
|
|
|
|
};
|
|
|
|
static const int logoframetimes[] = { 9, 9, 9 };
|
|
|
|
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs;
|
2020-06-28 19:38:25 +00:00
|
|
|
int job = 0;
|
2020-08-15 11:04:15 +00:00
|
|
|
if (!userConfig.nologo)
|
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
if (!isShareware()) jobs.Push(PlayVideo("logo.anm", logosound, logoframetimes));
|
|
|
|
if (!isNam()) jobs.Push(Create<DDRealmsScreen>());
|
2020-08-15 11:04:15 +00:00
|
|
|
}
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(Create<DTitleScreen>());
|
|
|
|
RunScreenJob(jobs, completion, SJ_BLOCKUI);
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-06-25 19:51:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-28 12:42:31 +00:00
|
|
|
|
2020-06-29 18:50:18 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
2020-06-27 22:32:28 +00:00
|
|
|
|
2020-07-19 09:57:00 +00:00
|
|
|
void showtwoscreens(const CompletionFunc& completion)
|
2020-07-01 10:55:32 +00:00
|
|
|
{
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs;
|
2020-07-01 10:55:32 +00:00
|
|
|
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(Create<DImageScreen>(3291));
|
|
|
|
jobs.Push(Create<DImageScreen>(3290));
|
|
|
|
RunScreenJob(jobs, completion);
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-07-01 10:55:32 +00:00
|
|
|
}
|
|
|
|
|
2020-07-19 09:57:00 +00:00
|
|
|
void doorders(const CompletionFunc& completion)
|
2020-07-01 10:55:32 +00:00
|
|
|
{
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs;
|
2020-07-01 10:55:32 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(Create<DImageScreen>(ORDERING + i));
|
|
|
|
RunScreenJob(jobs, completion);
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-07-01 10:55:32 +00:00
|
|
|
}
|
|
|
|
|
2020-07-01 18:31:29 +00:00
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2020-09-03 21:10:28 +00:00
|
|
|
void dobonus_d(int bonusonly, const CompletionFunc& completion)
|
2020-07-01 10:55:32 +00:00
|
|
|
{
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs;
|
2020-07-01 18:31:29 +00:00
|
|
|
|
|
|
|
FX_StopAllSounds();
|
|
|
|
|
2020-09-03 21:10:28 +00:00
|
|
|
if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0)
|
2020-07-01 18:31:29 +00:00
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs);
|
2020-07-01 18:31:29 +00:00
|
|
|
}
|
2020-09-27 18:16:03 +00:00
|
|
|
else
|
|
|
|
Mus_Stop();
|
2020-07-01 18:31:29 +00:00
|
|
|
|
|
|
|
if (playerswhenstarted > 1 && ud.coop != 1)
|
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(Create<DDukeMultiplayerBonusScreen>(playerswhenstarted));
|
2020-07-01 18:31:29 +00:00
|
|
|
}
|
2020-09-03 21:10:28 +00:00
|
|
|
else if (bonusonly <= 0 && ud.multimode <= 1)
|
2020-07-01 18:31:29 +00:00
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(Create<DDukeLevelSummaryScreen>());
|
2020-07-01 18:31:29 +00:00
|
|
|
}
|
2021-04-21 22:51:14 +00:00
|
|
|
if (jobs.Size())
|
2021-04-15 22:43:45 +00:00
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
RunScreenJob(jobs, completion);
|
2021-04-15 22:43:45 +00:00
|
|
|
}
|
2020-07-01 18:31:29 +00:00
|
|
|
else if (completion) completion(false);
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-07-01 18:31:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
2020-07-19 09:57:00 +00:00
|
|
|
void e4intro(const CompletionFunc& completion)
|
2020-07-01 18:31:29 +00:00
|
|
|
{
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs;
|
2020-07-01 18:31:29 +00:00
|
|
|
|
|
|
|
static const AnimSound vol42a[] =
|
|
|
|
{
|
|
|
|
{ 1, INTRO4_B + 1 },
|
|
|
|
{ 12, SHORT_CIRCUIT + 1 },
|
|
|
|
{ 18, INTRO4_5 + 1 },
|
|
|
|
{ 34, SHORT_CIRCUIT + 1 },
|
|
|
|
{ -1,-1 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const AnimSound vol41a[] =
|
|
|
|
{
|
|
|
|
{ 1, INTRO4_1 + 1 },
|
|
|
|
{ 7, INTRO4_3 + 1 },
|
|
|
|
{ 12, INTRO4_2 + 1 },
|
|
|
|
{ 26, INTRO4_4 + 1 },
|
|
|
|
{ -1,-1 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const AnimSound vol43a[] =
|
|
|
|
{
|
|
|
|
{ 10, INTRO4_6 + 1 },
|
|
|
|
{ -1,-1 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const int framespeed_10[] = { 10, 10, 10 };
|
|
|
|
static const int framespeed_14[] = { 14, 14, 14 };
|
|
|
|
|
|
|
|
S_PlaySpecialMusic(MUS_BRIEFING);
|
2021-04-21 22:51:14 +00:00
|
|
|
jobs.Push(PlayVideo("vol41a.anm", vol41a, framespeed_10));
|
|
|
|
jobs.Push(PlayVideo("vol42a.anm", vol42a, framespeed_14));
|
|
|
|
jobs.Push(PlayVideo("vol43a.anm", vol43a, framespeed_10));
|
|
|
|
RunScreenJob(jobs, completion, SJ_SKIPALL);
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-07-01 10:55:32 +00:00
|
|
|
}
|
2020-06-27 22:32:28 +00:00
|
|
|
|
2021-04-25 18:02:40 +00:00
|
|
|
#if 0
|
2020-07-03 07:59:24 +00:00
|
|
|
|
2020-09-09 20:42:01 +00:00
|
|
|
void loadscreen_d(MapRecord *rec, CompletionFunc func)
|
|
|
|
{
|
2021-04-21 22:51:14 +00:00
|
|
|
TArray<DScreenJob*> jobs(1, true);
|
|
|
|
|
|
|
|
jobs[0] = Create<DDukeLoadScreen>(rec);
|
|
|
|
RunScreenJob(jobs, func);
|
2020-09-09 20:42:01 +00:00
|
|
|
}
|
2021-04-25 18:02:40 +00:00
|
|
|
#endif
|
2020-09-09 20:42:01 +00:00
|
|
|
|
2020-07-03 08:53:35 +00:00
|
|
|
void PrintPaused_d()
|
|
|
|
{
|
2021-04-25 19:52:58 +00:00
|
|
|
BigText(160, 100, GStrings("Game Paused"));
|
2020-07-03 08:53:35 +00:00
|
|
|
}
|
|
|
|
|
2020-09-25 18:22:30 +00:00
|
|
|
|
2020-06-26 20:49:56 +00:00
|
|
|
END_DUKE_NS
|