X-Git-Url: http://royale.zerezo.com/git/?p=zeRace;a=blobdiff_plain;f=server.c;h=a2ccbcd76931f037166184e93ecfe9c2444fca64;hp=047d98536201263751eb4e81c5e704f6ed050567;hb=1be6de5da72b6218e87c20e29782ce6f9d99196e;hpb=ee6ec6d95d78f74973a2ba97077cc94709bb6c61 diff --git a/server.c b/server.c index 047d985..a2ccbcd 100644 --- a/server.c +++ b/server.c @@ -13,6 +13,7 @@ struct _clients int lasttime; struct _car car; IPaddress address; + int dx,dy; } clients [MAX_CLIENTS]; /* UDP stuff */ @@ -21,6 +22,7 @@ UDPpacket *packet; struct _tracklist *tracklist; SDL_Surface *fun; +SDL_Surface *cars[256]; /* return the id of a connected address */ @@ -82,22 +84,56 @@ void announce(char *name,int clients) } +/* load the car sprite and rotate it for every angles */ +void zeRace_generate_cars() +{ + int j; + SDL_Surface *car; + char temp[20]="sprites/carX.png"; + temp[11]='A'; + /* load the car sprite */ + car=IMG_Load(temp); + /* and rotate it for all available angles */ + for (j=0;j<256;j++) + { + float x,y; + float tcos,tsin; + if ((cars[j]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,RMASK,GMASK,BMASK,AMASK))==NULL) + { + fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError()); + }; + tcos=cos(2*M_PI*j/256); + tsin=sin(2*M_PI*j/256); + for (x=0;xw;x++) for (y=0;yh;y++) + { + int x2,y2; + x2=(x-cars[j]->w/2.0)*tcos+(y-cars[j]->h/2.0)*tsin+car->w/2.0; + y2=(x-cars[j]->w/2.0)*tsin-(y-cars[j]->h/2.0)*tcos+car->h/2.0; + if (x2>0 && x2w && y2>0 && y2h) + putpixel(cars[j],x,y,getpixel(car,x2,y2)); + } + } + SDL_FreeSurface(car); +} + + /* main program */ int main(int argc,char *argv[]) { int id,i,j,time=0,nb; char *tmp; unsigned char ip[4]; - int nb_laps,network_speed,pub; + int nb_laps,network_speed,pub,col; - if (argc!=5) + if (argc!=6) { fprintf(stderr, - "usage: %s 'server_name' nb_laps network_speed (public|private)\n" + "usage: %s 'server_name' nb_laps network_speed (public|private) (col|nocol)\n" " server_name : the name of the server\n" " nb_laps : the number of laps to complete for each race\n" " network_speed : frequency of network messages (1 for fast network, 10 for slow network...)\n" " private : this server will not be listed in the 'internet games'\n" + " col : the server will compute collisions between cars\n" ,argv[0] ); exit(1); @@ -106,6 +142,7 @@ int main(int argc,char *argv[]) printf("nb_laps : %d\n",nb_laps=atoi(argv[2])); printf("network_speed : %d\n",network_speed=atoi(argv[3])); printf("public : %d\n",pub=strcmp("private",argv[4])); + printf("col : %d\n",col=strcmp("nocol",argv[5])); if (!zeRace_get_tracks(&tracklist)) exit(1); @@ -133,7 +170,9 @@ int main(int argc,char *argv[]) fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError()); exit(2); } - + + zeRace_generate_cars(); + for (;;) { /* announce the server on internet if wanted */ @@ -197,7 +236,6 @@ int main(int argc,char *argv[]) /* look for type of message */ tmp=packet->data; - /*printf("%s\n",tmp);*/ /* new connection ? */ if (strcmp(tmp,"connect")==0) @@ -264,22 +302,58 @@ int main(int argc,char *argv[]) } else { - int temp; + int temp,x,y,x2,y2; tmp+=strlen(tmp)+1; temp=SDLNet_Read32(tmp); tmp+=4; + x=SDLNet_Read32(tmp); + tmp+=4; + y=SDLNet_Read32(tmp); + tmp+=4; if (clients[id].lasttime<=temp) { tmp+=temp-clients[id].lasttime; - /* printf("servertime = %d lasttime = %d temp = %d strlen(tmp) = %d\n",time,clients[id].lasttime,temp,strlen(tmp)); */ - /*printf("keys = %s\n",tmp);*/ while (*tmp) { move_car(&clients[id].car,*tmp-'A',fun); - /*printf("%d = %f\n",id,clients[id].car.angle);*/ clients[id].lasttime++; tmp++; } + /* check that the server and the client are still synchronized */ + x2=clients[id].car.x; + y2=clients[id].car.y; + if (x!=x2 || y!=y2) + { + int round; + /* this should not happen with a perfect network protocol :) */ + printf("client %d unsync at %d\n",id,time); + /* instead of dropping the client, we send him a "dumb" collision to resync him */ + tmp=packet->data; + strcpy(tmp,"collision"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(time,tmp); + tmp+=4; + round=(clients[id].car.x+100)*65536; + clients[id].car.x=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.y+100)*65536; + clients[id].car.y=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.speed+100)*65536; + clients[id].car.speed=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[id].car.angle+100)*65536; + clients[id].car.angle=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + packet->len=(void *)tmp-(void *)packet->data; + packet->address=clients[id].address; + SDLNet_UDP_Send(udpsock,-1,packet); + clients[id].lasttime=time; + } } } } @@ -295,6 +369,83 @@ int main(int argc,char *argv[]) clients[i].connected=0; } + /* should we check for collisions ? */ + if (col) + { + /* check for collisions */ + for (i=0;i0 && x2<30 && y2>0 && y2<30) + { + if (getpixel(cars[(unsigned char)(256*clients[j].car.angle/2.0/M_PI)%256],x2,y2)!=0) + { + if (x1<30/2) { clients[i].dx++; clients[j].dx--; } else { clients[i].dx--; clients[j].dx++; } + if (y1<30/2) { clients[i].dy++; clients[j].dy--; } else { clients[i].dy--; clients[j].dy++; } + } + } + } + } + + /* now compute the collisions */ + for (i=0;i5) dx/=2; + while (abs(dy)>5) dy/=2; + /* get the pixel color under the center of car in the function map */ + c=getpixel(fun,clients[i].car.x+dx,clients[i].car.y+dy); + /* green layer (road quality) */ + SDL_GetRGB(c,fun->format,&t,&g,&t); + /* if the destination is not a wall and not outside of the track */ + if (g!=0 && clients[i].car.x>cars[0]->w && clients[i].car.xw-cars[0]->w && clients[i].car.y>cars[0]->h && clients[i].car.yh-cars[0]->h) + { + int round; + clients[i].car.x+=dx; + clients[i].car.y+=dy; + tmp=packet->data; + strcpy(tmp,"collision"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(time,tmp); + tmp+=4; + round=(clients[i].car.x+100)*65536; + clients[i].car.x=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.y+100)*65536; + clients[i].car.y=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.speed+100)*65536; + clients[i].car.speed=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + round=(clients[i].car.angle+100)*65536; + clients[i].car.angle=(float)round/65536-100; + SDLNet_Write32(round,tmp); + tmp+=4; + packet->len=(void *)tmp-(void *)packet->data; + packet->address=clients[i].address; + SDLNet_UDP_Send(udpsock,-1,packet); + clients[i].lasttime=time; + } + } + } + /* send update to clients */ if (time%network_speed==0) for (i=0;idata+strlen("positions")+1+4+4); @@ -326,6 +483,7 @@ int main(int argc,char *argv[]) } /* did someone finish the track ? */ + for (i=0;i