From: Antoine Jacquet Date: Fri, 15 Apr 2005 22:00:00 +0000 (+0200) Subject: version 0.5 X-Git-Tag: v0.5 X-Git-Url: http://royale.zerezo.com/git/?p=zeRace;a=commitdiff_plain;h=1be6de5da72b6218e87c20e29782ce6f9d99196e version 0.5 * added "formula" track (thank you Julien) * added some new car sprites (thank you Julien) * added collisions between cars in network mode * added a synchronization check between server and clients * added informations about missed checkpoints and wrong laps (thank you Julien) * added car lights (red lights, backwards lights, warnings) * added night mode with car night lights * fixed a bug with Win32 version downloading new tracks * fixed SDL_Init(0) in bot framework * use SDL_GetRGB and SDL_MapRGB to handle colors --- diff --git a/CHANGELOG b/CHANGELOG index 421f75c..a8daa9a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,17 @@ Change log file for zeRace +version 0.5 (2005-04-16) + * added "formula" track (thank you Julien) + * added some new car sprites (thank you Julien) + * added collisions between cars in network mode + * added a synchronization check between server and clients + * added informations about missed checkpoints and wrong laps (thank you Julien) + * added car lights (red lights, backwards lights, warnings) + * added night mode with car night lights + * fixed a bug with Win32 version downloading new tracks + * fixed SDL_Init(0) in bot framework + * use SDL_GetRGB and SDL_MapRGB to handle colors + version 0.4 (2004-11-28) * added "loop" track * fixed "car" track diff --git a/README b/README index ff68211..699c954 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -zeRace 0.4 +zeRace 0.5 site: http://royale.zerezo.com/zerace/ mail: royale@zerezo.com @@ -10,7 +10,7 @@ make CC=i586-mingw32msvc-gcc SDLCONFIG=/path/to/sdl-config WINDRES=i586-mingw32m bots: To play a game against bots, you will first need to launch a local server : -./server "My private server" 5 1 private +./server "My private server" 5 1 private col Then launch as many bots as you want : ./bot_anticip localhost 3600 0 ./bot_anticip localhost 3600 8 diff --git a/bot.c b/bot.c index ef93b04..b9631a9 100644 --- a/bot.c +++ b/bot.c @@ -60,9 +60,9 @@ void zeRace_init() /* robot configuration */ sprintf(config.pseudo,"\"%s\" bot(%d)",bot_name(),aleas); - config.color=rand()%12; + config.color=rand()%16; - if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) + if (SDL_Init(0)<0) { fprintf(stderr,"could not initialize SDL : %s\n",SDL_GetError()); zeRace_exit(); @@ -134,6 +134,9 @@ void zeRace_launch(int alltime,int go) net.keys[net.time+1]='\0'; } + /* move the car */ + move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); + delay=DELAY; /* if we are in network mode */ if (udpsock!=NULL) @@ -155,6 +158,16 @@ void zeRace_launch(int alltime,int go) lastack=clienttime; } } + else if (strcmp(packet->data,"collision")==0) + { + net.time=-1; + net.keys[0]='\0'; + lastack=SDLNet_Read32(packet->data+strlen("collision")+1); + car.x=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4)/65536-100; + car.y=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4)/65536-100; + car.speed=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4+4)/65536-100; + car.angle=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4+4+4)/65536-100; + } else /* end of this network race */ { SDL_FreeSurface(cir); @@ -168,6 +181,10 @@ void zeRace_launch(int alltime,int go) tmp+=strlen(tmp)+1; SDLNet_Write32(lastack,tmp); tmp+=4; + SDLNet_Write32(car.x,tmp); + tmp+=4; + SDLNet_Write32(car.y,tmp); + tmp+=4; strcpy(tmp,net.keys); tmp+=strlen(tmp)+1; packet->len=(void *)tmp-(void *)packet->data+10; @@ -179,9 +196,6 @@ void zeRace_launch(int alltime,int go) } } - /* move the car */ - move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); - /* let the system breath */ SDL_Delay(delay); @@ -232,7 +246,7 @@ void zeRace_connect(char *host,int port) tmp+=strlen(tmp)+1; go=*tmp++; printf("server asked for track : %s\n",tmp); - while (tracklist->next!=loopcheck) if (strcmp(tracklist->name,tmp)==0) break; else tracklist=tracklist->next; + do if (strcmp(tracklist->name,tmp)==0) break; else tracklist=tracklist->next; while (tracklist!=loopcheck); if (strcmp(tracklist->name,tmp)!=0) { fprintf(stderr,"unknown track : %s\n",tmp); diff --git a/bot_anticip.c b/bot_anticip.c index 22de8dd..424e875 100644 --- a/bot_anticip.c +++ b/bot_anticip.c @@ -19,8 +19,10 @@ char *bot_name() void bot_ia(char *trackname,struct _car *car,SDL_Surface *fun,int *ku,int *kd,int *kl,int *kr) { - int a1,a2,c,g,tg,og,l,x1,x2,x3,x4,y1,y2,y3,y4; + int a1,a2,l,x1,x2,x3,x4,y1,y2,y3,y4; float o,m,s; + Uint32 c; + Uint8 g,og,tg,t; /* adjust the properties depending of the track, this was "manually" optimized ;) */ if (strcmp(trackname,"car")==0) @@ -77,6 +79,15 @@ void bot_ia(char *trackname,struct _car *car,SDL_Surface *fun,int *ku,int *kd,in s=car->speed/3.3+0.4; og=1; } + else if (strcmp(trackname,"formula")==0) + { + a1=150; + a2=90; + o=0.8; + m=0.1; + s=car->speed/3.3+0.4; + og=120; + } /* some default values that may work on some tracks */ else { @@ -95,8 +106,8 @@ void bot_ia(char *trackname,struct _car *car,SDL_Surface *fun,int *ku,int *kd,in { x1=car->x-cos(car->angle)*l*s; y1=car->y-sin(car->angle)*l*s; - if (x1>0 && y1>0 && x1w && y1h) c=getpixel(fun,x1,y1); else c=0; - g=(c>>GSHIFT)&0xff; + if (x1>0 && y1>0 && x1w && y1h) c=getpixel(fun,x1,y1); else c=SDL_MapRGB(fun->format,0,0,0); + SDL_GetRGB(c,fun->format,&t,&g,&t); if (gspeed>m) { *ku=0,*kd=1; break; } } @@ -112,10 +123,10 @@ void bot_ia(char *trackname,struct _car *car,SDL_Surface *fun,int *ku,int *kd,in x4=car->x-cos(car->angle+o)*l*s; y4=car->y-sin(car->angle+o)*l*s; - if (x3>0 && y3>0 && x3w && y3h) c=getpixel(fun,x3,y3); else c=0; - tg=(c>>GSHIFT)&0xff; - if (x4>0 && y4>0 && x4w && y4h) c=getpixel(fun,x4,y4); else c=0; - g=(c>>GSHIFT)&0xff; + if (x3>0 && y3>0 && x3w && y3h) c=getpixel(fun,x3,y3); else c=SDL_MapRGB(fun->format,0,0,0); + SDL_GetRGB(c,fun->format,&t,&tg,&t); + if (x4>0 && y4>0 && x4w && y4h) c=getpixel(fun,x4,y4); else c=SDL_MapRGB(fun->format,0,0,0); + SDL_GetRGB(c,fun->format,&t,&g,&t); if (g>tg) { *kr=1; break; } else if (glapflag=0; car->crashflag=0; /* get the pixel color under the center of car in the function map */ c=getpixel(fun,car->x,car->y); /* red layer (checkpoints) */ - r=(c>>RSHIFT)&0xff; /* green layer (road quality) */ - g=(c>>GSHIFT)&0xff; /* blue layer (grip) */ - b=(c>>BSHIFT)&0xff; + SDL_GetRGB(c,fun->format,&r,&g,&b); if (keys & 8) /* up */ car->speed+=0.01*2*COEFF; @@ -69,8 +67,17 @@ void move_car(struct _car *car,int keys,SDL_Surface *fun) car->crashflag=1; } - /* if we are on the next checkpoint, validate it (no missing allowed) */ - if (r/8==car->lastcheck+1) car->lastcheck++; + /* if we are on the next checkpoint, validate it */ + if (r/8==car->lastcheck+1) + { + /* If we validate a missed checkpoint */ + if (car->lapflag==3) car->lapflag=4; + car->lastcheck++; + } + + /* if we missed a checkpoint */ + if ((r/8>car->lastcheck+1) && (car->lastcheck!=0)) car->lapflag=3; + /* if we validate all and start over, we complete a turn */ if (r/8==0 && car->lastcheck==31) { @@ -80,5 +87,24 @@ void move_car(struct _car *car,int keys,SDL_Surface *fun) car->lapflag=1; } + /* if we are at the start but not each checkpoint validate, it's an incomplete lap */ + if (r/8==0 && r!=0 && car->lastcheck!=31 && car->lastcheck>0) + { + car->lastcheck=0; + car->lapflag=2; + } + + /* if the car is braking, display red lights */ + if (keys & 4 && car->speed>0.1) car->lights_brake=1; else car->lights_brake=0; + + /* if the car is going backwards, display white lights */ + if (car->speed<-0.1) car->lights_backwards=1; else car->lights_backwards=0; + + /* if the car is stopped, then warning */ + if (car->speed>=-0.1 && car->speed<=0.1) + car->lights_warning=1; + else + car->lights_warning=0; + return; } diff --git a/car.h b/car.h index cb9e511..e6260d7 100644 --- a/car.h +++ b/car.h @@ -13,6 +13,7 @@ struct _car int w,h,lastcheck,lap; int lapflag,crashflag; int color; + int lights_brake,lights_backwards,lights_warning; }; void move_car(struct _car *car,int keys,SDL_Surface *function); diff --git a/network.h b/network.h index 206cfe6..1d3b0f7 100644 --- a/network.h +++ b/network.h @@ -4,4 +4,4 @@ #define MAX_LAG 500 #define MAX_CLIENTS 32 #define PORT "3600" -#define VERSION "0.4" +#define VERSION "0.5" diff --git a/sdl.h b/sdl.h index 3eceb70..26245c5 100644 --- a/sdl.h +++ b/sdl.h @@ -6,15 +6,15 @@ /* endianness setup */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN - #define RSHIFT 24 - #define GSHIFT 16 - #define BSHIFT 8 - #define ASHIFT 0 + #define RMASK 0xff000000 + #define GMASK 0x00ff0000 + #define BMASK 0x0000ff00 + #define AMASK 0x000000ff #else - #define RSHIFT 0 - #define GSHIFT 8 - #define BSHIFT 16 - #define ASHIFT 24 + #define RMASK 0x000000ff + #define GMASK 0x0000ff00 + #define BMASK 0x00ff0000 + #define AMASK 0xff000000 #endif void print(SDL_Surface *dst,int x,int y,unsigned char *text); 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 @@ -41,6 +41,14 @@ #define WIDTH 1024 #define HEIGHT 768 #define MAXRECORDKEYS 9999 +#define NB_CARS 16 + +/* some usefull colors */ +#define C_BLACK SDL_MapRGB(screen->format,0,0,0) +#define C_WHITE SDL_MapRGB(screen->format,255,255,255) +#define C_RED SDL_MapRGB(screen->format,255,0,0) +#define C_ORANGE SDL_MapRGB(screen->format,255,200,0) +#define C_YELLOW SDL_MapRGB(screen->format,255,255,100) /* tracklist */ struct _tracklist *tracklist; @@ -59,7 +67,8 @@ struct _config SDLKey right; int color; SDLKey boss; -} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6,SDLK_b}; + int bynight; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6,SDLK_b,0}; /* full script for a lap */ struct _record @@ -71,7 +80,7 @@ struct _record /* display and all directions for the car */ SDL_Surface *screen; -SDL_Surface *cars[12][256]; +SDL_Surface *cars[NB_CARS][256]; /* network stuff */ UDPsocket udpsock=NULL; @@ -83,7 +92,7 @@ int network_speed=1; void zeRace_read_config() { FILE *fic; - if ((fic=fopen("zeRace.cfg","rt"))==NULL) + if ((fic=fopen("zeRace.cfg","rb"))==NULL) { fprintf(stderr,"can't open config file \"zeRace.cfg\"\n"); return; @@ -97,7 +106,7 @@ void zeRace_read_config() void zeRace_save_config() { FILE *fic; - if ((fic=fopen("zeRace.cfg","wt"))==NULL) + if ((fic=fopen("zeRace.cfg","wb"))==NULL) { fprintf(stderr,"can't create config file \"zeRace.cfg\"\n"); return; @@ -268,7 +277,7 @@ void zeRace_download_file(char *file) fprintf(stderr,"SDLNet_TCP_Send: %s\n",SDLNet_GetError()); else { - if ((fic=fopen(file,"wt"))==NULL) + if ((fic=fopen(file,"wb"))==NULL) { fprintf(stderr,"can't create \"%s\" file\n",file); zeRace_exit(); @@ -294,7 +303,7 @@ void zeRace_generate_cars() int i,j; SDL_Surface *car; char temp[20]="sprites/carX.png"; - for (i=0;i<12;i++) + for (i=0;inext!=loopcheck) + do { zeRace_download_file(tracklist->full); zeRace_download_file(tracklist->function); tracklist=tracklist->next; - } + } while (tracklist!=loopcheck); srand(time(NULL)); @@ -481,10 +490,35 @@ void print_time(int x,int y,int time) } +/* car lights */ +void lights(int x,int y,int r,Uint32 pixel) +{ + putpixel(screen,x,y,pixel); + if (r>1) + { + putpixel(screen,x-1,y,pixel); + putpixel(screen,x+1,y,pixel); + putpixel(screen,x,y-1,pixel); + putpixel(screen,x,y+1,pixel); + } + if (r>2) + { + putpixel(screen,x-2,y,pixel); + putpixel(screen,x+2,y,pixel); + putpixel(screen,x,y-2,pixel); + putpixel(screen,x,y+2,pixel); + putpixel(screen,x-1,y-1,pixel); + putpixel(screen,x-1,y+1,pixel); + putpixel(screen,x+1,y-1,pixel); + putpixel(screen,x+1,y+1,pixel); + } +} + + /* launch a new race */ void zeRace_launch(int alltime,int go) { - SDL_Surface *cir,*fun; + SDL_Surface *cir,*fun,*hilight; SDL_Rect pos; SDL_Event event; int ku=0,kd=0,kl=0,kr=0,i; @@ -496,7 +530,8 @@ void zeRace_launch(int alltime,int go) int lastack=alltime; struct _record net; struct _car oldnetpos[MAX_CLIENTS],newnetpos[MAX_CLIENTS]; - + int l=80,o=15; + /* free memory */ void free_mem() { @@ -513,13 +548,31 @@ void zeRace_launch(int alltime,int go) } cir=IMG_Load(tracklist->full); + /* dark the track if it is night */ + if (config.bynight) + { + for (pos.x=0;pos.xw;pos.x++) + for (pos.y=0;pos.yh;pos.y++) + { + Uint32 c; + Uint8 r,g,b; + c=getpixel(cir,pos.x,pos.y); + SDL_GetRGB(c,cir->format,&r,&g,&b); + r*=0.3; + g*=0.3; + b*=0.3; + putpixel(cir,pos.x,pos.y,SDL_MapRGB(cir->format,r,g,b)); + } + } fun=IMG_Load(tracklist->function); + hilight=IMG_Load("sprites/light.png"); current.speed=car.speed=0; current.angle=car.angle=tracklist->a*2*M_PI/360; current.x=car.ox=car.x=tracklist->x; current.y=car.oy=car.y=tracklist->y; car.lastcheck=0; + car.lapflag=0; car.w=cars[0][0]->w; car.h=cars[0][0]->h; current.time=0; @@ -626,6 +679,9 @@ void zeRace_launch(int alltime,int go) net.keys[net.time+1]='\0'; } + /* move the car */ + move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); + delay=DELAY; /* if we are in network mode */ if (udpsock!=NULL) @@ -648,14 +704,27 @@ void zeRace_launch(int alltime,int go) for (i=0;idata+strlen("positions")+1+4+4+2+i*8); - newnetpos[i].y=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*8+2); - newnetpos[i].angle=(float)SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*8+2+2)/1000; - newnetpos[i].color=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*8+2+2+2); + newnetpos[i].x=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14); + newnetpos[i].y=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2); + newnetpos[i].angle=(float)SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2+2)/1000; + newnetpos[i].color=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2+2+2); + newnetpos[i].lights_brake=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2+2+2+2); + newnetpos[i].lights_backwards=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2+2+2+2+2); + newnetpos[i].lights_warning=SDLNet_Read16(packet->data+strlen("positions")+1+4+4+2+i*14+2+2+2+2+2+2); } lastack=clienttime; } } + else if (strcmp(packet->data,"collision")==0) + { + net.time=-1; + net.keys[0]='\0'; + lastack=SDLNet_Read32(packet->data+strlen("collision")+1); + car.x=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4)/65536-100; + car.y=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4)/65536-100; + car.speed=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4+4)/65536-100; + car.angle=(float)SDLNet_Read32(packet->data+strlen("collision")+1+4+4+4+4)/65536-100; + } else /* end of this network race */ { zeRace_send_time(best); @@ -669,6 +738,10 @@ void zeRace_launch(int alltime,int go) tmp+=strlen(tmp)+1; SDLNet_Write32(lastack,tmp); tmp+=4; + SDLNet_Write32(car.x,tmp); + tmp+=4; + SDLNet_Write32(car.y,tmp); + tmp+=4; strcpy(tmp,net.keys); tmp+=strlen(tmp)+1; packet->len=(void *)tmp-(void *)packet->data+10; @@ -697,6 +770,25 @@ void zeRace_launch(int alltime,int go) pos.h=car.h; SDL_BlitSurface(cir,&pos,screen,&pos); + /* clear the lights */ + if (config.bynight) + { + pos.x=car.ox-cos(car.angle)*l-sin(car.angle)*o; + pos.y=car.oy-sin(car.angle)*l+cos(car.angle)*o; + pos.x-=60; + pos.y-=60; + pos.w=120; + pos.h=120; + SDL_BlitSurface(cir,&pos,screen,&pos); + pos.x=car.ox-cos(car.angle)*l+sin(car.angle)*o; + pos.y=car.oy-sin(car.angle)*l-cos(car.angle)*o; + pos.x-=60; + pos.y-=60; + pos.w=120; + pos.h=120; + SDL_BlitSurface(cir,&pos,screen,&pos); + } + /* display the network car at the new position */ if (udpsock) for (i=0;iscreen->w) pos.w=screen->w-pos.x; + if (pos.y+pos.h>screen->h) pos.h=screen->h-pos.y; + SDL_UpdateRect(screen,pos.x,pos.y,pos.w,pos.h); + pos.x=car.x-cos(car.angle)*l+sin(car.angle)*15; + pos.y=car.y-sin(car.angle)*l-cos(car.angle)*15; + pos.x-=60; + pos.y-=60; + pos.w=120; + pos.h=120; + if (pos.x<0) pos.x=0; + if (pos.y<0) pos.y=0; + if (pos.x+pos.w>screen->w) pos.w=screen->w-pos.x; + if (pos.y+pos.h>screen->h) pos.h=screen->h-pos.y; + SDL_UpdateRect(screen,pos.x,pos.y,pos.w,pos.h); + } + memcpy(oldnetpos,newnetpos,MAX_CLIENTS*sizeof(struct _car)); - /* move the car */ - move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); - /* play engine sound if no sound is currently playing */ if (lastsound_time+100w/2-splash->w/2-1; pos.w=splash->w+2; pos.y=screen->h/2-splash->h/2-1; pos.h=splash->h+2; - SDL_FillRect(screen,&pos,0xffffff); + SDL_FillRect(screen,&pos,C_WHITE); pos.x=screen->w/2-splash->w/2; pos.y=screen->h/2-splash->h/2; SDL_BlitSurface(splash,NULL,screen,&pos); @@ -844,7 +1053,7 @@ void zeRace_local() { SDL_Surface *full,*preview; SDL_Rect pos; - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); print(screen,WIDTH/2-28*5,HEIGHT/6,"* Please choose your race *"); print(screen,WIDTH/2-strlen(tracklist->title)*5,5*HEIGHT/6-20,tracklist->title); print(screen,WIDTH/2-(strlen(tracklist->author)+strlen("Author : "))*5,5*HEIGHT/6+0,"Author : "); @@ -862,7 +1071,7 @@ void zeRace_local() pos.w=preview->w+2; pos.y=screen->h/2-preview->h/2-1; pos.h=preview->h+2; - SDL_FillRect(screen,&pos,0xffffff); + SDL_FillRect(screen,&pos,C_WHITE); pos.x=WIDTH/2-preview->w/2; pos.y=screen->h/2-preview->h/2; SDL_BlitSurface(preview,NULL,screen,&pos); @@ -914,7 +1123,7 @@ void zeRace_top10(char *buf) { int i,nb,tmp; SDL_Rect pos; - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); nb=SDLNet_Read16(buf); buf+=2; print(screen,WIDTH/2-16*5,HEIGHT/14,"* Race results *"); @@ -966,7 +1175,7 @@ void zeRace_connect(char *host,int port) tmp+=strlen(tmp)+1; go=*tmp++; printf("server asked for track : %s\n",tmp); - while (tracklist->next!=loopcheck) if (strcmp(tracklist->name,tmp)==0) break; else tracklist=tracklist->next; + do if (strcmp(tracklist->name,tmp)==0) break; else tracklist=tracklist->next; while (tracklist!=loopcheck); if (strcmp(tracklist->name,tmp)!=0) { fprintf(stderr,"unknown track : %s\n",tmp); @@ -999,7 +1208,7 @@ void zeRace_network() void update() { - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); print(screen,380,HEIGHT/(NETWORK_OPTIONS+4)*(3+active),">"); print(screen,WIDTH/2-18*5,HEIGHT/(NETWORK_OPTIONS+4),"* Network screen *"); print(screen,400,HEIGHT/(NETWORK_OPTIONS+4)*3,"Server : "); @@ -1128,7 +1337,7 @@ void zeRace_internet() void update() { int i; - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); print(screen,380,HEIGHT/(INTERNET_OPTIONS+4)*(3+active),">"); print(screen,WIDTH/2-19*5,HEIGHT/(INTERNET_OPTIONS+4),"* Internet screen *"); for (i=0;i<10;i++) @@ -1186,12 +1395,12 @@ void zeRace_config() { SDL_Event event; int active=0; - #define CONFIG_OPTIONS 12 + #define CONFIG_OPTIONS 13 void update() { SDL_Rect pos; - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); print(screen,20,HEIGHT/(CONFIG_OPTIONS+4)*(3+active),">"); print(screen,WIDTH/2-24*5,HEIGHT/(CONFIG_OPTIONS+4),"* Configuration screen *"); print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*3,"Pseudo : "); @@ -1218,6 +1427,8 @@ void zeRace_config() SDL_BlitSurface(cars[config.color][0],NULL,screen,&pos); print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*13,"Boss key : "); print(screen,40+10*strlen("Boss key : "),HEIGHT/(CONFIG_OPTIONS+4)*13,config.boss?SDL_GetKeyName(config.boss):""); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*14,"By night : "); + print(screen,40+10*strlen("By night : "),HEIGHT/(CONFIG_OPTIONS+4)*14,config.bynight?"Yes":"No"); print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu"); SDL_Flip(screen); } @@ -1267,11 +1478,12 @@ void zeRace_config() case 8: config.right=0; update(); config.right=read_key(); break; case 9: if (event.key.keysym.sym==SDLK_LEFT) config.color--; else config.color++; - if (config.color<0) config.color=11; - if (config.color>11) config.color=0; + if (config.color<0) config.color=NB_CARS-1; + if (config.color>NB_CARS-1) config.color=0; break; case 10: config.boss=0; update(); config.boss=read_key(); break; - case 11: + case 11: config.bynight=!config.bynight; break; + case 12: return; } update(); @@ -1306,7 +1518,7 @@ void zeRace_menu() void update() { SDL_Rect pos; - SDL_FillRect(screen,NULL,0x000000); + SDL_FillRect(screen,NULL,C_BLACK); pos.x=WIDTH/2-logo->w/2; pos.y=HEIGHT/6-logo->h/2; SDL_BlitSurface(logo,NULL,screen,&pos);