2006-02-24 04:48:15 +00:00
|
|
|
// 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:
|
|
|
|
// Game completion, final screen animation.
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <math.h>
|
2009-04-07 07:06:07 +00:00
|
|
|
#include <stdlib.h>
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "m_swap.h"
|
|
|
|
#include "v_video.h"
|
|
|
|
#include "i_video.h"
|
|
|
|
#include "v_text.h"
|
|
|
|
#include "w_wad.h"
|
|
|
|
#include "s_sound.h"
|
|
|
|
#include "gstrings.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "r_state.h"
|
|
|
|
#include "r_draw.h"
|
|
|
|
#include "hu_stuff.h"
|
|
|
|
#include "cmdlib.h"
|
|
|
|
#include "gi.h"
|
|
|
|
#include "p_conversation.h"
|
|
|
|
#include "a_strifeglobal.h"
|
|
|
|
#include "templates.h"
|
2007-02-24 12:09:36 +00:00
|
|
|
#include "c_bind.h"
|
2007-12-26 16:06:03 +00:00
|
|
|
#include "r_translate.h"
|
2008-09-14 23:54:38 +00:00
|
|
|
#include "g_level.h"
|
|
|
|
#include "d_event.h"
|
2008-09-15 14:11:05 +00:00
|
|
|
#include "v_palette.h"
|
2009-05-30 08:56:40 +00:00
|
|
|
#include "d_main.h"
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
static void FadePic ();
|
|
|
|
static void GetFinaleText (const char *msgLumpName);
|
|
|
|
|
|
|
|
// Stage of animation:
|
|
|
|
// 0 = text
|
|
|
|
// 1 = art screen
|
|
|
|
// 2 = underwater screen
|
|
|
|
// 3 = character cast
|
|
|
|
// 4 = Heretic title
|
|
|
|
// 5 = Strife slideshow
|
|
|
|
static unsigned int FinaleStage;
|
|
|
|
|
|
|
|
static size_t FinaleCount, FinaleEndCount;
|
|
|
|
static int FinalePart;
|
|
|
|
|
|
|
|
static int TEXTSPEED;
|
|
|
|
#define TEXTWAIT 250
|
|
|
|
|
|
|
|
static int FinaleSequence;
|
|
|
|
static SBYTE FadeDir;
|
|
|
|
static bool FinaleHasPic;
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
static FString FinaleText;
|
2006-02-24 04:48:15 +00:00
|
|
|
static size_t FinaleTextLen;
|
2006-12-29 03:38:37 +00:00
|
|
|
static const char *FinaleFlat;
|
2007-09-26 21:50:05 +00:00
|
|
|
static bool FinaleEnding;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
void F_StartCast (void);
|
|
|
|
void F_CastTicker (void);
|
2006-09-14 00:02:31 +00:00
|
|
|
bool F_CastResponder (event_t *ev);
|
2006-02-24 04:48:15 +00:00
|
|
|
void F_CastDrawer (void);
|
|
|
|
void F_AdvanceSlideshow ();
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_StartFinale
|
|
|
|
//
|
2009-02-03 19:11:43 +00:00
|
|
|
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
|
|
|
|
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2009-03-22 11:37:56 +00:00
|
|
|
bool loopmusic = ending ? !gameinfo.noloopfinalemusic : true;
|
2006-02-24 04:48:15 +00:00
|
|
|
gameaction = ga_nothing;
|
|
|
|
gamestate = GS_FINALE;
|
|
|
|
viewactive = false;
|
|
|
|
automapactive = false;
|
|
|
|
|
|
|
|
// Okay - IWAD dependend stuff.
|
|
|
|
// This has been changed severely, and some stuff might have changed in the process.
|
|
|
|
//
|
|
|
|
// [RH] More flexible now (even more severe changes)
|
|
|
|
// FinaleFlat, FinaleText, and music are now determined in G_WorldDone() based on
|
|
|
|
// data in a level_info_t and a cluster_info_t.
|
|
|
|
|
|
|
|
if (cdtrack == 0 || !S_ChangeCDMusic (cdtrack, cdid))
|
|
|
|
{
|
|
|
|
if (music == NULL)
|
|
|
|
{
|
|
|
|
S_ChangeMusic (gameinfo.finaleMusic, 0, loopmusic);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
S_ChangeMusic (music, musicorder, loopmusic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FinaleFlat = (flat != NULL && *flat != 0) ? flat : gameinfo.finaleFlat;
|
|
|
|
|
|
|
|
if (textInLump)
|
|
|
|
{
|
|
|
|
GetFinaleText (text);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *from = (text != NULL) ? text : "Empty message";
|
|
|
|
FinaleText = from;
|
|
|
|
FinaleTextLen = FinaleText.Len() + 1;
|
|
|
|
}
|
|
|
|
if (lookupText)
|
|
|
|
{
|
|
|
|
const char *str = GStrings[FinaleText.GetChars()];
|
|
|
|
if (str != NULL)
|
|
|
|
{
|
|
|
|
FinaleText = str;
|
|
|
|
FinaleTextLen = FinaleText.Len() + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FinaleStage = 0;
|
|
|
|
V_SetBlend (0,0,0,0);
|
|
|
|
TEXTSPEED = 2;
|
|
|
|
|
|
|
|
FinaleHasPic = !!finalePic;
|
|
|
|
FinaleCount = 0;
|
|
|
|
FinaleEndCount = 70;
|
|
|
|
FadeDir = -1;
|
2007-09-26 21:50:05 +00:00
|
|
|
FinaleEnding = ending;
|
2006-02-24 04:48:15 +00:00
|
|
|
S_StopAllChannels ();
|
|
|
|
|
|
|
|
if (ending)
|
|
|
|
{
|
2009-08-02 03:38:57 +00:00
|
|
|
FinaleSequence = level.EndSequence;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (EndSequences[FinaleSequence].EndType == END_Chess)
|
|
|
|
{
|
|
|
|
TEXTSPEED = 3; // Slow the text to its original rate to match the music.
|
|
|
|
S_ChangeMusic ("hall", 0, loopmusic);
|
|
|
|
FinaleStage = 10;
|
|
|
|
GetFinaleText ("win1msg");
|
|
|
|
V_SetBlend (0,0,0,256);
|
|
|
|
}
|
|
|
|
else if (EndSequences[FinaleSequence].EndType == END_Strife)
|
|
|
|
{
|
|
|
|
if (players[0].mo->FindInventory (QuestItemClasses[24]) ||
|
2006-04-21 16:32:49 +00:00
|
|
|
players[0].mo->FindInventory (QuestItemClasses[27]))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
FinalePart = 10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FinalePart = 17;
|
|
|
|
}
|
|
|
|
FinaleStage = 5;
|
|
|
|
FinaleEndCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void F_EndFinale ()
|
|
|
|
{
|
|
|
|
FinaleText = NULL;
|
|
|
|
FinaleTextLen = 0;
|
|
|
|
}
|
|
|
|
|
2006-09-14 00:02:31 +00:00
|
|
|
bool F_Responder (event_t *event)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
if (FinaleStage == 3)
|
|
|
|
{
|
|
|
|
return F_CastResponder (event);
|
|
|
|
}
|
|
|
|
else if (FinaleStage == 2 && event->type == EV_KeyDown)
|
|
|
|
{ // We're showing the water pic; make any key kick to demo mode
|
|
|
|
FinaleStage = 4;
|
|
|
|
V_ForceBlend (0, 0, 0, 0);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_Ticker
|
|
|
|
//
|
|
|
|
void F_Ticker ()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
bool interrupt = false;
|
|
|
|
|
|
|
|
// check for skipping
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
|
|
{
|
|
|
|
// Only for buttons going down
|
|
|
|
if (!interrupt)
|
|
|
|
{
|
|
|
|
for (size_t j = 0; j < sizeof(players[i].cmd.ucmd.buttons)*8; ++j)
|
|
|
|
{
|
|
|
|
if (((players[i].cmd.ucmd.buttons >> j) & 1) &&
|
|
|
|
!((players[i].oldbuttons >> j) & 1))
|
|
|
|
{
|
|
|
|
interrupt = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
players[i].oldbuttons = players[i].cmd.ucmd.buttons;
|
|
|
|
}
|
|
|
|
|
|
|
|
// [RH] Non-commercial can be skipped now, too
|
|
|
|
if (FinaleStage == 0)
|
|
|
|
{
|
|
|
|
if (interrupt ||
|
2009-03-22 11:37:56 +00:00
|
|
|
((!(gameinfo.flags & GI_MAPxx) || gameinfo.flags & GI_SHAREWARE)
|
2006-02-24 04:48:15 +00:00
|
|
|
&& FinaleCount > FinaleTextLen*TEXTSPEED+TEXTWAIT))
|
|
|
|
{
|
|
|
|
if (FinaleCount < FinaleTextLen*TEXTSPEED+10)
|
|
|
|
{
|
|
|
|
FinaleCount = FinaleTextLen*TEXTSPEED+10;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-26 21:50:05 +00:00
|
|
|
if (FinaleEnding)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
// [RH] Don't automatically advance end-of-game messages
|
|
|
|
if (interrupt)
|
|
|
|
{
|
2009-08-02 03:38:57 +00:00
|
|
|
FinaleSequence = level.EndSequence;
|
2006-02-24 04:48:15 +00:00
|
|
|
if (EndSequences[FinaleSequence].EndType == END_Cast)
|
|
|
|
{
|
|
|
|
F_StartCast ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FinaleCount = 0;
|
|
|
|
FinaleStage = 1;
|
|
|
|
wipegamestate = GS_FORCEWIPE;
|
|
|
|
if (EndSequences[FinaleSequence].EndType == END_Bunny)
|
|
|
|
{
|
2008-05-30 06:56:50 +00:00
|
|
|
if (!EndSequences[FinaleSequence].Advanced)
|
2009-02-08 11:28:30 +00:00
|
|
|
S_StartMusic ("$music_bunny");
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-30 06:56:50 +00:00
|
|
|
if (EndSequences[FinaleSequence].Advanced &&
|
|
|
|
!EndSequences[FinaleSequence].Music.IsEmpty())
|
|
|
|
{
|
|
|
|
S_ChangeMusic(EndSequences[FinaleSequence].Music, 0, EndSequences[FinaleSequence].MusicLooping);
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gameaction = ga_worlddone;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (FinaleStage >= 10)
|
|
|
|
{
|
|
|
|
// Hexen chess ending with three pages of text.
|
|
|
|
// [RH] This can be interrupted to speed it up.
|
|
|
|
if (interrupt)
|
|
|
|
{
|
|
|
|
if (FinaleStage == 11 || FinaleStage == 12 || FinaleStage == 15)
|
|
|
|
{ // Stages that display text
|
|
|
|
if (FinaleCount < FinaleEndCount-TEXTWAIT)
|
|
|
|
{
|
|
|
|
FinaleCount = FinaleEndCount-TEXTWAIT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FinaleCount = FinaleEndCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (FinaleCount < 69)
|
|
|
|
{ // Stages that fade pictures
|
|
|
|
FinaleCount = 69;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (FinaleStage < 15 && FinaleCount >= FinaleEndCount)
|
|
|
|
{
|
|
|
|
FinaleCount = 0;
|
|
|
|
FinaleStage++;
|
|
|
|
switch (FinaleStage)
|
|
|
|
{
|
|
|
|
case 11: // Text 1
|
|
|
|
FinaleEndCount = FinaleTextLen*TEXTSPEED+TEXTWAIT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12: // Pic 2, Text 2
|
|
|
|
GetFinaleText ("win2msg");
|
|
|
|
FinaleEndCount = FinaleTextLen*TEXTSPEED+TEXTWAIT;
|
2009-03-22 11:37:56 +00:00
|
|
|
S_ChangeMusic ("orb", 0, !gameinfo.noloopfinalemusic);
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 13: // Pic 2 -- Fade out
|
|
|
|
FinaleEndCount = 70;
|
|
|
|
FadeDir = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 14: // Pic 3 -- Fade in
|
|
|
|
FinaleEndCount = 71;
|
|
|
|
FadeDir = -1;
|
2009-03-22 11:37:56 +00:00
|
|
|
S_ChangeMusic ("chess", 0, !gameinfo.noloopfinalemusic);
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 15: // Pic 3, Text 3
|
|
|
|
GetFinaleText ("win3msg");
|
|
|
|
FinaleEndCount = FinaleTextLen*TEXTSPEED+TEXTWAIT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (FinaleStage == 10 || FinaleStage == 13 || FinaleStage == 14)
|
|
|
|
{
|
|
|
|
FadePic ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (FinaleStage >= 5)
|
|
|
|
{ // Strife slideshow
|
|
|
|
if (interrupt)
|
|
|
|
{
|
|
|
|
FinaleCount = FinaleEndCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// advance animation
|
|
|
|
FinaleCount++;
|
|
|
|
|
|
|
|
if (FinaleStage == 3)
|
|
|
|
{
|
|
|
|
F_CastTicker ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (FinaleStage == 5 && FinaleCount > FinaleEndCount)
|
|
|
|
{
|
2008-07-01 04:06:56 +00:00
|
|
|
S_StopSound (CHAN_VOICE);
|
2006-02-24 04:48:15 +00:00
|
|
|
F_AdvanceSlideshow ();
|
|
|
|
FinaleCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// FadePic
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
static void FadePic ()
|
|
|
|
{
|
|
|
|
int blend = int(256*FinaleCount/70);
|
|
|
|
|
|
|
|
if (FadeDir < 0)
|
|
|
|
{
|
|
|
|
blend = 256 - blend;
|
|
|
|
}
|
|
|
|
V_SetBlend (0,0,0,blend);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_TextWrite
|
|
|
|
//
|
|
|
|
void F_TextWrite (void)
|
|
|
|
{
|
|
|
|
FTexture *pic;
|
|
|
|
int w;
|
|
|
|
size_t count;
|
|
|
|
const char *ch;
|
|
|
|
int c;
|
|
|
|
int cx;
|
|
|
|
int cy;
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
const FRemapTable *range;
|
2006-02-24 04:48:15 +00:00
|
|
|
int leftmargin;
|
|
|
|
int rowheight;
|
|
|
|
bool scale;
|
|
|
|
|
|
|
|
if (FinaleCount < 11)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// draw some of the text onto the screen
|
2008-08-30 19:44:19 +00:00
|
|
|
leftmargin = (gameinfo.gametype & (GAME_DoomStrifeChex|GAME_Hexen) ? 10 : 20) - 160;
|
2008-11-27 17:43:36 +00:00
|
|
|
rowheight = SmallFont->GetHeight () +
|
2008-08-30 19:44:19 +00:00
|
|
|
(gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1);
|
2006-02-24 04:48:15 +00:00
|
|
|
scale = (CleanXfac != 1 || CleanYfac != 1);
|
|
|
|
|
|
|
|
cx = leftmargin;
|
|
|
|
if (FinaleStage == 15)
|
|
|
|
{
|
|
|
|
cy = 135 - 100;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-30 19:44:19 +00:00
|
|
|
cy = (gameinfo.gametype & (GAME_DoomStrifeChex) ? 10 : 5) - 100;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
ch = FinaleText.GetChars();
|
|
|
|
|
|
|
|
count = (FinaleCount - 10)/TEXTSPEED;
|
2008-11-27 17:43:36 +00:00
|
|
|
range = SmallFont->GetColorTranslation (CR_UNTRANSLATED);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
for ( ; count ; count-- )
|
|
|
|
{
|
|
|
|
c = *ch++;
|
|
|
|
if (!c)
|
|
|
|
break;
|
|
|
|
if (c == '\n')
|
|
|
|
{
|
|
|
|
cx = leftmargin;
|
|
|
|
cy += rowheight;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-11-27 17:43:36 +00:00
|
|
|
pic = SmallFont->GetChar (c, &w);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (cx+w > SCREENWIDTH)
|
|
|
|
continue;
|
|
|
|
if (pic != NULL)
|
|
|
|
{
|
|
|
|
if (scale)
|
|
|
|
{
|
|
|
|
screen->DrawTexture (pic,
|
|
|
|
cx + 320 / 2,
|
|
|
|
cy + 200 / 2,
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
DTA_Translation, range,
|
2006-02-24 04:48:15 +00:00
|
|
|
DTA_Clean, true,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
screen->DrawTexture (pic,
|
|
|
|
cx + 320 / 2,
|
|
|
|
cy + 200 / 2,
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
DTA_Translation, range,
|
2006-02-24 04:48:15 +00:00
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cx += w;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Final DOOM 2 animation
|
|
|
|
// Casting by id Software.
|
|
|
|
// in order of appearance
|
|
|
|
//
|
2009-03-28 11:49:44 +00:00
|
|
|
struct castinfo_t
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
const char *type;
|
|
|
|
const AActor *info;
|
2006-12-02 15:38:50 +00:00
|
|
|
const PClass *Class;
|
2009-03-28 11:49:44 +00:00
|
|
|
};
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
castinfo_t castorder[] =
|
|
|
|
{
|
|
|
|
{"CC_ZOMBIE", "ZombieMan"},
|
|
|
|
{"CC_SHOTGUN", "ShotgunGuy"},
|
|
|
|
{"CC_HEAVY", "ChaingunGuy"},
|
|
|
|
{"CC_IMP", "DoomImp"},
|
|
|
|
{"CC_DEMON", "Demon"},
|
|
|
|
{"CC_LOST", "LostSoul"},
|
|
|
|
{"CC_CACO", "Cacodemon"},
|
|
|
|
{"CC_HELL", "HellKnight"},
|
|
|
|
{"CC_BARON", "BaronOfHell"},
|
|
|
|
{"CC_ARACH", "Arachnotron"},
|
|
|
|
{"CC_PAIN", "PainElemental"},
|
|
|
|
{"CC_REVEN", "Revenant"},
|
|
|
|
{"CC_MANCU", "Fatso"},
|
|
|
|
{"CC_ARCH", "Archvile"},
|
|
|
|
{"CC_SPIDER", "SpiderMastermind"},
|
|
|
|
{"CC_CYBER", "Cyberdemon"},
|
|
|
|
{"CC_HERO", "DoomPlayer"},
|
|
|
|
|
|
|
|
{0, NULL}
|
|
|
|
};
|
|
|
|
|
2006-05-22 01:34:07 +00:00
|
|
|
static struct
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
const char *type;
|
2006-09-14 00:02:31 +00:00
|
|
|
BYTE melee;
|
|
|
|
BYTE ofs;
|
2006-02-24 04:48:15 +00:00
|
|
|
const char *sound;
|
|
|
|
FState *match;
|
|
|
|
} atkstates[] =
|
|
|
|
{
|
|
|
|
{ "DoomPlayer", 0, 0, "weapons/sshotf" },
|
|
|
|
{ "ZombieMan", 0, 1, "grunt/attack" },
|
|
|
|
{ "ShotgunGuy", 0, 1, "shotguy/attack" },
|
|
|
|
{ "Archvile", 0, 1, "vile/start" },
|
|
|
|
{ "Revenant", 1, 1, "skeleton/swing" },
|
|
|
|
{ "Revenant", 1, 3, "skeleton/melee" },
|
|
|
|
{ "Revenant", 0, 1, "skeleton/attack" },
|
|
|
|
{ "Fatso", 0, 1, "fatso/attack" },
|
|
|
|
{ "Fatso", 0, 4, "fatso/attack" },
|
|
|
|
{ "Fatso", 0, 7, "fatso/attack" },
|
|
|
|
{ "ChaingunGuy", 0, 1, "chainguy/attack" },
|
|
|
|
{ "ChaingunGuy", 0, 2, "chainguy/attack" },
|
|
|
|
{ "ChaingunGuy", 0, 3, "chainguy/attack" },
|
|
|
|
{ "DoomImp", 0, 2, "imp/attack" },
|
|
|
|
{ "Demon", 1, 1, "demon/melee" },
|
|
|
|
{ "BaronOfHell", 0, 1, "baron/attack" },
|
|
|
|
{ "HellKnight", 0, 1, "baron/attack" },
|
|
|
|
{ "Cacodemon", 0, 1, "caco/attack" },
|
|
|
|
{ "LostSoul", 0, 1, "skull/melee" },
|
|
|
|
{ "SpiderMastermind", 0, 1, "spider/attack" },
|
|
|
|
{ "SpiderMastermind", 0, 2, "spider/attack" },
|
|
|
|
{ "Arachnotron", 0, 1, "baby/attack" },
|
|
|
|
{ "Cyberdemon", 0, 1, "weapons/rocklf" },
|
|
|
|
{ "Cyberdemon", 0, 3, "weapons/rocklf" },
|
|
|
|
{ "Cyberdemon", 0, 5, "weapons/rocklf" },
|
|
|
|
{ "PainElemental", 0, 2, "skull/melee" },
|
|
|
|
{ NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
int castnum;
|
|
|
|
int casttics;
|
|
|
|
int castsprite; // [RH] For overriding the player sprite with a skin
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
const FRemapTable *casttranslation; // [RH] Draw "our hero" with their chosen suit color
|
2006-02-24 04:48:15 +00:00
|
|
|
FState* caststate;
|
2006-09-14 00:02:31 +00:00
|
|
|
bool castdeath;
|
2006-02-24 04:48:15 +00:00
|
|
|
int castframes;
|
|
|
|
int castonmelee;
|
2006-09-14 00:02:31 +00:00
|
|
|
bool castattacking;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
static FState *advplayerstate;
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_StartCast
|
|
|
|
//
|
|
|
|
extern gamestate_t wipegamestate;
|
|
|
|
|
|
|
|
|
|
|
|
void F_StartCast (void)
|
|
|
|
{
|
2006-05-10 02:40:43 +00:00
|
|
|
const PClass *type;
|
2006-02-24 04:48:15 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
// [RH] Set the names and defaults for the cast
|
|
|
|
for (i = 0; castorder[i].type; i++)
|
|
|
|
{
|
2006-05-10 02:40:43 +00:00
|
|
|
type = PClass::FindClass (castorder[i].type);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (type == NULL)
|
2006-12-02 15:38:50 +00:00
|
|
|
{
|
2006-02-24 04:48:15 +00:00
|
|
|
castorder[i].info = GetDefault<AActor>();
|
2006-12-02 15:38:50 +00:00
|
|
|
castorder[i].Class= RUNTIME_CLASS(AActor);
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
else
|
2006-12-02 15:38:50 +00:00
|
|
|
{
|
2006-02-24 04:48:15 +00:00
|
|
|
castorder[i].info = GetDefaultByType (type);
|
2006-12-02 15:38:50 +00:00
|
|
|
castorder[i].Class= type;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; atkstates[i].type; i++)
|
|
|
|
{
|
2006-05-10 02:40:43 +00:00
|
|
|
type = PClass::FindClass (atkstates[i].type);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (type != NULL)
|
|
|
|
{
|
|
|
|
if (atkstates[i].melee)
|
2006-05-10 02:40:43 +00:00
|
|
|
atkstates[i].match = ((AActor *)(type->Defaults))->MeleeState + atkstates[i].ofs;
|
2006-02-24 04:48:15 +00:00
|
|
|
else
|
2006-05-10 02:40:43 +00:00
|
|
|
atkstates[i].match = ((AActor *)(type->Defaults))->MissileState + atkstates[i].ofs;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
atkstates[i].match = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-10 02:40:43 +00:00
|
|
|
type = PClass::FindClass (NAME_DoomPlayer);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (type != NULL)
|
2006-05-10 02:40:43 +00:00
|
|
|
advplayerstate = ((AActor *)(type->Defaults))->MissileState;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
wipegamestate = GS_FORCEWIPE;
|
|
|
|
castnum = 0;
|
|
|
|
caststate = castorder[castnum].info->SeeState;
|
2008-08-10 14:19:47 +00:00
|
|
|
castsprite = caststate->sprite;
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
casttranslation = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
casttics = caststate->GetTics ();
|
|
|
|
castdeath = false;
|
|
|
|
FinaleStage = 3;
|
|
|
|
castframes = 0;
|
|
|
|
castonmelee = 0;
|
|
|
|
castattacking = false;
|
2008-05-30 06:56:50 +00:00
|
|
|
if (!EndSequences[FinaleSequence].Advanced)
|
2009-02-08 11:28:30 +00:00
|
|
|
S_ChangeMusic ("$music_evil");
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_CastTicker
|
|
|
|
//
|
|
|
|
void F_CastTicker (void)
|
|
|
|
{
|
|
|
|
if (--casttics > 0 && caststate != NULL)
|
|
|
|
return; // not time to change state yet
|
|
|
|
|
|
|
|
if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL)
|
|
|
|
{
|
|
|
|
// switch from deathstate to next monster
|
|
|
|
do
|
|
|
|
{
|
|
|
|
castnum++;
|
|
|
|
castdeath = false;
|
|
|
|
if (castorder[castnum].name == 0)
|
|
|
|
castnum = 0;
|
|
|
|
if (castorder[castnum].info->SeeSound)
|
|
|
|
{
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, castorder[castnum].info->SeeSound, 1, ATTN_NONE);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
caststate = castorder[castnum].info->SeeState;
|
|
|
|
// [RH] Skip monsters that have been hacked to no longer have attack states
|
|
|
|
if (castorder[castnum].info->MissileState == NULL &&
|
|
|
|
castorder[castnum].info->MeleeState == NULL)
|
|
|
|
{
|
|
|
|
caststate = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (caststate == NULL);
|
|
|
|
if (castnum == 16)
|
|
|
|
{
|
|
|
|
castsprite = skins[players[consoleplayer].userinfo.skin].sprite;
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
casttranslation = translationtables[TRANSLATION_Players][consoleplayer];
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-10 14:19:47 +00:00
|
|
|
castsprite = caststate->sprite;
|
- Discovered that Shader Model 1.4 clamps my constants, so I can't use
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)
2007-12-26 04:42:15 +00:00
|
|
|
casttranslation = NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
castframes = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// sound hacks....
|
|
|
|
if (caststate != NULL)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; atkstates[i].type; i++)
|
|
|
|
{
|
|
|
|
if (atkstates[i].match == caststate)
|
|
|
|
{
|
|
|
|
S_StopAllChannels ();
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_WEAPON | CHAN_UI, atkstates[i].sound, 1, ATTN_NONE);
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// just advance to next state in animation
|
|
|
|
if (caststate == advplayerstate)
|
|
|
|
goto stopattack; // Oh, gross hack!
|
|
|
|
|
|
|
|
caststate = caststate->GetNextState();
|
|
|
|
castframes++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (castframes == 12)
|
|
|
|
{
|
|
|
|
// go into attack frame
|
|
|
|
castattacking = true;
|
|
|
|
if (castonmelee)
|
|
|
|
caststate = castorder[castnum].info->MeleeState;
|
|
|
|
else
|
|
|
|
caststate = castorder[castnum].info->MissileState;
|
|
|
|
castonmelee ^= 1;
|
|
|
|
if (caststate == NULL)
|
|
|
|
{
|
|
|
|
if (castonmelee)
|
|
|
|
caststate = castorder[castnum].info->MeleeState;
|
|
|
|
else
|
|
|
|
caststate = castorder[castnum].info->MissileState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (castattacking)
|
|
|
|
{
|
|
|
|
if (castframes == 24
|
|
|
|
|| caststate == castorder[castnum].info->SeeState )
|
|
|
|
{
|
|
|
|
stopattack:
|
|
|
|
castattacking = false;
|
|
|
|
castframes = 0;
|
|
|
|
caststate = castorder[castnum].info->SeeState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
casttics = caststate->GetTics();
|
|
|
|
if (casttics == -1)
|
|
|
|
casttics = 15;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_CastResponder
|
|
|
|
//
|
|
|
|
|
2006-09-14 00:02:31 +00:00
|
|
|
bool F_CastResponder (event_t* ev)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
if (ev->type != EV_KeyDown)
|
|
|
|
return false;
|
2007-02-24 12:09:36 +00:00
|
|
|
|
|
|
|
const char *cmd = C_GetBinding (ev->data1);
|
|
|
|
|
|
|
|
if (cmd != NULL && !stricmp (cmd, "toggleconsole"))
|
|
|
|
return false;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
if (castdeath)
|
|
|
|
return true; // already in dying frames
|
|
|
|
|
|
|
|
// go into death frame
|
|
|
|
castdeath = true;
|
2006-12-16 14:06:21 +00:00
|
|
|
caststate = castorder[castnum].Class->ActorInfo->FindState(NAME_Death);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (caststate != NULL)
|
|
|
|
{
|
|
|
|
casttics = caststate->GetTics();
|
|
|
|
castframes = 0;
|
|
|
|
castattacking = false;
|
|
|
|
if (castnum == 16)
|
|
|
|
{
|
2008-07-19 12:40:10 +00:00
|
|
|
int snd = S_FindSkinnedSound(players[consoleplayer].mo, "*death");
|
|
|
|
if (snd != 0) S_Sound (CHAN_VOICE | CHAN_UI, snd, 1, ATTN_NONE);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
else if (castorder[castnum].info->DeathSound)
|
|
|
|
{
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, castorder[castnum].info->DeathSound, 1, ATTN_NONE);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_CastDrawer
|
|
|
|
//
|
|
|
|
void F_CastDrawer (void)
|
|
|
|
{
|
|
|
|
spriteframe_t* sprframe;
|
|
|
|
FTexture* pic;
|
|
|
|
|
|
|
|
// erase the entire screen to a background
|
|
|
|
screen->DrawTexture (TexMan["BOSSBACK"], 0, 0,
|
|
|
|
DTA_DestWidth, screen->GetWidth(),
|
|
|
|
DTA_DestHeight, screen->GetHeight(),
|
|
|
|
TAG_DONE);
|
|
|
|
|
2008-11-27 17:43:36 +00:00
|
|
|
screen->DrawText (SmallFont, CR_UNTRANSLATED,
|
2006-02-24 04:48:15 +00:00
|
|
|
(SCREENWIDTH - SmallFont->StringWidth (GStrings(castorder[castnum].name)) * CleanXfac)/2,
|
|
|
|
(SCREENHEIGHT * 180) / 200,
|
|
|
|
GStrings(castorder[castnum].name),
|
|
|
|
DTA_CleanNoMove, true, TAG_DONE);
|
|
|
|
|
|
|
|
// draw the current frame in the middle of the screen
|
|
|
|
if (caststate != NULL)
|
|
|
|
{
|
|
|
|
sprframe = &SpriteFrames[sprites[castsprite].spriteframes + caststate->GetFrame()];
|
|
|
|
pic = TexMan(sprframe->Texture[0]);
|
|
|
|
|
|
|
|
screen->DrawTexture (pic, 160, 170,
|
|
|
|
DTA_320x200, true,
|
|
|
|
DTA_FlipX, sprframe->Flip & 1,
|
|
|
|
DTA_Translation, casttranslation,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
==================
|
|
|
|
=
|
|
|
|
= F_DemonScroll
|
|
|
|
=
|
|
|
|
==================
|
|
|
|
*/
|
|
|
|
|
|
|
|
void F_DemonScroll ()
|
|
|
|
{
|
2008-05-30 06:56:50 +00:00
|
|
|
const char *tex1, *tex2;
|
|
|
|
if (EndSequences[FinaleSequence].Advanced)
|
|
|
|
{
|
|
|
|
tex1 = EndSequences[FinaleSequence].PicName;
|
|
|
|
tex2 = EndSequences[FinaleSequence].PicName2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tex1 = "FINAL1";
|
|
|
|
tex2 = "FINAL2";
|
|
|
|
}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
int yval;
|
2008-05-30 06:56:50 +00:00
|
|
|
FTexture *final1 = TexMan(tex1);
|
|
|
|
FTexture *final2 = TexMan(tex2);
|
2006-02-24 04:48:15 +00:00
|
|
|
int fwidth = final1->GetWidth();
|
|
|
|
int fheight = final1->GetHeight();
|
|
|
|
|
|
|
|
if (FinaleCount < 70)
|
|
|
|
{
|
|
|
|
screen->DrawTexture (final1, 0, 0,
|
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
|
|
|
screen->FillBorder (NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
yval = int(FinaleCount) - 70;
|
|
|
|
if (yval < 600)
|
|
|
|
{
|
|
|
|
yval = Scale (yval, fheight, 600);
|
|
|
|
screen->DrawTexture (final1, 0, yval,
|
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
2008-05-30 06:56:50 +00:00
|
|
|
screen->DrawTexture (final2, 0, yval - fheight,
|
2006-02-24 04:48:15 +00:00
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ //else, we'll just sit here and wait, for now
|
2008-05-30 06:56:50 +00:00
|
|
|
screen->DrawTexture (final2, 0, 0,
|
2006-02-24 04:48:15 +00:00
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
|
|
|
}
|
|
|
|
screen->FillBorder (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==================
|
|
|
|
=
|
|
|
|
= F_DrawUnderwater
|
|
|
|
=
|
|
|
|
==================
|
|
|
|
*/
|
2007-01-02 09:51:04 +00:00
|
|
|
extern int NoWipe;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
void F_DrawUnderwater(void)
|
|
|
|
{
|
|
|
|
extern EMenuState menuactive;
|
|
|
|
FTexture *pic;
|
|
|
|
|
|
|
|
switch (FinaleStage)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
{
|
|
|
|
PalEntry *palette;
|
2006-09-14 00:02:31 +00:00
|
|
|
const BYTE *orgpal;
|
2006-02-24 04:48:15 +00:00
|
|
|
FMemLump lump;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
lump = Wads.ReadLump ("E2PAL");
|
2006-09-14 00:02:31 +00:00
|
|
|
orgpal = (BYTE *)lump.GetMem();
|
2006-02-24 04:48:15 +00:00
|
|
|
palette = screen->GetPalette ();
|
|
|
|
for (i = 256; i > 0; i--, orgpal += 3)
|
|
|
|
{
|
|
|
|
*palette++ = PalEntry (orgpal[0], orgpal[1], orgpal[2]);
|
|
|
|
}
|
|
|
|
screen->UpdatePalette ();
|
2007-01-02 09:51:04 +00:00
|
|
|
FinaleStage = 2;
|
|
|
|
}
|
|
|
|
// intentional fall-through
|
|
|
|
case 2:
|
2006-02-24 04:48:15 +00:00
|
|
|
pic = TexMan("E2END");
|
|
|
|
screen->DrawTexture (pic, 0, 0,
|
|
|
|
DTA_VirtualWidth, pic->GetWidth(),
|
|
|
|
DTA_VirtualHeight, pic->GetHeight(),
|
|
|
|
TAG_DONE);
|
|
|
|
screen->FillBorder (NULL);
|
|
|
|
paused = false;
|
|
|
|
menuactive = MENU_Off;
|
2007-01-02 09:51:04 +00:00
|
|
|
NoWipe = -1;
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
{
|
|
|
|
PalEntry *palette;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
palette = screen->GetPalette ();
|
|
|
|
for (i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
palette[i] = GPalette.BaseColors[i];
|
|
|
|
}
|
|
|
|
screen->UpdatePalette ();
|
|
|
|
|
|
|
|
pic = TexMan("TITLE");
|
|
|
|
screen->DrawTexture (pic, 0, 0,
|
|
|
|
DTA_VirtualWidth, pic->GetWidth(),
|
|
|
|
DTA_VirtualHeight, pic->GetHeight(),
|
|
|
|
TAG_DONE);
|
|
|
|
screen->FillBorder (NULL);
|
2007-01-02 09:51:04 +00:00
|
|
|
NoWipe = 0;
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==================
|
|
|
|
=
|
|
|
|
= F_BunnyScroll
|
|
|
|
=
|
|
|
|
==================
|
|
|
|
*/
|
|
|
|
void F_BunnyScroll (void)
|
|
|
|
{
|
|
|
|
static size_t laststage;
|
|
|
|
|
2008-05-30 06:56:50 +00:00
|
|
|
bool bunny = false;
|
2006-02-24 04:48:15 +00:00
|
|
|
int scrolled;
|
|
|
|
char name[10];
|
|
|
|
size_t stage;
|
|
|
|
FTexture *tex;
|
|
|
|
int fwidth;
|
|
|
|
int fheight;
|
2008-05-30 06:56:50 +00:00
|
|
|
const char *tex1;
|
|
|
|
const char *tex2;
|
|
|
|
|
|
|
|
if (EndSequences[FinaleSequence].Advanced)
|
|
|
|
{
|
|
|
|
tex1 = EndSequences[FinaleSequence].PicName;
|
|
|
|
tex2 = EndSequences[FinaleSequence].PicName2;
|
|
|
|
bunny = EndSequences[FinaleSequence].PlayTheEnd;
|
|
|
|
}
|
|
|
|
else if (EndSequences[FinaleSequence].EndType == END_BuyStrife)
|
|
|
|
{
|
|
|
|
tex1 = "CREDIT";
|
|
|
|
tex2 = "VELLOGO";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tex1 = "PFUB1";
|
|
|
|
tex2 = "PFUB2";
|
|
|
|
bunny = true;
|
|
|
|
}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
|
|
|
|
|
2008-05-30 06:56:50 +00:00
|
|
|
tex = TexMan(tex1);
|
2006-02-24 04:48:15 +00:00
|
|
|
fwidth = tex->GetWidth();
|
|
|
|
fheight = tex->GetHeight();
|
|
|
|
|
|
|
|
scrolled = clamp (((signed)FinaleCount-230)*fwidth/640, 0, fwidth);
|
|
|
|
|
|
|
|
screen->DrawTexture (tex, scrolled, 0,
|
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
|
|
|
|
2008-05-30 06:56:50 +00:00
|
|
|
tex = TexMan(tex2);
|
2006-02-24 04:48:15 +00:00
|
|
|
screen->DrawTexture (tex, scrolled - fwidth, 0,
|
|
|
|
DTA_VirtualWidth, fwidth,
|
|
|
|
DTA_VirtualHeight, fheight,
|
|
|
|
DTA_Masked, false,
|
|
|
|
TAG_DONE);
|
|
|
|
|
|
|
|
screen->FillBorder (NULL);
|
|
|
|
|
|
|
|
if (bunny)
|
|
|
|
{
|
|
|
|
if (FinaleCount < 1130)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (FinaleCount < 1180)
|
|
|
|
{
|
|
|
|
screen->DrawTexture (TexMan("END0"), (320-13*8)/2, (200-8*8)/2, DTA_320x200, true, TAG_DONE);
|
|
|
|
laststage = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
stage = (FinaleCount-1180) / 5;
|
|
|
|
if (stage > 6)
|
|
|
|
stage = 6;
|
|
|
|
if (stage > laststage)
|
|
|
|
{
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_WEAPON | CHAN_UI, "weapons/pistol", 1, ATTN_NONE);
|
2006-02-24 04:48:15 +00:00
|
|
|
laststage = stage;
|
|
|
|
}
|
|
|
|
|
About a week's worth of changes here. As a heads-up, I wouldn't be
surprised if this doesn't build in Linux right now. The CMakeLists.txt
were checked with MinGW and NMake, but how they fair under Linux is an
unknown to me at this time.
- Converted most sprintf (and all wsprintf) calls to either mysnprintf or
FStrings, depending on the situation.
- Changed the strings in the wbstartstruct to be FStrings.
- Changed myvsnprintf() to output nothing if count is greater than INT_MAX.
This is so that I can use a series of mysnprintf() calls and advance the
pointer for each one. Once the pointer goes beyond the end of the buffer,
the count will go negative, but since it's an unsigned type it will be
seen as excessively huge instead. This should not be a problem, as there's
no reason for ZDoom to be using text buffers larger than 2 GB anywhere.
- Ripped out the disabled bit from FGameConfigFile::MigrateOldConfig().
- Changed CalcMapName() to return an FString instead of a pointer to a static
buffer.
- Changed startmap in d_main.cpp into an FString.
- Changed CheckWarpTransMap() to take an FString& as the first argument.
- Changed d_mapname in g_level.cpp into an FString.
- Changed DoSubstitution() in ct_chat.cpp to place the substitutions in an
FString.
- Fixed: The MAPINFO parser wrote into the string buffer to construct a map
name when given a Hexen map number. This was fine with the old scanner
code, but only a happy coincidence prevents it from crashing with the new
code
- Added the 'B' conversion specifier to StringFormat::VWorker() for printing
binary numbers.
- Added CMake support for building with MinGW, MSYS, and NMake. Linux support
is probably broken until I get around to booting into Linux again. Niceties
provided over the existing Makefiles they're replacing:
* All command-line builds can use the same build system, rather than having
a separate one for MinGW and another for Linux.
* Microsoft's NMake tool is supported as a target.
* Progress meters.
* Parallel makes work from a fresh checkout without needing to be primed
first with a single-threaded make.
* Porting to other architectures should be simplified, whenever that day
comes.
- Replaced the makewad tool with zipdir. This handles the dependency tracking
itself instead of generating an external makefile to do it, since I couldn't
figure out how to generate a makefile with an external tool and include it
with a CMake-generated makefile. Where makewad used a master list of files
to generate the package file, zipdir just zips the entire contents of one or
more directories.
- Added the gdtoa package from netlib's fp library so that ZDoom's printf-style
formatting can be entirely independant of the CRT.
SVN r1082 (trunk)
2008-07-23 04:57:26 +00:00
|
|
|
mysnprintf (name, countof(name), "END%d", (int)stage);
|
2006-02-24 04:48:15 +00:00
|
|
|
screen->DrawTexture (TexMan(name), (320-13*8)/2, (200-8*8)/2, DTA_320x200, true, TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// F_StartSlideshow
|
|
|
|
//
|
|
|
|
// Starts running the slideshow previously set up.
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
void F_StartSlideshow ()
|
|
|
|
{
|
|
|
|
gameaction = ga_nothing;
|
|
|
|
gamestate = GS_FINALE;
|
|
|
|
wipegamestate = GS_FINALE;
|
|
|
|
viewactive = false;
|
|
|
|
automapactive = false;
|
|
|
|
|
|
|
|
S_StopAllChannels ();
|
|
|
|
S_ChangeMusic ("D_DARK", 0, true);
|
|
|
|
V_SetBlend (0,0,0,0);
|
|
|
|
|
|
|
|
// The slideshow is determined solely by the map you're on.
|
2009-02-03 19:11:43 +00:00
|
|
|
if (!multiplayer && level.flags2 & LEVEL2_DEATHSLIDESHOW)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
FinalePart = 14;
|
|
|
|
}
|
|
|
|
else switch (level.levelnum)
|
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
FinalePart = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
FinalePart = 5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
FinalePart = -99;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
FinaleCount = 0;
|
|
|
|
FinaleStage = 5;
|
|
|
|
FinaleEndCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// F_AdvanceSlideshow
|
|
|
|
//
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
void F_AdvanceSlideshow ()
|
|
|
|
{
|
|
|
|
switch (FinalePart)
|
|
|
|
{
|
|
|
|
case -99:
|
|
|
|
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
|
2009-02-03 19:11:43 +00:00
|
|
|
S_ChangeMusic (level.Music, level.musicorder);
|
2006-02-24 04:48:15 +00:00
|
|
|
gamestate = GS_LEVEL;
|
|
|
|
wipegamestate = GS_LEVEL;
|
|
|
|
P_ResumeConversation ();
|
|
|
|
viewactive = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
wipegamestate = GS_FORCEWIPEFADE;
|
|
|
|
FinaleStage = 6;
|
|
|
|
S_StartMusic ("D_FAST");
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Macil's speech on map 3 about the Programmer.
|
|
|
|
case 1:
|
|
|
|
FinaleFlat = "SS2F1";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac10", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 2;
|
|
|
|
FinaleEndCount = 9 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
FinaleFlat = "SS2F2";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac11", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 3;
|
|
|
|
FinaleEndCount = 10 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
FinaleFlat = "SS2F3";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac12", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 4;
|
|
|
|
FinaleEndCount = 12 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
FinaleFlat = "SS2F4";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac13", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = -99;
|
|
|
|
FinaleEndCount = 17 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Macil's speech on map 10 about the Sigil.
|
|
|
|
case 5:
|
|
|
|
FinaleFlat = "SS3F1";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac16", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 6;
|
|
|
|
FinaleEndCount = 10 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
FinaleFlat = "SS3F2";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac17", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 7;
|
|
|
|
FinaleEndCount = 12 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
FinaleFlat = "SS3F3";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac18", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 8;
|
|
|
|
FinaleEndCount = 12 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
FinaleFlat = "SS3F4";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/mac19", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinaleEndCount = 11 * TICRATE;
|
|
|
|
FinalePart = -99;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// You won! You are a hero!
|
|
|
|
case 10:
|
|
|
|
FinaleFlat = "SS4F1";
|
|
|
|
S_StartMusic ("D_HAPPY");
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/rie01", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinaleEndCount = 13 * TICRATE;
|
|
|
|
FinalePart = 11;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
FinaleFlat = "SS4F2";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/bbx01", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinaleEndCount = 11 * TICRATE;
|
|
|
|
FinalePart = 12;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12:
|
|
|
|
FinaleFlat = "SS4F3";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/bbx02", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinaleEndCount = 14 * TICRATE;
|
|
|
|
FinalePart = 13;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 13:
|
|
|
|
FinaleFlat = "SS4F4";
|
|
|
|
FinaleEndCount = 28 * TICRATE;
|
|
|
|
FinalePart = -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// You are dead! All hope is lost!
|
|
|
|
case 14:
|
|
|
|
S_StartMusic ("D_SAD");
|
|
|
|
FinaleFlat = "SS5F1";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss501b", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 15;
|
|
|
|
FinaleEndCount = 11 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 15:
|
|
|
|
FinaleFlat = "SS5F2";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss502b", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 16;
|
|
|
|
FinaleEndCount = 10 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
FinaleFlat = "SS5F3";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss503b", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = -1;
|
|
|
|
FinaleEndCount = 11 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// You won, but at what cost?
|
|
|
|
case 17:
|
|
|
|
S_StartMusic ("D_END");
|
|
|
|
FinaleFlat = "SS6F1";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss601a", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinaleEndCount = 8 * TICRATE;
|
|
|
|
FinalePart = 18;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 18:
|
|
|
|
FinaleFlat = "SS6F2";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss602a", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = 19;
|
|
|
|
FinaleEndCount = 8 * TICRATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 19:
|
|
|
|
FinaleFlat = "SS6F3";
|
2008-07-19 12:40:10 +00:00
|
|
|
S_Sound (CHAN_VOICE | CHAN_UI, "svox/ss603a", 1, ATTN_NORM);
|
2006-02-24 04:48:15 +00:00
|
|
|
FinalePart = -1;
|
|
|
|
FinaleEndCount = 9 * TICRATE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// F_Drawer
|
|
|
|
//
|
|
|
|
void F_Drawer (void)
|
|
|
|
{
|
|
|
|
const char *picname = NULL;
|
|
|
|
|
|
|
|
switch (FinaleStage)
|
|
|
|
{
|
|
|
|
case 0: // Intermission or end-of-episode text
|
|
|
|
// erase the entire screen to a tiled background (or picture)
|
|
|
|
if (!FinaleHasPic)
|
|
|
|
{
|
2008-06-15 18:36:26 +00:00
|
|
|
FTextureID picnum = TexMan.CheckForTexture (FinaleFlat, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
|
|
|
|
if (picnum.isValid())
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan(picnum));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-12-22 04:52:51 +00:00
|
|
|
screen->Clear (0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
picname = FinaleFlat;
|
|
|
|
}
|
|
|
|
V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
case 4:
|
|
|
|
switch (EndSequences[FinaleSequence].EndType)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case END_Pic1:
|
2009-03-22 11:37:56 +00:00
|
|
|
picname = gameinfo.GetFinalePage(1);
|
2006-02-24 04:48:15 +00:00
|
|
|
screen->DrawTexture (TexMan[picname], 0, 0,
|
|
|
|
DTA_DestWidth, screen->GetWidth(),
|
|
|
|
DTA_DestHeight, screen->GetHeight(), TAG_DONE);
|
|
|
|
break;
|
|
|
|
case END_Pic2:
|
2009-03-22 11:37:56 +00:00
|
|
|
picname = gameinfo.GetFinalePage(2);
|
2006-02-24 04:48:15 +00:00
|
|
|
screen->DrawTexture (TexMan[picname], 0, 0,
|
|
|
|
DTA_DestWidth, screen->GetWidth(),
|
|
|
|
DTA_DestHeight, screen->GetHeight(), TAG_DONE);
|
|
|
|
break;
|
|
|
|
case END_Pic3:
|
2009-03-22 11:37:56 +00:00
|
|
|
picname = gameinfo.GetFinalePage(3);
|
2006-02-24 04:48:15 +00:00
|
|
|
screen->DrawTexture (TexMan[picname], 0, 0,
|
|
|
|
DTA_DestWidth, screen->GetWidth(),
|
|
|
|
DTA_DestHeight, screen->GetHeight(), TAG_DONE);
|
|
|
|
break;
|
|
|
|
case END_Pic:
|
|
|
|
picname = EndSequences[FinaleSequence].PicName;
|
|
|
|
break;
|
|
|
|
case END_Bunny:
|
|
|
|
case END_BuyStrife:
|
|
|
|
F_BunnyScroll ();
|
|
|
|
break;
|
|
|
|
case END_Underwater:
|
|
|
|
F_DrawUnderwater ();
|
|
|
|
break;
|
|
|
|
case END_Demon:
|
|
|
|
F_DemonScroll ();
|
|
|
|
break;
|
2009-05-30 08:56:40 +00:00
|
|
|
case END_TitleScreen:
|
|
|
|
D_StartTitle ();
|
|
|
|
break;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
F_CastDrawer ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
picname = FinaleFlat;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
picname = "CREDIT";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
case 11:
|
|
|
|
picname = "FINALE1";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 12:
|
|
|
|
case 13:
|
|
|
|
picname = "FINALE2";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 14:
|
|
|
|
case 15:
|
|
|
|
picname = "FINALE3";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (picname != NULL)
|
|
|
|
{
|
|
|
|
FTexture *pic = TexMan[picname];
|
|
|
|
screen->DrawTexture (pic, 0, 0,
|
|
|
|
DTA_VirtualWidth, pic->GetWidth(),
|
|
|
|
DTA_VirtualHeight, pic->GetHeight(),
|
|
|
|
TAG_DONE);
|
|
|
|
screen->FillBorder (NULL);
|
|
|
|
if (FinaleStage >= 14)
|
|
|
|
{ // Chess pic, draw the correct character graphic
|
|
|
|
if (multiplayer)
|
|
|
|
{
|
|
|
|
screen->DrawTexture (TexMan["CHESSALL"], 20, 0,
|
|
|
|
DTA_VirtualWidth, pic->GetWidth(),
|
|
|
|
DTA_VirtualHeight, pic->GetHeight(), TAG_DONE);
|
|
|
|
}
|
|
|
|
else if (players[consoleplayer].CurrentPlayerClass > 0)
|
|
|
|
{
|
|
|
|
picname = players[consoleplayer].CurrentPlayerClass == 1 ? "CHESSC" : "CHESSM";
|
|
|
|
screen->DrawTexture (TexMan[picname], 60, 0,
|
|
|
|
DTA_VirtualWidth, pic->GetWidth(),
|
|
|
|
DTA_VirtualHeight, pic->GetHeight(), TAG_DONE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch (FinaleStage)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 11:
|
|
|
|
case 12:
|
|
|
|
case 15:
|
|
|
|
F_TextWrite ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// GetFinaleText
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void GetFinaleText (const char *msgLumpName)
|
|
|
|
{
|
|
|
|
int msgLump;
|
|
|
|
|
2008-04-05 12:14:33 +00:00
|
|
|
msgLump = Wads.CheckNumForFullName(msgLumpName, true);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (msgLump != -1)
|
|
|
|
{
|
|
|
|
char *textbuf;
|
|
|
|
FinaleTextLen = Wads.LumpLength(msgLump);
|
|
|
|
textbuf = (char *)alloca (FinaleTextLen + 1);
|
|
|
|
Wads.ReadLump (msgLump, textbuf);
|
|
|
|
textbuf[FinaleTextLen] = '\0';
|
|
|
|
FinaleText = textbuf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FinaleText = "Unknown message ";
|
|
|
|
FinaleText += msgLumpName;
|
|
|
|
FinaleTextLen = FinaleText.Len();
|
|
|
|
}
|
|
|
|
}
|