summaryrefslogtreecommitdiff
path: root/src/netlem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/netlem.c')
-rw-r--r--src/netlem.c165
1 files changed, 75 insertions, 90 deletions
diff --git a/src/netlem.c b/src/netlem.c
index 2b62fb2..32b339d 100644
--- a/src/netlem.c
+++ b/src/netlem.c
@@ -19,6 +19,8 @@
// Application version number
#include "netlem.h"
+#define STATS_TICKCOUNT 10
+
// Thread arguments structures
struct _networkReadProc_args {
client_t *client;
@@ -45,24 +47,27 @@ int loadLevelProc(void *a);
// Client-specific functions
void signals(int signum);
-void processLocalEvents(gameGraphics_t *gGraph);
-int act(tick_t *tick, int loadProgress, TCPsocket sockClient, int *dirtRectsCount, SDL_Rect **dirtRects);
-int updateGraphics(gameGraphics_t *gGraph);
+void processLocalEvents(SDL_Rect *terrain, SDL_Rect *viewport, gameObjectsState_t *objStates, localParams_t *params);
+int act(tick_t *tick, int loadProgress, TCPsocket sockClient, gameObjectsState_t *objStates);
+int updateGraphics(gameObjectsState_t *objStates, localParams_t *params, gameGraphics_t *gGraph);
int main(int argc, char **argv) {
int drift_ms=0, endMainLoop, result;
tick_t tick=0, lastServerTick=0;
- Uint32 timeBefore_ms[10], beforeWait[10], wantWait[10], waited[10], t;
+ Uint32 timeBefore_ms[STATS_TICKCOUNT], beforeWait[STATS_TICKCOUNT], wantWait[STATS_TICKCOUNT], t;
Uint8 loadProgress=0;
- double fps, waitedMean, wantWaitMean;
+ double fps, wantWaitMean;
client_t client;
serverParams_t serverParams;
+ localParams_t localParams;
+
gameConfig_t conf;
gameIni_t gIni;
gameRess_t gRess;
gameGraphics_t gGraph;
+ gameObjectsState_t gObjStates;
char logMsg[128];
struct _networkReadProc_args args;
@@ -145,49 +150,36 @@ int main(int argc, char **argv) {
return 6;
}
- memset(timeBefore_ms, 0, 10*sizeof(Uint32));
- memset(beforeWait, 0, 10*sizeof(Uint32));
- memset(wantWait, 0, 10*sizeof(Uint32));
- memset(waited, 0, 10*sizeof(Uint32));
+ memset(timeBefore_ms, 0, STATS_TICKCOUNT*sizeof(Uint32));
+ memset(beforeWait, 0, STATS_TICKCOUNT*sizeof(Uint32));
+ memset(wantWait, 0, STATS_TICKCOUNT*sizeof(Uint32));
t=0;
// Main game loop
endMainLoop=0;
while(!endMainLoop) {
- // Store loop begin date in a 10 entries rotate buffer
- t=(t+1)%10;
+ // Store loop begin date in a STATS_TICKCOUNT entries rotate buffer
+ t=(t+1)%STATS_TICKCOUNT;
timeBefore_ms[t] = SDL_GetTicks();
// Process local player keyboard and mouse events
// (note: remote events are processed by network read thread)
- processLocalEvents(&gGraph);
+ processLocalEvents(&(gGraph.surfaces.terrain->clip_rect), &(gGraph.viewport), &gObjStates, &localParams );
- endMainLoop=act(&tick, loadProgress, client.sockClient, &(gGraph.dirtRectsCount), &(gGraph.dirtRects));
+ endMainLoop=act(&tick, loadProgress, client.sockClient, &gObjStates);
// Display that new game state to the local user
- updateGraphics(&gGraph);
-
+ updateGraphics(&gObjStates, &localParams, &gGraph);
// Delay that we have to wait for the next frame (depends on execution time and network time drift)
- beforeWait[t]=SDL_GetTicks();
wantWait[t]=waitForNextTick(timeBefore_ms[t], drift_ms);
- waited[t]=SDL_GetTicks();
- waited[t] -= beforeWait[t];
- // Compute & display FPS mean value on 10 loops
- if (t==0) {
- fps=10000.0/(timeBefore_ms[t]-timeBefore_ms[(t+1)%10]);
- wantWaitMean=0;
- waitedMean=0;
- for(;t<10;t++) {
- wantWaitMean+=wantWait[t];
- waitedMean+=waited[t];
- }
- t=0;
- wantWaitMean/=10.0;
- waitedMean/=10.0;
-// snprintf(logMsg, 128, "tick:%d\tlastServerTick:%d\tdrift_ms:%d\t\t%.1f FPS\t WW:%.1f\tW:%.1f\n", tick, lastServerTick, drift_ms, fps, wantWaitMean, waitedMean);
- snprintf(logMsg, 128, "tick:%d\tlastServerTick:%d\tdrift_ms:%d\t\t%.1f FPS\t WW:%d\tW:%d\n", tick, lastServerTick, drift_ms, fps, wantWait[3], waited[3]);
+ // Compute & display FPS mean value on STATS_TICKCOUNT ticks
+ if (t==0) {
+ fps=(STATS_TICKCOUNT*1000.0)/(timeBefore_ms[t]-timeBefore_ms[(t+1)%STATS_TICKCOUNT]);
+ wantWaitMean=0; for(;t<STATS_TICKCOUNT;t++) { wantWaitMean+=wantWait[t]; }
+ t=0; wantWaitMean/=(double) STATS_TICKCOUNT;
+ snprintf(logMsg, 128, "tick:%d\tlastServerTick:%d\tdrift_ms:%d\tFPS:%.1f\t wantWait:%.1f ms (%.1f %%)\n", tick, lastServerTick, drift_ms, fps, wantWaitMean, (double)wantWaitMean/TICK_DURATION_MS);
logs(LOG_DEBUG, logMsg);
}
}
@@ -235,7 +227,7 @@ void signals(int signum) {
}
}
-int act(tick_t *tick, int loadProgress, TCPsocket sockClient, int *dirtRectsCount, SDL_Rect **dirtRects) {
+int act(tick_t *tick, int loadProgress, TCPsocket sockClient, gameObjectsState_t *objStates) {
int res;
switch(getState()) {
@@ -262,7 +254,7 @@ int act(tick_t *tick, int loadProgress, TCPsocket sockClient, int *dirtRectsCoun
case eSingleGame:
case eMultiGame:
// Make game evolve from the current state to the next time chunk (ie. frame, or tick)
- play((*tick)++, dirtRectsCount, dirtRects);
+ play((*tick)++, objStates);
break;
default:
return 1;
@@ -422,9 +414,7 @@ int loadLevelProc(void *a) {
#define MAP_SCROLL_BOUND 32
#define MAP_SCROLL_SPEED 16
-//FIXME : tous les champs de gGraph utilisés dans cette méthode devraient être déplacés dans une structure autre
-//void processLocalEvents(SDL_Rect *viewport, SDL_Rect *screen, SDL_Rect *terrain, int *debugFlags) {
-void processLocalEvents(gameGraphics_t *gGraph) {
+void processLocalEvents(SDL_Rect *terrain, SDL_Rect *viewport, gameObjectsState_t *objStates, localParams_t *params) {
static int mouseActive=1, mouseX=100, mouseY=100;
SDL_Event event;
@@ -456,7 +446,7 @@ void processLocalEvents(gameGraphics_t *gGraph) {
changeState(eEnd);
break;
case SDLK_d:
- gGraph->debugFlags ^= DEBUG_DIRTYRECTANGLES;
+ params->debugFlags ^= DEBUG_DIRTYRECTANGLES;
break;
default:
break;
@@ -470,19 +460,12 @@ void processLocalEvents(gameGraphics_t *gGraph) {
case SDL_MOUSEMOTION:
mouseX = event.motion.x;
mouseY = event.motion.y;
-
- //FIXME : utiliser une méthode addDirtRect
- gGraph->dirtRects=malloc(1*sizeof(SDL_Rect));
- gGraph->dirtRects[0].x=mouseX-16;
- gGraph->dirtRects[0].y=mouseY-16;
- gGraph->dirtRects[0].w=32;
- gGraph->dirtRects[0].h=32;
- gGraph->dirtRectsCount=1;
-
+ objStates->cursor.pos.x = mouseX;
+ objStates->cursor.pos.y = mouseY;
+ objStates->cursor.dirty=1;
break;
case SDL_MOUSEBUTTONDOWN:
//err=mouse_action(&gInit, mouseX, mouseY,camera.x,camera.y );
- //if(err!=0){return err;} //FIXME : WTF ?
break;
case SDL_QUIT:
changeState(eEnd);
@@ -493,15 +476,15 @@ void processLocalEvents(gameGraphics_t *gGraph) {
switch(getState()) {
case eMultiGame:
if (mouseActive) {
- if(mouseY <= gGraph->surfaces.terrain->h){
- if (mouseX > (gGraph->screen->w - MAP_SCROLL_BOUND)){
- if (gGraph->viewport.x < (gGraph->surfaces.terrain->w - gGraph->screen->clip_rect.w ) ) {
- gGraph->viewport.x += MAP_SCROLL_SPEED;
+ if(mouseY <= terrain->h){
+ if (mouseX > (viewport->w - MAP_SCROLL_BOUND)){
+ if (viewport->x < (terrain->w - viewport->w ) ) {
+ viewport->x += MAP_SCROLL_SPEED;
}
}
if (mouseX < MAP_SCROLL_BOUND){
- if (gGraph->viewport.x >= MAP_SCROLL_SPEED ) {
- gGraph->viewport.x -= MAP_SCROLL_SPEED;
+ if (viewport->x >= MAP_SCROLL_SPEED ) {
+ viewport->x -= MAP_SCROLL_SPEED;
}
}
}
@@ -514,11 +497,12 @@ void processLocalEvents(gameGraphics_t *gGraph) {
return;
}
-int updateGraphics(gameGraphics_t *gGraph) {
+int updateGraphics(gameObjectsState_t *objStates, localParams_t *params, gameGraphics_t *gGraph) {
int i, res;
- static SDL_Rect lastViewport= {-1,-1,-1,-1};
- SDL_Rect srcRect;
+ static SDL_Rect lastViewport= {0,0,0,0};
+ SDL_Rect srcRect, dstRect;
SDL_Surface *tmpSurf;
+ struct gameObjectState *o;
//TODO : modifier les calques
switch(getState()) {
@@ -527,48 +511,49 @@ int updateGraphics(gameGraphics_t *gGraph) {
break;
case eMultiGame:
// If we had a camera movement, we have to refesh all the screen
- //if ( memcmp(&lastViewport, &(gGraph->viewport), sizeof(SDL_Rect)) != 0) {
+ tmpSurf=gGraph->surfaces.tmpSurf;
if ( lastViewport.x != gGraph->viewport.x ) {
- //lastViewport=gGraph->viewport;
lastViewport.x=gGraph->viewport.x;
- if ( gGraph->dirtRectsCount > 0 ) {
- free(gGraph->dirtRects);
- }
- // Put only one dirt rectangle, of the size of the screen
- gGraph->dirtRects=malloc(1*sizeof(SDL_Rect));
- memcpy(gGraph->dirtRects, &(gGraph->screen->clip_rect), sizeof(SDL_Rect));
- gGraph->dirtRectsCount=1;
- }
-
- // We use a dirty rectangle method for performance
- tmpSurf=gGraph->surfaces.tmpSurf;
- for(i=0; i<gGraph->dirtRectsCount; i++) {
- srcRect.x=gGraph->dirtRects[i].x+lastViewport.x;
- srcRect.y=gGraph->dirtRects[i].y+lastViewport.y;
- srcRect.w=gGraph->dirtRects[i].w;
- srcRect.h=gGraph->dirtRects[i].h;
-
- res=repaint(&gGraph->surfaces, &srcRect, tmpSurf, srcRect);
+ srcRect.x=lastViewport.x;
+ srcRect.y=lastViewport.y;
+ srcRect.w=gGraph->screen->clip_rect.w;
+ srcRect.h=gGraph->screen->clip_rect.h;
+ res=repaint(objStates, &gGraph->surfaces, &srcRect, tmpSurf, srcRect);
if ( res != 0 ) {
logs(LOG_WARN, "updateGraphics(), repaint() failed");
}
- if ( (gGraph->debugFlags & DEBUG_DIRTYRECTANGLES) == 0 ) {
- res=SDL_BlitSurface(tmpSurf, &srcRect, gGraph->screen, gGraph->dirtRects+i);
- if ( res!=0 ) {
- logs2(LOG_DEBUG, "repaint(), SDL_BlitSurface()", SDL_GetError());
- }
+ } else {
+ // We use a dirty rectangle method for performance
+ for(i=0; i<objStates->objCount; i++) {
+ o=objStates->allObj+i;
+
+ dstRect.x=o->pos.x;
+ dstRect.y=o->pos.y;
+ dstRect.w=o->s->clip_rect.w;
+ dstRect.h=o->s->clip_rect.h;
+ if ( /*TODO intersect(viewport, dstRect) &&*/ o->dirty == 1 ) {
+ srcRect.x=o->pos.x+lastViewport.x;
+ srcRect.y=o->pos.y+lastViewport.y;
+ srcRect.w=o->s->clip_rect.w;
+ srcRect.h=o->s->clip_rect.h;
+
+ res=repaint(objStates, &gGraph->surfaces, &srcRect, tmpSurf, srcRect);
+ if ( res != 0 ) {
+ logs(LOG_WARN, "updateGraphics(), repaint() failed");
+ }
+ if ( (params->debugFlags & DEBUG_DIRTYRECTANGLES) == 0 ) {
+ res=SDL_BlitSurface(tmpSurf, &srcRect, gGraph->screen, &dstRect);
+ if ( res!=0 ) {
+ logs2(LOG_DEBUG, "repaint(), SDL_BlitSurface()", SDL_GetError());
+ }
- SDL_UpdateRect(gGraph->screen,
- gGraph->dirtRects[i].x, gGraph->dirtRects[i].y,
- gGraph->dirtRects[i].w, gGraph->dirtRects[i].h);
+ SDL_UpdateRect(gGraph->screen, dstRect.x, dstRect.y, dstRect.w, dstRect.h);
+ }
+ }
}
}
- if (gGraph->dirtRectsCount > 0) {
- gGraph->dirtRectsCount=0;
- free(gGraph->dirtRects);
- }
- if ( (gGraph->debugFlags & DEBUG_DIRTYRECTANGLES) == DEBUG_DIRTYRECTANGLES ) {
+ if ( (params->debugFlags & DEBUG_DIRTYRECTANGLES) == DEBUG_DIRTYRECTANGLES ) {
srcRect.x=lastViewport.x;
srcRect.y=lastViewport.y;
srcRect.w=gGraph->screen->clip_rect.w;