rott/rott/rt_msg.c

813 lines
14 KiB
C
Executable File

/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "rt_def.h"
#include "rt_view.h"
#include "z_zone.h"
#include "w_wad.h"
#include "lumpy.h"
#include "rt_util.h"
#include "rt_vid.h"
#include "rt_str.h"
#include "rt_menu.h"
#include "_rt_msg.h"
#include "rt_msg.h"
#include "rt_playr.h"
#include "isr.h"
#include "rt_main.h"
#include "rt_net.h"
#include "rt_com.h"
#ifdef DOS
#include <mem.h>
#endif
#include <stdlib.h>
//MED
#include "memcheck.h"
/*
=============================================================================
GLOBALS
=============================================================================
*/
messagetype Messages[MAXMSGS];
/*
=============================================================================
LOCAL
=============================================================================
*/
static int UpdateMessageBackground;
static int MessageSystemStarted=0;
static int LastMessageTime;
static boolean EraseMessage[ MAXMSGS ];
static int MessageOrder[ MAXMSGS ];
static int TotalMessages = 0;
static int MsgPos = 0;
boolean MessagesEnabled = true;
int StringLength (char *string)
{
int length=0;
while ((*string)!=0)
{
length++;
string++;
}
length++;
return length;
}
/*
====================
=
= ResetMessageTime
=
====================
*/
void ResetMessageTime ( void )
{
LastMessageTime=GetTicCount();
}
/*
====================
=
= InitializeMessages
=
====================
*/
void InitializeMessages
(
void
)
{
int i;
boolean start;
start = false;
if ( MessageSystemStarted == 0 )
{
start = true;
MessageSystemStarted = 1;
memset( Messages, 0, sizeof( Messages ) );
}
for ( i = 0; i < MAXMSGS; i++ )
{
if ( Messages[ i ].active == 1 )
{
SafeFree( Messages[ i ].text );
Messages[ i ].active = 0;
Messages[ i ].tictime = 0;
Messages[ i ].flags = 0;
Messages[ i ].text = NULL;
}
}
MSG.messageon = false;
LastMessageTime = 0;
UpdateMessageBackground = 0;
TotalMessages = 0;
memset( EraseMessage, 0, sizeof( EraseMessage ) );
memset( MessageOrder, -1, sizeof( MessageOrder ) );
// Only print startup message if it's the first time in
if ( start && !quiet )
{
printf( "RT_MSG: Message System Started\n" );
}
}
/*
====================
=
= GetMessageOrder
=
====================
*/
void GetMessageOrder
(
void
)
{
int i;
int lowest;
int lowesttime;
byte done[ MAXMSGS ];
boolean found;
memset( &done[ 0 ], 0, sizeof( done ) );
memset( MessageOrder, -1, sizeof( MessageOrder ) );
for( TotalMessages = 0; TotalMessages < MAXMSGS; TotalMessages++ )
{
found = false;
lowesttime = 1000;
lowest = 0;
for( i = 0; i < MAXMSGS; i++ )
{
if ( ( Messages[ i ].active == 1 ) && ( done[ i ] == 0 ) &&
( Messages[ i ].tictime < lowesttime ) )
{
lowesttime = Messages[ i ].tictime;
lowest = i;
found = true;
}
}
if ( !found )
{
break;
}
done[ lowest ] = 1;
MessageOrder[ TotalMessages ] = lowest;
}
}
/*
====================
=
= DeleteMessage
=
====================
*/
void DeleteMessage
(
int num
)
{
int i;
int msg;
boolean found;
found = false;
for( i = 0; i < TotalMessages; i++ )
{
msg = MessageOrder[ i ];
if ( msg == num )
{
found = true;
}
if ( found )
{
UpdateMessageBackground -= EraseMessage[ i ];
UpdateMessageBackground += 3;
EraseMessage[ i ] = 3;
}
}
SafeFree( Messages[ num ].text );
memset( &Messages[ num ], 0, sizeof( messagetype ) );
GetMessageOrder();
}
/*
====================
=
= DeletePriorityMessage
=
====================
*/
void DeletePriorityMessage ( int flags )
{
int i;
for (i=0;i<MAXMSGS;i++)
{
if (Messages[i].active==1)
{
if (Messages[i].flags==flags)
DeleteMessage(i);
}
}
}
/*
====================
=
= GetFreeMessage
=
====================
*/
int GetFreeMessage
(
void
)
{
int i;
int found;
for( i = 0; i < MAXMSGS; i++ )
{
if ( Messages[ i ].active == 0 )
{
return( i );
}
}
found = -1;
for( i = 0; i < MAXMSGS; i++ )
{
if ( Messages[ i ].tictime >= 0 )
{
if ( found == -1 )
{
found = i;
}
else
{
if ( Messages[ i ].tictime < Messages[ found ].tictime )
{
found = i;
}
}
}
}
DeleteMessage( found );
return( found );
}
/*
====================
=
= SetMessage
=
====================
*/
void SetMessage
(
int num,
char *text,
int flags
)
{
int i;
int msg;
int length;
boolean found;
if (iGLOBAL_SCREENWIDTH >= 640){
CurrentFont = newfont1;//smallfont;
}else{
CurrentFont = smallfont;
}
length = StringLength( text );
Messages[ num ].active = 1;
Messages[ num ].flags = flags;
if ( PERMANENT_MSG( flags ) )
{
int l;
l = COM_MAXTEXTSTRINGLENGTH + 1;
Messages[ num ].text = SafeMalloc( l );
memset( Messages[ num ].text, 0, l );
// Hack so that we can place menu in certain order
Messages[ num ].tictime = -100 + MsgPos;
}
else
{
Messages[ num ].text = SafeMalloc( length );
memset( Messages[ num ].text, 0, length );
Messages[ num ].tictime = MESSAGETIME;
}
memcpy( Messages[ num ].text, text, length );
GetMessageOrder();
found = false;
for( i = 0; i < TotalMessages; i++ )
{
msg = MessageOrder[ i ];
if ( msg == num )
{
found = true;
}
else if ( found )
{
UpdateMessageBackground -= EraseMessage[ i - 1 ];
UpdateMessageBackground += 3;
EraseMessage[ i - 1 ] = 3;
}
}
}
/*
====================
=
= AddMessage
=
====================
*/
int AddMessage
(
char *text,
int flags
)
{
int new;
if ( MessageSystemStarted == 0 )
{
Error( "Called AddMessage without starting Message system\n" );
}
if ( !( flags & MSG_NODELETE ) )
{
DeletePriorityMessage( flags );
}
new = GetFreeMessage();
SetMessage( new, text, flags );
return( new );
}
/*
====================
=
= UpdateMessages
=
====================
*/
void UpdateMessages
(
void
)
{
int messagetics;
int i;
messagetics = GetTicCount() - LastMessageTime;
LastMessageTime = GetTicCount();
if ( GamePaused == true )
{
return;
}
for( i = 0; i < MAXMSGS; i++ )
{
if ( ( Messages[ i ].active == 1 ) &&
( !PERMANENT_MSG( Messages[ i ].flags ) ) )
{
Messages[ i ].tictime -= messagetics;
if ( Messages[ i ].tictime <= 0 )
{
DeleteMessage( i );
}
}
}
}
/*
====================
=
= DisplayMessage
=
====================
*/
void DisplayMessage (int num,int position)
{
PrintX = 1;
if (iGLOBAL_SCREENWIDTH > 320){
PrintY = 2 + ( position * (9*2) );
}else{
PrintY = 2 + ( position * (9*1) );
}
if ( SHOW_TOP_STATUS_BAR() )
{
PrintY += 16;
}
if ( !MessagesEnabled )
{
switch ( Messages[ num ].flags )
{
case MSG_QUIT:
case MSG_MACRO:
case MSG_MODEM:
case MSG_NAMEMENU:
case MSG_MSGSYSTEM:
break;
case MSG_REMOTERIDICULE:
case MSG_REMOTE:
case MSG_GAME:
case MSG_DOOR:
case MSG_BONUS:
case MSG_BONUS1:
case MSG_CHEAT:
case MSG_SYSTEM:
default :
DeleteMessage( num );
return;
}
}
switch ( Messages[ num ].flags )
{
case MSG_REMOTERIDICULE:
case MSG_REMOTE:
fontcolor = egacolor[ WHITE ];
break;
case MSG_MODEM:
fontcolor = egacolor[ LIGHTBLUE ];
DrawIString( PrintX, PrintY, "Message>", Messages[ num ].flags );
if ( iGLOBAL_SCREENWIDTH == 320) {
PrintX += 8 * 8;
}else if ( iGLOBAL_SCREENWIDTH == 640) {
PrintX += 8 * 8*2;
}else if ( iGLOBAL_SCREENWIDTH == 800) {
PrintX += 8 * 8*2;
}
fontcolor = egacolor[ LIGHTGRAY ];
break;
case MSG_GAME:
case MSG_DOOR:
case MSG_BONUS:
case MSG_BONUS1:
case MSG_NAMEMENU:
fontcolor = egacolor[ GREEN ];
break;
case MSG_CHEAT:
fontcolor = egacolor[ YELLOW ];
break;
case MSG_MSGSYSTEM:
case MSG_SYSTEM:
case MSG_QUIT:
case MSG_MACRO:
fontcolor = egacolor[ RED ];
break;
default :
#if ((DEVELOPMENT == 1))
Error( "DisplayMessage called with invalid priority number." );
#else
fontcolor = egacolor[ LIGHTGREEN ];
#endif
}
DrawIString( PrintX, PrintY, Messages[ num ].text, Messages[ num ].flags );
}
/*
====================
=
= RestoreMessageBackground
=
====================
*/
void RestoreMessageBackground
(
void
)
{
pic_t *shape;
int i;
int y;
if ( UpdateMessageBackground > 0 )
{
y = 18;
for( i = 0; i < MAXMSGS; i++ )
{
if ( EraseMessage[ i ] )
{
UpdateMessageBackground--;
EraseMessage[ i ]--;
if ( viewsize < 15 )
{
shape = ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );//w=32 h=8
//SetTextMode ( );
//DrawTiledRegion( 0, y, 320, 9, 0, y, shape );KILLS_HEIGHT bna--
DrawTiledRegion( 0, y, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
DrawTiledRegion( 0, y+8, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
DrawTiledRegion( 0, y+16, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
//DrawTiledRegion( 0, y, iGLOBAL_SCREENWIDTH, 212, 0, y, shape );
}
if ( viewsize == 0 )
{
if ( ( y + 9 > YOURCPUSUCKS_Y ) &&
( y < ( YOURCPUSUCKS_Y + YOURCPUSUCKS_HEIGHT ) ) )
{
DrawCPUJape();
}
}
}
y += 9;
}
}
}
/*
====================
=
= DrawMessages
=
====================
*/
void DrawMessages
(
void
)
{
int i;
if ( TotalMessages > 0 )
{
IFont = ( cfont_t * )W_CacheLumpName( "ifnt", PU_CACHE, Cvt_cfont_t, 1 );
for( i = 0; i < TotalMessages; i++ )
{
DisplayMessage( MessageOrder[ i ], i );
}
}
UpdateMessages();
}
/*
====================
=
= UpdateModemMessage
=
====================
*/
void UpdateModemMessage
(
int num,
char c
)
{
int i;
Messages[ num ].text[ MSG.length - 1 ] = ( byte )c;
Messages[ num ].text[ MSG.length ] = ( byte )'_';
MSG.length++;
for( i = 0; i < TotalMessages; i++ )
{
if ( MessageOrder[ i ] == num )
{
UpdateMessageBackground -= EraseMessage[ i ];
UpdateMessageBackground += 3;
EraseMessage[ i ] = 3;
break;
}
}
}
/*
====================
=
= ModemMessageDeleteChar
=
====================
*/
void ModemMessageDeleteChar
(
int num
)
{
int i;
MSG.length--;
Messages[ num ].text[ MSG.length ] = ( byte )0;
Messages[ num ].text[ MSG.length - 1 ] = ( byte )'_';
for( i = 0; i < TotalMessages; i++ )
{
if ( MessageOrder[ i ] == num )
{
UpdateMessageBackground -= EraseMessage[ i ];
UpdateMessageBackground += 3;
EraseMessage[ i ] = 3;
break;
}
}
}
/*
====================
=
= DrawPlayerSelectionMenu
=
====================
*/
void DrawPlayerSelectionMenu
(
void
)
{
int i;
int p;
char str[ 20 ];
p = 1;
MsgPos = 1;
AddMessage( "Press a key from 0 to 9 to select", MSG_NAMEMENU );
MsgPos++;
AddMessage( "who to send your message to:", MSG_NAMEMENU );
MsgPos++;
for( i = 0; i < numplayers; i++ )
{
if ( i != consoleplayer )
{
strcpy( str, "0 - " );
strcat( str, PLAYERSTATE[ i ].codename );
str[ 0 ] = '0' + p;
p++;
if ( p > 9 )
{
p = 0;
}
AddMessage( str, MSG_NAMEMENU );
MsgPos++;
}
}
if ( ( MsgPos < MAXMSGS - 1 ) && ( gamestate.teamplay ) )
{
AddMessage( "T - All team members", MSG_NAMEMENU );
MsgPos++;
}
if ( MsgPos < MAXMSGS - 1 )
{
AddMessage( "A - All players", MSG_NAMEMENU );
}
MsgPos = 0;
}
/*
====================
=
= FinishModemMessage
=
====================
*/
void FinishModemMessage
(
int num,
boolean send
)
{
if ( ( !MSG.inmenu ) && ( MSG.length > 0 ) )
{
Messages[ num ].text[ MSG.length - 1 ] = ( byte )0;
MSG.length--;
}
if ( ( send == true ) && ( ( MSG.length > 0 ) ||
( MSG.remoteridicule != -1 ) ) )
{
if ( ( MSG.directed ) && ( !MSG.inmenu ) )
{
DrawPlayerSelectionMenu();
MSG.messageon = true;
MSG.inmenu = true;
return;
}
MSG.messageon = false;
if ( MSG.remoteridicule != -1 )
{
AddRemoteRidiculeCommand( consoleplayer, MSG.towho,
MSG.remoteridicule );
}
if ( MSG.length > 0 )
{
AddTextMessage( Messages[ num ].text, MSG.length, MSG.towho );
}
}
if ( MSG.inmenu )
{
DeletePriorityMessage( MSG_NAMEMENU );
}
DeleteMessage( num );
}