2019-09-19 22:42:45 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 Nuke . YKT
This file is part of NBlood .
NBlood is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation .
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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
//-------------------------------------------------------------------------
2019-09-21 18:59:54 +00:00
# include "ns.h" // Must come before everything else!
2019-09-19 22:42:45 +00:00
# include "build.h"
2020-08-16 07:46:37 +00:00
# include "g_input.h"
2020-09-06 10:44:58 +00:00
# include "automap.h"
2019-09-19 22:42:45 +00:00
# include "blood.h"
# include "choke.h"
2020-12-09 14:56:32 +00:00
2019-09-19 22:42:45 +00:00
# include "view.h"
2020-07-25 22:07:59 +00:00
# include "misc.h"
2019-10-26 18:47:37 +00:00
# include "gameconfigfile.h"
2019-11-01 18:25:42 +00:00
# include "gamecontrol.h"
# include "m_argv.h"
2019-11-12 21:59:51 +00:00
# include "statistics.h"
2020-10-04 16:31:48 +00:00
# include "razemenu.h"
2020-04-12 06:09:38 +00:00
# include "raze_sound.h"
2020-07-25 22:07:59 +00:00
# include "secrets.h"
2020-07-29 21:18:08 +00:00
# include "gamestate.h"
2021-05-21 23:34:00 +00:00
# include "screenjob_.h"
2020-08-16 11:26:57 +00:00
# include "mapinfo.h"
2020-09-01 21:34:04 +00:00
# include "d_net.h"
# include "v_video.h"
2020-10-04 16:31:48 +00:00
# include "v_draw.h"
2020-10-06 18:05:51 +00:00
# include "texturemanager.h"
2020-09-08 16:28:41 +00:00
# include "statusbar.h"
2021-04-28 18:16:13 +00:00
# include "vm.h"
2019-09-19 22:42:45 +00:00
2019-09-22 06:39:22 +00:00
BEGIN_BLD_NS
2020-08-03 18:51:31 +00:00
void InitCheats ( ) ;
2019-09-22 06:39:22 +00:00
2019-09-19 22:42:45 +00:00
bool bNoDemo = false ;
int gNetPlayers ;
int gChokeCounter = 0 ;
int blood_globalflags ;
2020-09-01 21:34:04 +00:00
PLAYER gPlayerTemp [ kMaxPlayers ] ;
int gHealthTemp [ kMaxPlayers ] ;
vec3_t startpos ;
2021-11-16 17:20:24 +00:00
int16_t startang ;
2021-11-23 23:55:57 +00:00
sectortype * startsector ;
2020-09-01 21:34:04 +00:00
2019-09-19 22:42:45 +00:00
void QuitGame ( void )
{
2020-09-01 21:34:04 +00:00
throw CExitEvent ( 0 ) ;
2019-09-19 22:42:45 +00:00
}
void EndLevel ( void )
{
2020-09-01 21:34:04 +00:00
gViewPos = VIEWPOS_0 ;
sndKillAllSounds ( ) ;
sfxKillAllSounds ( ) ;
ambKillAll ( ) ;
seqKillAll ( ) ;
2019-09-19 22:42:45 +00:00
}
2021-05-02 07:08:57 +00:00
void StartLevel ( MapRecord * level , bool newgame )
2019-09-19 22:42:45 +00:00
{
2020-09-01 21:34:04 +00:00
if ( ! level ) return ;
2020-09-02 05:47:26 +00:00
gFrameCount = 0 ;
2021-02-18 10:46:36 +00:00
PlayClock = 0 ;
2020-09-01 21:34:04 +00:00
EndLevel ( ) ;
2020-09-23 14:20:40 +00:00
inputState . ClearAllInput ( ) ;
2020-09-01 21:34:04 +00:00
currentLevel = level ;
if ( gGameOptions . nGameType = = 0 )
{
///////
2021-08-02 14:47:05 +00:00
gGameOptions . weaponsV10x = cl_bloodoldweapbalance ;
2020-09-01 21:34:04 +00:00
///////
}
2020-08-16 11:26:57 +00:00
#if 0
2021-05-02 07:08:57 +00:00
else if ( gGameOptions . nGameType > 0 & & newgame )
2020-09-01 21:34:04 +00:00
{
// todo
gBlueFlagDropped = false ;
gRedFlagDropped = false ;
}
2020-08-16 11:26:57 +00:00
# endif
2021-05-02 07:08:57 +00:00
if ( ! newgame )
2020-09-01 21:34:04 +00:00
{
for ( int i = connecthead ; i > = 0 ; i = connectpoint2 [ i ] )
{
memcpy ( & gPlayerTemp [ i ] , & gPlayer [ i ] , sizeof ( PLAYER ) ) ;
2021-09-05 07:53:06 +00:00
gHealthTemp [ i ] = gPlayer [ i ] . actor - > x ( ) . health ;
2020-09-01 21:34:04 +00:00
}
}
//drawLoadingScreen();
2021-11-23 23:55:57 +00:00
dbLoadMap ( currentLevel - > fileName , ( int * ) & startpos . x , ( int * ) & startpos . y , ( int * ) & startpos . z , & startang , & startsector , nullptr ) ;
2020-09-01 21:34:04 +00:00
SECRET_SetMapName ( currentLevel - > DisplayName ( ) , currentLevel - > name ) ;
2020-04-01 20:34:49 +00:00
STAT_NewLevel ( currentLevel - > fileName ) ;
2020-09-01 21:34:04 +00:00
wsrand ( dbReadMapCRC ( currentLevel - > LabelName ( ) ) ) ;
gKillMgr . Clear ( ) ;
gSecretMgr . Clear ( ) ;
automapping = 1 ;
2021-12-03 20:36:32 +00:00
// Here is where later the actors must be spawned.
// get a sorted list of all actors as we need to run some init code in spawn order. (iterating bloodActors would actually do, but that won't last forever)
TArray < DBloodActor * > actorlist ;
BloodSpriteIterator sit ;
while ( auto act = sit . Next ( ) )
{
actorlist . Push ( act ) ;
}
std : : sort ( actorlist . begin ( ) , actorlist . end ( ) , [ ] ( DBloodActor * a , DBloodActor * b ) { return a - > GetIndex ( ) < b - > GetIndex ( ) ; } ) ;
2020-09-01 21:34:04 +00:00
int modernTypesErased = 0 ;
2021-12-03 20:36:32 +00:00
for ( unsigned i = 0 ; i < actorlist . Size ( ) ; i + + )
2020-09-01 21:34:04 +00:00
{
2021-12-03 20:36:32 +00:00
auto actor = actorlist [ i ] ;
2021-08-27 12:11:59 +00:00
spritetype * pSprite = & actor - > s ( ) ;
2021-12-03 20:36:32 +00:00
if ( actor - > exists ( ) & & actor - > hasX ( ) )
2021-08-27 12:11:59 +00:00
{
2020-09-01 21:34:04 +00:00
2021-08-27 12:11:59 +00:00
XSPRITE * pXSprite = & actor - > x ( ) ;
2020-09-01 21:34:04 +00:00
if ( ( pXSprite - > lSkill & ( 1 < < gGameOptions . nDifficulty ) ) | | ( pXSprite - > lS & & gGameOptions . nGameType = = 0 )
| | ( pXSprite - > lB & & gGameOptions . nGameType = = 2 ) | | ( pXSprite - > lT & & gGameOptions . nGameType = = 3 )
| | ( pXSprite - > lC & & gGameOptions . nGameType = = 1 ) ) {
2021-09-04 10:47:34 +00:00
DeleteSprite ( actor ) ;
2020-09-01 21:34:04 +00:00
continue ;
}
# ifdef NOONE_EXTENSIONS
2021-08-27 12:11:59 +00:00
if ( ! gModernMap & & nnExtEraseModernStuff ( actor ) )
2020-09-01 21:34:04 +00:00
modernTypesErased + + ;
# endif
}
}
# ifdef NOONE_EXTENSIONS
if ( ! gModernMap & & modernTypesErased > 0 )
Printf ( PRINT_NONOTIFY , " > Modern types erased: %d. \n " , modernTypesErased ) ;
# endif
2021-11-23 23:55:57 +00:00
startpos . z = getflorzofslopeptr ( startsector , startpos . x , startpos . y ) ;
2020-09-01 21:34:04 +00:00
for ( int i = 0 ; i < kMaxPlayers ; i + + ) {
gStartZone [ i ] . x = startpos . x ;
gStartZone [ i ] . y = startpos . y ;
gStartZone [ i ] . z = startpos . z ;
2021-11-23 23:55:57 +00:00
gStartZone [ i ] . sector = startsector ;
2020-09-01 21:34:04 +00:00
gStartZone [ i ] . ang = startang ;
# ifdef NOONE_EXTENSIONS
// Create spawn zones for players in teams mode.
if ( gModernMap & & i < = kMaxPlayers / 2 ) {
gStartZoneTeam1 [ i ] . x = startpos . x ;
gStartZoneTeam1 [ i ] . y = startpos . y ;
gStartZoneTeam1 [ i ] . z = startpos . z ;
2021-11-23 23:55:57 +00:00
gStartZoneTeam1 [ i ] . sector = startsector ;
2020-09-01 21:34:04 +00:00
gStartZoneTeam1 [ i ] . ang = startang ;
gStartZoneTeam2 [ i ] . x = startpos . x ;
gStartZoneTeam2 [ i ] . y = startpos . y ;
gStartZoneTeam2 [ i ] . z = startpos . z ;
2021-11-23 23:55:57 +00:00
gStartZoneTeam2 [ i ] . sector = startsector ;
2020-09-01 21:34:04 +00:00
gStartZoneTeam2 [ i ] . ang = startang ;
}
# endif
}
InitSectorFX ( ) ;
2021-12-03 20:36:32 +00:00
warpInit ( actorlist ) ;
actInit ( actorlist ) ;
evInit ( actorlist ) ;
2020-09-01 21:34:04 +00:00
for ( int i = connecthead ; i > = 0 ; i = connectpoint2 [ i ] )
{
2021-05-02 07:08:57 +00:00
if ( newgame )
2020-09-01 21:34:04 +00:00
{
playerInit ( i , 0 ) ;
}
playerStart ( i , 1 ) ;
}
2021-05-02 07:08:57 +00:00
if ( ! newgame )
2020-09-01 21:34:04 +00:00
{
for ( int i = connecthead ; i > = 0 ; i = connectpoint2 [ i ] )
{
PLAYER * pPlayer = & gPlayer [ i ] ;
pPlayer - > pXSprite - > health & = 0xf000 ;
pPlayer - > pXSprite - > health | = gHealthTemp [ i ] ;
pPlayer - > weaponQav = gPlayerTemp [ i ] . weaponQav ;
pPlayer - > curWeapon = gPlayerTemp [ i ] . curWeapon ;
pPlayer - > weaponState = gPlayerTemp [ i ] . weaponState ;
pPlayer - > weaponAmmo = gPlayerTemp [ i ] . weaponAmmo ;
pPlayer - > qavCallback = gPlayerTemp [ i ] . qavCallback ;
pPlayer - > qavLoop = gPlayerTemp [ i ] . qavLoop ;
pPlayer - > weaponTimer = gPlayerTemp [ i ] . weaponTimer ;
pPlayer - > nextWeapon = gPlayerTemp [ i ] . nextWeapon ;
2021-08-05 02:38:26 +00:00
pPlayer - > qavLastTick = gPlayerTemp [ i ] . qavLastTick ;
pPlayer - > qavTimer = gPlayerTemp [ i ] . qavTimer ;
2020-09-01 21:34:04 +00:00
}
}
PreloadCache ( ) ;
InitMirrors ( ) ;
2021-12-03 20:36:32 +00:00
trInit ( actorlist ) ;
2020-09-16 00:14:04 +00:00
if ( ! gMe - > packSlots [ 1 ] . isActive ) // if diving suit is not active, turn off reverb sound effect
2020-09-01 21:34:04 +00:00
sfxSetReverb ( 0 ) ;
ambInit ( ) ;
Net_ClearFifo ( ) ;
gChokeCounter = 0 ;
2020-07-27 22:01:16 +00:00
M_ClearMenus ( ) ;
2020-09-01 21:34:04 +00:00
// viewSetMessage("");
viewSetErrorMessage ( " " ) ;
paused = 0 ;
levelTryPlayMusic ( ) ;
2020-09-01 18:08:37 +00:00
gChoke . reset ( ) ;
2020-09-08 16:28:41 +00:00
setLevelStarted ( level ) ;
2019-09-19 22:42:45 +00:00
}
2019-09-24 02:14:59 +00:00
2021-05-02 07:08:57 +00:00
void NewLevel ( MapRecord * sng , int skill , bool newgame )
2020-09-01 21:34:04 +00:00
{
2021-04-28 18:16:13 +00:00
if ( skill ! = - 1 ) gGameOptions . nDifficulty = skill ;
gSkill = gGameOptions . nDifficulty ;
2021-05-02 07:08:57 +00:00
StartLevel ( sng , newgame ) ;
2021-04-28 18:16:13 +00:00
gameaction = ga_level ;
2020-09-01 21:34:04 +00:00
}
2021-04-15 16:50:48 +00:00
void GameInterface : : NewGame ( MapRecord * sng , int skill , bool )
2020-09-04 18:46:44 +00:00
{
gGameOptions . uGameFlags = 0 ;
2020-10-10 18:20:12 +00:00
cheatReset ( ) ;
2021-05-02 07:08:57 +00:00
NewLevel ( sng , skill , true ) ;
2020-09-04 18:46:44 +00:00
}
2020-09-01 21:34:04 +00:00
2020-09-04 18:46:44 +00:00
void GameInterface : : NextLevel ( MapRecord * map , int skill )
{
2021-05-02 07:08:57 +00:00
NewLevel ( map , skill , false ) ;
2020-09-04 18:46:44 +00:00
}
2020-09-01 21:34:04 +00:00
2021-07-20 08:50:46 +00:00
int GameInterface : : GetCurrentSkill ( )
{
return gGameOptions . nDifficulty ;
}
2020-09-01 21:34:04 +00:00
void GameInterface : : Ticker ( )
2019-09-19 22:42:45 +00:00
{
2020-09-01 21:34:04 +00:00
for ( int i = connecthead ; i > = 0 ; i = connectpoint2 [ i ] )
{
auto & inp = gPlayer [ i ] . input ;
auto oldactions = inp . actions ;
inp = playercmds [ i ] . ucmd ;
inp . actions | = oldactions & ~ ( SB_BUTTON_MASK | SB_RUN | SB_WEAPONMASK_BITS ) ; // should be everything non-button and non-weapon
int newweap = inp . getNewWeapon ( ) ;
if ( newweap > 0 & & newweap < WeaponSel_MaxBlood ) gPlayer [ i ] . newWeapon = newweap ;
}
2021-09-05 10:35:13 +00:00
BloodSpriteIterator it ;
while ( DBloodActor * act = it . Next ( ) ) act - > interpolated = false ;
2020-11-26 16:19:42 +00:00
ClearMovementInterpolations ( ) ;
UpdateInterpolations ( ) ;
2020-09-02 05:47:26 +00:00
2020-09-02 05:11:47 +00:00
if ( ! ( paused | | ( gGameOptions . nGameType = = 0 & & M_Active ( ) ) ) )
2020-09-01 21:34:04 +00:00
{
2020-09-02 05:11:47 +00:00
thinktime . Reset ( ) ;
thinktime . Clock ( ) ;
for ( int i = connecthead ; i > = 0 ; i = connectpoint2 [ i ] )
{
viewBackupView ( i ) ;
playerProcess ( & gPlayer [ i ] ) ;
}
2020-09-01 21:34:04 +00:00
2020-09-02 05:11:47 +00:00
trProcessBusy ( ) ;
2021-02-18 10:46:36 +00:00
evProcess ( PlayClock ) ;
2020-09-02 05:11:47 +00:00
seqProcess ( 4 ) ;
DoSectorPanning ( ) ;
actortime . Reset ( ) ;
actortime . Clock ( ) ;
actProcessSprites ( ) ;
actPostProcess ( ) ;
actortime . Unclock ( ) ;
viewCorrectPrediction ( ) ;
ambProcess ( ) ;
viewUpdateDelirium ( ) ;
gi - > UpdateSounds ( ) ;
if ( gMe - > hand = = 1 )
2020-09-01 21:34:04 +00:00
{
2020-09-02 05:11:47 +00:00
const int CHOKERATE = 8 ;
const int COUNTRATE = 30 ;
gChokeCounter + = CHOKERATE ;
while ( gChokeCounter > = COUNTRATE )
{
2020-11-21 14:45:37 +00:00
gChoke . callback ( gMe ) ;
2020-09-02 05:11:47 +00:00
gChokeCounter - = COUNTRATE ;
}
2020-09-01 21:34:04 +00:00
}
2020-09-02 05:11:47 +00:00
thinktime . Unclock ( ) ;
2020-09-01 21:34:04 +00:00
2020-09-02 05:11:47 +00:00
gFrameCount + + ;
2021-02-18 10:46:36 +00:00
PlayClock + = kTicsPerFrame ;
if ( PlayClock = = 8 ) gameaction = ga_autosave ; // let the game run for 1 frame before saving.
2020-09-01 21:34:04 +00:00
2020-09-02 05:11:47 +00:00
for ( int i = 0 ; i < 8 ; i + + )
{
2021-11-14 12:33:35 +00:00
team_ticker [ i ] - = 4 ;
2020-11-22 12:16:58 +00:00
if ( team_ticker [ i ] < 0 )
team_ticker [ i ] = 0 ;
2020-09-02 05:11:47 +00:00
}
2020-09-01 18:14:15 +00:00
2021-05-02 07:08:57 +00:00
if ( gGameOptions . uGameFlags & GF_AdvanceLevel )
2020-09-01 21:34:04 +00:00
{
2021-05-02 07:08:57 +00:00
gGameOptions . uGameFlags & = ~ GF_AdvanceLevel ;
2020-09-02 05:11:47 +00:00
seqKillAll ( ) ;
2021-05-02 07:08:57 +00:00
STAT_Update ( gNextLevel = = nullptr ) ;
CompleteLevel ( gNextLevel ) ;
2020-09-01 21:34:04 +00:00
}
2020-09-02 05:11:47 +00:00
r_NoInterpolate = false ;
2020-09-01 21:34:04 +00:00
}
2020-09-02 05:11:47 +00:00
else r_NoInterpolate = true ;
2020-09-01 21:34:04 +00:00
}
void GameInterface : : DrawBackground ( )
{
twod - > ClearScreen ( ) ;
2021-05-18 22:07:50 +00:00
auto tex = TexMan . CheckForTexture ( " titlescreen " , ETextureType : : Any ) ;
DrawTexture ( twod , TexMan . GetGameTexture ( tex ) , 0 , 0 , DTA_FullscreenEx , FSMode_ScaleToFit43 , TAG_DONE ) ;
2019-09-19 22:42:45 +00:00
}
2020-10-06 18:05:51 +00:00
# define x(a, b) registerName(#a, b);
static void SetTileNames ( )
{
auto registerName = [ ] ( const char * name , int index )
{
TexMan . AddAlias ( name , tileGetTexture ( index ) ) ;
} ;
# include "namelist.h"
2021-05-18 22:07:50 +00:00
// Oh Joy! Plasma Pak changes the tile number of the title screen, but we preferably want mods that use the original one to display it.
// So let's make this remapping depend on the CRC.
if ( tileGetCRC32 ( 2518 ) = = 1170870757 & & ( tileGetCRC32 ( 2046 ) ! = 290208654 | | tileWidth ( 2518 ) = = 0 ) ) registerName ( " titlescreen " , 2046 ) ;
else registerName ( " titlescreen " , 2518 ) ;
2020-10-06 18:05:51 +00:00
}
# undef x
2019-10-28 21:19:50 +00:00
2019-09-19 22:42:45 +00:00
2020-01-22 20:09:45 +00:00
void ReadAllRFS ( ) ;
2020-11-10 21:07:45 +00:00
void GameInterface : : loadPalette ( void )
{
// in nearly typical Blood fashion it had to use an inverse of the original translucency settings...
static glblend_t const bloodglblend =
{
{
{ 1.f / 3.f , STYLEALPHA_Src , STYLEALPHA_InvSrc , 0 } ,
{ 2.f / 3.f , STYLEALPHA_Src , STYLEALPHA_InvSrc , 0 } ,
} ,
} ;
static const char * PLU [ 15 ] = {
" NORMAL.PLU " ,
" SATURATE.PLU " ,
" BEAST.PLU " ,
" TOMMY.PLU " ,
" SPIDER3.PLU " ,
" GRAY.PLU " ,
" GRAYISH.PLU " ,
" SPIDER1.PLU " ,
" SPIDER2.PLU " ,
" FLAME.PLU " ,
" COLD.PLU " ,
" P1.PLU " ,
" P2.PLU " ,
" P3.PLU " ,
" P4.PLU "
} ;
static const char * PAL [ 5 ] = {
" BLOOD.PAL " ,
" WATER.PAL " ,
" BEAST.PAL " ,
" SEWER.PAL " ,
" INVULN1.PAL "
} ;
for ( auto & x : glblend ) x = bloodglblend ;
for ( int i = 0 ; i < 5 ; i + + )
{
auto pal = fileSystem . LoadFile ( PAL [ i ] ) ;
if ( pal . Size ( ) < 768 ) I_FatalError ( " %s: file too small " , PAL [ i ] ) ;
paletteSetColorTable ( i , pal . Data ( ) , false , false ) ;
}
numshades = 64 ;
for ( int i = 0 ; i < MAXPALOOKUPS ; i + + )
{
int lump = i < 15 ? fileSystem . FindFile ( PLU [ i ] ) : fileSystem . FindResource ( i , " PLU " ) ;
if ( lump < 0 )
{
if ( i < 15 ) I_FatalError ( " %s: file not found " , PLU [ i ] ) ;
else continue ;
}
auto data = fileSystem . GetFileData ( lump ) ;
if ( data . Size ( ) ! = 64 * 256 )
{
if ( i < 15 ) I_FatalError ( " %s: Incorrect PLU size " , PLU [ i ] ) ;
else continue ;
}
lookups . setTable ( i , data . Data ( ) ) ;
}
lookups . setFadeColor ( 1 , 255 , 255 , 255 ) ;
paletteloaded = PALETTE_SHADE | PALETTE_TRANSLUC | PALETTE_MAIN ;
}
2020-08-23 15:47:05 +00:00
void GameInterface : : app_init ( )
2019-09-19 22:42:45 +00:00
{
2021-11-25 20:42:49 +00:00
for ( int i = 0 ; i < MAXSPRITES ; i + + )
{
actorArray [ i ] = & bloodActors [ i ] ;
}
2020-09-01 21:34:04 +00:00
InitCheats ( ) ;
memcpy ( & gGameOptions , & gSingleGameOptions , sizeof ( GAMEOPTIONS ) ) ;
gGameOptions . nMonsterSettings = ! userConfig . nomonsters ;
ReadAllRFS ( ) ;
HookReplaceFunctions ( ) ;
levelLoadDefaults ( ) ;
2021-04-28 18:16:13 +00:00
//---------
2020-10-06 18:05:51 +00:00
SetTileNames ( ) ;
2020-10-25 14:31:20 +00:00
C_InitConback ( TexMan . CheckForTexture ( " BACKTILE " , ETextureType : : Any ) , true , 0.25 ) ;
2020-09-01 21:34:04 +00:00
Printf ( PRINT_NONOTIFY , " Initializing view subsystem \n " ) ;
viewInit ( ) ;
Printf ( PRINT_NONOTIFY , " Initializing dynamic fire \n " ) ;
FireInit ( ) ;
Printf ( PRINT_NONOTIFY , " Initializing weapon animations \n " ) ;
WeaponInit ( ) ;
2021-05-02 16:10:59 +00:00
Printf ( PRINT_NONOTIFY , " Initializing sound system \n " ) ;
sndInit ( ) ;
2020-09-01 21:34:04 +00:00
myconnectindex = connecthead = 0 ;
gNetPlayers = numplayers = 1 ;
connectpoint2 [ 0 ] = - 1 ;
gGameOptions . nGameType = 0 ;
UpdateNetworkMenus ( ) ;
2020-11-21 19:10:45 +00:00
gChoke . init ( 518 , chokeCallback ) ;
2020-09-01 21:34:04 +00:00
UpdateDacs ( 0 , true ) ;
2020-09-16 00:14:04 +00:00
enginecompatibility_mode = ENGINECOMPATIBILITY_19960925 ;
2021-06-26 08:11:50 +00:00
gViewIndex = myconnectindex ;
gMe = gView = & gPlayer [ myconnectindex ] ;
2020-07-29 21:18:08 +00:00
}
2020-01-23 10:50:12 +00:00
2020-07-29 21:18:08 +00:00
static void gameInit ( )
{
2020-09-01 21:34:04 +00:00
gViewIndex = myconnectindex ;
gMe = gView = & gPlayer [ myconnectindex ] ;
2020-07-29 21:18:08 +00:00
UpdateNetworkMenus ( ) ;
2020-09-01 21:34:04 +00:00
if ( gGameOptions . nGameType > 0 )
{
inputState . ClearAllInput ( ) ;
}
2020-07-29 21:18:08 +00:00
}
2020-01-29 13:19:05 +00:00
2020-09-01 21:34:04 +00:00
void GameInterface : : Startup ( )
2020-07-29 21:18:08 +00:00
{
2020-09-01 21:34:04 +00:00
gameInit ( ) ;
2021-04-27 18:04:11 +00:00
PlayLogos ( ga_mainmenu , ga_mainmenu , true ) ;
2020-07-29 21:18:08 +00:00
}
2020-01-30 13:05:34 +00:00
2020-09-01 21:34:04 +00:00
2020-07-29 21:18:08 +00:00
2020-09-01 21:34:04 +00:00
void GameInterface : : Render ( )
2020-07-29 21:18:08 +00:00
{
2020-09-01 21:34:04 +00:00
drawtime . Reset ( ) ;
drawtime . Clock ( ) ;
viewDrawScreen ( ) ;
drawtime . Unclock ( ) ;
2019-09-19 22:42:45 +00:00
}
2019-06-28 12:45:39 +00:00
void sndPlaySpecialMusicOrNothing ( int nMusic )
{
2021-05-11 23:58:42 +00:00
if ( ! Mus_Play ( quoteMgr . GetQuote ( nMusic ) , true ) )
2020-09-01 21:34:04 +00:00
{
Mus_Stop ( ) ;
}
2019-06-28 12:45:39 +00:00
}
2019-09-21 20:53:00 +00:00
2019-12-24 18:47:34 +00:00
extern IniFile * BloodINI ;
void GameInterface : : FreeGameData ( )
{
2020-09-01 21:34:04 +00:00
if ( BloodINI ) delete BloodINI ;
2019-12-24 18:47:34 +00:00
}
2020-09-03 21:10:28 +00:00
void GameInterface : : FreeLevelData ( )
{
EndLevel ( ) ;
: : GameInterface : : FreeLevelData ( ) ;
}
2020-08-16 00:55:50 +00:00
ReservedSpace GameInterface : : GetReservedScreenSpace ( int viewsize )
2020-01-01 08:49:06 +00:00
{
2020-09-01 21:34:04 +00:00
int top = 0 ;
if ( gGameOptions . nGameType > 0 & & gGameOptions . nGameType < = 3 )
{
2020-11-22 23:18:07 +00:00
top = ( tileHeight ( 2229 ) * ( ( gNetPlayers + 3 ) / 4 ) ) ;
2020-09-01 21:34:04 +00:00
}
return { top , 25 } ;
2020-01-01 08:49:06 +00:00
}
2019-11-03 11:32:58 +00:00
: : GameInterface * CreateInterface ( )
{
return new GameInterface ;
}
2019-09-22 06:39:22 +00:00
2021-04-28 18:16:13 +00:00
enum
{
kLoadScreenCRC = - 2051908571 ,
kLoadScreenWideBackWidth = 256 ,
kLoadScreenWideSideWidth = 128 ,
} ;
DEFINE_ACTION_FUNCTION ( _Blood , OriginalLoadScreen )
{
static int bLoadScreenCrcMatch = - 1 ;
if ( bLoadScreenCrcMatch = = - 1 ) bLoadScreenCrcMatch = tileGetCRC32 ( kLoadScreen ) = = kLoadScreenCRC ;
ACTION_RETURN_INT ( bLoadScreenCrcMatch ) ;
}
DEFINE_ACTION_FUNCTION ( _Blood , PlayIntroMusic )
{
2021-05-11 23:58:42 +00:00
Mus_Play ( " PESTIS.MID " , false ) ;
2021-04-28 18:16:13 +00:00
return 0 ;
}
DEFINE_ACTION_FUNCTION ( _Blood , sndStartSample )
{
PARAM_PROLOGUE ;
PARAM_INT ( id ) ;
PARAM_INT ( vol ) ;
PARAM_INT ( chan ) ;
PARAM_BOOL ( looped ) ;
PARAM_INT ( chanflags ) ;
sndStartSample ( id , vol , chan , looped , EChanFlags : : FromInt ( chanflags ) ) ;
return 0 ;
}
DEFINE_ACTION_FUNCTION ( _Blood , sndStartSampleNamed )
{
PARAM_PROLOGUE ;
PARAM_STRING ( id ) ;
PARAM_INT ( vol ) ;
PARAM_INT ( chan ) ;
sndStartSample ( id , vol , chan ) ;
return 0 ;
}
2021-05-11 20:21:52 +00:00
DEFINE_ACTION_FUNCTION ( _Blood , PowerupIcon )
{
PARAM_PROLOGUE ;
PARAM_INT ( pwup ) ;
int tile = - 1 ;
if ( pwup > = 0 & & pwup < ( int ) countof ( gPowerUpInfo ) )
{
tile = gPowerUpInfo [ pwup ] . picnum ;
}
FGameTexture * tex = tileGetTexture ( tile ) ;
ACTION_RETURN_INT ( tex ? tex - > GetID ( ) . GetIndex ( ) : - 1 ) ;
}
DEFINE_ACTION_FUNCTION ( _Blood , GetViewPlayer )
{
PARAM_PROLOGUE ;
ACTION_RETURN_POINTER ( gView ) ;
}
DEFINE_ACTION_FUNCTION ( _BloodPlayer , GetHealth )
{
PARAM_SELF_STRUCT_PROLOGUE ( PLAYER ) ;
XSPRITE * pXSprite = self - > pXSprite ;
ACTION_RETURN_INT ( pXSprite - > health ) ;
}
DEFINE_ACTION_FUNCTION_NATIVE ( _BloodPlayer , powerupCheck , powerupCheck )
{
PARAM_SELF_STRUCT_PROLOGUE ( PLAYER ) ;
PARAM_INT ( pwup ) ;
ACTION_RETURN_INT ( powerupCheck ( self , pwup ) ) ;
}
2019-09-22 06:39:22 +00:00
END_BLD_NS