rott/rott/rt_main.c

3503 lines
84 KiB
C
Executable File
Raw Permalink Blame History

/*
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 "lumpy.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <string.h>
#ifdef DOS
#include <malloc.h>
#include <dos.h>
#include <io.h>
#include <conio.h>
#include <graph.h>
#include <process.h>
#include <direct.h>
#include <bios.h>
#else
#include <signal.h>
#endif
#if USE_SDL
/* Need to redefine main to SDL_main on some platforms... */
#include "SDL.h"
#endif
#include "rt_actor.h"
#include "rt_stat.h"
#include "rt_vid.h"
#include "rt_menu.h"
#include "rt_sound.h"
#include "watcom.h"
#include "scriplib.h"
#include "rt_main.h"
#include "_rt_main.h"
#include "rt_com.h"
#include "rt_util.h"
#include "z_zone.h"
#include "w_wad.h"
#include "rt_game.h"
#include "rt_floor.h"
#include "rt_playr.h"
#include "rt_draw.h"
#include "rt_str.h"
#include "rt_view.h"
#include "rt_door.h"
#include "rt_ted.h"
#include "rt_in.h"
#include "rt_map.h"
#include "rt_rand.h"
#include "rt_debug.h"
#include "isr.h"
#include "rt_cfg.h"
#include "develop.h"
#include "version.h"
#include "rt_menu.h"
#include "rt_dr_a.h"
#include "rt_msg.h"
#include "rt_build.h"
#include "rt_error.h"
#include "modexlib.h"
#include "rt_net.h"
#include "cin_main.h"
#include "rottnet.h"
#include "rt_scale.h"
#include "music.h"
#include "fx_man.h"
//MED
#include "memcheck.h"
volatile int oldtime;
volatile int gametime;
boolean tedlevel;
int tedlevelnum;
int tedx=0;
int tedy=0;
boolean warp;
int warpx=0;
int warpy=0;
int warpa=0;
int NoSound;
int polltime;
int oldpolltime;
boolean fizzlein = false;
int pheight;
boolean SCREENSHOTS = false;
boolean MONOPRESENT = false;
boolean MAPSTATS = false;
boolean TILESTATS = false;
boolean HUD = false;
boolean IS8250 = false;
boolean dopefish;
boolean newlevel = false;
boolean infopause;
#ifdef DOS
boolean SOUNDSETUP=false;
#endif
boolean quiet = false;
#if (DEVELOPMENT == 1)
boolean DebugOk = true;
#else
boolean DebugOk = false;
#endif
#if (WHEREAMI==1)
int programlocation=-1;
#endif
#if SAVE_SCREEN
static char savename[13] = "ROTT0000.LBM";
static int totalbytes;
static byte *bptr;
#endif
static boolean turbo;
static int NoWait;
static int startlevel=0;
static int demonumber=-1;
char CWD[40]; // curent working directory
static boolean quitactive = false;
int timelimit;
int maxtimelimit;
boolean timelimitenabled;
boolean demoexit;
boolean noecho;
void CheckCommandLineParameters( void );
void PlayTurboGame( void );
void Init_Tables (void);
void CheckRemoteRidicule ( int scancode );
void SetRottScreenRes (int Width, int Height);
#ifndef DOS
extern void crash_print (int);
extern int setup_homedir (void);
#endif
//extern int G_argc;
//extern char G_argv[30][80];
int G_weaponscale;
extern int iDropDemo;
extern boolean iG_aimCross;
extern boolean sdl_fullscreen;
extern void ComSetTime ( void );
extern void VH_UpdateScreen (void);
extern void RottConsole ( void );
extern void ReadDelay(long delay);
extern void RecordDemoQuery ( void );
int main (int argc, char *argv[])
{
char *macwd;
#ifndef DOS
_argc = argc;
_argv = argv;
#endif
#if defined(PLATFORM_MACOSX)
{
/* OS X will give us a path in the form '/Applications/Rise of the Triad.app/Contents/MacOS/Rise of the Triad'.
Our data is in Contents/Resources. */
char *path;
const char suffix[] = "/Resources/";
int end;
path = (char *)malloc(strlen(argv[0]) + strlen(suffix) + 1);
if (path == NULL) return 1;
strcpy(path, argv[0]);
/* Back up two '/'s. */
for (end = strlen(path)-1; end >= 0 && path[end] != '/'; end--);
if (end >= 0) for (--end; end >= 0 && path[end] != '/'; end--);
strcpy(&path[end], suffix);
printf("Changing to working directory: %s\n", path);
chdir(path);
free(path);
}
#endif
#ifndef DOS
signal (11, crash_print);
if (setup_homedir() == -1) return 1;
#endif
// Set which release version we're on
gamestate.Version = ROTTVERSION;
#if ( SHAREWARE == 1 )
gamestate.Product = ROTT_SHAREWARE;
#elif ( SUPERROTT == 1 )
gamestate.Product = ROTT_SUPERCD;
#elif ( SITELICENSE == 1 )
gamestate.Product = ROTT_SITELICENSE;
#else
gamestate.Product = ROTT_REGISTERED;
#endif
DrawRottTitle ();
gamestate.randomseed=-1;
gamestate.autorun = 0;
StartupSoftError();
// UL_ErrorStartup ();
CheckCommandLineParameters();
// Start up Memory manager with a certain amount of reserved memory
Z_Init(50000,1000000);
IN_Startup ();
InitializeGameCommands();
if (standalone==false)
{
ReadConfig ();
ReadSETUPFiles ();
doublestep=0;
SetupWads();
BuildTables ();
GetMenuInfo ();
}
SetRottScreenRes (iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT);
// if (modemgame==true)
// {
// SCREENSHOTS=true;
// if (standalone==false)
// {
// MenuFixup ();
// }
// MAPSTATS=true;
// }
if (standalone==false)
{
int status1 = 0;
int status2 = 0;
int status3 = 0;
if ( !NoSound && !IS8250 )
{
if (!quiet)
printf( "MU_Startup: " );
status1 = MU_Startup(false);
if (!quiet)
printf( "%s\n", MUSIC_ErrorString( MUSIC_Error ) );
}
else if ( IS8250 )
{
printf( "==============================================================================\n");
printf( "WARNING: 8250 detected.\n" );
printf( "Music has been disabled. This is necessary to maintain high interrupt\n" );
printf( "rates with the 8250 UART which will improve overall game performance.\n");
printf( " < Press any key to continue >\n");
printf( "==============================================================================\n");
getch();
}
if (!NoSound)
{
int nv, nb, nc;
if (!quiet)
printf( "SD_SetupFXCard: " );
status2 = SD_SetupFXCard (&nv, &nb, &nc);
if (!quiet)
printf( "%s\n", FX_ErrorString( FX_Error ) );
if ( !status2 )
{
if (!quiet)
printf( "SD_Startup: " );
status3 = SD_Startup(false);
if (!quiet)
printf( "%s\n", FX_ErrorString( FX_Error ) );
}
}
else
{
if (!quiet)
printf( "Sound FX disabled.\n" );
}
#ifdef DOS
if ( status1 || status2 || status3 )
{
printf( "\n\nROTT was unable to initialize your " );
if ( status1 )
{
printf( "music " );
MusicMode = 0;
}
if ( status2 || status3 )
{
if ( status1 )
{
printf( "or " );
}
printf( "sound fx " );
FXMode = 0;
}
printf( "hardware.\n"
"Now entering sound setup.\n" );
SOUNDSETUP = true;
}
#endif
Init_Tables ();
InitializeRNG ();
InitializeMessages();
LoadColorMap();
}
if (infopause==true)
{
printf("\n< Press any key to continue >\n");
getch();
}
I_StartupTimer();
I_StartupKeyboard();
#if 0
#if (SHAREWARE == 1)
if ((!SOUNDSETUP) && (standalone==false))
{
byte * txtscn;
int i;
for (i=0;i<20;i++)
printf("\n");
txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("rotts10"), PU_CACHE);
memcpy ((byte *)0xB8000, txtscn, 4000);
I_Delay (600);
}
#endif
#endif
locplayerstate = &PLAYERSTATE[consoleplayer];
if (standalone==true)
ServerLoop();
VL_SetVGAPlaneMode();
VL_SetPalette(origpal);
// SetTextMode();
// GraphicsMode();
// SetTextMode();
// VL_SetVGAPlaneMode();
// VL_SetPalette(origpal);
// SetBorderColor(155);
SetViewSize(8);
#ifdef DOS
if ( SOUNDSETUP )
{
SwitchPalette( origpal, 35 );
CP_SoundSetup();
}
#endif
playstate = ex_titles;
// I_SetKeyboardLEDs( caps_lock, 0 );
gamestate.battlemode = battle_StandAloneGame;
BATTLE_SetOptions( &BATTLE_Options[ battle_StandAloneGame ] );
if (turbo || tedlevel)
{
if (modemgame == true)
{
turbo = false;
NoWait = true;
}
else
{
PlayTurboGame();
}
}
else
{
#if (SHAREWARE == 0)
if ( dopefish == true )
{
DopefishTitle();
}
else if ( NoWait == false )
{
ApogeeTitle();
}
#else
if ( NoWait == false )
{
if (W_CheckNumForName("svendor") != -1)
{
lbm_t * LBM;
LBM = (lbm_t *) W_CacheLumpName( "svendor", PU_CACHE, Cvt_lbm_t, 1);
VL_DecompressLBM (LBM,true);
I_Delay(40);
MenuFadeOut();
}
// ParticleIntro ();
ApogeeTitle();
}
#endif
}
GameLoop();
QuitGame();
return 0;
}
void DrawRottTitle ( void )
{
char title[80];
char buf[5];
SetTextMode();
TurnOffTextCursor ();
if (CheckParm("QUIET") == 0)
{
SetTextMode();
TurnOffTextCursor ();
#ifdef DOS
if (CheckParm ("SOUNDSETUP") == 0)
{
#endif
#ifdef ANSIESC
printf("\n\n\n");
#endif
strcpy (title,"Rise of the Triad Startup Version ");
strcat (title,itoa(ROTTMAJORVERSION,&buf[0],10));
strcat (title,".");
//MED
#if (SHAREWARE==1)||(DOPEFISH==0)
strcat (title,itoa(ROTTMINORVERSION,&buf[0],10));
#else
strcat (title,"DFISH");
#endif
#ifndef ANSIESC
strcat (title,"\n");
#endif
px=(80-strlen(title))>>1;
py=0;
UL_printf(title);
memset (title,0,sizeof(title));
if (gamestate.Product == ROTT_SHAREWARE)
{
#if (DELUXE==1)
strcpy(title,"Lasersoft Deluxe Version");
#elif (LOWCOST==1)
strcpy(title,"Episode One");
#else
strcpy(title,"Shareware Version");
#endif
}
else if (gamestate.Product == ROTT_SUPERCD)
strcpy(title,"CD Version");
else if (gamestate.Product == ROTT_SITELICENSE)
strcpy(title,"Site License CD Version");
else
strcpy(title,"Commercial Version");
px=(80-strlen(title))>>1;
py=1;
UL_printf(title);
#ifndef ANSIESC
printf ("\n");
#endif
UL_ColorBox (0, 0, 80, 2, 0x1e);
#ifdef DOS
}
else
{
printf("\n\n");
strcpy (title,"Rise of the Triad Sound Setup Version ");
strcat (title,itoa(ROTTMAJORVERSION,&buf[0],10));
strcat (title,".");
strcat (title,itoa(ROTTMINORVERSION,&buf[0],10));
px=(80-strlen(title))>>1;
py=0;
UL_printf(title);
UL_ColorBox (0, 0, 80, 1, 0x1e);
}
#endif
}
else
{
TurnOffTextCursor ();
}
}
void CheckCommandLineParameters( void )
{
char *PStrings[] = {"TEDLEVEL","NOWAIT","NOSOUND","NOW",
"TRANSPORT","DOPEFISH","SCREENSHOTS",
"MONO","MAPSTATS","TILESTATS","VER","net",
"PAUSE","SOUNDSETUP","WARP","IS8250","ENABLEVR",
"TIMELIMIT","MAXTIMELIMIT","NOECHO","DEMOEXIT","QUIET",NULL};
int i,n;
infopause=false;
#ifdef DOS
SOUNDSETUP = false;
#endif
tedlevel=false;
NoWait=false;
NoSound=false;
turbo=false;
warp=false;
dopefish=false;
modemgame=false;
SCREENSHOTS=false;
MONOPRESENT=false;
MAPSTATS=false;
TILESTATS=false;
IS8250 = false;
vrenabled = false;
demoexit = false;
modemgame=false;
networkgame=false;
consoleplayer=0;
numplayers = 1;
timelimit=-1;
timelimitenabled=false;
noecho = false;
quiet = false;
if (
(CheckParm("?\0")) ||
(CheckParm("HELP")) ||
(
(_argc>1) &&
(_argv[1][0]=='?')
)
)
{
SetTextMode ();
printf ("Rise of the Triad (c) 1995 Apogee Software\n\n");
printf ("COMMAND LINE PARAMETERS\n");
printf (" AIM - Give Aim Crosshair.\n");
printf (" FULLSCREEN - Start in fullscreen mode\n");
printf (" WINDOW - Start in windowed mode\n");
printf (" RESOLUTION - Specify the screen resolution to use\n");
printf (" - next param is <widthxheight>, valid resolutions are:\n");
printf (" - 320x200, 640x480 and 800x600\n");
#if (SHAREWARE==0)
printf (" FILERTL - used to load Userlevels (RTL files)\n");
printf (" - next parameter is RTL filename\n");
printf (" FILERTC - used to load Battlelevels (RTC files)\n");
printf (" - next parameter is RTC filename\n");
printf (" FILE - used to load Extern WAD files\n");
printf (" - next parameter is WAD filename\n");
#endif
printf (" SPACEBALL - Enable check for Spaceball.\n");
printf (" NOJOYS - Disable check for joystick.\n");
printf (" NOMOUSE - Disable check for mouse.\n");
printf (" CYBERMAN - Enable check for Cyberman.\n");
printf (" ASSASSIN - Enable check for Wingman Assassin.\n");
printf (" VER - Version number.\n");
printf (" MAPSTATS - Dump Map statistics to ERROR.\n");
printf (" TILESTATS - Dump Tile statistics to ERROR.\n");
printf (" MONO - Enable mono-monitor support.\n");
printf (" SCREENSHOTS- Clean screen capture for shots.\n");
printf (" PAUSE - Pauses startup screen information.\n");
#ifdef DOS
printf (" SOUNDSETUP - Setup sound for ROTT\n");
#endif
printf (" ENABLEVR - Enable VR helmet input devices\n");
printf (" NOECHO - Turn off sound reverb\n");
printf (" DEMOEXIT - Exit program when demo is terminated\n");
printf (" WARP - Warp to specific ROTT level\n");
printf (" next parameter is level to start on\n");
printf (" TIMELIMIT - Play ROTT in time limit mode\n");
printf (" next parameter is time in seconds\n");
printf (" MAXTIMELIMIT - Maximimum time to count down from\n");
printf (" next parameter is time in seconds\n");
printf (" DOPEFISH - ?\n");
printf (" \n");
printf ("CONTROLS\n");
printf (" Arrows - Move\n");
printf (" Ctrl - Fire\n");
printf (" Comma/Alt+left - Sidestep Left\n");
printf (" Period/Alt+right - Sidestep Right\n");
printf (" Shift - Run/Turn faster\n");
printf (" Space - Use/Open\n");
printf (" 1-4 - Choose Weapon\n");
printf (" 5-6 - Scale Weapon Up/Down\n");
printf (" Enter - Swap Weapon\n");
printf (" Backspace - Turn 180\n");
printf (" Delete - Drop Weapon\n");
printf (" +/- - Change Viewsize\n");
printf (" PgUp/PgDn - Look Up/Down\n");
printf (" Home/End - Aim Up/Down\n");
printf (" [ ] - Sound Volumen\n");
printf (" ( ) - Music Volumen\n");
printf (" Tab - Enter Automapper\n");
printf (" \n");
printf ("AUTO-MAPPER\n");
printf (" Arrows - Scroll around\n");
printf (" PgUp - Zoom Out\n");
printf (" PgDn - Zoom In\n");
printf (" Tab - Exit Auto-Mapper\n");
printf (" \n");
printf ("HOTKEYS\n");
printf (" F1 - Help\n");
printf (" F2 - Save Game\n");
printf (" F3 - Restore Game\n");
printf (" F4 - Controls/Sound/Music\n");
printf (" F5 - Change Detail Level\n");
printf (" F6 - Quick Save\n");
printf (" F7 - Messages On/Off\n");
printf (" F8 - End Game\n");
printf (" F9 - Quick Load\n");
printf (" F10 - Quit\n");
printf (" F11 - Gamma Correction\n");
printf (" \n");
printf ("COMM-BAT\n");
printf (" F1 - F10 - RemoteRidicule(tm) sounds\n");
printf (" F12 - Live RemoteRidicule\n");
printf (" T - Type message to all\n");
printf (" Z - Type directed message\n");
printf (" Tab - Toggle KillCount display\n");
printf (" \n");
printf ("SCREENSHOOT\n");
#ifdef DOS /* makes no sense under Linux as there are no lbm viewers there */
printf (" Alt+V - Screenshoot in LBM format\n");
#endif
printf (" Alt+C - Screenshoot in PCX format\n");
exit (0);
}
// Check For command line parameters
for (i = 1;i < _argc;i++)
{
n = US_CheckParm(_argv[i],PStrings);
switch(n)
{
#if (TEDLAUNCH==1)
case 0:
tedlevelnum = ParseNum(_argv[i + 1]);
tedlevel=true;
if (i+3>=_argc)
{
tedx=0;
tedy=0;
}
else
{
tedx=ParseNum(_argv[i + 2]);
tedy=ParseNum(_argv[i + 3]);
}
MenuFixup ();
break;
#endif
case 1:
NoWait = true;
break;
case 2:
NoSound = true;
break;
case 3:
turbo = true;
break;
case 4:
warp = true;
warpx=ParseNum(_argv[i + 1]);
warpy=ParseNum(_argv[i + 2]);
warpa=ParseNum(_argv[i + 3]);
break;
case 5:
dopefish=true;
break;
case 6:
SCREENSHOTS = true;
break;
case 7:
MONOPRESENT = true;
break;
case 8:
MAPSTATS = true;
break;
case 9:
TILESTATS = true;
break;
case 10:
SetTextMode ();
printf ("Rise of the Triad (c) 1995 Apogee Software\n");
//MED
if (gamestate.Product == ROTT_SHAREWARE)
{
#if (DELUXE==1)
printf("Lasersoft Deluxe ");
#elif (LOWCOST==1)
printf("Episode One ");
#else
printf("Shareware ");
#endif
}
else if (gamestate.Product == ROTT_SUPERCD)
printf("CD ");
else if (gamestate.Product == ROTT_SITELICENSE)
printf("Site License ");
else
printf("Commercial ");
printf ("Version %d.%d\n", ROTTMAJORVERSION,ROTTMINORVERSION);
exit (0);
break;
case 11:
InitROTTNET();
numplayers = rottcom->numplayers;
if (numplayers>MAXPLAYERS)
Error("Too many players.\n");
if (!quiet)
printf("Playing %ld player ROTT\n",(long int)numplayers);
modemgame=true;
if (rottcom->gametype==NETWORK_GAME)
{
if (!quiet)
printf("NETWORK GAME\n");
networkgame=true;
}
else
{
if (!quiet)
printf("MODEM GAME\n");
}
break;
case 12:
infopause=true;
break;
case 13:
#ifdef DOS
SOUNDSETUP = true;
#endif
break;
case 14:
startlevel = (ParseNum(_argv[i + 1])-1);
break;
case 15:
IS8250 = true;
break;
case 16:
vrenabled = true;
if (!quiet)
printf("Virtual Reality Mode enabled\n");
break;
case 17:
timelimitenabled = true;
timelimit = ParseNum(_argv[i + 1]);
if (!quiet)
printf("Time Limit = %ld Seconds\n",(long int)timelimit);
timelimit *= VBLCOUNTER;
break;
case 18:
maxtimelimit = ParseNum(_argv[i + 1]);
maxtimelimit *= VBLCOUNTER;
break;
case 19:
noecho = true;
break;
case 20:
demoexit = true;
break;
case 21:
quiet = true;
break;
}
}
}
void SetupWads( void )
{
char *newargs[99];
int i, arg, argnum = 0;
char tempstr[129];
char *PStrings[] = {"AIM", "FULLSCREEN", "WINDOW", "RESOLUTION", NULL };
// These must be checked here so that they can override the cfg file
for (i = 1;i < _argc;i++)
{
arg = US_CheckParm(_argv[i],PStrings);
switch(arg)
{
case 0:
iG_aimCross = 1;
break;
case 1:
sdl_fullscreen = 1;
break;
case 2:
sdl_fullscreen = 0;
break;
case 3:
i++;
if (i < _argc)
{
int width, height;
if ( (sscanf(_argv[i], "%dx%d", &width, &height) == 2) &&
( ( (width == 320) && (height == 200) ) ||
( (width == 640) && (height == 480) ) ||
( (width == 800) && (height == 600) ) ) )
{
iGLOBAL_SCREENWIDTH = width;
iGLOBAL_SCREENHEIGHT = height;
}
else
printf("Invalid resolution parameter: %s\n", _argv[i]);
}
else
printf("Missing resolution parameter\n");
break;
}
}
#if (SHAREWARE==0)
// Check for rtl files
arg = CheckParm ("filertl");
if (arg!=0)
{
FILE *f;char buf[32];
if (_argv[arg+1] != 0) { //are there a filename included
strcpy (tempstr,_argv[arg+1]);//copy it to tempstr
if (strlen (tempstr) < MAX_PATH) {
if (access (tempstr, 0) != 0) { //try open
strcat (tempstr,".rtc");//non exists, try add .rtc
if (access (tempstr, 0) != 0) { //try open again
//stil no useful filename
strcat (tempstr," not found, skipping RTL file ");
printf("%s", tempstr);
goto NoRTL;
}
}
if((f = fopen( tempstr, "r" )) == NULL ){ //try opnong file
strcat (tempstr," not could not be opened, skipping RTL file ");
printf("%s", tempstr);
goto NoRTL;
}else{
fread(buf,3,3,f);//is the 3 first letters RTL (RTC)
if (((strstr(buf,"RTL") != 0)||strstr(buf,"RTC") != 0)) {
strcpy (GameLevels.file,tempstr);
GameLevels.avail++;
strcpy (buf,"Adding ");
strcat (buf,tempstr);
printf("%s", buf);
}
fclose(f);
}
}
}else{printf("Missing RTL filename");}
}
NoRTL:;
// Check for rtc files
arg = CheckParm ("filertc");
if (arg!=0)
{
FILE *f;char buf[32];
if (_argv[arg+1] != 0) { //are there a filename included
strcpy (tempstr,_argv[arg+1]);//copy it to tempstr
if (strlen (tempstr) < MAX_PATH) {
if (access (tempstr, 0) != 0) { //try open
strcat (tempstr,".rtc");//non exists, try add .rtc
if (access (tempstr, 0) != 0) { //try open again
//stil no useful filename
strcat (tempstr," not found, skipping RTC file ");
printf("%s", tempstr);
goto NoRTL;
}
}
if((f = fopen( tempstr, "r" )) == NULL ){ //try opening file
strcat (tempstr," not could not be opened, skipping RTC file ");
printf("%s", tempstr);
goto NoRTL;
}else{
fread(buf,3,3,f);//is the 3 first letters RTL (RTC)
if (((strstr(buf,"RTL") != 0)||strstr(buf,"RTC") != 0)) {
strcpy (BattleLevels.file,tempstr);
BattleLevels.avail++;
strcpy (buf,"Adding ");
strcat (buf,tempstr);
printf("%s", buf);
}
fclose(f);
}
}
}else{printf("Missing RTC filename");}
}
NoRTC:;
// Check for User wads
arg = CheckParm ("file");
if (arg!=0)
{
newargs [argnum++] = _argv[arg+1];
}
arg = CheckParm ("file1");
if (arg!=0)
{
newargs [argnum++] = _argv[arg+1];
}
arg = CheckParm ("file2");
if (arg!=0)
{
newargs [argnum++] = _argv[arg+1];
}
#else
if (
(CheckParm ("file") > 0) ||
(CheckParm ("file1") > 0) ||
(CheckParm ("file2") > 0)
)
printf("External wads ignored.\n");
#endif
// Normal ROTT wads
#if (SHAREWARE)
newargs [argnum++] = DATADIR "HUNTBGIN.WAD";
#else
newargs [argnum++] = DATADIR "DARKWAR.WAD";
#endif
// newargs [argnum++] = "credits.wad";
// Check for Remote Ridicule WAD
if (RemoteSounds.avail == true)
{
char *src;
strcpy (tempstr,RemoteSounds.path);
src = RemoteSounds.path + strlen(RemoteSounds.path) - 1;
if (*src != '\\')
strcat (tempstr,"\\\0");
strcat (tempstr,RemoteSounds.file);
newargs [argnum++] = tempstr;
}
else
{
newargs [argnum++] = DATADIR "REMOTE1.RTS";
}
newargs [argnum++] = NULL;
W_InitMultipleFiles(newargs);
}
void PlayTurboGame
(
void
)
{
NewGame = true;
locplayerstate->player = DefaultPlayerCharacter;
playstate = ex_resetgame;
GameLoop();
}
//***************************************************************************
//
// Init_Tables () - Init tables needed for double buffering
//
//***************************************************************************
void Init_Tables (void)
{
int i;
int x,
y;
unsigned *blockstart;
byte * shape;
memset (&CWD[0], 0, 40);
getcwd (CWD, 40); // get the current directory
origpal=SafeMalloc(768);
memcpy (origpal, W_CacheLumpName("pal",PU_CACHE, CvtNull, 1), 768);
FindEGAColors();
for (i=0;i<PORTTILESHIGH;i++)
uwidthtable[i] = UPDATEWIDE*i;
updateptr = &update[0];
blockstart = &blockstarts[0];
for (y=0;y<UPDATEHIGH;y++)
for (x=0;x<UPDATEWIDE;x++)
*blockstart++ = iG_SCREENWIDTH*16*y+x*TILEWIDTH;
for (i = 0; i < 0x300; i++)
*(origpal+(unsigned int)i) = (*(origpal+(unsigned int)i))>>2;
// Cache in fonts
shape = W_CacheLumpNum (W_GetNumForName ("smallfont"), PU_STATIC, Cvt_font_t, 1);
smallfont = (font_t *)shape;
CurrentFont = smallfont;
// Cache in tiny font
shape = W_CacheLumpNum (W_GetNumForName ("tinyfont"), PU_STATIC, Cvt_font_t, 1);
tinyfont = (font_t *)shape;
intensitytable=W_CacheLumpNum(W_GetNumForName("menucmap"),PU_STATIC, CvtNull, 1);
fontcolor = egacolor[4];
if (!quiet)
printf("RT_MAIN: Fonts Initialized\n");
}
int NumberOfTeams
(
void
)
{
int index;
int team[ MAXPLAYERCOLORS ];
int count;
int color;
memset( team, 0, sizeof( team ) );
count = 0;
for( index = 0; index < numplayers; index++ )
{
color = PLAYERSTATE[ index ].uniformcolor;
if ( !team[ color ] )
{
team[ color ] = true;
count++;
}
}
return( count );
}
void GameLoop (void)
{
boolean done = false;
boolean loadit = false;
int NextLevel;
wami(1);
while (1)
{
if ( playstate == ex_battledone )
{
while( damagecount > 0 )
{
DoBorderShifts();
}
damagecount = 0;
SetBorderColor (0);
StopWind();
ShutdownClientControls();
SD_Play (SD_LEVELDONESND);
if ( ( player->flags & FL_DOGMODE ) ||
( gamestate.battlemode == battle_Eluder ) )
MU_StartSong(song_dogend);
else
MU_StartSong(song_endlevel);
VL_FillPalette(255,255,255);
VL_FadeIn(0,255,origpal,10);
BattleLevelCompleted( consoleplayer );
BATTLE_Shutdown();
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
ingame = false;
if ( networkgame == true )
{
AddGameEndCommand ();
}
AdjustMenuStruct ();
CalcTics();
CalcTics();
playstate = ex_titles;
}
switch (playstate)
{
case ex_titles:
BATTLE_Shutdown();
MU_StartSong(song_title);
EnableScreenStretch();
if ((NoWait==false)&&(!modemgame))
{
byte dimpal[768];
int i;
for (i = 0; i < 0x300; i++)
dimpal[i] = origpal[i]>>2;
CalcTics();
CalcTics();
IN_ClearKeysDown ();
while (IN_GetMouseButtons()) {}
while ((!LastScan) && (!IN_GetMouseButtons()))
{
int i;
byte *tempbuf;
MenuFadeOut();
ClearGraphicsScreen();
SetPalette(&dimpal[0]);
PlayMovie ("shartitl", true);
if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
{
break;
}
PlayMovie ("shartit2", true);
if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
{
break;
}
SD_Play (SD_LIGHTNINGSND);
MenuFadeIn();
I_Delay(30);
SD_Play (SD_ACTORSQUISHSND);
tempbuf=bufferofs;
bufferofs=page1start; // fixed, was displayofs
DrawNormalSprite(320-94,200-41,W_GetNumForName("rsac"));
VW_UpdateScreen(); // fixed, was missing
bufferofs=tempbuf;
I_Delay(30);
if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
{
break;
}
DoCreditScreen ();
if ((!LastScan) && (!IN_GetMouseButtons()))
CheckHighScore (0, 0, false);
#if (SHAREWARE==0)
if ((!LastScan) && (!IN_GetMouseButtons()))
{
DoMicroStoryScreen ();
}
#endif
if (
(!LastScan) &&
(!IN_GetMouseButtons()) &&
(lowmemory==0) &&
(GameLevels.avail==false)
)
{
if (demonumber==-1)
demonumber=RandomNumber("GameLoop",0);
for (i=0;i<4;i++)
{
demonumber=(demonumber+1)%4;
if (DemoExists (demonumber+1) == true)
break;
}
if (DemoExists (demonumber+1) == true)
{
ingame=true;
LoadDemo (demonumber+1);
break;
}
}
}
}
if (playstate != ex_demoplayback)
{
if (demoexit == true)
{
QuitGame();
}
NoWait = false;
SwitchPalette(origpal,35);
CP_MainMenu();
}
break;
case ex_resetgame:
// SetTextMode ( ); //12345678
EnableScreenStretch();//bna++ shut on streech mode
InitCharacter();
InitializeMessages();
fizzlein = true;
BATTLE_GetSpecials();
BATTLE_SetOptions( &BATTLE_Options[ gamestate.battlemode ] );
if ( modemgame == true )
{
fizzlein = false;
if ( consoleplayer == 0 )
{
// Setup Master
SetupGameMaster();
}
else
{
// Setup slave
SetupGamePlayer();
}
if ( gamestate.Version < ROTTVERSION )
{
Error( "This version of Rise of the Triad (%d.%d) is incompatible with\n"
"version %d.%d.", ROTTMAJORVERSION, ROTTMINORVERSION,
gamestate.Version / 10, gamestate.Version % 10 );
}
if ( gamestate.teamplay )
{
int teams;
teams = NumberOfTeams();
if ( gamestate.battlemode == battle_CaptureTheTriad )
{
if ( teams != 2 )
{
CP_CaptureTheTriadError();
playstate = ex_titles;
continue;
}
}
else if ( teams < 2 )
{
CP_TeamPlayErrorMessage();
playstate = ex_titles;
continue;
}
}
}
InitCharacter();
BATTLE_Init( gamestate.battlemode, numplayers );
NewGame = true;
if ( ( BATTLEMODE ) && ( BATTLE_ShowKillCount ) )
{
StatusBar |= STATUS_KILLS;
}
else
{
StatusBar &= ~STATUS_KILLS;
}
if (loadedgame == false)
{
if ( !BATTLEMODE )
{
PlayCinematic();
}
SetupGameLevel();
}
IN_ClearKeyboardQueue();
SetupScreen (true);
MenuFixup ();
playstate=ex_stillplaying;
DisableScreenStretch();//bna++ shut off streech mode
break;
case ex_stillplaying:
InitializeMessages();
SHAKETICS = 0xFFFF;
if (modemgame==true)
{
ComSetTime();
turbo = false;
}
else if (turbo==true)
turbo=false;
else
newlevel=true;
PlayLoop ();
break;
case ex_died:
loadit = done = false;
// SetTextMode ( ); //12345678
Died ();
StopWind();
DisableScreenStretch();//bna++ shut off streech mode
while (damagecount>0)
DoBorderShifts();
damagecount = 0;
SetBorderColor (0);
if (demorecord)
{
FreeDemo ();
}
if (demoplayback)
{
FreeDemo ();
playstate=ex_demodone;
}
else
{
ShutdownClientControls();
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
if (CheckForQuickLoad()==false)
{
if (locplayerstate->lives < 0)
{
if (timelimitenabled == false)
{
CheckHighScore (gamestate.score, gamestate.mapon+1, false);
playstate = ex_titles;
AdjustMenuStruct ();
ingame = false;
locplayerstate->health = MaxHitpointsForCharacter(locplayerstate);
gamestate.score = 0;
locplayerstate->lives = 3;
locplayerstate->weapon = wp_pistol;
locplayerstate->triads = 0;
UpdateLives (locplayerstate->lives);
UpdateScore (gamestate.score);
}
else
{
QuitGame();
}
}
else
{
fizzlein = true;
SetupGameLevel ();
UpdateTriads(player,0);
playstate = ex_stillplaying;
}
}
}
break;
case ex_warped:
StopWind();
TurnShakeOff();
SHAKETICS = 0xffff;
gamestate.TimeCount = 0;
gamestate.frame=0;
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
fizzlein = true;
SetupGameLevel ();
playstate = ex_stillplaying;
break;
case ex_skiplevel:
case ex_secretdone:
case ex_secretlevel:
case ex_completed:
case ex_bossdied:
ShutdownClientControls();
TurnShakeOff();
SHAKETICS = 0xffff;
if (timelimitenabled == false)
{
gamestate.TimeCount = 0;
gamestate.frame=0;
}
StopWind();
#if (SHAREWARE==0)
if ((playstate==ex_bossdied) && (gamestate.mapon!=30))
{
int shape;
lbm_t * LBM;
byte *s;
patch_t *p;
char str[50];
int width, height;
LBM = (lbm_t *) W_CacheLumpName( "deadboss", PU_CACHE, Cvt_lbm_t, 1);
VL_DecompressLBM (LBM,false);
MenuFadeOut();
switch (gamestate.mapon)
{
case 6:
shape = W_GetNumForName("deadstev");
break;
case 14:
shape = W_GetNumForName("deadjoe");
break;
case 22:
shape = W_GetNumForName("deadrobo");
break;
case 33:
shape = W_GetNumForName("deadtom");
break;
// default:
// Error("Boss died on an illegal level\n");
// break;
}
s = W_CacheLumpNum (shape, PU_CACHE, Cvt_patch_t, 1);
p = (patch_t *)s;
DrawNormalSprite ((320-p->origsize)>>1, (230-(p->height-p->topoffset))>>1, shape);
switch (gamestate.mapon)
{
case 6:
strcpy(&str[0],"\"General\" John Darian");
break;
case 14:
strcpy(&str[0],"Sebastian \"Doyle\" Krist");
break;
case 22:
strcpy(&str[0],"the NME");
break;
case 33:
strcpy(&str[0],"El Oscuro");
break;
// default:
// Error("Boss died on an illegal level\n");
// break;
}
CurrentFont=smallfont;
US_MeasureStr (&width, &height, "%s", str);
US_ClippedPrint ((320-width)>>1, 180, str);
VW_UpdateScreen();
MenuFadeIn();
WaitKeyUp();
LastScan = 0;
while (!LastScan) IN_UpdateKeyboard(); // Thanks again DrLex
LastScan=0;
}
#endif
LevelCompleted ( playstate );
NextLevel = GetNextMap(player->tilex,player->tiley);
demoplayback = false;
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
if (NextLevel != -1 )
{
gamestate.mapon = NextLevel;
PlayCinematic();
fizzlein = true;
SetupGameLevel ();
playstate = ex_stillplaying;
}
else
{
playstate = ex_gameover;
}
break;
case ex_demodone:
ingame=false;
ShutdownClientControls();
TurnShakeOff();
SHAKETICS = 0xffff;
gamestate.TimeCount = 0;
gamestate.frame=0;
demoplayback = false;
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
if (predemo_violence != -1)
{
gamestate.violence = predemo_violence;
predemo_violence = -1;
}
playstate=ex_titles;
break;
case ex_gameover:
StopWind();
DoEndCinematic();
if (playstate==ex_gameover)
{
CheckHighScore (gamestate.score, gamestate.mapon+1, false);
ingame = false;
AdjustMenuStruct ();
playstate = ex_titles;
}
break;
case ex_demorecord:
ShutdownClientControls();
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
RecordDemo();
SetupGameLevel ();
fizzlein = true;
playstate = ex_stillplaying;
break;
case ex_demoplayback:
ShutdownClientControls();
Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND); // Free current level
SetupDemo();
SetupGameLevel ();
fizzlein = true;
playstate = ex_stillplaying;
break;
default:
;
}
}
waminot();
}
boolean CheckForQuickLoad (void )
{
EnableScreenStretch();//bna++
if ( pickquick )
{
SetupMenuBuf();
pickquick = CP_DisplayMsg( "\nQuick load saved game?\n", 12 );
if ( pickquick )
{
AllocateSavedScreenPtr();
CP_LoadGame( 1, 1 );
FreeSavedScreenPtr();
}
else
{
// Erase the quick load message
VL_FadeOut( 0, 255, 0, 0, 0, 20 );
}
ShutdownMenuBuf();
}
return( pickquick );
}
//===========================================================================
void ShutDown ( void )
{
if ( ( standalone == false )
#ifdef DOS
|| ( SOUNDSETUP )
#endif
)
{
WriteConfig ();
}
// if (
// (networkgame==false) &&
// (modemgame==true)
// )
// {
// ShutdownModemGame ();
// }
ShutdownClientControls();
I_ShutdownKeyboard();
#ifdef DOS /* the UL_ErrorStartup() call is commented out... */
UL_ErrorShutdown ();
#endif
ShutdownGameCommands();
MU_Shutdown();
I_ShutdownTimer();
SD_Shutdown();
IN_Shutdown ();
ShutdownSoftError ();
Z_ShutDown();
// _settextcursor (0x0607);
}
//===========================================================================
#if (DEVELOPMENT == 1)
extern int totallevelsize;
#endif
void QuitGame ( void )
{
#if (DEBUG == 1)
char buf[5];
#endif
#if (DEVELOPMENT == 1)
int temp;
#else
byte *txtscn;
#endif
int k;
MU_FadeOut(200);
while (MU_FadeActive())
{
int time=GetTicCount();
while (GetTicCount()==time) {}
}
PrintMapStats();
PrintTileStats();
SetTextMode();
#if (DEVELOPMENT == 1)
printf("Clean Exit\n");
if (gamestate.TimeCount)
{
temp=(gamestate.frame*VBLCOUNTER*100)/gamestate.TimeCount;
printf("fps = %2ld.%2ld\n",temp/100,temp%100);
}
printf("argc=%ld\n",_argc);
for (k=0;k<_argc;k++) printf("%s\n",_argv[k]);
switch( _heapchk() )
{
case _HEAPOK:
printf( "OK - heap is good\n" );
break;
case _HEAPEMPTY:
printf( "OK - heap is empty\n" );
break;
case _HEAPBADBEGIN:
printf( "ERROR - heap is damaged\n" );
break;
case _HEAPBADNODE:
printf( "ERROR - bad node in heap\n" );
break;
}
printf("\nLight Characteristics\n");
printf("---------------------\n");
if (fog)
printf("FOG is ON\n");
else
printf("FOG is OFF\n");
printf("LIGHTLEVEL=%ld\n",GetLightLevelTile());
printf("LIGHTRATE =%ld\n",GetLightRateTile());
printf("\nCENTERY=%ld\n",centery);
#else
#ifdef DOS
if ( !SOUNDSETUP )
{
#endif
#if (SHAREWARE==0)
txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("regend"), PU_CACHE, CvtNull, 1);
#else
txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("shareend"), PU_CACHE, CvtNull, 1);
#endif
#if DOS
for (k = 0; k < 23; k++)
printf ("\n");
memcpy ((byte *)0xB8000, txtscn, 4000);
#elif defined (ANSIESC)
DisplayTextSplash (txtscn, 25);
#endif
#if (DEBUG == 1)
px = ERRORVERSIONCOL;
py = ERRORVERSIONROW;
#if (BETA == 1)
UL_printf ("<EFBFBD>");
#else
UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
#endif
// Skip the dot
px++;
UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
#endif
#ifdef DOS
}
#endif
#endif
#ifdef DOS
if ( SOUNDSETUP )
{
printf( "\nSound setup complete.\n"
"Type ROTT to run the game.\n" );
}
ShutDown();
#endif
exit(0);
}
void InitCharacter
(
void
)
{
locplayerstate->health = MaxHitpointsForCharacter( locplayerstate );
if (timelimitenabled == true)
{
locplayerstate->lives = 1;
}
else
{
locplayerstate->lives = 3;
}
ClearTriads (locplayerstate);
locplayerstate->playerheight = characters[ locplayerstate->player ].height;
// locplayerstate->stepwhich = 0;
// locplayerstate->steptime = 0;
gamestate.score = 0;
if ( gamestate.battlemode == battle_StandAloneGame )
{
gamestate.mapon = startlevel;
gamestate.difficulty = DefaultDifficulty;
}
else
{
gamestate.difficulty = gd_hard;
}
gamestate.dipballs = 0;
gamestate.TimeCount = 0;
godmode = 0;
damagecount = 0;
UpdateScore( gamestate.score );
}
void UpdateGameObjects ( void )
{
int j;
volatile int atime;
objtype * ob,*temp;
battle_status BattleStatus;
wami(2);
if (controlupdatestarted==0)
{
return;
waminot();
}
atime=GetFastTics();
UpdateClientControls ();
if (demoplayback == false)
PollControls ();
CalcTics ();
UpdateClientControls ();
while (oldpolltime<oldtime)
{
UpdateClientControls ();
MoveDoors();
ProcessElevators();
MovePWalls();
UpdateLightning ();
TriggerStuff();
CheckCriticalStatics();
for(j=0;j<numclocks;j++)
if (Clocks[j].time1 &&
((gamestate.TimeCount == Clocks[j].time1) ||
(gamestate.TimeCount == Clocks[j].time2)))
TRIGGER[Clocks[j].linkindex]=1;
for (ob = firstactive; ob;)
{
temp = ob->nextactive;
DoActor (ob);
#if (DEVELOPMENT == 1)
if ((ob->x<=0) || (ob->y<=0))
Error("object xy below zero obj->x=%ld obj->y=%ld obj->obclass=%ld\n",ob->x,ob->y,ob->obclass);
if ((ob->angle<0) || (ob->angle>=FINEANGLES))
Error("object angle below zero obj->angle=%ld obj->obclass=%ld\n",ob->angle,ob->obclass);
#endif
ob = temp;
}
BattleStatus = BATTLE_CheckGameStatus( battle_refresh, 0 );
if ( BattleStatus != battle_no_event )
{
switch( BattleStatus )
{
case battle_end_game :
case battle_out_of_time :
playstate = ex_battledone;
break;
case battle_end_round :
SetWhoHaveWeapons();
break;
default:
;
}
if ( playstate == ex_battledone )
{
break;
}
}
#if (SYNCCHECK == 1)
CheckForSyncCheck();
#endif
if (timelimitenabled == true)
{
if (timelimit-gamestate.TimeCount>maxtimelimit)
timelimit = maxtimelimit+gamestate.TimeCount;
if (gamestate.TimeCount == timelimit)
{
locplayerstate->lives=-1;
playstate=ex_died;
}
}
gamestate.TimeCount ++;
ResetCurrentCommand();
oldpolltime++;
if (GamePaused==true)
break;
}
actortime=GetFastTics()-atime;
UpdateClientControls ();
if (noecho == false)
{
if ( player->flags & FL_SHROOMS )
{
FX_SetReverb( 230 );
}
else if (sky == 0)
{
FX_SetReverb( min( numareatiles[ player->areanumber ] >> 1, 90 ) );
}
}
waminot();
}
void PauseLoop ( void )
{
StopWind();
UpdateClientControls ();
while (oldpolltime<oldtime)
{
CheckUnPause();
#if (SYNCCHECK == 1)
CheckForSyncCheck();
#endif
oldpolltime++;
if (GamePaused==false)
{
//bna++ section
if (( playstate == ex_stillplaying )&&(iGLOBAL_SCREENWIDTH > 320)){
pic_t *shape;
shape = ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );
DisableScreenStretch();//dont strech when we go BACK TO GAME
DrawPlayScreen(true);//repaint ammo and life stat
VW_UpdateScreen ();//update screen
}
StartupClientControls();
//bna section end
break;
}
}
CalcTics ();
if (demoplayback==false)
PollControls ();
if ((RefreshPause == true) &&
(GamePaused == true) &&
((GetTicCount() - pausedstartedticcount) >= blanktime))
{
RefreshPause = false;
StartupScreenSaver();
}
}
void PlayLoop
(
void
)
{
volatile int atime;
boolean canquit = true;
int quittime = 0;
wami(3);
if ( (loadedgame == false) && (timelimitenabled == false) )
{
gamestate.TimeCount = 0;
gamestate.frame = 0;
}
fromloadedgame:
GamePaused = false;
if ( loadedgame == false )
{
DrawPlayScreen( true );
missobj = NULL;
}
else
{
loadedgame = false;
DoLoadGameSequence();
}
drawtime = 0;
actortime = 0;
tics = 0;
SetFastTics(0);
if ( fizzlein == false )
{
StartupClientControls();
}
else
{
ShutdownClientControls();
}
// set detail level
doublestep = 2 - DetailLevel;
ResetMessageTime();
DeletePriorityMessage( MSG_SYSTEM );
if ( ( gamestate.battlemode == battle_Normal ) &&
( numplayers == 1 ) )
{
AddMessage( "Comm-bat is for Modem and Network games.", MSG_GAME );
AddMessage( "You will not be facing any", MSG_GAME );
AddMessage( "opponents. Have fun and explore.", MSG_GAME );
}
while( playstate == ex_stillplaying )
{
UpdateClientControls();
if ( GamePaused )
{
PauseLoop();
atime = GetFastTics();
if ( RefreshPause )
{
ThreeDRefresh();
}
else
{
UpdateScreenSaver();
}
}
else
{
if (controlupdatestarted == 1)
UpdateGameObjects();
atime = GetFastTics();
ThreeDRefresh();
}
SyncToServer();
drawtime = GetFastTics() - atime;
// Don't allow player to quit if entering message
canquit = !MSG.messageon;
PollKeyboard();
MISCVARS->madenoise = false;
AnimateWalls();
UpdateClientControls();
#if (DEVELOPMENT == 1)
Z_CheckHeap();
#endif
if ( AutoDetailOn == true )
{
AdaptDetail();
}
UpdateClientControls();
DoSprites();
DoAnimatedMaskedWalls();
UpdatePlayers();
DrawTime( false );
UpdateClientControls();
if ( ( !BATTLEMODE ) && ( CP_CheckQuick( LastScan ) ) )
{
boolean escaped=false;
if (LastScan == sc_Escape)
{
MU_StoreSongPosition();
MU_StartSong(song_menu);
escaped = true;
}
TurnShakeOff();
StopWind();
SetBorderColor( 0 );
ShutdownClientControls();
if (demoplayback==true)
{
FreeDemo();
playstate = ex_demodone;
if (demoexit==true)
{
QuitGame();
}
return;
}
ControlPanel( LastScan );
// set detail level
doublestep = 2 - DetailLevel;
inmenu = false;
if ( playstate == ex_titles )
{
return;
}
if ( playstate == ex_stillplaying )
{
SetupScreen( false );
}
if ( loadedgame == true )
{
goto fromloadedgame;
}
if (
( playstate == ex_stillplaying ) &&
( ( fizzlein == false ) ||
( GamePaused )
)
)
{
StartupClientControls();
}
if (
(playstate == ex_stillplaying) &&
(GamePaused == false) &&
(escaped == true)
)
{
MU_StartSong(song_level);
MU_RestoreSongPosition();
}
}
if ( BATTLEMODE )
{
if ( MSG.messageon == false )
{
CheckRemoteRidicule( LastScan );
}
if ( quitactive == false )
{
if ( ( LastScan == sc_Escape ) && ( canquit ) )
{
quitactive = true;
quittime = GetTicCount() + QUITTIMEINTERVAL;
if ( (consoleplayer == 0) || (networkgame == false) )
{
AddMessage( "Do you want to end this game? "
"(\\FY\\O/\\FN\\O)", MSG_QUIT );
}
else
{
AddMessage( "Do you want to exit to DOS? "
"(\\FY\\O/\\EN\\O)", MSG_QUIT );
}
}
}
else
{
if ( GetTicCount() > quittime )
{
quitactive = false;
}
else if ( LastScan == sc_N )
{
DeletePriorityMessage( MSG_QUIT );
quitactive = false;
}
else if ( LastScan == sc_Y )
{
DeletePriorityMessage( MSG_QUIT );
if ( (consoleplayer == 0) || (networkgame==false) )
{
AddEndGameCommand();
}
else
{
AddQuitCommand();
}
}
}
}
}
waminot();
}
//******************************************************************************
//
// CheckRemoteRidicule ()
//
//******************************************************************************
void CheckRemoteRidicule ( int scancode )
{
int num=-1;
wami(4);
switch (scancode)
{
case sc_F1:
num=0;
break;
case sc_F2:
num=1;
break;
case sc_F3:
num=2;
break;
case sc_F4:
num=3;
break;
case sc_F5:
if ( !Keyboard[ sc_RShift ] )
{
num=4;
}
break;
case sc_F6:
num=5;
break;
case sc_F7:
if ( !Keyboard[ sc_RShift ] )
{
num=6;
}
break;
case sc_F8:
num=7;
break;
case sc_F9:
num=8;
break;
case sc_F10:
num=9;
break;
}
if (num>=0)
{
AddRemoteRidiculeCommand ( consoleplayer, MSG_DIRECTED_TO_ALL, num );
LastScan=0;
}
waminot();
}
//******************************************************************************
//
// DoBossKey ()
//
//******************************************************************************
void DoBossKey ( void )
{
#ifdef DOS
union REGS regs;
ShutdownClientControls();
SetTextMode();
// move cursor to the row 0 column 4
regs.w.ax = 0x0200;
regs.w.bx = 0;
regs.w.dx = 0x0004;
int386(0x10,&regs,&regs);
px=0;
py=0;
UL_printf("C:\\>\n");
LastScan = 0;
IN_WaitForKey ();
VL_SetVGAPlaneMode();
VL_SetPalette(origpal);
SetBorderColor(0);
TurnShakeOff();
SetupScreen(true);
ThreeDRefresh();
StartupClientControls();
#else
STUB_FUNCTION;
#endif
}
//******************************************************************************
//
// PollKeyboard ()
//
//******************************************************************************
void PollKeyboard
(
void
)
{
static char autopressed = false;
wami(5);
if (demoplayback==true)
{
IN_UpdateKeyboard();
}
if ( !BATTLEMODE )
{
CheckDebug ();
if (
( Keyboard[ sc_CapsLock ] ) &&
( DebugOk )
)
{
DebugKeys ();
}
}
if ( locplayerstate->buttonstate[ bt_autorun ] )
{
if ( !autopressed )
{
autopressed = true;
gamestate.autorun ^= 1;
if ( gamestate.autorun == 0 )
{
AddMessage( "AutoRun is \\cOFF", MSG_SYSTEM );
}
else
{
AddMessage( "AutoRun is \\cON", MSG_SYSTEM );
}
}
}
else
{
autopressed = false;
}
#if 0
if ( modemgame == false )
{
CheckDevelopmentKeys();
}
#endif
if ( ( MSG.messageon == false ) && ( !quitactive ) )
{
if ( ( Keyboard[ buttonscan[ bt_message ] ] ) && ( BATTLEMODE ) )
{
// Send message to all
MSG.messageon = true;
MSG.directed = false;
MSG.inmenu = false;
MSG.remoteridicule = -1;
MSG.towho = MSG_DIRECTED_TO_ALL;
MSG.textnum = AddMessage( "_", MSG_MODEM );
MSG.length = 1;
DeletePriorityMessage( MSG_MACRO );
}
else if ( ( Keyboard[ buttonscan[ bt_directmsg ] ] ) && ( BATTLEMODE ) )
{
// Send directed message
MSG.messageon = true;
MSG.directed = true;
MSG.inmenu = false;
MSG.remoteridicule = -1;
MSG.towho = 0;
MSG.textnum = AddMessage( "_", MSG_MODEM );
MSG.length = 1;
DeletePriorityMessage( MSG_MACRO );
}
if ( buttonpoll[ bt_map ] )
{
if ( !BATTLEMODE )
{
// Automap
StopWind();
DoMap( player->tilex, player->tiley );
}
else
{
// Show kill counts
if ( SHOW_KILLS() )
{
BATTLE_ShowKillCount = false;
StatusBar &= ~STATUS_KILLS;
}
else
{
StatusBar |= STATUS_KILLS;
BATTLE_ShowKillCount = true;
}
SetupScreen( true );
}
}
// Shrink screen
if ( Keyboard[ sc_Minus ] )
{
Keyboard[ sc_Minus ] = false; // HDG debounce
if ( viewsize > 0 )
{
viewsize--;
SetupScreen( true );
}
}
// Expand screen
if ( Keyboard[ sc_Plus ] )
{
Keyboard[ sc_Plus ] = false; // HDG debounce
if ( viewsize < MAXVIEWSIZES - 1 )
{
viewsize++;
SetupScreen( true );
}
}
// Set detail
if ( ( Keyboard[ sc_F5 ] ) && ( ( !BATTLEMODE ) ||
( Keyboard[ sc_RShift ] ) ) )
{
Keyboard[ sc_F5 ] = false;
LastScan = 0;
DetailLevel++;
if ( DetailLevel > 2 )
{
DetailLevel = 0;
}
switch( DetailLevel )
{
case 0 :
AddMessage( "Low detail", MSG_SYSTEM );
break;
case 1 :
AddMessage( "Medium detail", MSG_SYSTEM );
break;
case 2 :
AddMessage( "High detail", MSG_SYSTEM );
break;
}
doublestep = 2 - DetailLevel;
}
// Turn messages on/off
if ( ( Keyboard[ sc_F7 ] ) && ( ( !BATTLEMODE ) ||
( Keyboard[ sc_RShift ] ) ) )
{
Keyboard[ sc_F7 ] = false;
LastScan = 0;
MessagesEnabled = !MessagesEnabled;
if ( !MessagesEnabled )
{
AddMessage( "Messages disabled.", MSG_MSGSYSTEM );
}
else
{
AddMessage( "Messages enabled.", MSG_MSGSYSTEM );
}
}
if ( ( Keyboard[ sc_F6 ] ) && ( !BATTLEMODE ) )
{
Keyboard[ sc_F6 ] = false;
if (Keyboard[sc_RShift])
{
ShutdownClientControls();
UndoQuickSaveGame();
StartupClientControls();
}
else if (quicksaveslot==-1)
{
ShutdownClientControls();
LastScan=sc_F2;
inmenu = true;
ControlPanel( LastScan );
StartupClientControls();
}
else
{
LastScan = 0;
ShutdownClientControls();
ThreeDRefresh();
QuickSaveGame();
StartupClientControls();
}
}
//#if 0
if ( ( Keyboard[ sc_F12 ] ) && ( !BATTLEMODE ) )
{
Keyboard[ sc_F12 ] = false;
LastScan = 0;
DoBossKey();
}
//#endif
// Gamma correction
if ( Keyboard[ sc_F11 ] )
{
char str[ 50 ] = "Gamma Correction Level ";
char str2[ 10 ];
gammaindex++;
if ( gammaindex == NUMGAMMALEVELS )
{
gammaindex = 0;
}
VL_SetPalette( origpal );
itoa( gammaindex, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
while( Keyboard[ sc_F11 ] )
{
IN_UpdateKeyboard();
}
}
#if 0
if ( Keyboard[ sc_M ] )
{
char str[ 50 ] = "Mouse Y-Rotation Input Scale ";
char str2[ 10 ];
if ( Keyboard[ sc_RShift ] )
mouse_ry_input_scale += 50;
else
mouse_ry_input_scale -= 50;
itoa(mouse_ry_input_scale,str2,10);
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
#endif
// Increase volume
if ( Keyboard[ sc_CloseBracket ] )
{
if ( Keyboard[ sc_RShift ] )
{
char str[ 50 ] = "Music Volume Level ";
char str2[ 10 ];
if ( MUvolume < 255 )
{
MUvolume++;
}
MU_SetVolume( MUvolume );
itoa( MUvolume, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
else
{
char str[ 50 ] = "Sound FX Volume Level ";
char str2[ 10 ];
if ( FXvolume < 255 )
{
FXvolume++;
}
FX_SetVolume( FXvolume );
itoa( FXvolume, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
}
// Decrease volume
if ( Keyboard[ sc_OpenBracket ] )
{
if ( Keyboard[ sc_RShift ] )
{
char str[ 50 ] = "Music Volume Level ";
char str2[ 10 ];
if ( MUvolume > 0 )
{
MUvolume--;
}
MU_SetVolume( MUvolume );
itoa( MUvolume, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
else
{
char str[ 50 ] = "Sound FX Volume Level ";
char str2[ 10 ];
if ( FXvolume > 0 )
{
FXvolume--;
}
FX_SetVolume( FXvolume );
itoa( FXvolume, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
}
#if SAVE_SCREEN
#if (DEVELOPMENT == 1)
if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_C ] )
{
SaveScreen( true );
}
else if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_X ] )
{
SaveScreen( false );
}
#endif
else if ( Keyboard[ sc_Alt] && Keyboard[ sc_C ] )
{
SaveScreen( false );
}
#ifdef DOS /* makes no sense under Linux as there are no lbm viewers there */
else if ( Keyboard[ sc_Alt] && Keyboard[ sc_V ] )
{
SaveScreen( true );
}
#endif
#endif
}
#ifdef USE_SDL
/* SDL doesn't send proper release events for these */
if (Keystate[sc_CapsLock])
{
Keystate[sc_CapsLock]++;
if (Keystate[sc_CapsLock] == 3)
Keystate[sc_CapsLock] = 0;
}
if (Keystate[0x45]) /* numlock */
{
Keystate[0x45]++;
if (Keystate[0x45] == 3)
Keystate[0x45] = 0;
}
#endif
waminot();
}
//******************************************************************************
//
// CheckDevelopmentKeys ()
//
//******************************************************************************
#if 0
void CheckDevelopmentKeys
(
void
)
{
#if (DEBUG == 1)
if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_T ] )
{
if ( warp == true )
{
player->x = warpx;
player->y = warpy;
player->angle = warpa;
locplayerstate->anglefrac = warpa << ANGLEBITS;
player->momentumx = 0;
player->momentumy = 0;
player->momentumz = 0;
}
return;
}
#endif
// Lower wall height
if ( Keyboard[ sc_5 ] )
{
if ( levelheight > 1 )
{
levelheight--;
}
while( Keyboard[ sc_5 ] )
{
IN_UpdateKeyboard ();
}
maxheight = ( levelheight << 6 ) - 32;
nominalheight = maxheight - 32;
}
// Raise wall height
if ( Keyboard[ sc_6 ] )
{
levelheight++;
while( Keyboard[ sc_6 ] )
{
IN_UpdateKeyboard();
}
maxheight = ( levelheight << 6 ) - 32;
nominalheight = maxheight - 32;
}
if ( Keyboard[ sc_8 ] )
{
char str[ 50 ] = "You are now player ";
char str2[ 10 ];
locplayerstate->player++;
if ( locplayerstate->player == 5 )
{
locplayerstate->player = 0;
}
while( Keyboard[ sc_8 ] )
{
IN_UpdateKeyboard ();
}
itoa( locplayerstate->player, str2, 10 );
strcat( str, str2 );
AddMessage( str, MSG_SYSTEM );
}
#if 0
// Cycle forward through wall textures
if (Keyboard[sc_W] && (modemgame==false))
{int i,j;
for(i=0;i<128;i++)
for(j=0;j<128;j++)
{if (IsWall(i,j))
{if (tilemap[i][j] ==
(W_GetNumForName("WALLSTOP")-W_GetNumForName("WALLSTRT")-1))
tilemap[i][j] = 1;
else
tilemap[i][j] ++;
}
}
while(Keyboard[sc_W])
IN_UpdateKeyboard ();
}
if (Keyboard[sc_Q] && (modemgame==false))
{int i,j;
for(i=0;i<128;i++)
for(j=0;j<128;j++)
{if (IsWall(i,j))
{if (tilemap[i][j] == 1)
tilemap[i][j] = 74;
else
tilemap[i][j] --;
}
}
while(Keyboard[sc_Q])
IN_UpdateKeyboard ();
}
#endif
// Step through cieling/skies
if ( Keyboard[ sc_K ] )
{
if ( sky > 0 )
{
MAPSPOT( 1, 0, 0 )++;
if ( MAPSPOT( 1, 0, 0 ) > 239 )
{
MAPSPOT( 1, 0, 0 ) = 234;
}
}
else
{
MAPSPOT( 1, 0, 0 )++;
if ( MAPSPOT( 1, 0, 0 ) > 198 + 15 )
{
MAPSPOT( 1, 0, 0 ) = 198;
}
}
SetPlaneViewSize();
while( Keyboard[ sc_K ] )
{
IN_UpdateKeyboard();
}
}
// Step through floors
if ( Keyboard[ sc_L ] )
{
MAPSPOT( 0, 0, 0 )++;
if ( MAPSPOT( 0, 0, 0 ) > 180 + 15 )
{
MAPSPOT( 0, 0, 0 ) = 180;
SetPlaneViewSize();
while( Keyboard[ sc_L ] )
{
IN_UpdateKeyboard();
}
}
}
// Increase darkness level
if ( Keyboard[ sc_M ] )
{
if ( darknesslevel < 7 )
{
darknesslevel++;
}
SetLightLevels( darknesslevel );
while( Keyboard[ sc_M ] )
{
IN_UpdateKeyboard();
}
}
// Decrease darkness level
if ( Keyboard[ sc_N ] )
{
if ( darknesslevel > 0 )
{
darknesslevel--;
}
SetLightLevels( darknesslevel );
while( Keyboard[ sc_N ] )
{
IN_UpdateKeyboard();
}
}
// Increase light rate
if ( Keyboard[ sc_B ] )
{
SetLightRate( GetLightRate() + 1 );
myprintf( "normalshade = %ld\n", normalshade );
while( Keyboard[ sc_B ] )
{
IN_UpdateKeyboard();
}
}
// Decrease light rate
if ( Keyboard[ sc_V ] )
{
SetLightRate( GetLightRate() - 1 );
myprintf( "normalshade = %ld\n", normalshade );
while( Keyboard[ sc_V ] )
{
IN_UpdateKeyboard();
}
}
// Toggle light diminishing on/off
if ( Keyboard[ sc_T ] )
{
fulllight ^= 1;
while( Keyboard[ sc_T ] )
{
IN_UpdateKeyboard();
}
}
}
#endif
#if SAVE_SCREEN
short BigShort (short l)
{
byte b1,b2;
b1 = l&255;
b2 = (l>>8)&255;
return (b1<<8) + b2;
}
long BigLong (long l)
{
byte b1,b2,b3,b4;
b1 = l&255;
b2 = (l>>8)&255;
b3 = (l>>16)&255;
b4 = (l>>24)&255;
return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
}
/*
==============
=
= WriteLBMfile
=
==============
*/
void WriteLBMfile (char *filename, byte *data, int width, int height)
{
byte *lbm, *lbmptr;
long *formlength, *bmhdlength, *cmaplength, *bodylength;
long length;
bmhd_t basebmhd;
int handle;
int i;
lbm = lbmptr = (byte *) SafeMalloc ((iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT)+4000);
//
// start FORM
//
*lbmptr++ = 'F';
*lbmptr++ = 'O';
*lbmptr++ = 'R';
*lbmptr++ = 'M';
formlength = (long*)lbmptr;
lbmptr+=4; // leave space for length
*lbmptr++ = 'P';
*lbmptr++ = 'B';
*lbmptr++ = 'M';
*lbmptr++ = ' ';
//
// write BMHD
//
*lbmptr++ = 'B';
*lbmptr++ = 'M';
*lbmptr++ = 'H';
*lbmptr++ = 'D';
bmhdlength = (long *)lbmptr;
lbmptr+=4; // leave space for length
memset (&basebmhd,0,sizeof(basebmhd));
basebmhd.w = BigShort(width);
basebmhd.h = BigShort(height);
basebmhd.nPlanes = BigShort(8);
basebmhd.xAspect = BigShort(5);
basebmhd.yAspect = BigShort(6);
basebmhd.pageWidth = BigShort(width);
basebmhd.pageHeight = BigShort(height);
memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
lbmptr += sizeof(basebmhd);
length = lbmptr-(byte *)bmhdlength-4;
*bmhdlength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write CMAP
//
*lbmptr++ = 'C';
*lbmptr++ = 'M';
*lbmptr++ = 'A';
*lbmptr++ = 'P';
cmaplength = (long *)lbmptr;
lbmptr+=4; // leave space for length
for (i = 0; i < 0x300; i++)
*lbmptr++ = (*(origpal+i))<<2;
// memcpy (lbmptr,&origpal[0],768);
// lbmptr += 768;
length = lbmptr-(byte *)cmaplength-4;
*cmaplength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write BODY
//
*lbmptr++ = 'B';
*lbmptr++ = 'O';
*lbmptr++ = 'D';
*lbmptr++ = 'Y';
bodylength = (long *)lbmptr;
lbmptr+=4; // leave space for length
memcpy (lbmptr,data,width*height);
lbmptr += width*height;
length = lbmptr-(byte *)bodylength-4;
*bodylength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// done
//
length = lbmptr-(byte *)formlength-4;
*formlength = BigLong(length);
if (length&1)
*lbmptr++ = 0; // pad chunk to even offset
//
// write output file
//
handle = SafeOpenWrite (filename);
SafeWrite (handle, lbm, lbmptr-lbm);
close (handle);
SafeFree(lbm);
}
//****************************************************************************
//
// GetFileName ()
//
//****************************************************************************
void GetFileName (boolean saveLBM)
{
#ifdef DOS
char num[4];
int cnt = 0;
struct find_t fblock;
if (saveLBM)
memcpy (savename, "ROTT0000.LBM\0", 13);
else
memcpy (savename, "ROTT0000.PCX\0", 13);
if (_dos_findfirst (savename, 0, &fblock) != 0)
return;
do
{
cnt++;
memset (&num[0], 0, 4);
itoa (cnt, num, 10);
if (cnt > 99)
{
savename[5] = num[0];
savename[6] = num[1];
savename[7] = num[2];
}
else
if (cnt > 9)
{
savename[6] = num[0];
savename[7] = num[1];
}
else
savename[7] = num[0];
}
while (_dos_findfirst (savename, 0, &fblock) == 0);
#else
int i;
for (i = 0; i < 9999; i++) {
char filename[128];
if (saveLBM) {
sprintf(savename, "rott%04d.lbm", i);
} else {
sprintf(savename, "rott%04d.pcx", i);
}
GetPathFromEnvironment( filename, ApogeePath, savename );
if (access(filename, F_OK) != 0) {
return;
}
}
#endif
}
//****************************************************************************
//
// SaveScreen ()
//
//****************************************************************************
boolean inhmenu;
#if (BETA == 1)
#define SSX (160-(46*2))
#define SSY (17)
#endif
void SaveScreen (boolean saveLBM)
{
byte *buffer;
byte * screen;
boolean oldHUD;
char filename[ 128 ];
#if (BETA == 1)
unsigned tmp;
char buf[30];
int i;
#endif
oldHUD=HUD;
HUD=false;
doublestep=0;
if (inhmenu==false)
screen = (byte *) bufferofs;
else
screen = (byte *) displayofs;
if (inhmenu==false)
ThreeDRefresh ();
doublestep = 2 - DetailLevel;
//buffer = (byte *) SafeMalloc (65000);
buffer = (byte *) SafeMalloc ((iGLOBAL_SCREENHEIGHT*iGLOBAL_SCREENWIDTH)+4000);
#if (BETA == 1)
if (SCREENSHOTS == false)
{
if (screen!=(byte *)bufferofs)
{
tmp=bufferofs;
bufferofs=displayofs;
}
CurrentFont=tinyfont;
VGAMAPMASK(15);
for (i=-1;i<6;i++)
memset((byte *)bufferofs+(ylookup[i+SSY])+(SSX>>2),0,46);
px=SSX;
py=SSY;
VW_DrawPropString(" Rise of the Triad (c) 1995 Apogee Version ");
VW_DrawPropString(itoa(ROTTMAJORVERSION,&buf[0],10));
VW_DrawPropString(".");
VW_DrawPropString(itoa(ROTTMINORVERSION,&buf[0],10));
px=SSX+13;
py=SSY+8;
VW_DrawPropString(" Episode ");
VW_DrawPropString(itoa(gamestate.episode,&buf[0],10));
VW_DrawPropString(" Area ");
VW_DrawPropString(itoa(GetLevel(gamestate.episode, gamestate.mapon),&buf[0],10));
if (screen!=(byte *)bufferofs)
bufferofs=tmp;
}
#endif
GetFileName (saveLBM);
GetPathFromEnvironment( filename, ApogeePath, savename );
//
memcpy(buffer,screen , iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);//bna
//bna--VL_CopyPlanarPageToMemory(screen,buffer);
if (saveLBM)
{
WriteLBMfile (filename, buffer, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT);
#if (DEVELOPMENT == 1)
while (Keyboard[sc_CapsLock] && Keyboard[sc_C])
#else
while (Keyboard[sc_Alt] && Keyboard[sc_V])
#endif
IN_UpdateKeyboard ();
}
else
{
WritePCX (filename, buffer);
#if (DEVELOPMENT == 1)
while (Keyboard[sc_CapsLock] && Keyboard[sc_X])
#else
while (Keyboard[sc_Alt] && Keyboard[sc_C])
#endif
IN_UpdateKeyboard ();
}
SafeFree(buffer);
HUD=oldHUD;
}
//****************************************************************************
//
// WritePCX ()
//
//****************************************************************************
void WritePCX (char * file, byte * source)
{
PCX_HEADER pcxHDR;
byte *tempbuffer;
byte pal[0x300];
int pcxhandle;
int i, j, y;
unsigned char c;
unsigned char buffer1[GAP_SIZE];
pcxhandle = SafeOpenWrite (file);
/* --- init the header that we'll write.
* Note: since DPaint never reads & writes at the same time,
* it is okay to share the same read & write structure,
* unlike in CONVERT.EXE.
*/
memset (&pcxHDR, 0, sizeof(PCX_HEADER));
pcxHDR.manufacturer = 10;
pcxHDR.version = 5;
pcxHDR.encoding = 1;
pcxHDR.bitsperpixel = 8; //bpp;
pcxHDR.xmin = pcxHDR.ymin = 0;
pcxHDR.xmax = iGLOBAL_SCREENWIDTH - 1;
pcxHDR.ymax = iGLOBAL_SCREENHEIGHT - 1;
pcxHDR.hres = iGLOBAL_SCREENWIDTH; //N_COLUMNS;
pcxHDR.vres = iGLOBAL_SCREENHEIGHT; //N_LINES;
// bytesperline doesn't take into account multiple planes.
// Output in same format as bitmap (planar vs packed).
//
pcxHDR.bytesperline = iGLOBAL_SCREENWIDTH; //bitmap->width;
pcxHDR.nplanes = 1; //bitmap->planes;
pcxHDR.reserved = 0;
// First 16 colors of our palette info.
for (i = 0, j = 0; i < 16; ++i, j += 3) {
pcxHDR.colormap[i][0] = (unsigned char)(origpal[j]);
pcxHDR.colormap[i][1] = (unsigned char)(origpal[j]+2);
pcxHDR.colormap[i][2] = (unsigned char)(origpal[j]+3);
}
//
// Write the 128-byte header
//
SafeWrite(pcxhandle,&pcxHDR, sizeof (PCX_HEADER));
memset (buffer1, 0, GAP_SIZE);
SafeWrite (pcxhandle, &buffer1, GAP_SIZE);
tempbuffer = (byte *) SafeMalloc ((iGLOBAL_SCREENHEIGHT*iGLOBAL_SCREENWIDTH)+4000);
bptr = tempbuffer;
totalbytes = 0;
//
// Write to a bit-packed file.
//
for (y = 0; y < iGLOBAL_SCREENHEIGHT; ++y) // for each line in band
if (PutBytes (((unsigned char *) (source+(y*iGLOBAL_SCREENWIDTH))),
pcxHDR.bytesperline))
Error ("Error writing PCX bit-packed line!\n");
SafeWrite (pcxhandle, tempbuffer, totalbytes);
//
// Write out PCX palette
//
c = 0x0C;
for (i = 0; i < 0x300; i++)
pal[i] = (*(origpal+i))<<2;
SafeWrite (pcxhandle, &c, 1);
SafeWrite (pcxhandle, &pal[0], 768);
close (pcxhandle);
SafeFree (tempbuffer);
}
//****************************************************************************
//
// PutBytes ()
//
// Write bytes to a file, handling packing as it goes.
// Returns : 0 == SUCCESS
// 1 == FAIL.
//
//****************************************************************************
int PutBytes (unsigned char *ptr, unsigned int bytes)
{
unsigned int startbyte, count;
char b;
while (bytes > 0) {
// check for a repeating byte value
startbyte = *ptr;
*ptr++ = 0;
--bytes;
count = 1;
while (*ptr == startbyte && bytes > 0 && count < 63)
{
*ptr = 0;
++ptr;
--bytes;
++count;
}
// If we can pack the sequence, or if we have to add a
// byte before it because the top 2 bits of the value
// are 1's, write a packed sequence of 2 bytes.
// Otherwise, just write the byte value.
//
if (count > 1 || (startbyte & 0xc0) == 0xc0)
{
b = 0xc0 | count;
*bptr++ = b;
totalbytes++;
}
b = startbyte;
*bptr++ = b;
totalbytes++;
}
return (0);
}
#endif
//****************************************************************************
//
// PlayCinematic () - Play intro cinematics
//
//****************************************************************************
void PlayCinematic (void)
{
if ((tedlevel == true) || (turbo == true))
return;
switch (gamestate.mapon)
{
#if (SHAREWARE == 0)
byte pal[768];
case 0: // Start of EPISODE 1
MU_StartSong ( song_cinematic1 );
VL_FadeOut (0, 255, 0, 0, 0, 20);
VL_ClearBuffer (bufferofs, 0);
DrawNormalSprite(0,30,W_GetNumForName("nicolas"));
DrawNormalSprite(0,168,W_GetNumForName("oneyear"));
FlipPage();
memcpy(&pal[0],W_CacheLumpName("nicpal",PU_CACHE, CvtNull, 1),768);
VL_NormalizePalette(&pal[0]);
VL_FadeIn(0,255,pal,20);
I_Delay (60);
VL_FadeOut (0, 255, 0, 0, 0, 20);
IN_UpdateKeyboard();
if (LastScan!=0)
{
LastScan=0;
return;
}
SD_PlayPitchedSound(SD_LIGHTNINGSND,255,-1500);
DoInBetweenCinematic (20, W_GetNumForName("binoculr"), 80,
"The HUNT cases an\n"
"ancient monastery."
);
IN_UpdateKeyboard();
if (LastScan!=0)
{
LastScan=0;
return;
}
SD_Play(SD_NMESEESND);
DoInBetweenCinematic (20, W_GetNumForName("binosee"), 80,
"\"There they are,\" says\n"
"Cassatt. \"Let's get back\n"
"to the boat and inform HQ.\""
);
IN_UpdateKeyboard();
if (LastScan!=0)
{
LastScan=0;
return;
}
SD_Play(SD_HIGHGUARD1SEESND);
DoInBetweenCinematic (20, W_GetNumForName("boatgard"), 80,
"\"The intruders, on that hill!\""
);
IN_UpdateKeyboard();
if (LastScan!=0)
{
LastScan=0;
return;
}
SD_Play(SD_EXPLODESND);
DoInBetweenCinematic (20, W_GetNumForName("boatblow"), 80,
"\"There goes our ride home,\"\n"
"says Barrett. \"Looks like\n"
"the only way out is in....\""
);
IN_UpdateKeyboard();
LastScan=0;
break;
case 8: // Start of EPISODE 2
MU_StartSong ( song_cinematic2 );
DoInBetweenCinematic (0, W_GetNumForName("epi12"), 1200,
"The HUNT makes their way\n"
"into the main keep."
);
IN_UpdateKeyboard();
LastScan=0;
break;
case 16: // Start of EPISODE 3
MU_StartSong ( song_cinematic1 );
DoInBetweenCinematic (20, W_GetNumForName("epi23"), 1200,
"The HUNT stands before a pair\n"
"of ominous wooden doors.\n"
"The sounds of machinery and\n"
"servomotors fill the air.\n"
);
IN_UpdateKeyboard();
LastScan=0;
break;
case 24: // Start of EPISODE 4
MU_StartSong ( song_cinematic2 );
DoInBetweenCinematic (0, W_GetNumForName("epi34"), 1200,
"Stairs lead down beneath the\n"
"keep. From behind the doors\n"
"come the moans of the undead."
);
IN_UpdateKeyboard();
LastScan=0;
break;
#endif
}
}