Source to src/f_finale.c


Enter a symbol's name here to quickly find it.

// F_finale.c

#include "DoomDef.h"
#include "soundst.h"
#include <ctype.h>

int             finalestage;            // 0 = text, 1 = art screen
int             finalecount;

#define TEXTSPEED       3
#define TEXTWAIT        250

char    *e1text = E1TEXT;
char    *e2text = E2TEXT;
char    *e3text = E3TEXT;
char    *e4text = E4TEXT;
char    *e5text = E5TEXT;
char    *finaletext;
char    *finaleflat;

int FontABaseLump;

extern boolean automapactive;
extern boolean viewactive;

extern void D_StartTitle(void);

/*
=======================
=
= F_StartFinale
=
=======================
*/

void F_StartFinale (void)
{
	gameaction = ga_nothing;
	gamestate = GS_FINALE;
	viewactive = false;
	automapactive = false;
	players[consoleplayer].messageTics = 1;
	players[consoleplayer].message = NULL;

	switch(gameepisode)
	{
		case 1:
			finaleflat = "FLOOR25";
			finaletext = e1text;
			break;
		case 2:
			finaleflat = "FLATHUH1";
			finaletext = e2text;
			break;
		case 3:
			finaleflat = "FLTWAWA2";
			finaletext = e3text;
			break;
		case 4:
			finaleflat = "FLOOR28";
			finaletext = e4text;
			break;
		case 5:
			finaleflat = "FLOOR08";
			finaletext = e5text;
			break;
	}

	finalestage = 0;
	finalecount = 0;
	FontABaseLump = W_GetNumForName("FONTA_S")+1;

//      S_ChangeMusic(mus_victor, true);
	S_StartSong(mus_cptd, true);
}



boolean F_Responder (event_t *event)
{
	if(event->type != ev_keydown)
	{
		return false;
	}
	if(finalestage == 1 && gameepisode == 2)
	{ // we're showing the water pic, make any key kick to demo mode
		finalestage++;
		memset((byte *)0xa0000, 0, SCREENWIDTH*SCREENHEIGHT);
		memset(screen, 0, SCREENWIDTH*SCREENHEIGHT);
		I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
		return true;
	}
	return false;
}


/*
=======================
=
= F_Ticker
=
=======================
*/

void F_Ticker (void)
{
	finalecount++;
	if (!finalestage && finalecount>strlen (finaletext)*TEXTSPEED + TEXTWAIT)
	{
		finalecount = 0;
		if(!finalestage)
		{
			finalestage = 1;
		}

//              wipegamestate = -1;             // force a wipe
/*
		if (gameepisode == 3)
			S_StartMusic (mus_bunny);
*/
	}
}


/*
=======================
=
= F_TextWrite
=
=======================
*/

//#include "HU_stuff.h"
//extern        patch_t *hu_font[HU_FONTSIZE];

void F_TextWrite (void)
{
	byte    *src, *dest;
	int             x,y;
	int             count;
	char    *ch;
	int             c;
	int             cx, cy;
	patch_t *w;

//
// erase the entire screen to a tiled background
//
	src = W_CacheLumpName(finaleflat, PU_CACHE);
	dest = screen;
	for (y=0 ; y<SCREENHEIGHT ; y++)
	{
		for (x=0 ; x<SCREENWIDTH/64 ; x++)
		{
			memcpy (dest, src+((y&63)<<6), 64);
			dest += 64;
		}
		if (SCREENWIDTH&63)
		{
			memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
			dest += (SCREENWIDTH&63);
		}
	}

//      V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);

//
// draw some of the text onto the screen
//
	cx = 20;
	cy = 5;
	ch = finaletext;

	count = (finalecount - 10)/TEXTSPEED;
	if (count < 0)
		count = 0;
	for ( ; count ; count-- )
	{
		c = *ch++;
		if (!c)
			break;
		if (c == '\n')
		{
			cx = 20;
			cy += 9;
			continue;
		}

		c = toupper(c);
		if (c < 33)
		{
			cx += 5;
			continue;
		}

		w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
		if (cx+w->width > SCREENWIDTH)
			break;
		V_DrawPatch(cx, cy, w);
		cx += w->width;
	}

}


#if 0
/*
=======================
=
= F_Cast
=
=======================
*/

