mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 00:21:34 +00:00
1acc3d00c4
palettes smaller than 256 entries with the shader I wrote for it. Is there a list of gotchas like this listed some where? I'd really like to see it. Well, when compiled with SM2.0, the PalTex shader seems to be every-so- slightly faster on my GF7950GT than the SM1.4 version, so I guess it's a minor win for cards that support it. - Fixed: ST_Endoom() failed to free the bitmap it used. - Added the DTA_ColorOverlay attribute to blend a color with the texture being drawn. For software, this (currently) only works with black. For hardware, it works with any color. The motiviation for this was so I could rewrite the status bar calls that passed DIM_MAP to DTA_Translation to draw darker icons into something that didn't require making a whole new remap table. - After having an "OMG! How could I have been so stupid?" moment, I have removed the off-by-one check from D3DFB. I had thought the off-by-one error was caused by rounding errors by the shader hardware. Not so. Rather, I wasn't sampling what I thought I was sampling. A texture that uses palette index 255 passes the value 1.0 to the shader. The shader needs to adjust the range of its palette indexes, or it will end up trying to read color 256 from the palette texture when it should be reading color 255. Doh! - The TranslationToTable() function has been added to map from translation numbers used by actors to the tables those numbers represent. This function performs validation for the input and returns NULL if the input value is invalid. - Major changes to the way translation tables work: No longer are they each a 256-byte array. Instead, the FRemapTable structure is used to represent each one. It includes a remap array for the software renderer, a palette array for a hardware renderer, and a native texture pointer for D3DFB. The translationtables array itself is now an array of TArrays that point to the real tables. The DTA_Translation attribute must also be passed a pointer to a FRemapTable, not a byte array as previously. - Modified DFrameBuffer::DrawRateStuff() so that it can do its thing properly for D3DFB's 2D mode. Before, any fullscreen graphics (like help images) covered it up. SVN r640 (trunk)
2094 lines
48 KiB
C++
2094 lines
48 KiB
C++
// Emacs style mode select -*- C++ -*-
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Id:$
|
|
//
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
//
|
|
// This source is available for distribution and/or modification
|
|
// only under the terms of the DOOM Source Code License as
|
|
// published by id Software. All rights reserved.
|
|
//
|
|
// The source is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
|
// for more details.
|
|
//
|
|
// $Log:$
|
|
//
|
|
// DESCRIPTION:
|
|
// Intermission screens.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Enhancements by Graf Zahl
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
|
|
#include "m_random.h"
|
|
#include "m_swap.h"
|
|
#include "i_system.h"
|
|
#include "w_wad.h"
|
|
#include "g_game.h"
|
|
#include "g_level.h"
|
|
#include "r_local.h"
|
|
#include "s_sound.h"
|
|
#include "doomstat.h"
|
|
#include "v_video.h"
|
|
#include "i_video.h"
|
|
#include "wi_stuff.h"
|
|
#include "c_console.h"
|
|
#include "hu_stuff.h"
|
|
#include "v_palette.h"
|
|
#include "s_sndseq.h"
|
|
#include "sc_man.h"
|
|
#include "v_text.h"
|
|
#include "gi.h"
|
|
|
|
// States for the intermission
|
|
typedef enum
|
|
{
|
|
NoState = -1,
|
|
StatCount,
|
|
ShowNextLoc,
|
|
LeavingIntermission
|
|
} stateenum_t;
|
|
|
|
CVAR (Bool, wi_percents, true, CVAR_ARCHIVE)
|
|
CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
|
|
CVAR (Bool, wi_noautostartmap, false, CVAR_ARCHIVE)
|
|
|
|
|
|
void WI_loadData ();
|
|
void WI_unloadData ();
|
|
|
|
#define NEXTSTAGE (gameinfo.gametype == GAME_Doom ? "weapons/rocklx" : "doors/dr1_clos")
|
|
#define PASTSTATS (gameinfo.gametype == GAME_Doom ? "weapons/shotgr" : "plats/pt1_stop")
|
|
|
|
// GLOBAL LOCATIONS
|
|
#define WI_TITLEY 2
|
|
#define WI_SPACINGY 33
|
|
|
|
// SINGPLE-PLAYER STUFF
|
|
#define SP_STATSX 50
|
|
#define SP_STATSY 50
|
|
|
|
#define SP_TIMEX 8
|
|
#define SP_TIMEY (200-32)
|
|
|
|
|
|
// NET GAME STUFF
|
|
#define NG_STATSY 50
|
|
#define NG_STATSX (32 + star->GetWidth()/2 + 32*!dofrags)
|
|
|
|
#define NG_SPACINGX 64
|
|
|
|
|
|
// DEATHMATCH STUFF
|
|
#define DM_MATRIXX 42
|
|
#define DM_MATRIXY 68
|
|
|
|
#define DM_SPACINGX 40
|
|
|
|
#define DM_TOTALSX 269
|
|
|
|
#define DM_KILLERSX 10
|
|
#define DM_KILLERSY 100
|
|
#define DM_VICTIMSX 5
|
|
#define DM_VICTIMSY 50
|
|
|
|
// 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
|
|
typedef enum
|
|
{
|
|
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,
|
|
|
|
} animenum_t;
|
|
|
|
typedef struct
|
|
{
|
|
int x, y;
|
|
} yahpt_t;
|
|
|
|
struct lnode_t
|
|
{
|
|
int x; // x/y coordinate pair structure
|
|
int y;
|
|
char level[9];
|
|
} ;
|
|
|
|
|
|
#define FACEBACKOFS 4
|
|
|
|
|
|
//
|
|
// Animation.
|
|
// There is another anim_t used in p_spec.
|
|
// (which is why I have renamed this one!)
|
|
//
|
|
|
|
#define MAX_ANIMATION_FRAMES 20
|
|
typedef struct
|
|
{
|
|
int type; // Made an int so I can use '|'
|
|
int period; // period in tics between animations
|
|
int nanims; // number of animation frames
|
|
yahpt_t loc; // location of animation
|
|
int data; // ALWAYS: n/a, RANDOM: period deviation (<256)
|
|
FTexture * p[MAX_ANIMATION_FRAMES]; // actual graphics for frames of animations
|
|
|
|
// following must be initialized to zero before use!
|
|
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
|
|
|
|
char levelname[9];
|
|
char levelname2[9];
|
|
} in_anim_t;
|
|
|
|
static TArray<lnode_t> lnodes;
|
|
static TArray<in_anim_t> anims;
|
|
|
|
|
|
//
|
|
// GENERAL DATA
|
|
//
|
|
|
|
//
|
|
// Locally used stuff.
|
|
//
|
|
|
|
|
|
// States for single-player
|
|
#define SP_KILLS 0
|
|
#define SP_ITEMS 2
|
|
#define SP_SECRET 4
|
|
#define SP_FRAGS 6
|
|
#define SP_TIME 8
|
|
#define SP_PAR ST_TIME
|
|
|
|
#define SP_PAUSE 1
|
|
|
|
#define SHOWNEXTLOCDELAY 4 // in seconds
|
|
|
|
static int acceleratestage; // used to accelerate or skip a stage
|
|
static int me; // wbs->pnum
|
|
static stateenum_t state; // specifies current state
|
|
static wbstartstruct_t *wbs; // contains information passed into intermission
|
|
static wbplayerstruct_t*plrs; // wbs->plyr[]
|
|
static int cnt; // used for general timing
|
|
static int bcnt; // used for timing of background animation
|
|
static int cnt_kills[MAXPLAYERS];
|
|
static int cnt_items[MAXPLAYERS];
|
|
static int cnt_secret[MAXPLAYERS];
|
|
static int cnt_time;
|
|
static int cnt_total_time;
|
|
static int cnt_par;
|
|
static int cnt_pause;
|
|
static bool noautostartmap;
|
|
|
|
//
|
|
// GRAPHICS
|
|
//
|
|
|
|
static TArray<FTexture *> yah; // You Are Here graphic
|
|
static FTexture* splat; // splat
|
|
static FTexture* percent; // %, : graphics
|
|
static FTexture* colon;
|
|
static FTexture* slash;
|
|
static FTexture* num[10]; // 0-9 graphic
|
|
static FTexture* wiminus; // minus sign
|
|
static FTexture* finished; // "Finished!" graphics
|
|
static FTexture* entering; // "Entering" graphic
|
|
static FTexture* sp_secret; // "secret"
|
|
static FTexture* kills; // "Kills", "Scrt", "Items", "Frags"
|
|
static FTexture* secret;
|
|
static FTexture* items;
|
|
static FTexture* frags;
|
|
static FTexture* timepic; // Time sucks.
|
|
static FTexture* par;
|
|
static FTexture* sucks;
|
|
static FTexture* killers; // "killers", "victims"
|
|
static FTexture* victims;
|
|
static FTexture* total; // "Total", your face, your dead face
|
|
static FTexture* star;
|
|
static FTexture* bstar;
|
|
static FTexture* p; // Player graphic
|
|
static FTexture* lnames[2]; // Name graphics of each level (centered)
|
|
|
|
// [RH] Info to dynamically generate the level name graphics
|
|
static const char *lnametexts[2];
|
|
|
|
static FTexture *background;
|
|
|
|
//
|
|
// CODE
|
|
//
|
|
|
|
// ====================================================================
|
|
//
|
|
// Background script commands
|
|
//
|
|
// ====================================================================
|
|
|
|
static const char *WI_Cmd[]={
|
|
"Background",
|
|
"Splat",
|
|
"Pointer",
|
|
"Spots",
|
|
|
|
"IfEntering",
|
|
"IfNotEntering",
|
|
"IfVisited",
|
|
"IfNotVisited",
|
|
"IfLeaving",
|
|
"IfNotLeaving",
|
|
"IfTravelling",
|
|
"IfNotTravelling",
|
|
|
|
"Animation",
|
|
"Pic",
|
|
|
|
"NoAutostartMap",
|
|
|
|
NULL
|
|
};
|
|
|
|
//====================================================================
|
|
//
|
|
// 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.
|
|
//
|
|
//====================================================================
|
|
static bool IsExMy(const char * name)
|
|
{
|
|
// Only check for the first 3 episodes. They are the only ones with default intermission scripts.
|
|
// Level names can be upper- and lower case so use tolower to check!
|
|
return (tolower(name[0])=='e' && name[1]>='1' && name[1]<='3' && tolower(name[2])=='m');
|
|
}
|
|
|
|
void WI_LoadBackground(bool isenterpic)
|
|
{
|
|
const char * lumpname = NULL;
|
|
char buffer[10];
|
|
in_anim_t an;
|
|
lnode_t pt;
|
|
int texture = -1;
|
|
|
|
bcnt=0;
|
|
|
|
if (isenterpic)
|
|
{
|
|
level_info_t * li = FindLevelInfo(wbs->next);
|
|
if (li != NULL) lumpname = li->enterpic;
|
|
}
|
|
else
|
|
{
|
|
lumpname = level.info->exitpic;
|
|
}
|
|
|
|
// Try to get a default if nothing specified
|
|
if (lumpname == NULL || lumpname[0]==0)
|
|
{
|
|
lumpname = NULL;
|
|
switch(gameinfo.gametype)
|
|
{
|
|
case GAME_Doom:
|
|
if (gamemode != commercial)
|
|
{
|
|
char * level = isenterpic? wbs->next : wbs->current;
|
|
if (IsExMy(level))
|
|
{
|
|
sprintf(buffer, "$IN_EPI%c", level[1]);
|
|
lumpname = buffer;
|
|
}
|
|
}
|
|
if (!lumpname)
|
|
{
|
|
if (isenterpic)
|
|
{
|
|
// One special case needs to be handled here!
|
|
// If going from E1-E3 to E4 the default should be used, not the exit pic.
|
|
|
|
// Not if the exit pic is user defined!
|
|
if (level.info->exitpic[0]!=0) return;
|
|
|
|
// E1-E3 need special treatment when playing Doom 1.
|
|
if (gamemode!=commercial)
|
|
{
|
|
// not if the last level is not from the first 3 episodes
|
|
if (!IsExMy(wbs->current)) return;
|
|
|
|
// not if the next level is one of the first 3 episodes
|
|
if (IsExMy(wbs->next)) return;
|
|
}
|
|
}
|
|
lumpname = "INTERPIC";
|
|
}
|
|
break;
|
|
|
|
case GAME_Heretic:
|
|
if (isenterpic)
|
|
{
|
|
if (IsExMy(wbs->next))
|
|
{
|
|
sprintf(buffer, "$IN_HTC%c", wbs->next[1]);
|
|
lumpname = buffer;
|
|
}
|
|
}
|
|
if (!lumpname)
|
|
{
|
|
if (isenterpic) return;
|
|
lumpname = "FLOOR16";
|
|
}
|
|
break;
|
|
|
|
case GAME_Hexen:
|
|
if (isenterpic) return;
|
|
lumpname = "INTERPIC";
|
|
break;
|
|
|
|
case GAME_Strife:
|
|
default:
|
|
// Strife doesn't have an intermission pic so choose something neutral.
|
|
if (isenterpic) return;
|
|
lumpname = gameinfo.borderFlat;
|
|
break;
|
|
}
|
|
}
|
|
if (lumpname == NULL)
|
|
{
|
|
// shouldn't happen!
|
|
background = NULL;
|
|
return;
|
|
}
|
|
|
|
lnodes.Clear();
|
|
anims.Clear();
|
|
yah.Clear();
|
|
splat=NULL;
|
|
|
|
// a name with a starting '$' indicates an intermission script
|
|
if (*lumpname!='$')
|
|
{
|
|
// The background picture can also be a flat so just using AddPatch doesn't work
|
|
texture = TexMan.CheckForTexture(lumpname, FTexture::TEX_MiscPatch, FTextureManager::TEXMAN_TryAny);
|
|
if (texture == -1) texture = TexMan.AddPatch(lumpname);
|
|
}
|
|
else
|
|
{
|
|
int lumpnum=Wads.GetNumForName(lumpname+1);
|
|
if (lumpnum>=0)
|
|
{
|
|
SC_OpenLumpNum(lumpnum,lumpname+1);
|
|
while (SC_GetString())
|
|
{
|
|
memset(&an,0,sizeof(an));
|
|
int caseval=SC_MustMatchString(WI_Cmd);
|
|
switch(caseval)
|
|
{
|
|
case 0: // Background
|
|
SC_MustGetString();
|
|
texture=TexMan.CheckForTexture(sc_String, FTexture::TEX_MiscPatch,FTextureManager::TEXMAN_TryAny);
|
|
if (texture == -1) texture = TexMan.AddPatch(sc_String);
|
|
break;
|
|
|
|
case 1: // Splat
|
|
SC_MustGetString();
|
|
splat=TexMan[TexMan.AddPatch(sc_String)];
|
|
break;
|
|
|
|
case 2: // Pointers
|
|
while (SC_GetString() && !sc_Crossed)
|
|
{
|
|
int v=TexMan.AddPatch(sc_String);
|
|
yah.Push(TexMan[v]);
|
|
}
|
|
if (sc_Crossed) SC_UnGet();
|
|
break;
|
|
|
|
case 3: // Spots
|
|
SC_MustGetStringName("{");
|
|
while (!SC_CheckString("}"))
|
|
{
|
|
SC_MustGetString();
|
|
strncpy(pt.level, sc_String,8);
|
|
pt.level[8]=0;
|
|
SC_MustGetNumber();
|
|
pt.x=sc_Number;
|
|
SC_MustGetNumber();
|
|
pt.y=sc_Number;
|
|
lnodes.Push(pt);
|
|
}
|
|
break;
|
|
|
|
case 4: // IfEntering
|
|
an.type=ANIM_IFENTERING;
|
|
goto readanimation;
|
|
|
|
case 5: // IfEntering
|
|
an.type=ANIM_IFNOTENTERING;
|
|
goto readanimation;
|
|
|
|
case 6: // IfVisited
|
|
an.type=ANIM_IFVISITED;
|
|
goto readanimation;
|
|
|
|
case 7: // IfNotVisited
|
|
an.type=ANIM_IFNOTVISITED;
|
|
goto readanimation;
|
|
|
|
case 8: // IfLeaving
|
|
an.type=ANIM_IFLEAVING;
|
|
goto readanimation;
|
|
|
|
case 9: // IfNotLeaving
|
|
an.type=ANIM_IFNOTLEAVING;
|
|
goto readanimation;
|
|
|
|
case 10: // IfTravelling
|
|
an.type=ANIM_IFTRAVELLING;
|
|
SC_MustGetString();
|
|
strncpy(an.levelname2,sc_String,8);
|
|
an.levelname2[8]=0;
|
|
goto readanimation;
|
|
|
|
case 11: // IfNotTravelling
|
|
an.type=ANIM_IFTRAVELLING;
|
|
SC_MustGetString();
|
|
strncpy(an.levelname2,sc_String,8);
|
|
an.levelname2[8]=0;
|
|
goto readanimation;
|
|
|
|
case 14: // NoAutostartMap
|
|
noautostartmap=true;
|
|
break;
|
|
|
|
readanimation:
|
|
SC_MustGetString();
|
|
strncpy(an.levelname,sc_String,8);
|
|
an.levelname[8]=0;
|
|
SC_MustGetString();
|
|
caseval=SC_MustMatchString(WI_Cmd);
|
|
|
|
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())
|
|
{
|
|
if (SC_Compare("ONCE"))
|
|
{
|
|
an.data=1;
|
|
}
|
|
else
|
|
{
|
|
SC_UnGet();
|
|
}
|
|
}
|
|
if (!SC_CheckString("{"))
|
|
{
|
|
SC_MustGetString();
|
|
an.p[an.nanims++]=TexMan[TexMan.AddPatch(sc_String)];
|
|
}
|
|
else
|
|
{
|
|
while (!SC_CheckString("}"))
|
|
{
|
|
SC_MustGetString();
|
|
if (an.nanims<MAX_ANIMATION_FRAMES) an.p[an.nanims++]=TexMan[TexMan.AddPatch(sc_String)];
|
|
}
|
|
}
|
|
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.p[0]=TexMan[TexMan.AddPatch(sc_String)];
|
|
anims.Push(an);
|
|
break;
|
|
|
|
default:
|
|
SC_ScriptError("Unknown token %s in intermission script", sc_String);
|
|
}
|
|
}
|
|
}
|
|
SC_Close();
|
|
}
|
|
else
|
|
{
|
|
Printf("Intermission script %s not found!\n", lumpname+1);
|
|
texture = TexMan.GetTexture("INTERPIC", FTexture::TEX_MiscPatch);
|
|
}
|
|
}
|
|
background=TexMan[texture];
|
|
}
|
|
|
|
//====================================================================
|
|
//
|
|
// made this more generic and configurable through a script
|
|
// Removed all the ugly special case handling for different game modes
|
|
//
|
|
//====================================================================
|
|
|
|
void WI_updateAnimatedBack()
|
|
{
|
|
unsigned int i;
|
|
|
|
for(i=0;i<anims.Size();i++)
|
|
{
|
|
in_anim_t * a = &anims[i];
|
|
switch (a->type & ANIM_TYPE)
|
|
{
|
|
case ANIM_ALWAYS:
|
|
if (bcnt >= a->nexttic)
|
|
{
|
|
if (++a->ctr >= a->nanims)
|
|
{
|
|
if (a->data==0) a->ctr = 0;
|
|
else a->ctr--;
|
|
}
|
|
a->nexttic = bcnt + a->period;
|
|
}
|
|
break;
|
|
|
|
case ANIM_PIC:
|
|
a->ctr = 0;
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws the background including all animations
|
|
//
|
|
//====================================================================
|
|
|
|
void WI_drawBackground()
|
|
{
|
|
unsigned int i;
|
|
int animwidth=320; // For a flat fill or clear background scale animations to 320x200
|
|
int animheight=200;
|
|
|
|
if (background)
|
|
{
|
|
// background
|
|
if (background->UseType == FTexture::TEX_MiscPatch)
|
|
{
|
|
// 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
|
|
animwidth = background->GetWidth();
|
|
animheight = background->GetHeight();
|
|
screen->FillBorder (NULL);
|
|
screen->DrawTexture(background, 0, 0, DTA_VirtualWidth, animwidth,
|
|
DTA_VirtualHeight, animheight, TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
screen->FlatFill(0, 0, SCREENWIDTH, SCREENHEIGHT, background);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
screen->Clear(0,0, SCREENWIDTH, SCREENHEIGHT, 0, 0);
|
|
}
|
|
|
|
for(i=0;i<anims.Size();i++)
|
|
{
|
|
in_anim_t * a = &anims[i];
|
|
level_info_t * li;
|
|
|
|
switch (a->type & ANIM_CONDITION)
|
|
{
|
|
case ANIM_IFVISITED:
|
|
li = FindLevelInfo(a->levelname);
|
|
if (li == NULL || !(li->flags & LEVEL_VISITED)) continue;
|
|
break;
|
|
|
|
case ANIM_IFNOTVISITED:
|
|
li = FindLevelInfo(a->levelname);
|
|
if (li == NULL || (li->flags & LEVEL_VISITED)) continue;
|
|
break;
|
|
|
|
// StatCount means 'leaving' - everything else means 'entering'!
|
|
case ANIM_IFENTERING:
|
|
if (state == StatCount || strnicmp(a->levelname, wbs->next, 8)) continue;
|
|
break;
|
|
|
|
case ANIM_IFNOTENTERING:
|
|
if (state != StatCount && !strnicmp(a->levelname, wbs->next, 8)) continue;
|
|
break;
|
|
|
|
case ANIM_IFLEAVING:
|
|
if (state != StatCount || strnicmp(a->levelname, wbs->current, 8)) continue;
|
|
break;
|
|
|
|
case ANIM_IFNOTLEAVING:
|
|
if (state == StatCount && !strnicmp(a->levelname, wbs->current, 8)) continue;
|
|
break;
|
|
|
|
case ANIM_IFTRAVELLING:
|
|
if (strnicmp(a->levelname2, wbs->current, 8) || strnicmp(a->levelname, wbs->next, 8)) continue;
|
|
break;
|
|
|
|
case ANIM_IFNOTTRAVELLING:
|
|
if (!strnicmp(a->levelname2, wbs->current, 8) && !strnicmp(a->levelname, wbs->next, 8)) continue;
|
|
break;
|
|
}
|
|
if (a->ctr >= 0)
|
|
screen->DrawTexture(a->p[a->ctr], a->loc.x, a->loc.y,
|
|
DTA_VirtualWidth, animwidth, DTA_VirtualHeight, animheight, TAG_DONE);
|
|
}
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws a single character with a shadow
|
|
//
|
|
//====================================================================
|
|
|
|
static void WI_DrawCharPatch (FTexture *patch, int x, int y)
|
|
{
|
|
if (patch->UseType != FTexture::TEX_FontChar)
|
|
{
|
|
screen->DrawTexture (patch, x, y,
|
|
DTA_Clean, true,
|
|
DTA_ShadowAlpha, (gameinfo.gametype == GAME_Doom) ? 0 : FRACUNIT/2,
|
|
TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
screen->DrawTexture (patch, x, y,
|
|
DTA_Clean, true,
|
|
DTA_ShadowAlpha, (gameinfo.gametype == GAME_Doom) ? 0 : FRACUNIT/2,
|
|
DTA_Translation, BigFont->GetColorTranslation (CR_UNTRANSLATED), // otherwise it doesn't look good in Strife!
|
|
TAG_DONE);
|
|
}
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws a level name with the big font
|
|
//
|
|
// x is no longer passed as a parameter because the text is now broken into several lines
|
|
// if it is too long
|
|
//
|
|
//====================================================================
|
|
|
|
int WI_DrawName(int y,const char * levelname, bool nomove=false)
|
|
{
|
|
int i;
|
|
size_t l;
|
|
const char * p;
|
|
int h=0;
|
|
int lumph;
|
|
|
|
lumph=BigFont->GetHeight();
|
|
|
|
p=levelname;
|
|
l=strlen(p);
|
|
if (!l) return 0;
|
|
|
|
screen->SetFont(BigFont);
|
|
FBrokenLines *lines = V_BreakLines(BigFont, 320, p);
|
|
|
|
if (lines)
|
|
{
|
|
for (i = 0; lines[i].Width >= 0; i++)
|
|
{
|
|
if (!nomove)
|
|
{
|
|
screen->DrawText(CR_UNTRANSLATED, 160 - lines[i].Width/2, y+h, lines[i].Text, DTA_Clean, true, TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
screen->DrawText(CR_UNTRANSLATED, (SCREENWIDTH - lines[i].Width * CleanXfac) / 2, (y+h) * CleanYfac,
|
|
lines[i].Text, DTA_CleanNoMove, true, TAG_DONE);
|
|
}
|
|
h+=lumph;
|
|
}
|
|
V_FreeBrokenLines(lines);
|
|
}
|
|
screen->SetFont(SmallFont);
|
|
return h+lumph/4;
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws "<Levelname> Finished!"
|
|
//
|
|
// Either uses the specified patch or the big font
|
|
// A level name patch can be specified for all games now, not just Doom.
|
|
//
|
|
//====================================================================
|
|
void WI_drawLF ()
|
|
{
|
|
int y = WI_TITLEY;
|
|
|
|
FTexture * tex = wbs->lname0[0]? TexMan[TexMan.AddPatch(wbs->lname0)] : NULL;
|
|
|
|
// draw <LevelName>
|
|
if (tex)
|
|
{
|
|
screen->DrawTexture(tex, 160-tex->GetWidth()/2, y, DTA_Clean, true, TAG_DONE);
|
|
y += tex->GetHeight() + BigFont->GetHeight()/4;
|
|
}
|
|
else
|
|
{
|
|
y+=WI_DrawName(y, lnametexts[0]);
|
|
}
|
|
|
|
// draw "Finished!"
|
|
if (y < NG_STATSY - screen->Font->GetHeight()*3/4)
|
|
{
|
|
// don't draw 'finished' if the level name is too high!
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
screen->DrawTexture(finished, 160 - finished->GetWidth()/2, y, DTA_Clean, true, TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
screen->SetFont(gameinfo.gametype&GAME_Raven? SmallFont : BigFont);
|
|
screen->DrawText(CR_WHITE, 160 - screen->Font->StringWidth("finished")/2, y-4, "finished",
|
|
DTA_Clean, true, TAG_DONE);
|
|
screen->SetFont(SmallFont);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws "Entering <LevelName>"
|
|
//
|
|
// Either uses the specified patch or the big font
|
|
// A level name patch can be specified for all games now, not just Doom.
|
|
//
|
|
//====================================================================
|
|
void WI_drawEL ()
|
|
{
|
|
int y = WI_TITLEY;
|
|
|
|
|
|
// draw "entering"
|
|
// be careful with the added height so that it works for oversized 'entering' patches!
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
screen->DrawTexture(entering, (SCREENWIDTH - entering->GetWidth() * CleanXfac) / 2, y * CleanYfac, DTA_CleanNoMove, true, TAG_DONE);
|
|
y += entering->GetHeight() + screen->Font->GetHeight()/4;
|
|
}
|
|
else
|
|
{
|
|
screen->SetFont(gameinfo.gametype&GAME_Raven? SmallFont : BigFont);
|
|
screen->DrawText(CR_WHITE, (SCREENWIDTH - screen->Font->StringWidth("now entering:") * CleanXfac) / 2, y * CleanYfac,
|
|
"now entering:", DTA_CleanNoMove, true, TAG_DONE);
|
|
y += screen->Font->GetHeight()*5/4;
|
|
screen->SetFont(SmallFont);
|
|
}
|
|
|
|
// draw <LevelName>
|
|
FTexture * tex = wbs->lname1[0]? TexMan[TexMan.AddPatch(wbs->lname1)] : NULL;
|
|
if (tex)
|
|
{
|
|
screen->DrawTexture(tex, (SCREENWIDTH - tex->GetWidth() * CleanXfac) / 2, y * CleanYfac, DTA_CleanNoMove, true, TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
WI_DrawName(y, lnametexts[1], true);
|
|
}
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws the splats and the 'You are here' arrows
|
|
//
|
|
//====================================================================
|
|
|
|
int WI_MapToIndex (char *map)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < lnodes.Size(); i++)
|
|
{
|
|
if (!strnicmp (lnodes[i].level, map, 8))
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
|
|
//====================================================================
|
|
//
|
|
// Draws the splats and the 'You are here' arrows
|
|
//
|
|
//====================================================================
|
|
|
|
void WI_drawOnLnode( int n, FTexture * c[] ,int numc)
|
|
{
|
|
int i;
|
|
for(i=0;i<numc;i++)
|
|
{
|
|
int left;
|
|
int top;
|
|
int right;
|
|
int bottom;
|
|
|
|
|
|
right = c[i]->GetWidth();
|
|
bottom = c[i]->GetHeight();
|
|
left = lnodes[n].x - c[i]->LeftOffset;
|
|
top = lnodes[n].y - c[i]->TopOffset;
|
|
right += left;
|
|
bottom += top;
|
|
|
|
if (left >= 0 && right < 320 && top >= 0 && bottom < 200)
|
|
{
|
|
screen->DrawTexture (c[i], lnodes[n].x, lnodes[n].y, DTA_320x200, true, TAG_DONE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ====================================================================
|
|
//
|
|
// Draws a number.
|
|
// If digits > 0, then use that many digits minimum,
|
|
// otherwise only use as many as necessary.
|
|
// Returns new x position.
|
|
//
|
|
// ====================================================================
|
|
int WI_drawNum (int x, int y, int n, int digits, bool leadingzeros = true)
|
|
{
|
|
int fontwidth = num[3]->GetWidth();
|
|
int xofs;
|
|
char text[8];
|
|
char *text_p;
|
|
|
|
if (leadingzeros)
|
|
{
|
|
sprintf (text, "%07d", n);
|
|
}
|
|
else
|
|
{
|
|
sprintf (text, "%7d", n);
|
|
if (digits < 0)
|
|
{
|
|
text_p = strrchr (text, ' ');
|
|
digits = (text_p == NULL) ? 7 : 6 - (int)(text_p - text);
|
|
x -= digits * fontwidth;
|
|
}
|
|
}
|
|
|
|
text_p = strchr (text, '-');
|
|
if (text_p == NULL || text_p - text > 7 - digits)
|
|
{
|
|
text_p = text + 7 - digits;
|
|
}
|
|
|
|
xofs = x;
|
|
|
|
if (*text_p == '-')
|
|
{
|
|
x -= fontwidth;
|
|
WI_DrawCharPatch (wiminus, x, y);
|
|
}
|
|
|
|
// draw the new number
|
|
while (*text_p)
|
|
{
|
|
if (*text_p >= '0' && *text_p <= '9')
|
|
{
|
|
FTexture *p = num[*text_p - '0'];
|
|
WI_DrawCharPatch (p, xofs + (fontwidth - p->GetWidth())/2, y);
|
|
}
|
|
text_p++;
|
|
xofs += fontwidth;
|
|
}
|
|
return x;
|
|
|
|
}
|
|
|
|
// ====================================================================
|
|
//
|
|
//
|
|
//
|
|
// ====================================================================
|
|
|
|
void WI_drawPercent (int x, int y, int p, int b)
|
|
{
|
|
if (p < 0)
|
|
return;
|
|
|
|
if (wi_percents)
|
|
{
|
|
WI_DrawCharPatch (percent, x, y);
|
|
|
|
if (b == 0)
|
|
WI_drawNum (x, y, 100, -1, false);
|
|
else
|
|
WI_drawNum(x, y, p * 100 / b, -1, false);
|
|
}
|
|
else
|
|
{
|
|
int y2 = y + percent->GetHeight() - screen->Font->GetHeight ();
|
|
x = WI_drawNum (x, y, b, -1, false);
|
|
x -= SmallFont->StringWidth (" OF ");
|
|
screen->DrawText (CR_UNTRANSLATED, x, y2, " OF",
|
|
DTA_Clean, true, TAG_DONE);
|
|
WI_drawNum (x, y, p, -1, false);
|
|
}
|
|
}
|
|
|
|
//====================================================================
|
|
//
|
|
// Display level completion time and par, or "sucks" message if overflow.
|
|
//
|
|
//====================================================================
|
|
void WI_drawTime (int x, int y, int t, bool no_sucks=false)
|
|
{
|
|
bool sucky;
|
|
|
|
if (t<0)
|
|
return;
|
|
|
|
sucky = !no_sucks && t >= wbs->sucktime * 60 * 60 && wbs->sucktime > 0;
|
|
int hours = t / 3600;
|
|
t -= hours * 3600;
|
|
int minutes = t / 60;
|
|
t -= minutes * 60;
|
|
int seconds = t;
|
|
|
|
// Why were these offsets hard coded? Half the WADs with custom patches
|
|
// I tested screwed up miserably in this function!
|
|
int num_spacing = num[3]->GetWidth();
|
|
int colon_spacing = colon->GetWidth();
|
|
|
|
x -= 2*num_spacing;
|
|
WI_drawNum (x, y, seconds, 2);
|
|
x -= colon_spacing;
|
|
WI_DrawCharPatch (colon, x , y);
|
|
x -= 2*num_spacing ;
|
|
WI_drawNum (x, y, minutes, 2, hours!=0);
|
|
if (hours)
|
|
{
|
|
x -= colon_spacing;
|
|
WI_DrawCharPatch (colon, x , y);
|
|
x -= 2*num_spacing ;
|
|
WI_drawNum (x, y, hours, 2);
|
|
}
|
|
|
|
if (sucky)
|
|
{ // "sucks"
|
|
if (sucks != NULL)
|
|
{
|
|
screen->DrawTexture (sucks, x - sucks->GetWidth(), y - num[0]->GetHeight() - 2,
|
|
DTA_Clean, true, TAG_DONE);
|
|
}
|
|
else
|
|
{
|
|
screen->SetFont (BigFont);
|
|
screen->DrawText (CR_UNTRANSLATED, x - BigFont->StringWidth("SUCKS"), y - BigFont->GetHeight() - 2,
|
|
"SUCKS", DTA_Clean, true, TAG_DONE);
|
|
screen->SetFont (SmallFont);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WI_End ()
|
|
{
|
|
state = LeavingIntermission;
|
|
WI_unloadData ();
|
|
|
|
//Added by mc
|
|
if (deathmatch)
|
|
{
|
|
bglobal.RemoveAllBots (consoleplayer != Net_Arbitrator);
|
|
}
|
|
}
|
|
|
|
void WI_initNoState ()
|
|
{
|
|
state = NoState;
|
|
acceleratestage = 0;
|
|
cnt = 10;
|
|
}
|
|
|
|
void WI_updateNoState ()
|
|
{
|
|
WI_updateAnimatedBack();
|
|
|
|
|
|
if (!wi_noautostartmap && !noautostartmap) cnt--;
|
|
if (acceleratestage) cnt=0;
|
|
|
|
if (cnt==0)
|
|
{
|
|
WI_End();
|
|
G_WorldDone();
|
|
}
|
|
}
|
|
|
|
static bool snl_pointeron = false;
|
|
|
|
void WI_initShowNextLoc ()
|
|
{
|
|
if (wbs->next_ep == -1)
|
|
{
|
|
// Last map in episode - there is no next location!
|
|
WI_End();
|
|
G_WorldDone();
|
|
return;
|
|
}
|
|
|
|
state = ShowNextLoc;
|
|
acceleratestage = 0;
|
|
cnt = SHOWNEXTLOCDELAY * TICRATE;
|
|
WI_LoadBackground(true);
|
|
}
|
|
|
|
void WI_updateShowNextLoc ()
|
|
{
|
|
WI_updateAnimatedBack();
|
|
|
|
if (!--cnt || acceleratestage)
|
|
WI_initNoState();
|
|
else
|
|
snl_pointeron = (cnt & 31) < 20;
|
|
}
|
|
|
|
void WI_drawShowNextLoc(void)
|
|
{
|
|
unsigned int i;
|
|
|
|
WI_drawBackground();
|
|
|
|
if (splat)
|
|
{
|
|
for (i=0 ; i<lnodes.Size() ; i++)
|
|
{
|
|
level_info_t * li = FindLevelInfo (lnodes[i].level);
|
|
if (li && li->flags & LEVEL_VISITED) WI_drawOnLnode(i, &splat,1); // draw a splat on taken cities.
|
|
}
|
|
}
|
|
|
|
// draw flashing ptr
|
|
if (snl_pointeron && yah.Size())
|
|
{
|
|
unsigned int v = WI_MapToIndex (wbs->next);
|
|
// Draw only if it points to a valid level on the current screen!
|
|
if (v<lnodes.Size()) WI_drawOnLnode (v, &yah[0], yah.Size());
|
|
}
|
|
|
|
// draws which level you are entering..
|
|
WI_drawEL ();
|
|
|
|
}
|
|
|
|
void WI_drawNoState ()
|
|
{
|
|
snl_pointeron = true;
|
|
WI_drawShowNextLoc();
|
|
}
|
|
|
|
int WI_fragSum (int playernum)
|
|
{
|
|
int i;
|
|
int frags = 0;
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
{
|
|
if (playeringame[i]
|
|
&& i!=playernum)
|
|
{
|
|
frags += plrs[playernum].frags[i];
|
|
}
|
|
}
|
|
|
|
// JDC hack - negative frags.
|
|
frags -= plrs[playernum].frags[playernum];
|
|
|
|
return frags;
|
|
}
|
|
|
|
static int dm_state;
|
|
static int dm_frags[MAXPLAYERS][MAXPLAYERS];
|
|
static int dm_totals[MAXPLAYERS];
|
|
|
|
void WI_initDeathmatchStats (void)
|
|
{
|
|
|
|
int i, j;
|
|
|
|
state = StatCount;
|
|
acceleratestage = 0;
|
|
dm_state = 1;
|
|
|
|
cnt_pause = TICRATE;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (playeringame[i])
|
|
{
|
|
for (j=0 ; j<MAXPLAYERS ; j++)
|
|
if (playeringame[j])
|
|
dm_frags[i][j] = 0;
|
|
|
|
dm_totals[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WI_updateDeathmatchStats ()
|
|
{
|
|
/*
|
|
int i, j;
|
|
bool stillticking;
|
|
*/
|
|
|
|
WI_updateAnimatedBack();
|
|
|
|
if (acceleratestage && dm_state != 4)
|
|
{
|
|
/*
|
|
acceleratestage = 0;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (playeringame[i])
|
|
{
|
|
for (j=0 ; j<MAXPLAYERS ; j++)
|
|
if (playeringame[j])
|
|
dm_frags[i][j] = plrs[i].frags[j];
|
|
|
|
dm_totals[i] = WI_fragSum(i);
|
|
}
|
|
}
|
|
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
*/
|
|
dm_state = 4;
|
|
}
|
|
|
|
|
|
if (dm_state == 2)
|
|
{
|
|
/*
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
stillticking = false;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (playeringame[i])
|
|
{
|
|
for (j=0 ; j<MAXPLAYERS ; j++)
|
|
{
|
|
if (playeringame[j]
|
|
&& dm_frags[i][j] != plrs[i].frags[j])
|
|
{
|
|
if (plrs[i].frags[j] < 0)
|
|
dm_frags[i][j]--;
|
|
else
|
|
dm_frags[i][j]++;
|
|
|
|
if (dm_frags[i][j] > 99)
|
|
dm_frags[i][j] = 99;
|
|
|
|
if (dm_frags[i][j] < -99)
|
|
dm_frags[i][j] = -99;
|
|
|
|
stillticking = true;
|
|
}
|
|
}
|
|
dm_totals[i] = WI_fragSum(i);
|
|
|
|
if (dm_totals[i] > 99)
|
|
dm_totals[i] = 99;
|
|
|
|
if (dm_totals[i] < -99)
|
|
dm_totals[i] = -99;
|
|
}
|
|
|
|
}
|
|
if (!stillticking)
|
|
{
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
dm_state++;
|
|
}
|
|
*/
|
|
dm_state = 3;
|
|
}
|
|
else if (dm_state == 4)
|
|
{
|
|
if (acceleratestage)
|
|
{
|
|
S_Sound (CHAN_VOICE, "players/male/gibbed", 1, ATTN_NONE);
|
|
|
|
if (gamemode == commercial)
|
|
WI_initNoState();
|
|
else
|
|
WI_initShowNextLoc();
|
|
}
|
|
}
|
|
else if (dm_state & 1)
|
|
{
|
|
if (!--cnt_pause)
|
|
{
|
|
dm_state++;
|
|
cnt_pause = TICRATE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void WI_drawDeathmatchStats ()
|
|
{
|
|
|
|
// draw animated background
|
|
WI_drawBackground();
|
|
WI_drawLF();
|
|
|
|
// [RH] Draw heads-up scores display
|
|
HU_DrawScores (&players[me]);
|
|
|
|
/*
|
|
int i;
|
|
int j;
|
|
int x;
|
|
int y;
|
|
int w;
|
|
|
|
int lh; // line height
|
|
|
|
lh = WI_SPACINGY;
|
|
|
|
// draw stat titles (top line)
|
|
V_DrawPatchClean(DM_TOTALSX-LittleShort(total->width)/2,
|
|
DM_MATRIXY-WI_SPACINGY+10,
|
|
&FB,
|
|
total);
|
|
|
|
V_DrawPatchClean(DM_KILLERSX, DM_KILLERSY, &FB, killers);
|
|
V_DrawPatchClean(DM_VICTIMSX, DM_VICTIMSY, &FB, victims);
|
|
|
|
// draw P?
|
|
x = DM_MATRIXX + DM_SPACINGX;
|
|
y = DM_MATRIXY;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (playeringame[i])
|
|
{
|
|
V_DrawPatchClean(x-LittleShort(p[i]->width)/2,
|
|
DM_MATRIXY - WI_SPACINGY,
|
|
&FB,
|
|
p[i]);
|
|
|
|
V_DrawPatchClean(DM_MATRIXX-LittleShort(p[i]->width)/2,
|
|
y,
|
|
&FB,
|
|
p[i]);
|
|
|
|
if (i == me)
|
|
{
|
|
V_DrawPatchClean(x-LittleShort(p[i]->width)/2,
|
|
DM_MATRIXY - WI_SPACINGY,
|
|
&FB,
|
|
bstar);
|
|
|
|
V_DrawPatchClean(DM_MATRIXX-LittleShort(p[i]->width)/2,
|
|
y,
|
|
&FB,
|
|
star);
|
|
}
|
|
}
|
|
x += DM_SPACINGX;
|
|
y += WI_SPACINGY;
|
|
}
|
|
|
|
// draw stats
|
|
y = DM_MATRIXY+10;
|
|
w = LittleShort(num[0]->width);
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
x = DM_MATRIXX + DM_SPACINGX;
|
|
|
|
if (playeringame[i])
|
|
{
|
|
for (j=0 ; j<MAXPLAYERS ; j++)
|
|
{
|
|
if (playeringame[j])
|
|
WI_drawNum(x+w, y, dm_frags[i][j], 2);
|
|
|
|
x += DM_SPACINGX;
|
|
}
|
|
WI_drawNum(DM_TOTALSX+w, y, dm_totals[i], 2);
|
|
}
|
|
y += WI_SPACINGY;
|
|
}
|
|
*/
|
|
}
|
|
|
|
static int cnt_frags[MAXPLAYERS];
|
|
static int dofrags;
|
|
static int ng_state;
|
|
|
|
void WI_initNetgameStats ()
|
|
{
|
|
|
|
int i;
|
|
|
|
state = StatCount;
|
|
acceleratestage = 0;
|
|
ng_state = 1;
|
|
|
|
cnt_pause = TICRATE;
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
|
|
|
|
dofrags += WI_fragSum (i);
|
|
}
|
|
|
|
dofrags = !!dofrags;
|
|
}
|
|
|
|
void WI_updateNetgameStats ()
|
|
{
|
|
|
|
int i;
|
|
int fsum;
|
|
bool stillticking;
|
|
|
|
WI_updateAnimatedBack ();
|
|
|
|
if (acceleratestage && ng_state != 10)
|
|
{
|
|
acceleratestage = 0;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_kills[i] = plrs[i].skills;
|
|
cnt_items[i] = plrs[i].sitems;
|
|
cnt_secret[i] = plrs[i].ssecret;
|
|
|
|
if (dofrags)
|
|
cnt_frags[i] = WI_fragSum (i);
|
|
}
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
ng_state = 10;
|
|
}
|
|
|
|
if (ng_state == 2)
|
|
{
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
stillticking = false;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_kills[i] += 2;
|
|
|
|
if (cnt_kills[i] > plrs[i].skills)
|
|
cnt_kills[i] = plrs[i].skills;
|
|
else
|
|
stillticking = true;
|
|
}
|
|
|
|
if (!stillticking)
|
|
{
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
ng_state++;
|
|
}
|
|
}
|
|
else if (ng_state == 4)
|
|
{
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
stillticking = false;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_items[i] += 2;
|
|
if (cnt_items[i] > plrs[i].sitems)
|
|
cnt_items[i] = plrs[i].sitems;
|
|
else
|
|
stillticking = true;
|
|
}
|
|
if (!stillticking)
|
|
{
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
ng_state++;
|
|
}
|
|
}
|
|
else if (ng_state == 6)
|
|
{
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
stillticking = false;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_secret[i] += 2;
|
|
|
|
if (cnt_secret[i] > plrs[i].ssecret)
|
|
cnt_secret[i] = plrs[i].ssecret;
|
|
else
|
|
stillticking = true;
|
|
}
|
|
|
|
if (!stillticking)
|
|
{
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
ng_state += 1 + 2*!dofrags;
|
|
}
|
|
}
|
|
else if (ng_state == 8)
|
|
{
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
stillticking = false;
|
|
|
|
for (i=0 ; i<MAXPLAYERS ; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
cnt_frags[i] += 1;
|
|
|
|
if (cnt_frags[i] >= (fsum = WI_fragSum(i)))
|
|
cnt_frags[i] = fsum;
|
|
else
|
|
stillticking = true;
|
|
}
|
|
|
|
if (!stillticking)
|
|
{
|
|
S_Sound (CHAN_VOICE, "player/male/death1", 1, ATTN_NONE);
|
|
ng_state++;
|
|
}
|
|
}
|
|
else if (ng_state == 10)
|
|
{
|
|
if (acceleratestage)
|
|
{
|
|
S_Sound (CHAN_VOICE, PASTSTATS, 1, ATTN_NONE);
|
|
WI_initShowNextLoc();
|
|
}
|
|
}
|
|
else if (ng_state & 1)
|
|
{
|
|
if (!--cnt_pause)
|
|
{
|
|
ng_state++;
|
|
cnt_pause = TICRATE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WI_drawNetgameStats ()
|
|
{
|
|
int i, x, y;
|
|
int pwidth = percent->GetWidth();
|
|
|
|
// draw animated background
|
|
WI_drawBackground();
|
|
|
|
WI_drawLF();
|
|
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
// draw stat titles (top line)
|
|
screen->DrawTexture (kills, NG_STATSX+NG_SPACINGX-kills->GetWidth(), NG_STATSY, DTA_Clean, true, TAG_DONE);
|
|
screen->DrawTexture (items, NG_STATSX+2*NG_SPACINGX-items->GetWidth(), NG_STATSY, DTA_Clean, true, TAG_DONE);
|
|
screen->DrawTexture (secret, NG_STATSX+3*NG_SPACINGX-secret->GetWidth(), NG_STATSY, DTA_Clean, true, TAG_DONE);
|
|
|
|
if (dofrags)
|
|
screen->DrawTexture (frags, NG_STATSX+4*NG_SPACINGX-frags->GetWidth(), NG_STATSY, DTA_Clean, true, TAG_DONE);
|
|
|
|
// draw stats
|
|
y = NG_STATSY + kills->GetHeight();
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
{
|
|
if (y >= 200-WI_SPACINGY)
|
|
break;
|
|
|
|
if (!playeringame[i])
|
|
continue;
|
|
|
|
x = NG_STATSX;
|
|
// [RH] Only use one graphic for the face backgrounds
|
|
screen->DrawTexture (p, x - p->GetWidth(), y,
|
|
DTA_Translation, translationtables[TRANSLATION_Players][i],
|
|
DTA_Clean, true,
|
|
TAG_DONE);
|
|
|
|
if (i == me)
|
|
screen->DrawTexture (star, x - p->GetWidth(), y,
|
|
DTA_Translation, translationtables[TRANSLATION_Players][i],
|
|
DTA_Clean, true,
|
|
TAG_DONE);
|
|
|
|
x += NG_SPACINGX;
|
|
WI_drawPercent (x-pwidth, y+10, cnt_kills[i], wbs->maxkills); x += NG_SPACINGX;
|
|
WI_drawPercent (x-pwidth, y+10, cnt_items[i], wbs->maxitems); x += NG_SPACINGX;
|
|
WI_drawPercent (x-pwidth, y+10, cnt_secret[i], wbs->maxsecret); x += NG_SPACINGX;
|
|
|
|
if (dofrags)
|
|
WI_drawNum(x, y+10, cnt_frags[i], -1, false);
|
|
|
|
y += WI_SPACINGY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (gameinfo.gametype & GAME_Raven)
|
|
{
|
|
screen->SetFont (BigFont);
|
|
screen->DrawText (CR_UNTRANSLATED, 95, 35, "KILLS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 155, 35, "BONUS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 232, 35, "SECRET", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
y = 50;
|
|
}
|
|
else
|
|
{
|
|
screen->SetFont (SmallFont);
|
|
screen->DrawText (CR_UNTRANSLATED, 95, 50, "KILLS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 155, 50, "BONUS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 232, 50, "SECRET", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
y = 62;
|
|
}
|
|
WI_drawLF ();
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
{
|
|
if (y >= 200-WI_SPACINGY)
|
|
break;
|
|
if (!playeringame[i])
|
|
continue;
|
|
if (gameinfo.gametype == GAME_Heretic)
|
|
{
|
|
screen->DrawTexture (star, 25, y,
|
|
DTA_Translation, translationtables[TRANSLATION_Players][i],
|
|
DTA_Clean, true,
|
|
TAG_DONE);
|
|
}
|
|
else // Hexen and Strife don't have a face graphic for this.
|
|
{
|
|
char pstr[3]={'P', '1'+i};
|
|
screen->SetFont (BigFont);
|
|
screen->DrawText(CR_UNTRANSLATED, 25, y+10, pstr, DTA_Clean, true, TAG_DONE);
|
|
}
|
|
|
|
WI_drawPercent (127, y+10, cnt_kills[i], wbs->maxkills);
|
|
if (ng_state >= 4)
|
|
{
|
|
WI_drawPercent (202, y+10, cnt_items[i], wbs->maxitems);
|
|
if (ng_state >= 6)
|
|
{
|
|
WI_drawPercent (279, y+10, cnt_secret[i], wbs->maxsecret);
|
|
}
|
|
}
|
|
y += 37;
|
|
}
|
|
screen->SetFont (SmallFont);
|
|
}
|
|
}
|
|
|
|
static int sp_state;
|
|
|
|
void WI_initStats ()
|
|
{
|
|
state = StatCount;
|
|
acceleratestage = 0;
|
|
sp_state = 1;
|
|
cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
|
|
cnt_time = cnt_par = -1;
|
|
cnt_pause = TICRATE;
|
|
|
|
cnt_total_time = -1;
|
|
}
|
|
|
|
void WI_updateStats ()
|
|
{
|
|
WI_updateAnimatedBack ();
|
|
|
|
if ((gameinfo.gametype != GAME_Doom || acceleratestage)
|
|
&& sp_state != 10)
|
|
{
|
|
if (acceleratestage)
|
|
{
|
|
acceleratestage = 0;
|
|
sp_state = 10;
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
}
|
|
cnt_kills[0] = plrs[me].skills;
|
|
cnt_items[0] = plrs[me].sitems;
|
|
cnt_secret[0] = plrs[me].ssecret;
|
|
cnt_time = plrs[me].stime / TICRATE;
|
|
cnt_par = wbs->partime / TICRATE;
|
|
cnt_total_time = wbs->totaltime / TICRATE;
|
|
}
|
|
|
|
if (sp_state == 2)
|
|
{
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
cnt_kills[0] += 2;
|
|
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
}
|
|
if (cnt_kills[0] >= plrs[me].skills)
|
|
{
|
|
cnt_kills[0] = plrs[me].skills;
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
sp_state++;
|
|
}
|
|
}
|
|
else if (sp_state == 4)
|
|
{
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
cnt_items[0] += 2;
|
|
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
}
|
|
if (cnt_items[0] >= plrs[me].sitems)
|
|
{
|
|
cnt_items[0] = plrs[me].sitems;
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
sp_state++;
|
|
}
|
|
}
|
|
else if (sp_state == 6)
|
|
{
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
cnt_secret[0] += 2;
|
|
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
}
|
|
if (cnt_secret[0] >= plrs[me].ssecret)
|
|
{
|
|
cnt_secret[0] = plrs[me].ssecret;
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
sp_state++;
|
|
}
|
|
}
|
|
else if (sp_state == 8)
|
|
{
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
if (!(bcnt&3))
|
|
S_Sound (CHAN_VOICE, "weapons/pistol", 1, ATTN_NONE);
|
|
|
|
cnt_time += 3;
|
|
cnt_par += 3;
|
|
cnt_total_time += 3;
|
|
}
|
|
|
|
if (cnt_time >= plrs[me].stime / TICRATE)
|
|
cnt_time = plrs[me].stime / TICRATE;
|
|
|
|
if (cnt_total_time >= wbs->totaltime / TICRATE)
|
|
cnt_total_time = wbs->totaltime / TICRATE;
|
|
|
|
if (cnt_par >= wbs->partime / TICRATE)
|
|
{
|
|
cnt_par = wbs->partime / TICRATE;
|
|
|
|
if (cnt_time >= plrs[me].stime / TICRATE)
|
|
{
|
|
cnt_total_time = wbs->totaltime / TICRATE;
|
|
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
|
|
sp_state++;
|
|
}
|
|
}
|
|
}
|
|
else if (sp_state == 10)
|
|
{
|
|
if (acceleratestage)
|
|
{
|
|
S_Sound (CHAN_VOICE, PASTSTATS, 1, ATTN_NONE);
|
|
WI_initShowNextLoc();
|
|
}
|
|
}
|
|
else if (sp_state & 1)
|
|
{
|
|
if (!--cnt_pause)
|
|
{
|
|
sp_state++;
|
|
cnt_pause = TICRATE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WI_drawStats (void)
|
|
{
|
|
// line height
|
|
int lh;
|
|
|
|
lh = (3*num[0]->GetHeight())/2;
|
|
|
|
// draw animated background
|
|
WI_drawBackground();
|
|
|
|
WI_drawLF();
|
|
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
screen->DrawTexture (kills, SP_STATSX, SP_STATSY, DTA_Clean, true, TAG_DONE);
|
|
WI_drawPercent (320 - SP_STATSX, SP_STATSY, cnt_kills[0], wbs->maxkills);
|
|
|
|
screen->DrawTexture (items, SP_STATSX, SP_STATSY+lh, DTA_Clean, true, TAG_DONE);
|
|
WI_drawPercent (320 - SP_STATSX, SP_STATSY+lh, cnt_items[0], wbs->maxitems);
|
|
|
|
screen->DrawTexture (sp_secret, SP_STATSX, SP_STATSY+2*lh, DTA_Clean, true, TAG_DONE);
|
|
WI_drawPercent(320 - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0], wbs->maxsecret);
|
|
|
|
screen->DrawTexture (timepic, SP_TIMEX, SP_TIMEY, DTA_Clean, true, TAG_DONE);
|
|
WI_drawTime (160 - SP_TIMEX, SP_TIMEY, cnt_time);
|
|
if (wi_showtotaltime)
|
|
{
|
|
WI_drawTime (160 - SP_TIMEX, SP_TIMEY + lh, cnt_total_time, true); // no 'sucks' for total time ever!
|
|
}
|
|
|
|
if (wbs->partime)
|
|
{
|
|
screen->DrawTexture (par, 160 + SP_TIMEX, SP_TIMEY, DTA_Clean, true, TAG_DONE);
|
|
WI_drawTime (320 - SP_TIMEX, SP_TIMEY, cnt_par);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
screen->SetFont (BigFont);
|
|
screen->DrawText (CR_UNTRANSLATED, 50, 65, "KILLS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 50, 90, "ITEMS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
screen->DrawText (CR_UNTRANSLATED, 50, 115, "SECRETS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
|
|
int slashpos = gameinfo.gametype==GAME_Strife? 235:237;
|
|
int countpos = gameinfo.gametype==GAME_Strife? 185:200;
|
|
if (sp_state >= 2)
|
|
{
|
|
WI_drawNum (countpos, 65, cnt_kills[0], 3, false);
|
|
WI_DrawCharPatch (slash, slashpos, 65);
|
|
WI_drawNum (248, 65, wbs->maxkills, 3, false);
|
|
}
|
|
if (sp_state >= 4)
|
|
{
|
|
WI_drawNum (countpos, 90, cnt_items[0], 3, false);
|
|
WI_DrawCharPatch (slash, slashpos, 90);
|
|
WI_drawNum (248, 90, wbs->maxitems, 3, false);
|
|
}
|
|
if (sp_state >= 6)
|
|
{
|
|
WI_drawNum (countpos, 115, cnt_secret[0], 3, false);
|
|
WI_DrawCharPatch (slash, slashpos, 115);
|
|
WI_drawNum (248, 115, wbs->maxsecret, 3, false);
|
|
}
|
|
if (sp_state >= 8)
|
|
{
|
|
screen->DrawText (CR_UNTRANSLATED, 85, 160, "TIME",
|
|
DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
|
|
WI_drawTime (249, 160, cnt_time);
|
|
if (wi_showtotaltime)
|
|
{
|
|
WI_drawTime (249, 180, cnt_total_time);
|
|
}
|
|
}
|
|
screen->SetFont (SmallFont);
|
|
}
|
|
}
|
|
|
|
// ====================================================================
|
|
// WI_checkForAccelerate
|
|
// Purpose: See if the player has hit either the attack or use key
|
|
// or mouse button. If so we set acceleratestage to 1 and
|
|
// all those display routines above jump right to the end.
|
|
// Args: none
|
|
// Returns: void
|
|
//
|
|
// ====================================================================
|
|
void WI_checkForAccelerate(void)
|
|
{
|
|
int i;
|
|
player_t *player;
|
|
|
|
// check for button presses to skip delays
|
|
for (i = 0, player = players; i < MAXPLAYERS; i++, player++)
|
|
{
|
|
if (playeringame[i])
|
|
{
|
|
if ((player->cmd.ucmd.buttons ^ player->oldbuttons) &&
|
|
((players[i].cmd.ucmd.buttons & players[i].oldbuttons)
|
|
== players[i].oldbuttons) && !player->isbot)
|
|
{
|
|
acceleratestage = 1;
|
|
}
|
|
player->oldbuttons = player->cmd.ucmd.buttons;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ====================================================================
|
|
// WI_Ticker
|
|
// Purpose: Do various updates every gametic, for stats, animation,
|
|
// checking that intermission music is running, etc.
|
|
// Args: none
|
|
// Returns: void
|
|
//
|
|
// ====================================================================
|
|
void WI_Ticker(void)
|
|
{
|
|
// counter for general background animation
|
|
bcnt++;
|
|
|
|
if (bcnt == 1)
|
|
{
|
|
// intermission music - use the defaults if none specified
|
|
if (level.info->intermusic != NULL)
|
|
S_ChangeMusic(level.info->intermusic, level.info->intermusicorder);
|
|
else if (gameinfo.gametype == GAME_Heretic)
|
|
S_ChangeMusic ("mus_intr");
|
|
else if (gameinfo.gametype == GAME_Hexen)
|
|
S_ChangeMusic ("hub");
|
|
else if (gameinfo.gametype == GAME_Strife) // Strife also needs a default
|
|
S_ChangeMusic ("d_slide");
|
|
else if (gamemode == commercial)
|
|
S_ChangeMusic ("d_dm2int");
|
|
else
|
|
S_ChangeMusic ("d_inter");
|
|
|
|
}
|
|
|
|
WI_checkForAccelerate();
|
|
|
|
switch (state)
|
|
{
|
|
case StatCount:
|
|
if (deathmatch) WI_updateDeathmatchStats();
|
|
else if (multiplayer) WI_updateNetgameStats();
|
|
else WI_updateStats();
|
|
break;
|
|
|
|
case ShowNextLoc:
|
|
WI_updateShowNextLoc();
|
|
break;
|
|
|
|
case NoState:
|
|
WI_updateNoState();
|
|
break;
|
|
|
|
case LeavingIntermission:
|
|
// Hush, GCC.
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WI_loadData(void)
|
|
{
|
|
int i;
|
|
char name[9];
|
|
|
|
if (gameinfo.gametype == GAME_Doom)
|
|
{
|
|
wiminus = TexMan["WIMINUS"]; // minus sign
|
|
percent = TexMan["WIPCNT"]; // percent sign
|
|
finished = TexMan["WIF"]; // "finished"
|
|
entering = TexMan["WIENTER"]; // "entering"
|
|
kills = TexMan["WIOSTK"]; // "kills"
|
|
secret = TexMan["WIOSTS"]; // "scrt"
|
|
sp_secret = TexMan["WISCRT2"]; // "secret"
|
|
items = TexMan["WIOSTI"]; // "items"
|
|
frags = TexMan["WIFRGS"]; // "frgs"
|
|
colon = TexMan["WICOLON"]; // ":"
|
|
timepic = TexMan["WITIME"]; // "time"
|
|
sucks = TexMan["WISUCKS"]; // "sucks"
|
|
par = TexMan["WIPAR"]; // "par"
|
|
killers = TexMan["WIKILRS"]; // "killers" (vertical]
|
|
victims = TexMan["WIVCTMS"]; // "victims" (horiz]
|
|
total = TexMan["WIMSTT"]; // "total"
|
|
star = TexMan["STFST01"]; // your face
|
|
bstar = TexMan["STFDEAD0"]; // dead face
|
|
p = TexMan["STPBANY"];
|
|
|
|
for (i = 0; i < 10; i++)
|
|
{ // numbers 0-9
|
|
sprintf (name, "WINUM%d", i);
|
|
num[i] = TexMan[name];
|
|
}
|
|
}
|
|
else if (gameinfo.gametype & GAME_Raven)
|
|
{
|
|
wiminus = TexMan["FONTB13"];
|
|
percent = TexMan["FONTB05"];
|
|
colon = TexMan["FONTB26"];
|
|
slash = TexMan["FONTB15"];
|
|
if (gameinfo.gametype==GAME_Heretic)
|
|
{
|
|
star = TexMan["FACEA0"];
|
|
bstar = TexMan["FACEB0"];
|
|
}
|
|
else
|
|
{
|
|
int dummywidth;
|
|
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
bstar = star;
|
|
}
|
|
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
sprintf (name, "FONTB%d", 16 + i);
|
|
num[i] = TexMan[name];
|
|
}
|
|
}
|
|
else // Strife needs some handling, too!
|
|
{
|
|
int dummywidth;
|
|
wiminus = BigFont->GetChar('-', &dummywidth);
|
|
percent = BigFont->GetChar('%', &dummywidth);
|
|
colon = BigFont->GetChar(':', &dummywidth);
|
|
slash = BigFont->GetChar('/', &dummywidth);
|
|
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
bstar = star;
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
num[i] = BigFont->GetChar('0'+i, &dummywidth);
|
|
}
|
|
}
|
|
|
|
// Use the local level structure which can be overridden by hubs if they eventually get names!
|
|
lnametexts[0] = level.level_name;
|
|
|
|
level_info_t * li = FindLevelInfo(wbs->next);
|
|
if (li) lnametexts[1] = G_MaybeLookupLevelName(li);
|
|
else lnametexts[1]=NULL;
|
|
|
|
WI_LoadBackground(false);
|
|
}
|
|
|
|
void WI_unloadData ()
|
|
{
|
|
// [RH] The texture data gets unloaded at pre-map time, so there's nothing to do here
|
|
return;
|
|
}
|
|
|
|
void WI_Drawer (void)
|
|
{
|
|
switch (state)
|
|
{
|
|
case StatCount:
|
|
if (deathmatch)
|
|
WI_drawDeathmatchStats();
|
|
else if (multiplayer)
|
|
WI_drawNetgameStats();
|
|
else
|
|
WI_drawStats();
|
|
break;
|
|
|
|
case ShowNextLoc:
|
|
WI_drawShowNextLoc();
|
|
break;
|
|
|
|
case LeavingIntermission:
|
|
break;
|
|
|
|
default:
|
|
WI_drawNoState();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void WI_initVariables (wbstartstruct_t *wbstartstruct)
|
|
{
|
|
wbs = wbstartstruct;
|
|
acceleratestage = 0;
|
|
cnt = bcnt = 0;
|
|
me = wbs->pnum;
|
|
plrs = wbs->plyr;
|
|
}
|
|
|
|
void WI_Start (wbstartstruct_t *wbstartstruct)
|
|
{
|
|
noautostartmap = false;
|
|
V_SetBlend (0,0,0,0);
|
|
WI_initVariables (wbstartstruct);
|
|
WI_loadData ();
|
|
if (deathmatch)
|
|
WI_initDeathmatchStats();
|
|
else if (multiplayer)
|
|
WI_initNetgameStats();
|
|
else
|
|
WI_initStats();
|
|
S_StopAllChannels ();
|
|
SN_StopAllSequences ();
|
|
}
|