summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-12-02 22:24:04 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-12-02 22:24:04 +0000
commit5a69d570e4e8e1762175333b737ccca96b90d7db (patch)
treee7b3f97accb6fde2d25d7cb9b2a2ab395c99f1d2
parent1098648f8c697e59e7e0b84f560909842b5f7b28 (diff)
download2010-netlemmings-5a69d570e4e8e1762175333b737ccca96b90d7db.tar.gz
2010-netlemmings-5a69d570e4e8e1762175333b737ccca96b90d7db.tar.bz2
2010-netlemmings-5a69d570e4e8e1762175333b737ccca96b90d7db.zip
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) git-svn-id: file:///var/svn/2010-netlemmings/trunk@182 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/include/data_localgame.h22
-rw-r--r--src/include/netlem_state_machine.h32
-rw-r--r--src/netlem.c101
-rw-r--r--src/netlem_state_machine.c68
5 files changed, 137 insertions, 88 deletions
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 <stdlib.h>
+
+#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);
+}
+