From 5a69d570e4e8e1762175333b737ccca96b90d7db Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Thu, 2 Dec 2010 22:24:04 +0000 Subject: Refactoring et splitting de code du client netlem.c. Prochaine étape, inclure le changement des levelpack.ini dans le main, puis tout ce qu'il y a dans le testfunc_004 pour charger un niveau (dans le thread prévu à cet effet) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2010-netlemmings/trunk@182 077b3477-7977-48bd-8428-443f22f7bfda --- src/CMakeLists.txt | 2 +- src/include/data_localgame.h | 22 -------- src/include/netlem_state_machine.h | 32 ++++++++++++ src/netlem.c | 101 +++++++++++++------------------------ src/netlem_state_machine.c | 68 +++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 88 deletions(-) create mode 100644 src/include/netlem_state_machine.h create mode 100644 src/netlem_state_machine.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d919b9..cbab0df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,7 @@ configure_file ( "${PROJECT_BINARY_DIR}/netlem_ds.h" ) -add_executable(netlem WIN32 netlem.c ${SRC_COMMON} game.c loader.c graphic.c parser/lex.yy.c parser/y.tab.c ) +add_executable(netlem WIN32 netlem.c ${SRC_COMMON} game.c loader.c graphic.c netlem_state_machine.c parser/lex.yy.c parser/y.tab.c ) target_link_libraries(netlem SDL SDL_net SDL_image) add_executable(netlem_ds WIN32 netlem_ds.c ${SRC_COMMON} ) diff --git a/src/include/data_localgame.h b/src/include/data_localgame.h index 45f7b2c..8a67b5f 100644 --- a/src/include/data_localgame.h +++ b/src/include/data_localgame.h @@ -4,28 +4,6 @@ #include "data_types.h" #define SCREEN_BPP 24 - -typedef enum { - eNull, // Pseudo_state for getOrChangeState : do not change state, just return current state - eLaunching, // Initial state, during system objects initialization - eSplash, // State for displaying Game Logo - eMenuMain, // State for main menu (next lines are sub-menus) - eMenuOptions, // State for general options (screen resolution, music...) - eMenuSingle, // State for single player options (level selection...) - eMenuMultiChooseServer, // State for network game server selection - eMenuMultiChooseOptions, // State for network game options selection (level, players, speed...) - eMultiWaitPlayers, // State for - eMultiLoading, // - eMultiWaitLoading, // - eMultiGame, // - eMultiReport, // - eSingleBrief, // State for single player level briefing (number of Lemmings to save...) - eSingleGame, // State for single player game (user is actually playing) - eSingleReport, // State for single player game report (number of saved Lemmings, access code...) - eCredits, // - eEnd // State reached when this program is exiting -} state_t; - typedef struct { SDL_Rect screen; diff --git a/src/include/netlem_state_machine.h b/src/include/netlem_state_machine.h new file mode 100644 index 0000000..0bc9779 --- /dev/null +++ b/src/include/netlem_state_machine.h @@ -0,0 +1,32 @@ +#ifndef NETLEM_STATE_MACHINE_H +#define NETLEM_STATE_MACHINE_H + +#include "SDL/SDL_net.h" + +typedef enum { + eNull, // Pseudo_state for _getOrChangeState : do not change state, just return current state + eLaunching, // Initial state, during system objects initialization + eSplash, // State for displaying Game Logo + eMenuMain, // State for main menu (next lines are sub-menus) + eMenuOptions, // State for general options (screen resolution, music...) + eMenuSingle, // State for single player options (level selection...) + eMenuMultiChooseServer, // State for network game server selection + eMenuMultiChooseOptions, // State for network game options selection (level, players, speed...) + eMultiWaitPlayers, // State for + eMultiLoading, // + eMultiWaitLoading, // + eMultiGame, // + eMultiReport, // + eSingleBrief, // State for single player level briefing (number of Lemmings to save...) + eSingleGame, // State for single player game (user is actually playing) + eSingleReport, // State for single player game report (number of saved Lemmings, access code...) + eCredits, // + eEnd // State reached when this program is exiting +} state_t; + + +state_t getState(); +state_t changeState(state_t s); +state_t changeStateAndNotify(state_t s, TCPsocket sockClient); + +#endif /*NETLEM_STATE_MACHINE_H*/ diff --git a/src/netlem.c b/src/netlem.c index e75336b..52750af 100644 --- a/src/netlem.c +++ b/src/netlem.c @@ -13,6 +13,7 @@ //#include "events.h" #include "loader.h" #include "timing.h" +#include "netlem_state_machine.h" // Application version number #include "netlem.h" @@ -41,7 +42,6 @@ int loadLevelProc(void *a); // Client-specific functions void signals(int signum); -state_t getOrChangeState(state_t s, TCPsocket sockClient); int init(gameConfig_t *conf, gameGraphics_t *graph); void loadGameConfig(gameConfig_t *conf); void processLocalEvents(); @@ -50,7 +50,7 @@ int updateGraphics(); int main(int argc, char **argv) { - int drift_ms=0,result; + int drift_ms=0, endMainLoop, result; Uint32 tick=0, timeBefore_ms; Uint8 loadProgress=0; @@ -91,6 +91,7 @@ int main(int argc, char **argv) { return 3; } + // Config file loading loadGameConfig(&conf); // Libraries initialization @@ -121,27 +122,28 @@ int main(int argc, char **argv) { args2.loadProgress=&loadProgress; SDL_Thread *loadLevelThread = SDL_CreateThread(loadLevelProc, &args2); if(!loadLevelThread) { - logs2(LOG_ERROR,"getOrChangeState(), SDL_CreateThread()", SDL_GetError()); + logs2(LOG_ERROR,"main(), SDL_CreateThread()", SDL_GetError()); return 4; //FIXME : autre num } //TODO : faire les menus et ne pas forcer ça ici - if ( getOrChangeState(eMultiLoading, client.sockClient) == eNull ) { + if ( changeStateAndNotify(eMultiLoading, client.sockClient) == eNull ) { return 6; } // Main game loop - while(getOrChangeState(eNull,NULL)!=eEnd) { + endMainLoop=0; + while(!endMainLoop) { timeBefore_ms = SDL_GetTicks(); // Process local player keyboard and mouse events // (note: remote events are processed by network read thread) processLocalEvents(); - switch(getOrChangeState(eNull,NULL)) { + switch(getState()) { case eMultiLoading: if(loadProgress==100) { - getOrChangeState(eMultiWaitLoading,client.sockClient); + changeStateAndNotify(eMultiWaitLoading,client.sockClient); } break; case eMultiWaitLoading: @@ -152,7 +154,8 @@ int main(int argc, char **argv) { return 7; break; case 0: - getOrChangeState(eMultiGame,NULL); +//FIXME : check return value + changeState(eMultiGame); break; default: break; @@ -164,6 +167,7 @@ int main(int argc, char **argv) { play(tick++); break; default: + endMainLoop=1; break; } @@ -184,50 +188,6 @@ int main(int argc, char **argv) { return 0; } -state_t getOrChangeState(state_t s, TCPsocket sockClient) { - const event_t evReady = {0,0,0,eReady,0,0,NULL,NULL}; - static state_t state=eLaunching; - int result; - - switch(s) { - case eMultiLoading: - //TODO : check current state before switching - logs(LOG_INFO, "Start game loading"); - result=SDL_SemPost(semLoadLevel); - if (result!=0) { - logs2(LOG_ERROR, "getOrChangeState()", SDL_GetError()); - return eNull; - } - - state=s; - break; - case eMultiWaitLoading: - //TODO : check current state before switching - - // Say to the server that we are ready to start the game and wait game start - result=sendEvent(sockClient, &evReady); - if (result!=0) return eNull; - - state=s; - break; - case eMultiGame: - //TODO : check current state before switching - logs(LOG_INFO, "Game started !"); - state=s; - break; - case eEnd: - state=s; - break; - - case eNull: - break; - default: - return eNull; - } - - return state; -} - void signals(int signum) { static int force=0; char buf[128]; @@ -235,7 +195,7 @@ void signals(int signum) { logs(LOG_WARN, buf); if(!force) { - getOrChangeState(eEnd,NULL); + changeState(eEnd); force=1; logs(LOG_WARN, "Trying to stop smoothly..."); } else { @@ -248,7 +208,7 @@ int init(gameConfig_t *conf, gameGraphics_t *graph) { int result; - //Initialisation des sous-systèmes de SDL + // SDL subsystems initialization result = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO ); if ( result != 0 ) { logs2(LOG_ERROR, "init(), SDL_Init()", SDL_GetError()); @@ -257,19 +217,20 @@ int init(gameConfig_t *conf, gameGraphics_t *graph) { atexit(SDL_Quit); signal(2,signals); - //Mise en place de l'écran + // Screen setup graph->screen = SDL_SetVideoMode(conf->screen.w, conf->screen.h, SCREEN_BPP, SDL_HWSURFACE | SDL_DOUBLEBUF ); if( graph->screen == NULL ) { logs2(LOG_ERROR, "init(), SDL_SetVideoMode()", SDL_GetError()); return 2; } - //Titre de la fenêtre SDL + // SDL main window caption SDL_WM_SetCaption(WIN_CAPTION, NULL); - //Désactiver le pointeur de la souris + // We dont want to see the standard mouse cursor in our main window SDL_ShowCursor(0); - // Allocation et initialisation des différents calques d'affichage et de collision + + // Memory allocation and initialization for all display layers graph->terrain = SDL_CreateRGBSurface(SDL_HWSURFACE, LEVEL_WIDTH, LEVEL_HEIGHT, SCREEN_BPP,0,0,0,0); if( graph->terrain == NULL ) { logs2(LOG_ERROR, "init(), SDL_CreateRGBSurface()", SDL_GetError()); @@ -300,12 +261,12 @@ int networkReadProc(void *a) { struct _networkReadProc_args *args = (struct _networkReadProc_args *)a; - while( getOrChangeState(eNull,NULL) != eEnd ) { + while( getState() != eEnd ) { // logs(LOG_DEBUG, "Waiting event"); result=receiveEvent(args->client,&e); if (result != 0) { logs(LOG_WARN, "networkReadProc(), receiveEvents() error"); - getOrChangeState(eEnd,NULL); + changeState(eEnd); continue; //TODO : je doute que ça skipe vriament la syncrho du temps :s } // logs(LOG_DEBUG, "Got event"); @@ -337,6 +298,15 @@ int networkReadProc(void *a) { return 0; } +int startLoadLevel() { + int result; + + logs(LOG_INFO, "Start game loading"); + result=SDL_SemPost(semLoadLevel); + + return result; +} + int loadLevelProc(void *a) { int result,i; //char logMsg[128]; @@ -344,7 +314,7 @@ int loadLevelProc(void *a) { struct _loadLevelProc_args *args = (struct _loadLevelProc_args *)a; logs(LOG_WARN, "loadLevelProc(), beginnng"); - while( getOrChangeState(eNull,NULL) != eEnd ) { + while( getState() != eEnd ) { result=SDL_SemWait(semLoadLevel); if (result!=0) { logs2(LOG_ERROR, "main(), SDL_SemTryWaitTimeout()", SDL_GetError()); @@ -352,10 +322,11 @@ int loadLevelProc(void *a) { } logs(LOG_WARN, "loadLevelProc(), start load level"); - for(i=0;i<100;i+=(rand()%10)) { - SDL_Delay(rand()%100); - *(args->loadProgress)=i; - } + + + + + *(args->loadProgress)=100; logs(LOG_WARN, "loadLevelProc(), end load level"); diff --git a/src/netlem_state_machine.c b/src/netlem_state_machine.c new file mode 100644 index 0000000..b9b7433 --- /dev/null +++ b/src/netlem_state_machine.c @@ -0,0 +1,68 @@ +#include + +#include "netlem_state_machine.h" + +#include "events.h" +#include "netgame.h" +#include "utils.h" + +//FIXME #include netlem.h ? +extern int startLoadLevel(); + + +state_t _getOrChangeState(state_t s, TCPsocket sockClient) { + const event_t evReady = {0,0,0,eReady,0,0,NULL,NULL}; + static state_t state=eLaunching; + int result; + + switch(s) { + case eNull: + break; + case eMultiLoading: + //TODO : check current state before switching + result=startLoadLevel(); + if (result!=0) { + logs2(LOG_ERROR, "getOrChangeState()", SDL_GetError()); + return eNull; + } + + state=s; + break; + case eMultiWaitLoading: + //TODO : check current state before switching + + // Say to the server that we are ready to start the game and wait game start + result=sendEvent(sockClient, &evReady); + if (result!=0) return eNull; + + state=s; + break; + case eMultiGame: + //TODO : check current state before switching + logs(LOG_INFO, "Game started !"); + state=s; + break; + case eEnd: + state=s; + break; + + default: + return eNull; + } + + return state; +} + + +state_t getState() { + return _getOrChangeState(eNull, NULL); +} + +state_t changeState(state_t s) { + return _getOrChangeState(s, NULL); +} + +state_t changeStateAndNotify(state_t s, TCPsocket sockClient) { + return _getOrChangeState(s, sockClient); +} + -- cgit v1.2.3