summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-12-12 21:19:10 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-12-12 21:19:10 +0000
commit76331a09ac00aea941f86a80bb95c398b51c7812 (patch)
tree3f1d0e4e65037f36ae71a49f9673e23af336706b
parent78cf86f630ab63b7e5079780b4f41605eb281032 (diff)
download2010-netlemmings-76331a09ac00aea941f86a80bb95c398b51c7812.tar.gz
2010-netlemmings-76331a09ac00aea941f86a80bb95c398b51c7812.tar.bz2
2010-netlemmings-76331a09ac00aea941f86a80bb95c398b51c7812.zip
ATTENTION - Version qui ne compile pas. Gros changements dans le fonctionnement des dirtyRectangles.
Le netlem.c est cohérent avec les .h mais par contre les .c correspondants aux .h n'ont pas été modifiés. git-svn-id: file:///var/svn/2010-netlemmings/trunk@206 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--src/include/data_localgame.h49
-rw-r--r--src/include/data_ress.h1
-rw-r--r--src/include/game.h3
-rw-r--r--src/include/graphic.h6
-rw-r--r--src/netlem.c165
5 files changed, 113 insertions, 111 deletions
diff --git a/src/include/data_localgame.h b/src/include/data_localgame.h
index db6a9dd..b4716f7 100644
--- a/src/include/data_localgame.h
+++ b/src/include/data_localgame.h
@@ -2,28 +2,15 @@
#define DATA_LOCALGAME_H
#include "data_types.h"
+#include "SDL/SDL.h"
#define DEBUG_DIRTYRECTANGLES 1
// Structures de données pour la partie en cours, sur l'ordinateur local
-// Etat des différents objets de la map
-typedef struct {
- // zOrder < 0 : dessiné avant le terrain, sinon après le terrain (0 est uen valeur réservée)
- int zOrder;
- // surfId : Index du SDL_Surface de l'objet consiédéré (confère gameGraphSurfaces_t / objectsSurf)
- int surfId;
- // Information sur l'état de l'animation de l'objet
- int animFrames, currentAnimFrame;
- // Bounding box (plus petit rectangle qui continet tous les pixels de l'objet, utile pour updateGraphics())
- SDL_Rect *objectsBBox;
-} gameGraphObjState_t;
-
// Ensemble des buffers graphiques du jeu (sauf l'écran)
typedef struct {
SDL_Surface *screen, *terrain, *stencil, *tmpSurf;
- // For loaded Gif tiles, see data_ress.h
- gameGraphObjState_t *objectsStat;
} gameGraphSurfaces_t;
// Gestion de l'écran et de la caméra
@@ -33,11 +20,39 @@ typedef struct {
gameGraphSurfaces_t surfaces;
- int dirtRectsCount;
- SDL_Rect *dirtRects; // Dirt rectangles to refresh for current tick
+} gameGraphics_t;
+
+// Etat des différents objets de la map
+struct gameObjectState {
+ // zOrder < 0 : dessiné avant le terrain. zOrder > 0 : déssiné après le terrain. 0 est une valeur réservée.
+ int zOrder;
+ // surfId : Index du SDL_Surface de l'objet considéré (confère gameGraphSurfaces_t / objectsSurf)
+ int surfId;
+ // Information sur l'état de l'animation de l'objet
+ int animFrames, currentAnimFrame;
+ // Flags pour objets dont la procédure de dessin est spéciale
+ int modifiers;
+ // Flag disant si l'objet a été déclanché ou non
+ int triggered;
+ // date (en ticks) du déclanchement de l'objet
+ tick_t trigDate;
+ // Signale que l'objet doit être redessiné
+ int dirty;
+ // Position de l'objet (et position précédente, pour updateGraphics())
+ pos_t pos, prevPos;
+ // Pointeur vers la surface correspondante (cf data_ress.h)
+ SDL_Surface *s;
+};
+typedef struct {
+ int objCount;
+ struct gameObjectState *allObj, cursor;
+} gameObjectsState_t;
+
+// Paramèters locaux dynamiques
+typedef struct {
int debugFlags;
-} gameGraphics_t;
+} localParams_t;
// Paramètes de jeu envoyés par le serveur (niveau en cours, etc)
typedef struct {
diff --git a/src/include/data_ress.h b/src/include/data_ress.h
index 2513e81..b09c996 100644
--- a/src/include/data_ress.h
+++ b/src/include/data_ress.h
@@ -11,6 +11,7 @@ struct miscRess {
SDL_Surface **lemmingAnims, **lemmingMasks, **lemmingImasks, **icons;
SDL_Surface *font1, *font2, *countdown, *cursor, *explode;
};
+
// Image ressources loaded from files referenced in the style INI file
typedef struct {
struct styleRess style;
diff --git a/src/include/game.h b/src/include/game.h
index fba84db..2b7e33b 100644
--- a/src/include/game.h
+++ b/src/include/game.h
@@ -2,8 +2,9 @@
#define GAME_H
#include "data_types.h"
+#include "data_localgame.h"
#include "SDL/SDL.h"
-void play(tick_t tick, int *dirtRectsCount, SDL_Rect **directRects );
+void play(tick_t tick, gameObjectsState_t *objStates);
#endif //GAME_H
diff --git a/src/include/graphic.h b/src/include/graphic.h
index 52cc031..13ac889 100644
--- a/src/include/graphic.h
+++ b/src/include/graphic.h
@@ -21,8 +21,8 @@ SDL_Surface * loadGif(char *filePath);
int init(char *winCaption, gameConfig_t *conf, gameGraphics_t *gGraph);
int paintTerrain(gameIni_t *gIni, gameRess_t *gRess, gameGraphics_t *gGraph);
-int repaint(gameGraphSurfaces_t *srcSurfs, SDL_Rect *srcRect, SDL_Surface *dstSurf, SDL_Rect dstRect);
-int findAndZSortObjects(gameGraphObjState_t *objectsStat, SDL_Rect *offsetRect, gameGraphObjState_t **objectsFound);
-int paintObject(gameGraphObjState_t *obj, SDL_Rect *srcRect, SDL_Surface *dstSurf, SDL_Rect *dstRect);
+int repaint(gameObjectsState_t *objStates, gameGraphSurfaces_t *srcSurfs, SDL_Rect *srcRect, SDL_Surface *dstSurf, SDL_Rect dstRect);
+int findAndZSortObjects(gameObjectsState_t *objectsStat, SDL_Rect *offsetRect, gameObjectsState_t **objectsFound);
+int paintObject(gameObjectsState_t *obj, SDL_Rect *srcRect, SDL_Surface *dstSurf, SDL_Rect *dstRect);
#endif /*GRAPHIC_H*/
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;