2017-03-18 20:19:32 +00:00
|
|
|
/*
|
|
|
|
** wi_stuff.cpp
|
|
|
|
** Support code for intermission status screens
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 2003-2017 Christoph Oelckers
|
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
|
|
** documentation and/or other materials provided with the distribution.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include "m_random.h"
|
|
|
|
#include "m_swap.h"
|
2019-01-31 18:38:04 +00:00
|
|
|
|
2020-04-11 11:36:23 +00:00
|
|
|
#include "filesystem.h"
|
2016-03-01 15:47:10 +00:00
|
|
|
#include "g_level.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "v_video.h"
|
|
|
|
#include "i_video.h"
|
|
|
|
#include "wi_stuff.h"
|
|
|
|
#include "hu_stuff.h"
|
|
|
|
#include "s_sndseq.h"
|
|
|
|
#include "v_text.h"
|
|
|
|
#include "gi.h"
|
|
|
|
#include "d_player.h"
|
|
|
|
#include "d_netinf.h"
|
2016-10-12 17:22:33 +00:00
|
|
|
#include "cmdlib.h"
|
2017-01-08 17:45:30 +00:00
|
|
|
#include "g_levellocals.h"
|
2017-04-12 23:12:04 +00:00
|
|
|
#include "vm.h"
|
2020-04-11 17:00:07 +00:00
|
|
|
#include "texturemanager.h"
|
2020-04-28 15:22:17 +00:00
|
|
|
#include "v_draw.h"
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
CVAR(Bool, wi_percents, true, CVAR_ARCHIVE)
|
|
|
|
CVAR(Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
|
|
|
|
CVAR(Bool, wi_noautostartmap, false, CVAR_USERINFO | CVAR_ARCHIVE)
|
|
|
|
CVAR(Int, wi_autoadvance, 0, CVAR_SERVERINFO)
|
2020-09-25 03:45:40 +00:00
|
|
|
EXTERN_CVAR(Bool, inter_classic_scaling)
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-25 16:55:20 +00:00
|
|
|
// States for the intermission
|
|
|
|
enum EState
|
|
|
|
{
|
|
|
|
NoState = -1,
|
|
|
|
StatCount,
|
|
|
|
ShowNextLoc,
|
|
|
|
LeavingIntermission
|
|
|
|
};
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
static const char *WI_Cmd[] = {
|
|
|
|
"Background",
|
|
|
|
"Splat",
|
|
|
|
"Pointer",
|
|
|
|
"Spots",
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
"IfEntering",
|
|
|
|
"IfNotEntering",
|
|
|
|
"IfVisited",
|
|
|
|
"IfNotVisited",
|
|
|
|
"IfLeaving",
|
|
|
|
"IfNotLeaving",
|
|
|
|
"IfTravelling",
|
|
|
|
"IfNotTravelling",
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
"Animation",
|
|
|
|
"Pic",
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
"NoAutostartMap",
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
NULL
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
class DInterBackground : public DObject
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
DECLARE_ABSTRACT_CLASS(DInterBackground, DObject)
|
|
|
|
|
2017-02-22 22:52:25 +00:00
|
|
|
// These animation variables, structures, etc. are used for the
|
|
|
|
// DOOM/Ultimate DOOM intermission screen animations. This is
|
|
|
|
// totally different from any sprite or texture/flat animations
|
|
|
|
enum EAnim
|
|
|
|
{
|
|
|
|
ANIM_ALWAYS, // determined by patch entry
|
|
|
|
ANIM_PIC, // continuous
|
|
|
|
|
|
|
|
// condition bitflags
|
|
|
|
ANIM_IFVISITED = 8,
|
|
|
|
ANIM_IFNOTVISITED = 16,
|
|
|
|
ANIM_IFENTERING = 32,
|
|
|
|
ANIM_IFNOTENTERING = 64,
|
|
|
|
ANIM_IFLEAVING = 128,
|
|
|
|
ANIM_IFNOTLEAVING = 256,
|
|
|
|
ANIM_IFTRAVELLING = 512,
|
|
|
|
ANIM_IFNOTTRAVELLING = 1024,
|
|
|
|
|
|
|
|
ANIM_TYPE = 7,
|
|
|
|
ANIM_CONDITION = ~7,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct yahpt_t
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lnode_t
|
|
|
|
{
|
|
|
|
int x; // x/y coordinate pair structure
|
|
|
|
int y;
|
2017-02-25 16:55:20 +00:00
|
|
|
FString Level;
|
2017-02-22 22:52:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct in_anim_t
|
|
|
|
{
|
|
|
|
int type; // Made an int so I can use '|'
|
|
|
|
int period; // period in tics between animations
|
|
|
|
yahpt_t loc; // location of animation
|
|
|
|
int data; // ALWAYS: n/a, RANDOM: period deviation (<256)
|
2020-04-13 23:01:29 +00:00
|
|
|
TArray<FGameTexture*> frames; // actual graphics for frames of animations
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-02-25 16:55:20 +00:00
|
|
|
// following must be initialized to zero before use!
|
2017-02-22 22:52:25 +00:00
|
|
|
int nexttic; // next value of bcnt (used in conjunction with period)
|
|
|
|
int ctr; // next frame number to animate
|
|
|
|
int state; // used by RANDOM and LEVEL when animating
|
|
|
|
|
2017-02-22 23:16:14 +00:00
|
|
|
FString LevelName;
|
|
|
|
FString LevelName2;
|
|
|
|
|
|
|
|
void Reset()
|
|
|
|
{
|
|
|
|
type = period = loc.x = loc.y = data = nexttic = ctr = state = 0;
|
|
|
|
LevelName = "";
|
|
|
|
LevelName2 = "";
|
|
|
|
frames.Clear();
|
|
|
|
}
|
2017-02-22 22:52:25 +00:00
|
|
|
};
|
|
|
|
|
2017-02-25 16:55:20 +00:00
|
|
|
private:
|
2017-02-22 22:52:25 +00:00
|
|
|
TArray<lnode_t> lnodes;
|
|
|
|
TArray<in_anim_t> anims;
|
2017-02-25 16:55:20 +00:00
|
|
|
int bcnt = 0; // used for timing of background animation
|
2020-04-13 23:01:29 +00:00
|
|
|
TArray<FGameTexture *> yah; // You Are Here graphic
|
|
|
|
FGameTexture* splat = nullptr; // splat
|
|
|
|
FGameTexture *background = nullptr;
|
2017-02-25 16:55:20 +00:00
|
|
|
wbstartstruct_t *wbs;
|
2019-01-06 08:03:58 +00:00
|
|
|
level_info_t *exitlevel;
|
2017-03-18 12:25:22 +00:00
|
|
|
|
2017-02-25 16:55:20 +00:00
|
|
|
public:
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
DInterBackground(wbstartstruct_t *wbst);
|
|
|
|
bool LoadBackground(bool isenterpic);
|
|
|
|
void updateAnimatedBack();
|
|
|
|
void drawBackground(int state, bool drawsplat, bool snl_pointeron);
|
|
|
|
|
|
|
|
private:
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-02-25 16:55:20 +00:00
|
|
|
bool IsExMy(const char * name)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
|
|
|
// Only check for the first 3 episodes. They are the only ones with default intermission scripts.
|
2017-03-18 12:25:22 +00:00
|
|
|
// Level names can be upper- and lower case so use tolower to check.
|
2017-02-25 16:55:20 +00:00
|
|
|
return (tolower(name[0]) == 'e' && name[1] >= '1' && name[1] <= '3' && tolower(name[2]) == 'm');
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Draws the splats and the 'You are here' arrows
|
|
|
|
//
|
|
|
|
//====================================================================
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
int MapToIndex(const char *map)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
unsigned int i;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
for (i = 0; i < lnodes.Size(); i++)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
if (!lnodes[i].Level.CompareNoCase(map))
|
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Draws the splats and the 'You are here' arrows
|
|
|
|
//
|
|
|
|
//====================================================================
|
|
|
|
|
2020-10-03 07:07:29 +00:00
|
|
|
void drawOnLnode(int n, FGameTexture * c[], int numc, double backwidth, double backheight)
|
2017-03-18 12:25:22 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i<numc; i++)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2020-04-13 23:01:29 +00:00
|
|
|
double left;
|
|
|
|
double top;
|
|
|
|
double right;
|
|
|
|
double bottom;
|
2017-03-18 12:25:22 +00:00
|
|
|
|
|
|
|
|
2018-12-06 19:12:15 +00:00
|
|
|
right = c[i]->GetDisplayWidth();
|
|
|
|
bottom = c[i]->GetDisplayHeight();
|
|
|
|
left = lnodes[n].x - c[i]->GetDisplayLeftOffset();
|
|
|
|
top = lnodes[n].y - c[i]->GetDisplayTopOffset();
|
2017-03-18 12:25:22 +00:00
|
|
|
right += left;
|
|
|
|
bottom += top;
|
|
|
|
|
|
|
|
if (left >= 0 && right < 320 && top >= 0 && bottom < 200)
|
|
|
|
{
|
2020-10-03 07:07:29 +00:00
|
|
|
DrawTexture(twod, c[i], lnodes[n].x, lnodes[n].y, DTA_FullscreenScale, FSMode_ScaleToFit43, DTA_VirtualWidthF, backwidth, DTA_VirtualHeightF, backheight, TAG_DONE);
|
2017-03-18 12:25:22 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
};
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
DInterBackground:: DInterBackground(wbstartstruct_t *wbst)
|
|
|
|
{
|
|
|
|
wbs = wbst;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION(DInterBackground, Create)
|
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
PARAM_POINTER(wbst, wbstartstruct_t);
|
2017-04-14 11:31:58 +00:00
|
|
|
ACTION_RETURN_POINTER(Create<DInterBackground>(wbst));
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Loads the background - either from a single texture
|
|
|
|
// or an intermission lump.
|
|
|
|
// Unfortunately the texture manager is incapable of recognizing text
|
|
|
|
// files so if you use a script you have to prefix its name by '$' in
|
|
|
|
// MAPINFO.
|
|
|
|
//
|
|
|
|
//====================================================================
|
|
|
|
|
|
|
|
bool DInterBackground::LoadBackground(bool isenterpic)
|
|
|
|
{
|
2019-01-06 08:03:58 +00:00
|
|
|
const char *lumpname = nullptr;
|
|
|
|
const char *exitpic = nullptr;
|
2017-03-18 12:25:22 +00:00
|
|
|
char buffer[10];
|
|
|
|
in_anim_t an;
|
|
|
|
lnode_t pt;
|
|
|
|
FTextureID texture;
|
|
|
|
bool noautostartmap = false;
|
|
|
|
|
|
|
|
bcnt = 0;
|
|
|
|
|
|
|
|
texture.SetInvalid();
|
2019-01-06 08:03:58 +00:00
|
|
|
|
|
|
|
level_info_t * li = FindLevelInfo(wbs->current);
|
2019-02-06 14:39:47 +00:00
|
|
|
if (li != nullptr) exitpic = li->ExitPic;
|
2019-01-06 08:03:58 +00:00
|
|
|
lumpname = exitpic;
|
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
if (isenterpic)
|
|
|
|
{
|
|
|
|
level_info_t * li = FindLevelInfo(wbs->next);
|
|
|
|
if (li != NULL) lumpname = li->EnterPic;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to get a default if nothing specified
|
|
|
|
if (lumpname == NULL || lumpname[0] == 0)
|
|
|
|
{
|
|
|
|
lumpname = NULL;
|
|
|
|
switch (gameinfo.gametype)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
case GAME_Chex:
|
|
|
|
case GAME_Doom:
|
|
|
|
if (!(gameinfo.flags & GI_MAPxx))
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2019-01-06 08:03:58 +00:00
|
|
|
const char *levelname = isenterpic ? wbs->next : wbs->current;
|
|
|
|
if (IsExMy(levelname))
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2019-01-06 08:03:58 +00:00
|
|
|
mysnprintf(buffer, countof(buffer), "$IN_EPI%c", levelname[1]);
|
2017-03-18 12:25:22 +00:00
|
|
|
lumpname = buffer;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
if (!lumpname)
|
|
|
|
{
|
|
|
|
if (isenterpic)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2019-01-06 08:03:58 +00:00
|
|
|
// One special case needs to be handled here:
|
2017-03-18 12:25:22 +00:00
|
|
|
// If going from E1-E3 to E4 the default should be used, not the exit pic.
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2019-01-06 08:03:58 +00:00
|
|
|
// Not if the exit pic is user defined.
|
|
|
|
if (exitpic && exitpic[0]) return false;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
// E1-E3 need special treatment when playing Doom 1.
|
|
|
|
if (!(gameinfo.flags & GI_MAPxx))
|
|
|
|
{
|
|
|
|
// not if the last level is not from the first 3 episodes
|
|
|
|
if (!IsExMy(wbs->current)) return false;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
// not if the next level is one of the first 3 episodes
|
|
|
|
if (IsExMy(wbs->next)) return false;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
lumpname = "INTERPIC";
|
|
|
|
}
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case GAME_Heretic:
|
|
|
|
if (isenterpic)
|
|
|
|
{
|
|
|
|
if (IsExMy(wbs->next))
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
mysnprintf(buffer, countof(buffer), "$IN_HTC%c", wbs->next[1]);
|
|
|
|
lumpname = buffer;
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
if (!lumpname)
|
|
|
|
{
|
2017-02-25 16:55:20 +00:00
|
|
|
if (isenterpic) return false;
|
2017-03-18 12:25:22 +00:00
|
|
|
lumpname = "FLOOR16";
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case GAME_Hexen:
|
|
|
|
if (isenterpic) return false;
|
|
|
|
lumpname = "INTERPIC";
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case GAME_Strife:
|
|
|
|
default:
|
|
|
|
// Strife doesn't have an intermission pic so choose something neutral.
|
|
|
|
if (isenterpic) return false;
|
|
|
|
lumpname = gameinfo.BorderFlat;
|
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
if (lumpname == NULL)
|
|
|
|
{
|
|
|
|
// shouldn't happen!
|
|
|
|
background = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
lnodes.Clear();
|
|
|
|
anims.Clear();
|
|
|
|
yah.Clear();
|
|
|
|
splat = NULL;
|
|
|
|
|
|
|
|
// a name with a starting '$' indicates an intermission script
|
|
|
|
if (*lumpname != '$')
|
|
|
|
{
|
2018-03-25 18:26:16 +00:00
|
|
|
texture = TexMan.CheckForTexture(lumpname, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 11:24:34 +00:00
|
|
|
int lumpnum = fileSystem.CheckNumForFullName(lumpname + 1, true);
|
2017-03-18 12:25:22 +00:00
|
|
|
if (lumpnum >= 0)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
FScanner sc(lumpnum);
|
|
|
|
while (sc.GetString())
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
an.Reset();
|
|
|
|
int caseval = sc.MustMatchString(WI_Cmd);
|
|
|
|
switch (caseval)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
case 0: // Background
|
|
|
|
sc.MustGetString();
|
2018-03-25 18:26:16 +00:00
|
|
|
texture = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
2017-03-18 12:25:22 +00:00
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 1: // Splat
|
|
|
|
sc.MustGetString();
|
2020-04-13 23:01:29 +00:00
|
|
|
splat = TexMan.GetGameTextureByName(sc.String);
|
2017-03-18 12:25:22 +00:00
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 2: // Pointers
|
|
|
|
while (sc.GetString() && !sc.Crossed)
|
|
|
|
{
|
2020-04-13 23:01:29 +00:00
|
|
|
yah.Push(TexMan.GetGameTextureByName(sc.String));
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
if (sc.Crossed)
|
|
|
|
sc.UnGet();
|
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 3: // Spots
|
|
|
|
sc.MustGetStringName("{");
|
|
|
|
while (!sc.CheckString("}"))
|
|
|
|
{
|
|
|
|
sc.MustGetString();
|
|
|
|
pt.Level = sc.String;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
pt.x = sc.Number;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
pt.y = sc.Number;
|
|
|
|
lnodes.Push(pt);
|
|
|
|
}
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 4: // IfEntering
|
|
|
|
an.type = ANIM_IFENTERING;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 5: // IfEntering
|
|
|
|
an.type = ANIM_IFNOTENTERING;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 6: // IfVisited
|
|
|
|
an.type = ANIM_IFVISITED;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 7: // IfNotVisited
|
|
|
|
an.type = ANIM_IFNOTVISITED;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 8: // IfLeaving
|
|
|
|
an.type = ANIM_IFLEAVING;
|
|
|
|
goto readanimation;
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 9: // IfNotLeaving
|
|
|
|
an.type = ANIM_IFNOTLEAVING;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 10: // IfTravelling
|
|
|
|
an.type = ANIM_IFTRAVELLING;
|
|
|
|
sc.MustGetString();
|
|
|
|
an.LevelName2 = sc.String;
|
|
|
|
goto readanimation;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 11: // IfNotTravelling
|
|
|
|
an.type = ANIM_IFTRAVELLING;
|
|
|
|
sc.MustGetString();
|
|
|
|
an.LevelName2 = sc.String;
|
|
|
|
goto readanimation;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case 14: // NoAutostartMap
|
|
|
|
noautostartmap = true;
|
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
readanimation:
|
|
|
|
sc.MustGetString();
|
|
|
|
an.LevelName = sc.String;
|
|
|
|
sc.MustGetString();
|
|
|
|
caseval = sc.MustMatchString(WI_Cmd);
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
default:
|
|
|
|
switch (caseval)
|
|
|
|
{
|
|
|
|
case 12: // Animation
|
|
|
|
an.type |= ANIM_ALWAYS;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
an.loc.x = sc.Number;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
an.loc.y = sc.Number;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
an.period = sc.Number;
|
|
|
|
an.nexttic = 1 + (M_Random() % an.period);
|
|
|
|
if (sc.GetString())
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
if (sc.Compare("ONCE"))
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
an.data = 1;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-02-22 22:52:25 +00:00
|
|
|
else
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
sc.UnGet();
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
if (!sc.CheckString("{"))
|
|
|
|
{
|
2017-02-22 22:52:25 +00:00
|
|
|
sc.MustGetString();
|
2020-04-13 23:01:29 +00:00
|
|
|
an.frames.Push(TexMan.GetGameTextureByName(sc.String));
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while (!sc.CheckString("}"))
|
|
|
|
{
|
|
|
|
sc.MustGetString();
|
2020-04-13 23:01:29 +00:00
|
|
|
an.frames.Push(TexMan.GetGameTextureByName(sc.String));
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
an.ctr = -1;
|
|
|
|
anims.Push(an);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 13: // Pic
|
|
|
|
an.type |= ANIM_PIC;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
an.loc.x = sc.Number;
|
|
|
|
sc.MustGetNumber();
|
|
|
|
an.loc.y = sc.Number;
|
|
|
|
sc.MustGetString();
|
|
|
|
an.frames.Reserve(1); // allocate exactly one element
|
2020-04-13 23:01:29 +00:00
|
|
|
an.frames[0] = TexMan.GetGameTextureByName(sc.String);
|
2017-03-18 12:25:22 +00:00
|
|
|
anims.Push(an);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
sc.ScriptError("Unknown token %s in intermission script", sc.String);
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Printf("Intermission script %s not found!\n", lumpname + 1);
|
2018-12-07 01:31:30 +00:00
|
|
|
texture = TexMan.GetTextureID("INTERPIC", ETextureType::MiscPatch);
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2020-04-13 23:01:29 +00:00
|
|
|
background = TexMan.GetGameTexture(texture);
|
2017-03-18 12:25:22 +00:00
|
|
|
return noautostartmap;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DInterBackground, LoadBackground)
|
|
|
|
{
|
|
|
|
PARAM_SELF_PROLOGUE(DInterBackground);
|
|
|
|
PARAM_BOOL(isenterpic);
|
|
|
|
ACTION_RETURN_BOOL(self->LoadBackground(isenterpic));
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// made this more generic and configurable through a script
|
|
|
|
// Removed all the ugly special case handling for different game modes
|
|
|
|
//
|
|
|
|
//====================================================================
|
|
|
|
|
|
|
|
void DInterBackground::updateAnimatedBack()
|
|
|
|
{
|
|
|
|
unsigned int i;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
bcnt++;
|
|
|
|
for (i = 0; i<anims.Size(); i++)
|
|
|
|
{
|
|
|
|
in_anim_t * a = &anims[i];
|
|
|
|
switch (a->type & ANIM_TYPE)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_ALWAYS:
|
|
|
|
if (bcnt >= a->nexttic)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
if (++a->ctr >= (int)a->frames.Size())
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
if (a->data == 0) a->ctr = 0;
|
|
|
|
else a->ctr--;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
a->nexttic = bcnt + a->period;
|
|
|
|
}
|
|
|
|
break;
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_PIC:
|
|
|
|
a->ctr = 0;
|
|
|
|
break;
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DInterBackground, updateAnimatedBack)
|
|
|
|
{
|
|
|
|
PARAM_SELF_PROLOGUE(DInterBackground);
|
|
|
|
self->updateAnimatedBack();
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Draws the background including all animations
|
|
|
|
//
|
|
|
|
//====================================================================
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointeron)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
double animwidth = 320; // For a flat fill or clear background scale animations to 320x200
|
|
|
|
double animheight = 200;
|
|
|
|
|
|
|
|
if (background)
|
|
|
|
{
|
|
|
|
// background
|
2018-12-06 19:12:15 +00:00
|
|
|
if (background->isMiscPatch())
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
// scale all animations below to fit the size of the base pic
|
|
|
|
// The base pic is always scaled to fit the screen so this allows
|
|
|
|
// placing the animations precisely where they belong on the base pic
|
2020-04-13 23:01:29 +00:00
|
|
|
animwidth = background->GetDisplayWidth();
|
|
|
|
animheight = background->GetDisplayHeight();
|
2020-10-03 07:07:29 +00:00
|
|
|
if (animheight == 200) animwidth = 320; // deal with widescreen replacements that keep the original coordinates.
|
|
|
|
DrawTexture(twod, background, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, TAG_DONE);
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-02-25 16:55:20 +00:00
|
|
|
else
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2020-09-25 03:45:40 +00:00
|
|
|
twod->AddFlatFill(0, 0, twod->GetWidth(), twod->GetHeight(), background, (inter_classic_scaling ? -1 : 0));
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-04-11 17:48:14 +00:00
|
|
|
ClearRect(twod, 0, 0, twod->GetWidth(), twod->GetHeight(), 0, 0);
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
for (i = 0; i<anims.Size(); i++)
|
|
|
|
{
|
|
|
|
in_anim_t * a = &anims[i];
|
2019-01-23 20:37:51 +00:00
|
|
|
level_info_t *li;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
switch (a->type & ANIM_CONDITION)
|
|
|
|
{
|
|
|
|
case ANIM_IFVISITED:
|
|
|
|
li = FindLevelInfo(a->LevelName);
|
|
|
|
if (li == NULL || !(li->flags & LEVEL_VISITED)) continue;
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFNOTVISITED:
|
|
|
|
li = FindLevelInfo(a->LevelName);
|
|
|
|
if (li == NULL || (li->flags & LEVEL_VISITED)) continue;
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
// StatCount means 'leaving' - everything else means 'entering'!
|
|
|
|
case ANIM_IFENTERING:
|
|
|
|
if (state == StatCount || strnicmp(a->LevelName, wbs->next, 8)) continue;
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFNOTENTERING:
|
|
|
|
if (state != StatCount && !strnicmp(a->LevelName, wbs->next, 8)) continue;
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFLEAVING:
|
|
|
|
if (state != StatCount || strnicmp(a->LevelName, wbs->current, 8)) continue;
|
|
|
|
break;
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFNOTLEAVING:
|
|
|
|
if (state == StatCount && !strnicmp(a->LevelName, wbs->current, 8)) continue;
|
|
|
|
break;
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFTRAVELLING:
|
|
|
|
if (strnicmp(a->LevelName2, wbs->current, 8) || strnicmp(a->LevelName, wbs->next, 8)) continue;
|
|
|
|
break;
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
case ANIM_IFNOTTRAVELLING:
|
|
|
|
if (!strnicmp(a->LevelName2, wbs->current, 8) && !strnicmp(a->LevelName, wbs->next, 8)) continue;
|
|
|
|
break;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 12:25:22 +00:00
|
|
|
if (a->ctr >= 0)
|
2020-04-11 17:46:57 +00:00
|
|
|
DrawTexture(twod, a->frames[a->ctr], a->loc.x, a->loc.y,
|
2020-10-03 07:07:29 +00:00
|
|
|
DTA_VirtualWidthF, animwidth, DTA_VirtualHeightF, animheight, DTA_FullscreenScale, FSMode_ScaleToFit43, TAG_DONE);
|
2017-02-25 16:55:20 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
if (drawsplat)
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
for (i = 0; i<lnodes.Size(); i++)
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
level_info_t * li = FindLevelInfo(lnodes[i].Level);
|
2020-10-03 07:07:29 +00:00
|
|
|
if (li && li->flags & LEVEL_VISITED) drawOnLnode(i, &splat, 1, animwidth, animheight); // draw a splat on taken cities.
|
2017-02-25 16:55:20 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
// draw flashing ptr
|
|
|
|
if (snl_pointeron && yah.Size())
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 12:25:22 +00:00
|
|
|
unsigned int v = MapToIndex(wbs->next);
|
|
|
|
// Draw only if it points to a valid level on the current screen!
|
2020-10-03 07:07:29 +00:00
|
|
|
if (v<lnodes.Size()) drawOnLnode(v, &yah[0], yah.Size(), animwidth, animheight);
|
2017-03-18 12:25:22 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DInterBackground, drawBackground)
|
|
|
|
{
|
|
|
|
PARAM_SELF_PROLOGUE(DInterBackground);
|
|
|
|
PARAM_INT(state);
|
|
|
|
PARAM_BOOL(splat);
|
|
|
|
PARAM_BOOL(pointer);
|
|
|
|
self->drawBackground(state, splat, pointer);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
IMPLEMENT_CLASS(DInterBackground, true, false)
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
DObject *WI_Screen;
|
|
|
|
|
2017-03-18 12:25:22 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//====================================================================
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
void WI_Ticker()
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
if (WI_Screen)
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2020-04-28 15:22:17 +00:00
|
|
|
ScaleOverrider s(twod);
|
2017-03-18 20:19:32 +00:00
|
|
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
VMValue self = WI_Screen;
|
2017-04-12 23:12:04 +00:00
|
|
|
VMCall(func, &self, 1, nullptr, 0);
|
2017-02-25 16:55:20 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-18 20:19:32 +00:00
|
|
|
}
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Called by main loop,
|
|
|
|
// draws the intermission directly into the screen buffer.
|
|
|
|
//
|
|
|
|
//====================================================================
|
2017-02-25 16:55:20 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
void WI_Drawer()
|
2017-02-25 16:55:20 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
if (WI_Screen)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2020-04-28 15:22:17 +00:00
|
|
|
ScaleOverrider s(twod);
|
2017-03-18 20:19:32 +00:00
|
|
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2020-06-06 08:19:02 +00:00
|
|
|
twod->ClearClipRect();
|
2020-06-15 22:11:06 +00:00
|
|
|
twod->ClearScreen();
|
2017-03-18 20:19:32 +00:00
|
|
|
VMValue self = WI_Screen;
|
2017-04-12 23:12:04 +00:00
|
|
|
VMCall(func, &self, 1, nullptr, 0);
|
2020-04-11 17:46:57 +00:00
|
|
|
twod->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
// The internal handling here is somewhat poor. After being set to 'LeavingIntermission'
|
|
|
|
// the screen is needed for one more draw operation so we cannot delete it right away but only here.
|
|
|
|
if (WI_Screen->IntVar("CurState") == LeavingIntermission)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
WI_Screen->Destroy();
|
|
|
|
GC::DelSoftRoot(WI_Screen);
|
|
|
|
WI_Screen = nullptr;
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 20:19:32 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
// Setup for an intermission screen.
|
|
|
|
//
|
|
|
|
//====================================================================
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
void WI_Start(wbstartstruct_t *wbstartstruct)
|
|
|
|
{
|
|
|
|
FName screenclass = deathmatch ? gameinfo.statusscreen_dm : multiplayer ? gameinfo.statusscreen_coop : gameinfo.statusscreen_single;
|
|
|
|
auto cls = PClass::FindClass(screenclass);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
if (cls == nullptr || !cls->IsDescendantOf("StatusScreen"))
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
// Name was invalid - pick some working default.
|
|
|
|
Printf("Status screen class %s not found - reverting to default", screenclass.GetChars());
|
|
|
|
screenclass = deathmatch ? NAME_DeathmatchStatusScreen : multiplayer ? NAME_CoopStatusScreen : NAME_RavenStatusScreen;
|
|
|
|
cls = PClass::FindClass(screenclass);
|
|
|
|
if (cls == nullptr)
|
2017-02-22 22:52:25 +00:00
|
|
|
{
|
2018-05-25 08:05:30 +00:00
|
|
|
I_FatalError("Cannot create status screen");
|
2017-02-22 22:52:25 +00:00
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
- allow the language table to supersede the title patches, if appropriate
For the Doom IWADs the provided font looks almost identical to the characters used on the title patches. So, for any level name that got replaced in some language, it will now check if the retrieved name comes from the default table, and if not, ignore the title patch and print the name with the specified font.
This also required removing the 'en' label from the default table, because with this present, the text would always be picked from 'en' instead of 'default'. Since 'en' and 'default' had the same contents, in any English locale the 'default' table was never hit, so this won't make any difference for the texts being chosen.
Last but not least, wminfo has been made a local variable in G_DoCompleted. There were two places where this was accessed from outside the summary screen or its setup code, and both were incorrect.
2019-02-14 23:29:24 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
WI_Screen = cls->CreateNew();
|
2020-04-28 15:22:17 +00:00
|
|
|
ScaleOverrider s(twod);
|
2017-03-18 20:19:32 +00:00
|
|
|
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
VMValue val[2] = { WI_Screen, wbstartstruct };
|
2017-04-12 23:12:04 +00:00
|
|
|
VMCall(func, val, 2, nullptr, 0);
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 20:19:32 +00:00
|
|
|
GC::AddSoftRoot(WI_Screen);
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//====================================================================
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DStatusScreen, GetPlayerWidths)
|
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
int maxnamewidth, maxscorewidth, maxiconheight;
|
|
|
|
HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight);
|
|
|
|
if (numret > 0) ret[0].SetInt(maxnamewidth);
|
|
|
|
if (numret > 1) ret[1].SetInt(maxscorewidth);
|
|
|
|
if (numret > 2) ret[2].SetInt(maxiconheight);
|
|
|
|
return MIN(numret, 3);
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//====================================================================
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DStatusScreen, GetRowColor)
|
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
PARAM_POINTER(p, player_t);
|
|
|
|
PARAM_BOOL(highlight);
|
|
|
|
ACTION_RETURN_INT(HU_GetRowColor(p, highlight));
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//====================================================================
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
DEFINE_ACTION_FUNCTION(DStatusScreen, GetSortedPlayers)
|
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
PARAM_POINTER(array, TArray<int>);
|
|
|
|
PARAM_BOOL(teamplay);
|
2017-02-22 22:52:25 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
player_t *sortedplayers[MAXPLAYERS];
|
|
|
|
// Sort all players
|
|
|
|
for (int i = 0; i < MAXPLAYERS; i++)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
sortedplayers[i] = &players[i];
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
if (teamplay)
|
|
|
|
qsort(sortedplayers, MAXPLAYERS, sizeof(player_t *), compareteams);
|
|
|
|
else
|
|
|
|
qsort(sortedplayers, MAXPLAYERS, sizeof(player_t *), comparepoints);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
array->Resize(MAXPLAYERS);
|
|
|
|
for (unsigned i = 0; i < MAXPLAYERS; i++)
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-03-18 20:19:32 +00:00
|
|
|
(*array)[i] = int(sortedplayers[i] - players);
|
2016-03-01 15:47:10 +00:00
|
|
|
}
|
2017-03-18 20:19:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-18 20:19:32 +00:00
|
|
|
//====================================================================
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//====================================================================
|
2017-03-18 18:34:03 +00:00
|
|
|
|
2017-02-23 23:28:33 +00:00
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, skills);
|
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, sitems);
|
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, ssecret);
|
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, stime);
|
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, frags);
|
|
|
|
DEFINE_FIELD_X(WBPlayerStruct, wbplayerstruct_t, fragcount);
|
|
|
|
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, finished_ep);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, next_ep);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, current);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, next);
|
2017-03-18 18:34:03 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, nextname);
|
- allow the language table to supersede the title patches, if appropriate
For the Doom IWADs the provided font looks almost identical to the characters used on the title patches. So, for any level name that got replaced in some language, it will now check if the retrieved name comes from the default table, and if not, ignore the title patch and print the name with the specified font.
This also required removing the 'en' label from the default table, because with this present, the text would always be picked from 'en' instead of 'default'. Since 'en' and 'default' had the same contents, in any English locale the 'default' table was never hit, so this won't make any difference for the texts being chosen.
Last but not least, wminfo has been made a local variable in G_DoCompleted. There were two places where this was accessed from outside the summary screen or its setup code, and both were incorrect.
2019-02-14 23:29:24 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, thisname);
|
2019-08-02 07:11:40 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, nextauthor);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, thisauthor);
|
2017-02-23 23:28:33 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, LName0);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, LName1);
|
2020-08-30 13:34:53 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, totalkills);
|
2017-02-23 23:28:33 +00:00
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, maxkills);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, maxitems);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, maxsecret);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, maxfrags);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, partime);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, sucktime);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, totaltime);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, pnum);
|
|
|
|
DEFINE_FIELD_X(WBStartStruct, wbstartstruct_t, plyr);
|
2017-03-18 11:16:44 +00:00
|
|
|
|