Event based mainloop. WARNING: Is not yet fully finished and may have some flaws. Comments are appreciated.

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1619 4a71c877-e1ca-e34f-864e-861f7616d084
master
Dennis Schridde 2007-05-12 17:52:31 +00:00
parent 03e7785ada
commit 22a7dd9dce
8 changed files with 452 additions and 427 deletions

View File

@ -60,15 +60,7 @@ static FPSmanager wzFPSmanager;
static UWORD currentCursorResID = UWORD_MAX;
SDL_Cursor *aCursors[MAX_CURSORS];
typedef enum _focus_state
{
FOCUS_OUT, // Window does not have the focus
FOCUS_SET, // Just received WM_SETFOCUS
FOCUS_IN, // Window has got the focus
FOCUS_KILL, // Just received WM_KILLFOCUS
} FOCUS_STATE;
FOCUS_STATE focusState, focusLast;
FOCUS_STATE focusState = FOCUS_IN;
/************************************************************************************
*
@ -225,7 +217,7 @@ BOOL frameInitialise(
BOOL fullScreen // Whether to start full screen or windowed
)
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CDROM) != 0)
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
{
debug( LOG_ERROR, "Error: Could not initialise SDL (%s).\n", SDL_GetError() );
return FALSE;
@ -233,9 +225,6 @@ BOOL frameInitialise(
SDL_WM_SetCaption(pWindowName, NULL);
focusState = FOCUS_IN;
focusLast = FOCUS_IN;
/* Initialise the trig stuff */
if (!trigInitialise())
{
@ -265,6 +254,7 @@ BOOL frameInitialise(
return TRUE;
}
/*
* frameUpdate
*
@ -273,105 +263,17 @@ BOOL frameInitialise(
*
* Returns FRAME_STATUS.
*/
FRAME_STATUS frameUpdate(void)
void frameUpdate(void)
{
SDL_Event event;
FRAME_STATUS retVal = FRAME_OK;
BOOL wzQuit = FALSE;
/* Tell the input system about the start of another frame */
inputNewFrame();
/* Deal with any windows messages */
while ( SDL_PollEvent( &event ) != 0)
{
switch (event.type)
{
case SDL_QUIT:
wzQuit = TRUE;
break;
case SDL_ACTIVEEVENT:
// Ignore focus loss through SDL_APPMOUSEFOCUS, since it mostly happens accidentialy
// active.state is a bitflag! Mixed events (eg. APPACTIVE|APPMOUSEFOCUS) will thus not be ignored.
if ( event.active.state != SDL_APPMOUSEFOCUS )
{
if ( event.active.gain == 1 )
{
debug( LOG_NEVER, "WM_SETFOCUS\n");
if (focusState != FOCUS_IN)
{
debug( LOG_NEVER, "FOCUS_SET\n");
focusState = FOCUS_SET;
}
}
else
{
debug( LOG_NEVER, "WM_KILLFOCUS\n");
if (focusState != FOCUS_OUT)
{
debug( LOG_NEVER, "FOCUS_KILL\n");
focusState = FOCUS_KILL;
}
/* Have to tell the input system that we've lost focus */
inputLooseFocus();
}
}
break;
case SDL_KEYUP:
case SDL_KEYDOWN:
inputHandleKeyEvent(&event);
break;
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
inputHandleMouseButtonEvent(&event);
break;
case SDL_MOUSEMOTION:
inputHandleMouseMotionEvent(&event);
break;
default:
break;
}
}
/* Now figure out what to return */
if (wzQuit)
{
retVal = FRAME_QUIT;
}
else if (focusState == FOCUS_SET && focusLast == FOCUS_OUT)
{
debug( LOG_NEVER, "frameUpdate: Returning SETFOCUS\n");
focusState = FOCUS_IN;
retVal = FRAME_SETFOCUS;
}
else if (focusState == FOCUS_KILL && focusLast == FOCUS_IN)
{
debug( LOG_NEVER, "frameUpdate: Returning KILLFOCUS\n");
focusState = FOCUS_OUT;
retVal = FRAME_KILLFOCUS;
}
if (focusState == FOCUS_SET || focusState == FOCUS_KILL)
{
/* Got a SET or KILL when we were already in or out of
focus respectively */
focusState = focusLast;
}
else if (focusLast != focusState)
{
debug( LOG_NEVER, "focusLast changing from %d to %d\n", focusLast, focusState);
focusLast = focusState;
}
/* If things are running normally update the framerate */
if (!wzQuit && focusState == FOCUS_IN)
if (focusState == FOCUS_IN)
{
/* Update the frame rate stuff */
MaintainFrameStuff();
SDL_framerateDelay( &wzFPSmanager );
}
return retVal;
}

View File

@ -74,21 +74,22 @@ extern BOOL frameInitialise(
*/
extern void frameShutDown(void);
/* The current status of the framework */
typedef enum _frame_status
typedef enum _focus_state
{
FRAME_OK, // Everything normal
FRAME_KILLFOCUS, // The main app window has lost focus (might well want to pause)
FRAME_SETFOCUS, // The main app window has focus back
FRAME_QUIT, // The main app window has been told to quit
} FRAME_STATUS;
FOCUS_OUT, // Window does not have the focus
FOCUS_SET, // Just received WM_SETFOCUS
FOCUS_IN, // Window has got the focus
FOCUS_KILL, // Just received WM_KILLFOCUS
} FOCUS_STATE;
/* Call this each cycle to allow the framework to deal with
* windows messages, and do general house keeping.
*
* Returns FRAME_STATUS.
*/
extern FRAME_STATUS frameUpdate(void);
extern void frameUpdate(void);
/* Set the current cursor from a Resource ID
* This is the same as calling:

View File

@ -58,16 +58,16 @@ typedef enum _key_state
static KEY_STATE aKeyState[KEY_MAXSCAN];
/* The current location of the mouse */
static SDWORD mouseXPos, mouseYPos;
static SDWORD mouseXPos, mouseYPos;
/* How far the mouse has to move to start a drag */
#define DRAG_THRESHOLD 5
/* Which button is being used for a drag */
static MOUSE_KEY_CODE dragKey;
static MOUSE_KEY_CODE dragKey;
/* The start of a possible drag by the mouse */
static SDWORD dragX, dragY;
static SDWORD dragX, dragY;
/* The current mouse button state */
static KEY_STATE aMouseState[6];
@ -363,7 +363,7 @@ void inputHandleMouseMotionEvent(SDL_Event * event)
// NOTE This should probably react on events?
void inputNewFrame(void)
{
UDWORD i;
unsigned int i;
/* Do the keyboard */
for (i = 0; i < KEY_MAXSCAN; i++)
@ -372,8 +372,8 @@ void inputNewFrame(void)
{
aKeyState[i] = KEY_DOWN;
}
else if ((aKeyState[i] == KEY_RELEASED) ||
(aKeyState[i] == KEY_PRESSRELEASE))
else if ( aKeyState[i] == KEY_RELEASED ||
aKeyState[i] == KEY_PRESSRELEASE )
{
aKeyState[i] = KEY_UP;
}
@ -483,7 +483,8 @@ void SetMousePos(UDWORD x, UDWORD y)
{
static int mousewarp = -1;
if (mousewarp == -1) {
if (mousewarp == -1)
{
SDWORD val;
mousewarp = 1;
@ -524,7 +525,3 @@ void setMouseUp(MOUSE_KEY_CODE code)
event.button.y = mouseY();
SDL_PushEvent(&event);
}

View File

@ -1019,7 +1019,7 @@ BOOL systemInitialise(void)
// ////////////////////////////////////////////////////////////////////////////
// Called once at program shutdown.
//
BOOL systemShutdown(void)
void systemShutdown(void)
{
// unsigned int i;
#ifdef ARROWS
@ -1032,17 +1032,9 @@ BOOL systemShutdown(void)
// free up all the load functions (all the data should already have been freed)
resReleaseAll();
/*
for( i = 0; i < data_dirs_size; i++ )
if (!bDisableLobby && !multiShutdown()) // ajl. init net stuff
{
free( data_dirs[i].name );
}
free( data_dirs );
*/
if (!bDisableLobby && !multiShutdown()) // ajl. init net stuff
{
return FALSE;
return;
}
debug(LOG_MAIN, "shutting down audio subsystems");
@ -1055,7 +1047,7 @@ BOOL systemShutdown(void)
if ( audio_Disabled() == FALSE && !audio_Shutdown() )
{
return FALSE;
return;
}
debug(LOG_MAIN, "shutting down graphics subsystem");
@ -1064,7 +1056,7 @@ BOOL systemShutdown(void)
levShutDown();
widgShutDown();
return TRUE;
return;
}
/***************************************************************************/
@ -1489,7 +1481,6 @@ BOOL stageTwoInitialise(void)
}
}
if (!dispInitialise()) /* Initialise the display system */
{
return FALSE;
@ -1512,18 +1503,6 @@ BOOL stageTwoInitialise(void)
return FALSE;
}
/*
if (!loadExtraIMDs())
{
return FALSE;
}
*/
/*if (!mechInitialise()) // Initialise the mechanics system
{
return FALSE;
}*/
if (!cmdDroidInit())
{
return FALSE;
@ -1550,48 +1529,26 @@ BOOL stageTwoInitialise(void)
LOADBARCALLBACK(); // loadingScreenCallback();
// if (!initTitle())
// {
// return(FALSE);
// }
if (!initMessage()) /* Initialise the message heaps */
{
return FALSE;
}
if (!gwInitialise())
{
return FALSE;
}
// keymappings
LOADBARCALLBACK(); // loadingScreenCallback();
keyClearMappings();
keyInitMappings(FALSE);
LOADBARCALLBACK(); // loadingScreenCallback();
frameSetCursorFromRes(IDC_DEFAULT);
SetFormAudioIDs(ID_SOUND_WINDOWOPEN,ID_SOUND_WINDOWCLOSE);
// mapNew(256,256); // Generate the largest size of map needed for the game
// if (!loadGame("final.gam"))
// if (!loadGame("savetest.gam"))
// {
// return FALSE;
// }
// intSetMapPos(43 << TILE_SHIFT, 43 << TILE_SHIFT);
debug(LOG_MAIN, "stageTwoInitialise: done");
return TRUE;

View File

@ -33,7 +33,7 @@
extern BOOL InitialiseGlobals(void);
extern BOOL systemInitialise(void);
extern BOOL systemShutdown(void);
extern void systemShutdown(void);
extern BOOL frontendInitialise(const char *ResourceFile);
extern BOOL frontendShutdown(void);
extern BOOL stageOneInitialise(void);

View File

@ -444,13 +444,14 @@ GAMECODE gameLoop(void)
scroll();
}
}
else//paused
else // paused
{
intRetVal = INT_NONE;
if (video)
if (loop_GetVideoStatus())
{
bQuitVideo = !seq_UpdateFullScreenVideo(NULL);
}
if(dragBox3D.status != DRAG_DRAGGING)
{
scroll();
@ -516,7 +517,7 @@ GAMECODE gameLoop(void)
/* Check for quit */
if (intRetVal == INT_QUIT)
{
if (!video)
if (!loop_GetVideoStatus())
{
//quitting from the game to the front end
//so get a new backdrop
@ -529,7 +530,7 @@ GAMECODE gameLoop(void)
bQuitVideo = TRUE;
}
}
if (!video && !quitting)
if (!loop_GetVideoStatus() && !quitting)
{
if (!gameUpdatePaused())
{
@ -580,7 +581,7 @@ GAMECODE gameLoop(void)
}
/* Check for toggling video playbackmode */
if (bQuitVideo && video)
if (bQuitVideo && loop_GetVideoStatus())
{
seq_StopFullScreenVideo();
bQuitVideo = FALSE;
@ -605,8 +606,7 @@ GAMECODE gameLoop(void)
if (!quitting)
{
/* Check for toggling display mode */
if ((keyDown(KEY_LALT) || keyDown(KEY_RALT)) &&
keyPressed(KEY_RETURN))
if ((keyDown(KEY_LALT) || keyDown(KEY_RALT)) && keyPressed(KEY_RETURN))
{
screenToggleMode();
#ifdef DISP2D
@ -666,7 +666,7 @@ GAMECODE gameLoop(void)
}
return GAMECODE_QUITGAME;
}
else if (video)
else if (loop_GetVideoStatus())
{
audio_StopAll();
return GAMECODE_PLAYVIDEO;
@ -689,7 +689,7 @@ GAMECODE videoLoop(void)
screen_GetBackDrop();
#endif
if (video)
if (loop_GetVideoStatus())
{
bQuitVideo = !seq_UpdateFullScreenVideo(NULL);
}
@ -806,6 +806,7 @@ GAMECODE videoLoop(void)
return GAMECODE_CONTINUE;
}
void loop_SetVideoPlaybackMode(void)
{
videoMode += 1;
@ -817,6 +818,7 @@ void loop_SetVideoPlaybackMode(void)
audio_StopAll();
}
void loop_ClearVideoPlaybackMode(void)
{
videoMode -=1;
@ -828,6 +830,7 @@ void loop_ClearVideoPlaybackMode(void)
ASSERT( videoMode == 0, "loop_ClearVideoPlaybackMode: out of sync." );
}
SDWORD loop_GetVideoMode(void)
{
return videoMode;
@ -838,12 +841,12 @@ BOOL loop_GetVideoStatus(void)
return video;
}
BOOL gamePaused( void )
BOOL gamePaused( void )
{
return(paused);
return paused;
}
void setGamePauseStatus( BOOL val )
void setGamePauseStatus( BOOL val )
{
paused = val;
}

View File

@ -25,8 +25,7 @@
// Get platform defines before checking for them!
#include "lib/framework/frame.h"
#include <SDL/SDL_main.h>
#include <SDL/SDL_timer.h>
#include <SDL/SDL.h>
#include <physfs.h>
/* For SHGetFolderPath */
@ -38,6 +37,7 @@
#endif // WZ_OS_WIN
#include "lib/framework/configfile.h"
#include "lib/framework/input.h"
#include "lib/gamelib/gtime.h"
#include "lib/ivis_common/piestate.h"
#include "lib/ivis_common/rendmode.h"
@ -77,6 +77,10 @@
# define WZ_WRITEDIR ".warzone2100"
#endif
typedef enum { RUN_GRAPHICS, RUN_GAMELOOP, RUN_TITLELOOP, RUN_VIDEOLOOP } userEvents;
char datadir[MAX_PATH] = "\0"; // Global that src/clparse.c:ParseCommandLine can write to, so it can override the default datadir on runtime. Needs to be \0 on startup for ParseCommandLine to work!
char * global_mods[MAX_MODS] = { NULL };
@ -87,7 +91,7 @@ char * multiplay_mods[MAX_MODS] = { NULL };
// Warzone 2100 . Pumpkin Studios
// Start game in title mode:
GS_GAMEMODE gameStatus = GS_TITLE_SCREEN, lastStatus = GS_TITLE_SCREEN;
GS_GAMEMODE gameStatus = GS_TITLE_SCREEN;
//flag to indicate when initialisation is complete
BOOL videoInitialised = FALSE;
BOOL gameInitialised = FALSE;
@ -101,6 +105,14 @@ char MultiPlayersPath[MAX_PATH];
char KeyMapPath[MAX_PATH];
char UserMusicPath[MAX_PATH];
static SDL_TimerID graphicsTimerID, gameLoopTimerID, titleLoopTimerID, videoLoopTimerID;
static int gameLoopStatus = 0;
extern FOCUS_STATE focusState;
static void runGameLoop(void);
static void runTitleLoop(void);
extern void debug_callback_stderr( void**, const char * );
extern void debug_callback_win32debug( void**, const char * );
@ -390,12 +402,372 @@ static void make_dir(char *dest, const char *dirname, const char *subdir)
}
static Uint32 graphicsTimer(Uint32 interval, void* param)
{
// Create a user event to call the graphics loop.
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = RUN_GRAPHICS;
event.user.data1 = NULL;
event.user.data2 = NULL;
SDL_PushEvent(&event);
return interval;
}
static Uint32 gameLoopTimer(Uint32 interval, void* param)
{
// Create a user event to call the game loop.
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = RUN_GAMELOOP;
event.user.data1 = NULL;
event.user.data2 = NULL;
SDL_PushEvent(&event);
return interval;
}
static Uint32 titleLoopTimer(Uint32 interval, void* param)
{
// Create a user event to call the title loop.
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = RUN_TITLELOOP;
event.user.data1 = NULL;
event.user.data2 = NULL;
SDL_PushEvent(&event);
return interval;
}
static Uint32 videoLoopTimer(Uint32 interval, void* param)
{
// Create a user event to call the video loop.
SDL_Event event;
event.type = SDL_USEREVENT;
event.user.code = RUN_VIDEOLOOP;
event.user.data1 = NULL;
event.user.data2 = NULL;
SDL_PushEvent(&event);
return interval;
}
void startGraphics(void)
{
graphicsTimerID = SDL_AddTimer(1000.0f/getFramerateLimit(), graphicsTimer, NULL); // 20 FPS
}
void stopGraphics(void)
{
SDL_RemoveTimer(graphicsTimerID);
}
void startVideoLoop(void)
{
videoLoopTimerID = SDL_AddTimer(1000.0f/getFramerateLimit(), videoLoopTimer, NULL); // 20 FPS
}
void stopVideoLoop(void)
{
SDL_RemoveTimer(videoLoopTimerID);
}
static void startTitleLoop(void)
{
screen_RestartBackDrop();
if (!frontendInitialise("wrf/frontend.wrf"))
{
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
frontendInitialised = TRUE;
frontendInitVars();
titleLoopTimerID = SDL_AddTimer(1000.0f/getFramerateLimit(), titleLoopTimer, NULL);
}
static void stopTitleLoop(void)
{
SDL_RemoveTimer(titleLoopTimerID);
if (!frontendShutdown())
{
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
frontendInitialised = FALSE;
}
static void startGameLoop(void)
{
if (!levLoadData(pLevelName, NULL, 0))
{
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
//after data is loaded check the research stats are valid
if (!checkResearchStats())
{
debug( LOG_ERROR, "Invalid Research Stats" );
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
//and check the structure stats are valid
if (!checkStructureStats())
{
debug( LOG_ERROR, "Invalid Structure Stats" );
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
//set a flag for the trigger/event system to indicate initialisation is complete
gameInitialised = TRUE;
screen_StopBackDrop();
gameLoopTimerID = SDL_AddTimer(1000.0f/getFramerateLimit(), gameLoopTimer, NULL);
}
static void stopGameLoop(void)
{
SDL_RemoveTimer(gameLoopTimerID);
if (gameLoopStatus != GAMECODE_NEWLEVEL)
{
initLoadingScreen(TRUE); // returning to f.e. do a loader.render not active
pie_EnableFog(FALSE); // dont let the normal loop code set status on
fogStatus = 0;
if (gameLoopStatus != GAMECODE_LOADGAME)
{
levReleaseAll();
}
}
gameInitialised = FALSE;
}
static void initSaveGameLoad(void)
{
screen_RestartBackDrop();
// load up a save game
if (!loadGameInit(saveGameName))
{
debug( LOG_ERROR, "Shutting down after failure" );
exit(EXIT_FAILURE);
}
screen_StopBackDrop();
SetGameMode(GS_NORMAL);
gameLoopTimerID = SDL_AddTimer(1000.0f/getFramerateLimit(), gameLoopTimer, NULL);
}
static void runGameLoop(void)
{
gameLoopStatus = gameLoop();
switch (gameLoopStatus)
{
case GAMECODE_CONTINUE:
case GAMECODE_PLAYVIDEO:
break;
case GAMECODE_QUITGAME:
debug(LOG_MAIN, "GAMECODE_QUITGAME");
SetGameMode(GS_TITLE_SCREEN);
stopGameLoop();
startTitleLoop();
break;
case GAMECODE_LOADGAME:
debug(LOG_MAIN, "GAMECODE_LOADGAME");
SetGameMode(GS_SAVEGAMELOAD);
stopGameLoop();
startTitleLoop();
break;
case GAMECODE_NEWLEVEL:
debug(LOG_MAIN, "GAMECODE_NEWLEVEL");
stopGameLoop();
break;
// Never trown:
case GAMECODE_FASTEXIT:
case GAMECODE_RESTARTGAME:
break;
default:
debug(LOG_ERROR, "Unknown code returned by gameLoop");
break;
}
}
static void runTitleLoop(void)
{
switch (titleLoop())
{
case TITLECODE_CONTINUE:
break;
case TITLECODE_QUITGAME:
debug(LOG_MAIN, "TITLECODE_QUITGAME");
stopTitleLoop();
{
// Create a quit event to halt game loop.
SDL_Event quitEvent;
quitEvent.type = SDL_QUIT;
SDL_PushEvent(&quitEvent);
}
break;
case TITLECODE_SAVEGAMELOAD:
debug(LOG_MAIN, "TITLECODE_SAVEGAMELOAD");
SetGameMode(GS_SAVEGAMELOAD);
stopTitleLoop();
initSaveGameLoad();
break;
case TITLECODE_STARTGAME:
debug(LOG_MAIN, "TITLECODE_STARTGAME");
SetGameMode(GS_NORMAL);
stopTitleLoop();
startGameLoop();
break;
case TITLECODE_SHOWINTRO:
debug(LOG_MAIN, "TITLECODE_SHOWINTRO");
seq_ClearSeqList();
seq_AddSeqToList("eidos-logo.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("pumpkin.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("titles.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("devastation.rpl", NULL, "devastation.txa", FALSE);
seq_StartNextFullScreenVideo();
break;
default:
debug(LOG_ERROR, "Unknown code returned by titleLoop");
break;
}
}
static void handleActiveEvent(SDL_Event * event)
{
// Ignore focus loss through SDL_APPMOUSEFOCUS, since it mostly happens accidentialy
// active.state is a bitflag! Mixed events (eg. APPACTIVE|APPMOUSEFOCUS) will thus not be ignored.
if ( event->active.state != SDL_APPMOUSEFOCUS )
{
if ( event->active.gain == 1 )
{
debug( LOG_NEVER, "WM_SETFOCUS\n");
if (focusState != FOCUS_IN)
{
debug( LOG_NEVER, "FOCUS_SET\n");
focusState = FOCUS_IN;
gameTimeStart();
// Should be: audio_ResumeAll();
}
}
else
{
debug( LOG_NEVER, "WM_KILLFOCUS\n");
if (focusState != FOCUS_OUT)
{
debug( LOG_NEVER, "FOCUS_KILL\n");
focusState = FOCUS_OUT;
gameTimeStop();
// Should be: audio_PauseAll();
audio_StopAll();
}
/* Have to tell the input system that we've lost focus */
inputLooseFocus();
}
}
}
static void handleUserEvent(SDL_Event * event)
{
// TODO Code which bails if the PC cannot keep up with the desired framerate
switch (event->user.code)
{
case RUN_GRAPHICS:
// FIXME To be implemented: runGraphics();
break;
case RUN_GAMELOOP:
runGameLoop();
break;
case RUN_TITLELOOP:
runTitleLoop();
break;
case RUN_VIDEOLOOP:
// FIXME To be implemented: runVideoLoop();
break;
default:
break;
}
}
static void mainLoop(void)
{
SDL_Event event;
/* Deal with any windows messages */
while (SDL_WaitEvent(&event))
{
switch (event.type)
{
if (focusState == FOCUS_IN)
{
case SDL_USEREVENT:
gameTimeUpdate();
// HACK The videoLoop should get an own timer!
if(loop_GetVideoStatus())
videoLoop();
else
handleUserEvent(&event);
frameUpdate(); // General housekeeping
break;
case SDL_KEYUP:
case SDL_KEYDOWN:
inputHandleKeyEvent(&event);
break;
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
inputHandleMouseButtonEvent(&event);
break;
case SDL_MOUSEMOTION:
inputHandleMouseMotionEvent(&event);
break;
}
case SDL_ACTIVEEVENT:
handleActiveEvent(&event);
break;
case SDL_QUIT:
return;
default:
break;
}
}
}
int main(int argc, char *argv[])
{
BOOL quit = FALSE;
BOOL Restart = FALSE;
BOOL lostFocus = FALSE;
int loopStatus = 0;
iColour* psPaletteBuffer = NULL;
UDWORD pSize = 0;
@ -476,8 +848,7 @@ int main(int argc, char *argv[])
scanDataDirs();
// find out if the lobby stuff has been disabled
if (!bDisableLobby &&
!lobbyInitialise())// ajl. Init net stuff. Lobby can modify startup conditions like commandline.
if (!bDisableLobby && !lobbyInitialise()) // ajl. Init net stuff. Lobby can modify startup conditions like commandline.
{
return -1;
}
@ -486,6 +857,7 @@ int main(int argc, char *argv[])
{
return -1;
}
atexit(frameShutDown);
pie_SetFogStatus(FALSE);
pie_ScreenFlip(CLEAR_BLACK);
@ -506,6 +878,7 @@ int main(int argc, char *argv[])
}
pal_AddNewPalette(psPaletteBuffer);
free(psPaletteBuffer);
atexit(pal_ShutDown);
pie_LoadBackDrop(SCREEN_RANDOMBDROP);
pie_SetFogStatus(FALSE);
@ -515,242 +888,34 @@ int main(int argc, char *argv[])
{
return -1;
}
atexit(systemShutdown);
//set all the pause states to false
setAllPauseStates(FALSE);
while (!quit)
switch(GetGameMode())
{
// Do the game mode specific initialisation.
switch(gameStatus)
{
case GS_TITLE_SCREEN:
screen_RestartBackDrop();
if (!frontendInitialise("wrf/frontend.wrf"))
{
goto exit;
}
case GS_TITLE_SCREEN:
startTitleLoop();
break;
case GS_SAVEGAMELOAD:
initSaveGameLoad();
break;
case GS_NORMAL:
startGameLoop();
break;
default:
debug(LOG_ERROR, "Weirdy game status, I'm afraid!!");
break;
}
frontendInitialised = TRUE;
frontendInitVars();
break;
debug(LOG_MAIN, "Entering main loop");
case GS_SAVEGAMELOAD:
screen_RestartBackDrop();
SetGameMode(GS_NORMAL);
// load up a save game
if (!loadGameInit(saveGameName))
{
goto exit;
}
screen_StopBackDrop();
break;
case GS_NORMAL:
if (!levLoadData(pLevelName, NULL, 0)) {
goto exit;
}
//after data is loaded check the research stats are valid
if (!checkResearchStats())
{
debug( LOG_ERROR, "Invalid Research Stats" );
goto exit;
}
//and check the structure stats are valid
if (!checkStructureStats())
{
debug( LOG_ERROR, "Invalid Structure Stats" );
goto exit;
}
//set a flag for the trigger/event system to indicate initialisation is complete
gameInitialised = TRUE;
screen_StopBackDrop();
break;
default:
debug( LOG_ERROR, "Unknown game status on shutdown!" );
}
debug(LOG_MAIN, "Entering main loop");
Restart = FALSE;
while (!Restart)
{
// Event handling, etc.
switch (frameUpdate())
{
case FRAME_KILLFOCUS:
lostFocus = TRUE;
gameTimeStop();
audio_StopAll();
break;
case FRAME_SETFOCUS:
lostFocus = FALSE;
gameTimeStart();
break;
case FRAME_QUIT:
debug(LOG_MAIN, "frame quit");
quit = TRUE;
Restart = TRUE;
break;
default:
break;
}
lastStatus = gameStatus;
if (!lostFocus && !quit)
{
if (loop_GetVideoStatus())
{
videoLoop();
}
else switch(gameStatus)
{
case GS_TITLE_SCREEN:
switch(titleLoop()) {
case TITLECODE_QUITGAME:
debug(LOG_MAIN, "TITLECODE_QUITGAME");
Restart = TRUE;
quit = TRUE;
break;
case TITLECODE_SAVEGAMELOAD:
debug(LOG_MAIN, "TITLECODE_SAVEGAMELOAD");
gameStatus = GS_SAVEGAMELOAD;
Restart = TRUE;
break;
case TITLECODE_STARTGAME:
debug(LOG_MAIN, "TITLECODE_STARTGAME");
SetGameMode(GS_NORMAL);
Restart = TRUE;
break;
case TITLECODE_SHOWINTRO:
debug(LOG_MAIN, "TITLECODE_SHOWINTRO");
seq_ClearSeqList();
seq_AddSeqToList("eidos-logo.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("pumpkin.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("titles.rpl", NULL, NULL, FALSE);
seq_AddSeqToList("devastation.rpl", NULL, "devastation.txa", FALSE);
seq_StartNextFullScreenVideo();
break;
case TITLECODE_CONTINUE:
break;
default:
debug(LOG_ERROR, "Unknown code returned by titleLoop");
}
break;
case GS_NORMAL:
loopStatus = gameLoop();
switch(loopStatus) {
case GAMECODE_QUITGAME:
debug(LOG_MAIN, "GAMECODE_QUITGAME");
SetGameMode(GS_TITLE_SCREEN);
Restart = TRUE;
if(NetPlay.bLobbyLaunched)
{
quit = TRUE;
}
break;
case GAMECODE_FASTEXIT:
debug(LOG_MAIN, "GAMECODE_FASTEXIT");
Restart = TRUE;
quit = TRUE;
break;
case GAMECODE_LOADGAME:
debug(LOG_MAIN, "GAMECODE_LOADGAME");
Restart = TRUE;
gameStatus = GS_SAVEGAMELOAD;
break;
case GAMECODE_PLAYVIDEO:
debug(LOG_MAIN, "GAMECODE_PLAYVIDEO");
Restart = FALSE;
break;
case GAMECODE_NEWLEVEL:
case GAMECODE_RESTARTGAME:
debug(LOG_MAIN, "GAMECODE_RESTARTGAME");
Restart = TRUE;
break;
case GAMECODE_CONTINUE:
break;
default:
debug(LOG_ERROR, "Unknown code returned by gameLoop");
}
break;
default:
debug(LOG_ERROR, "Weirdy game status, I'm afraid!!");
break;
}
gameTimeUpdate();
} // !lostFocus && !quit
else if (lostFocus && !quit)
{
// Prevent CPU hogging when we've lost focus
SDL_Delay(1);
}
} // End of !Restart loop.
debug(LOG_MAIN, "Preparing for shutdown/restart");
// Do game mode specific shutdown.
switch(lastStatus)
{
case GS_TITLE_SCREEN:
if (!frontendShutdown())
{
goto exit;
}
frontendInitialised = FALSE;
break;
case GS_NORMAL:
if (loopStatus != GAMECODE_NEWLEVEL)
{
initLoadingScreen(TRUE); // returning to f.e. do a loader.render not active
pie_EnableFog(FALSE);//dont let the normal loop code set status on
fogStatus = 0;
if (loopStatus != GAMECODE_LOADGAME)
{
levReleaseAll();
}
}
gameInitialised = FALSE;
break;
default:
debug(LOG_ERROR, "Unknown game status on shutdown!");
break;
}
} // End of !quit loop.
mainLoop();
debug(LOG_MAIN, "Shutting down Warzone 2100");
systemShutdown();
pal_ShutDown();
frameShutDown();
return 0;
exit:
debug(LOG_ERROR, "Shutting down after failure");
systemShutdown();
pal_ShutDown();
frameShutDown();
return 1;
return EXIT_SUCCESS;
}

View File

@ -442,9 +442,9 @@ static BOOL seq_StartFullScreenVideo(const char* videoName, const char* audioNam
}
else if (bCDPath)
{
ASSERT( (strlen(videoName) + strlen(aCDPath))<MAX_STR_LENGTH,"sequence path+name greater than max string" );
strcpy(aVideoName,aCDPath);
strcat(aVideoName,videoName);
ASSERT( (strlen(videoName) + strlen(aCDPath)) < MAX_STR_LENGTH, "sequence path+name greater than max string" );
strcpy(aVideoName, aCDPath);
strcat(aVideoName, videoName);
}
else
{
@ -456,9 +456,9 @@ static BOOL seq_StartFullScreenVideo(const char* videoName, const char* audioNam
//set audio path
if (audioName != NULL)
{
ASSERT( strlen(audioName)<244,"sequence path+name greater than max string" );
strcpy(aAudioName,"sequenceaudio/");
strcat(aAudioName,audioName);
ASSERT( strlen(audioName) < MAX_STR_LENGTH, "sequence path+name greater than max string" );
strcpy(aAudioName, "sequenceaudio/");
strcat(aAudioName, audioName);
}
//start video mode
@ -472,9 +472,9 @@ static BOOL seq_StartFullScreenVideo(const char* videoName, const char* audioNam
if (audioName != NULL)
{
ASSERT( strlen(audioName)<244,"sequence path+name greater than max string" );
strcpy(aAudioName,"sequenceaudio/");
strcat(aAudioName,audioName);
ASSERT( strlen(audioName) < MAX_STR_LENGTH, "sequence path+name greater than max string" );
strcpy(aAudioName, "sequenceaudio/");
strcat(aAudioName, audioName);
}