This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/common/host_state.c

201 lines
4.7 KiB
C
Raw Normal View History

2018-02-25 22:00:00 +01:00
/*
host_cmd.c - dedicated and normal host
Copyright (C) 2017 Uncle Mike
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 3 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.
*/
#include "common.h"
void COM_InitHostState( void )
{
memset( GameState, 0, sizeof( game_status_t ));
}
2018-02-27 22:00:00 +01:00
static void Host_SetState( host_state_t newState, qboolean clearNext )
2018-02-25 22:00:00 +01:00
{
if( clearNext )
GameState->nextstate = newState;
GameState->curstate = newState;
2018-09-08 23:00:00 +02:00
if( clearNext && newState == STATE_RUNFRAME )
{
// states finished here
GameState->backgroundMap = false;
GameState->loadGame = false;
GameState->newGame = false;
}
2018-02-25 22:00:00 +01:00
}
2018-02-27 22:00:00 +01:00
static void Host_SetNextState( host_state_t nextState )
2018-02-25 22:00:00 +01:00
{
ASSERT( GameState->curstate == STATE_RUNFRAME );
GameState->nextstate = nextState;
}
void COM_NewGame( char const *pMapName )
{
2018-02-27 22:00:00 +01:00
if( GameState->nextstate != STATE_RUNFRAME )
return;
2018-09-28 23:00:00 +02:00
if( UI_CreditsActive( ))
return;
2018-02-25 22:00:00 +01:00
Q_strncpy( GameState->levelName, pMapName, sizeof( GameState->levelName ));
2018-02-27 22:00:00 +01:00
Host_SetNextState( STATE_LOAD_LEVEL );
2018-02-25 22:00:00 +01:00
GameState->backgroundMap = false;
GameState->landmarkName[0] = 0;
2018-03-04 22:00:00 +01:00
GameState->loadGame = false;
2018-02-25 22:00:00 +01:00
GameState->newGame = true;
}
void COM_LoadLevel( char const *pMapName, qboolean background )
{
2018-02-27 22:00:00 +01:00
if( GameState->nextstate != STATE_RUNFRAME )
return;
2018-09-28 23:00:00 +02:00
if( UI_CreditsActive( ))
return;
2018-02-25 22:00:00 +01:00
Q_strncpy( GameState->levelName, pMapName, sizeof( GameState->levelName ));
2018-02-27 22:00:00 +01:00
Host_SetNextState( STATE_LOAD_LEVEL );
2018-02-25 22:00:00 +01:00
GameState->backgroundMap = background;
GameState->landmarkName[0] = 0;
2018-03-04 22:00:00 +01:00
GameState->loadGame = false;
2018-02-25 22:00:00 +01:00
GameState->newGame = false;
}
void COM_LoadGame( char const *pMapName )
{
2018-02-27 22:00:00 +01:00
if( GameState->nextstate != STATE_RUNFRAME )
return;
2018-09-28 23:00:00 +02:00
if( UI_CreditsActive( ))
return;
2018-02-25 22:00:00 +01:00
Q_strncpy( GameState->levelName, pMapName, sizeof( GameState->levelName ));
2018-02-27 22:00:00 +01:00
Host_SetNextState( STATE_LOAD_GAME );
2018-02-25 22:00:00 +01:00
GameState->backgroundMap = false;
GameState->newGame = false;
GameState->loadGame = true;
}
2018-03-08 22:00:00 +01:00
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName, qboolean background )
2018-02-25 22:00:00 +01:00
{
2018-02-27 22:00:00 +01:00
if( GameState->nextstate != STATE_RUNFRAME )
return;
2018-09-28 23:00:00 +02:00
if( UI_CreditsActive( ))
return;
2018-02-25 22:00:00 +01:00
Q_strncpy( GameState->levelName, pNewLevel, sizeof( GameState->levelName ));
2018-03-08 22:00:00 +01:00
GameState->backgroundMap = background;
2018-02-25 22:00:00 +01:00
if( COM_CheckString( pLandmarkName ))
{
Q_strncpy( GameState->landmarkName, pLandmarkName, sizeof( GameState->landmarkName ));
GameState->loadGame = true;
}
else
{
GameState->landmarkName[0] = 0;
GameState->loadGame = false;
}
2018-02-27 22:00:00 +01:00
Host_SetNextState( STATE_CHANGELEVEL );
2018-02-25 22:00:00 +01:00
GameState->newGame = false;
}
2018-02-27 22:00:00 +01:00
void Host_ShutdownGame( void )
2018-02-25 22:00:00 +01:00
{
2018-02-27 22:00:00 +01:00
SV_ShutdownGame();
2018-02-25 22:00:00 +01:00
switch( GameState->nextstate )
{
case STATE_LOAD_GAME:
case STATE_LOAD_LEVEL:
2018-02-27 22:00:00 +01:00
Host_SetState( GameState->nextstate, true );
2018-02-25 22:00:00 +01:00
break;
default:
2018-02-27 22:00:00 +01:00
Host_SetState( STATE_RUNFRAME, true );
2018-02-25 22:00:00 +01:00
break;
}
}
2018-02-27 22:00:00 +01:00
void Host_RunFrame( float time )
2018-02-25 22:00:00 +01:00
{
// engine main frame
Host_Frame( time );
switch( GameState->nextstate )
{
case STATE_RUNFRAME:
break;
case STATE_LOAD_GAME:
case STATE_LOAD_LEVEL:
SCR_BeginLoadingPlaque( GameState->backgroundMap );
// intentionally fallthrough
case STATE_GAME_SHUTDOWN:
2018-02-27 22:00:00 +01:00
Host_SetState( STATE_GAME_SHUTDOWN, false );
2018-02-25 22:00:00 +01:00
break;
case STATE_CHANGELEVEL:
2018-03-08 22:00:00 +01:00
SCR_BeginLoadingPlaque( GameState->backgroundMap );
2018-02-27 22:00:00 +01:00
Host_SetState( GameState->nextstate, true );
2018-02-25 22:00:00 +01:00
break;
default:
2018-02-27 22:00:00 +01:00
Host_SetState( STATE_RUNFRAME, true );
2018-02-25 22:00:00 +01:00
break;
}
}
void COM_Frame( float time )
{
int loopCount = 0;
2018-03-07 22:00:00 +01:00
if( setjmp( host.abortframe ))
return;
2018-02-25 22:00:00 +01:00
while( 1 )
{
int oldState = GameState->curstate;
2018-06-10 23:00:00 +02:00
// execute the current state (and transition to the next state if not in STATE_RUNFRAME)
2018-02-25 22:00:00 +01:00
switch( GameState->curstate )
{
case STATE_LOAD_LEVEL:
2018-02-27 22:00:00 +01:00
SV_ExecLoadLevel();
Host_SetState( STATE_RUNFRAME, true );
2018-02-25 22:00:00 +01:00
break;
case STATE_LOAD_GAME:
2018-02-27 22:00:00 +01:00
SV_ExecLoadGame();
Host_SetState( STATE_RUNFRAME, true );
2018-02-25 22:00:00 +01:00
break;
case STATE_CHANGELEVEL:
2018-02-27 22:00:00 +01:00
SV_ExecChangeLevel();
Host_SetState( STATE_RUNFRAME, true );
2018-02-25 22:00:00 +01:00
break;
case STATE_RUNFRAME:
2018-02-27 22:00:00 +01:00
Host_RunFrame( time );
2018-02-25 22:00:00 +01:00
break;
case STATE_GAME_SHUTDOWN:
2018-02-27 22:00:00 +01:00
Host_ShutdownGame();
2018-02-25 22:00:00 +01:00
break;
}
if( oldState == STATE_RUNFRAME )
break;
if(( GameState->curstate == oldState ) || ( ++loopCount > 8 ))
Sys_Error( "state infinity loop!\n" );
}
}