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-861f7616d084master
parent
03e7785ada
commit
22a7dd9dce
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
53
src/init.c
53
src/init.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
27
src/loop.c
27
src/loop.c
|
@ -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;
|
||||
}
|
||||
|
|
635
src/main.c
635
src/main.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue