diff options
Diffstat (limited to 'src/netlem.c')
-rw-r--r-- | src/netlem.c | 165 |
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; |