void F_Cast (void)
{
	byte    *src, *dest;
	int             x,y,w;
	int             count;
	char    *ch;
	int             c;
	int             cx, cy;

//
// erase the entire screen to a tiled background
//
	src = W_CacheLumpName ( "FWATER1" , PU_CACHE);
	dest = screen;

	for (y=0 ; y<SCREENHEIGHT ; y++)
	{
		for (x=0 ; x<SCREENWIDTH/64 ; x++)
		{
			memcpy (dest, src+((y&63)<<6), 64);
			dest += 64;
		}
		if (SCREENWIDTH&63)
		{
			memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
			dest += (SCREENWIDTH&63);
		}
	}

	V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);

	V_DrawPatch (105,21,0, W_CacheLumpName ( "
}
#endif


void F_DrawPatchCol (int x, patch_t *patch, int col)
{
	column_t        *column;
	byte            *source, *dest, *desttop;
	int                     count;

	column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
	desttop = screen+x;

// step through the posts in a column

	while (column->topdelta != 0xff )
	{
		source = (byte *)column + 3;
		dest = desttop + column->topdelta*SCREENWIDTH;
		count = column->length;

		while (count--)
		{
			*dest = *source++;
			dest += SCREENWIDTH;
		}
		column = (column_t *)(  (byte *)column + column->length+ 4 );
	}
}

/*
==================
=
= F_DemonScroll
=
==================
*/

void F_DemonScroll(void)
{
	byte *p1, *p2;
	static int yval = 0;
	static int nextscroll = 0;

	if(finalecount < nextscroll)
	{
		return;
	}
	p1 = W_CacheLumpName("FINAL1", PU_LEVEL);
	p2 = W_CacheLumpName("FINAL2", PU_LEVEL);
	if(finalecount < 70)
	{
		memcpy(screen, p1, SCREENHEIGHT*SCREENWIDTH);
		nextscroll = finalecount;
		return;
	}
	if(yval < 64000)
	{
		memcpy(screen, p2+SCREENHEIGHT*SCREENWIDTH-yval, yval);
		memcpy(screen+yval, p1, SCREENHEIGHT*SCREENWIDTH-yval);
		yval += SCREENWIDTH;
		nextscroll = finalecount+3;
	}
	else
	{ //else, we'll just sit here and wait, for now
		memcpy(screen, p2, SCREENWIDTH*SCREENHEIGHT);
	}
}

/*
==================
=
= F_DrawUnderwater
=
==================
*/

void F_DrawUnderwater(void)
{
	static boolean underwawa;
	extern boolean MenuActive;
	extern boolean askforquit;

	switch(finalestage)
	{
		case 1:
			if(!underwawa)
			{
				underwawa = true;
				memset((byte *)0xa0000, 0, SCREENWIDTH*SCREENHEIGHT);
				I_SetPalette(W_CacheLumpName("E2PAL", PU_CACHE));
				memcpy(screen, W_CacheLumpName("E2END", PU_CACHE),
					SCREENWIDTH*SCREENHEIGHT);
			}
			paused = false;
			MenuActive = false;
			askforquit = false;

			break;
		case 2:
			memcpy(screen, W_CacheLumpName("TITLE", PU_CACHE),
				SCREENWIDTH*SCREENHEIGHT);
			//D_StartTitle(); // go to intro/demo mode.
	}
}


#if 0
/*
==================
=
= F_BunnyScroll
=
==================
*/

void F_BunnyScroll (void)
{
	int                     scrolled, x;
	patch_t         *p1, *p2;
	char            name[10];
	int                     stage;
	static int      laststage;

	p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
	p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);

	V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);

	scrolled = 320 - (finalecount-230)/2;
	if (scrolled > 320)
		scrolled = 320;
	if (scrolled < 0)
		scrolled = 0;

	for ( x=0 ; x<SCREENWIDTH ; x++)
	{
		if (x+scrolled < 320)
			F_DrawPatchCol (x, p1, x+scrolled);
		else
			F_DrawPatchCol (x, p2, x+scrolled - 320);
	}

	if (finalecount < 1130)
		return;
	if (finalecount < 1180)
	{
		V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE));
		laststage = 0;
		return;
	}

	stage = (finalecount-1180) / 5;
	if (stage > 6)
		stage = 6;
	if (stage > laststage)
	{
		S_StartSound (NULL, sfx_pistol);
		laststage = stage;
	}

	sprintf (name,"END%i",stage);
	V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2, W_CacheLumpName (name,PU_CACHE));
}
#endif

/*
=======================
=
= F_Drawer
=
=======================
*/

void F_Drawer(void)
{
	UpdateState |= I_FULLSCRN;
	if (!finalestage)
		F_TextWrite ();
	else
	{
		switch (gameepisode)
		{
			case 1:
				if(shareware)
				{
					V_DrawRawScreen(W_CacheLumpName("ORDER", PU_CACHE));
				}
				else
				{
					V_DrawRawScreen(W_CacheLumpName("CREDIT", PU_CACHE));
				}
				break;
			case 2:
				F_DrawUnderwater();
				break;
			case 3:
				F_DemonScroll();
				break;
			case 4: // Just show credits screen for extended episodes
			case 5:
				V_DrawRawScreen(W_CacheLumpName("CREDIT", PU_CACHE));
				break;
		}
	}
}