From: Antoine Jacquet Date: Sat, 27 Nov 2004 23:00:00 +0000 (+0100) Subject: version 0.4 X-Git-Tag: v0.4 X-Git-Url: http://royale.zerezo.com/git/?a=commitdiff_plain;h=ee6ec6d95d78f74973a2ba97077cc94709bb6c61;p=zeRace version 0.4 * added "loop" track * fixed "car" track * fixed "hairpins" track * added boss key (thank you Christophe Sauthier) * tracks server (client can now download new tracks when they are available) * improved network protocol * added a framework to program bots * first bot for the game : "Anticip" * fixed memory management (server and client release memory when changing track) * generic Makefile (easier to compile Linux/Windows binaries) * network startup was fixed to avoid to much delay between clients and server * fixed a bug when sending keys for record validation * also send records in network mode * game and network protocol are now endian safe (thank you Markus W. Weissmann) --- diff --git a/CHANGELOG b/CHANGELOG index 528d161..421f75c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,21 @@ Change log file for zeRace +version 0.4 (2004-11-28) + * added "loop" track + * fixed "car" track + * fixed "hairpins" track + * added boss key (thank you Christophe Sauthier) + * tracks server (client can now download new tracks when they are available) + * improved network protocol + * added a framework to program bots + * first bot for the game : "Anticip" + * fixed memory management (server and client release memory when changing track) + * generic Makefile (easier to compile Linux/Windows binaries) + * network startup was fixed to avoid to much delay between clients and server + * fixed a bug when sending keys for record validation + * also send records in network mode + * game and network protocol are now endian safe (thank you Markus W. Weissmann) + version 0.3 (2004-09-27) * added network/internet mode * code is now split into generic modules diff --git a/Makefile b/Makefile index 0b67908..a359dba 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,31 @@ CC=gcc +SDLCONFIG=sdl-config -all:zeRace server +all:zeRace server bot_anticip -zeRace:zeRace.c network.h sdl.o car.o tracklist.o - $(CC) -ansi -Wall -o zeRace zeRace.c sdl.o car.o tracklist.o `sdl-config --cflags --libs` -lSDL_net -lSDL_mixer -lSDL_image -lSDL_gfx +zeRace:zeRace.c network.h sdl.o car.o tracklist.o $(ICON) + $(CC) -ansi -Wall -o zeRace$(EXT) zeRace.c sdl.o car.o tracklist.o $(ICON) `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_mixer -lSDL_image -lSDL_gfx -L. server:server.c network.h sdl.o car.o tracklist.o - $(CC) -ansi -Wall -o server server.c sdl.o car.o tracklist.o `sdl-config --cflags --libs` -lSDL_net -lSDL_image + $(CC) -ansi -Wall -o server$(EXT) server.c sdl.o car.o tracklist.o `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_image -L. + +bot_anticip:bot_anticip.c bot.o sdl.o car.o tracklist.o + $(CC) -ansi -Wall -o bot_anticip$(EXT) bot_anticip.c bot.o sdl.o car.o tracklist.o `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_image -L. sdl.o:sdl.c sdl.h - $(CC) -ansi -Wall -c sdl.c `sdl-config --cflags` + $(CC) -ansi -Wall -c sdl.c `$(SDLCONFIG) --cflags` -car.o:car.c car.h - $(CC) -ansi -Wall -c car.c `sdl-config --cflags` +car.o:car.c car.h sdl.h + $(CC) -ansi -Wall -c car.c `$(SDLCONFIG) --cflags` tracklist.o:tracklist.c tracklist.h $(CC) -ansi -Wall -c tracklist.c +bot.o:bot.c sdl.o car.o tracklist.o + $(CC) -ansi -Wall -c bot.c `$(SDLCONFIG) --cflags` + +icon.o:icon.rc + $(WINDRES) -i icon.rc -o icon.o + clean: - rm -f zeRace server *.o *.cfg + rm -f zeRace server bot_anticip *.exe *.o *.cfg diff --git a/README b/README index 1c0a1e6..ff68211 100644 --- a/README +++ b/README @@ -1,3 +1,19 @@ -zeRace 0.3 +zeRace 0.4 site: http://royale.zerezo.com/zerace/ mail: royale@zerezo.com + +install: +In order to compile the game, you will need SDL, SDL_net, SDL_mixer, SDL_image, SDL_gfx and the related developpement headers. +Then, just type "make" to build the game. +The Makefile as some parameters. For example, in order to cross-compile Windows binaries using MinGW you can type : +make CC=i586-mingw32msvc-gcc SDLCONFIG=/path/to/sdl-config WINDRES=i586-mingw32msvc-windres ICON=icon.o EXT=.exe + +bots: +To play a game against bots, you will first need to launch a local server : +./server "My private server" 5 1 private +Then launch as many bots as you want : +./bot_anticip localhost 3600 0 +./bot_anticip localhost 3600 8 +./bot_anticip localhost 3600 16 +Then you can join your own server in zeRace in the "network game" section. +If you are under Windows, replace by "server.exe" and "bot_anticip.exe" in MS-DOS commands. diff --git a/bot.c b/bot.c new file mode 100644 index 0000000..ef93b04 --- /dev/null +++ b/bot.c @@ -0,0 +1,266 @@ +#include "bot.h" + +#define DELAY 7 +#define MAXRECORDKEYS 9999 + +/* tracklist */ +struct _tracklist *tracklist; + +/* user setup */ +struct _config +{ + char pseudo[MAXLINELENGTH]; + char url[MAXLINELENGTH]; + int fullscreen; + int sound; + int tire; + SDLKey up; + SDLKey down; + SDLKey left; + SDLKey right; + int color; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6}; + +/* full script for a lap */ +struct _record +{ + float x,y,angle,speed; + char keys[MAXRECORDKEYS]; + int time; +}; + +/* network stuff */ +UDPsocket udpsock=NULL; +UDPpacket *packet; +int network_speed=1; +int aleas; + + +/* exit the game and clean */ +void zeRace_exit() +{ + printf("quit\n"); + SDLNet_Quit(); + SDL_Quit(); + exit(0); +} + + +/* initialize the game */ +void zeRace_init() +{ + /* do a clean exit in case of emergency */ + signal(SIGINT,zeRace_exit); + signal(SIGTERM,zeRace_exit); + + /* get the list of local tracks */ + if (!zeRace_get_tracks(&tracklist)) zeRace_exit(); + + srand(time(NULL)); + + /* robot configuration */ + sprintf(config.pseudo,"\"%s\" bot(%d)",bot_name(),aleas); + config.color=rand()%12; + + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) + { + fprintf(stderr,"could not initialize SDL : %s\n",SDL_GetError()); + zeRace_exit(); + } + atexit(SDL_Quit); + + if (SDLNet_Init()==-1) + { + fprintf(stderr,"could not initialize SDLNet : %s\n",SDLNet_GetError()); + zeRace_exit(); + } + + packet=SDLNet_AllocPacket(1024); + if (!packet) + { + fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError()); + zeRace_exit(); + } +} + + +/* launch a new race */ +void zeRace_launch(int alltime,int go) +{ + SDL_Surface *cir,*fun; + int ku=0,kd=0,kl=0,kr=0,i; + struct _car car; + int delay=DELAY; + int lastack=alltime; + struct _record net; + + cir=IMG_Load(tracklist->full); + fun=IMG_Load(tracklist->function); + + car.speed=0; + car.angle=tracklist->a*2*M_PI/360; + car.ox=car.x=tracklist->x; + car.oy=car.y=tracklist->y; + car.lastcheck=0; + car.w=30; + car.h=30; + net.time=0; + + /* startup countdown */ + for (i=4;i>=-1;i--) + { + if (!go) break; + if (i!=-1) SDL_Delay(1000); + } + + /* main loop */ + for (;;) + { + /* call the IA */ + bot_ia(tracklist->name,&car,fun,&ku,&kd,&kl,&kr); + + /* random movement if asked */ + if (aleas) if (rand()%aleas==0) + { + ku=rand()%2; + kl=rand()%2; + kr=rand()%2; + kd=rand()%2; + } + + if (udpsock) + { + net.keys[net.time]=(ku<<3 | kd<<2 | kl<<1 | kr)+'A'; + net.keys[net.time+1]='\0'; + } + + delay=DELAY; + /* if we are in network mode */ + if (udpsock!=NULL) + { + char *tmp; + while (SDLNet_UDP_Recv(udpsock,packet)) if (strcmp(packet->data,"positions")==0) + { + int servertime,clienttime,nb; + servertime=SDLNet_Read32(packet->data+strlen("positions")+1); + clienttime=SDLNet_Read32(packet->data+strlen("positions")+1+4); + nb=SDLNet_Read16(packet->data+strlen("positions")+1+4+4); + if (clienttime>lastack) + { + memcpy(net.keys,net.keys+clienttime-lastack,net.time+1); + net.time-=clienttime-lastack; + if (clienttime>servertime+5) delay+=DELAY; + if (clienttimedata; + strcpy(tmp,"keys"); + tmp+=strlen(tmp)+1; + SDLNet_Write32(lastack,tmp); + tmp+=4; + strcpy(tmp,net.keys); + tmp+=strlen(tmp)+1; + packet->len=(void *)tmp-(void *)packet->data+10; + if (net.time%network_speed==0) if (!SDLNet_UDP_Send(udpsock,-1,packet)) + { + fprintf(stderr,"SDLNet_UDP_Send: %s\n",SDLNet_GetError()); + exit(2); + }; + } + } + + /* move the car */ + move_car(&car,(ku<<3 | kd<<2 | kl<<1 | kr),fun); + + /* let the system breath */ + SDL_Delay(delay); + + /* game time */ + net.time++; + if (udpsock && net.time>MAX_LAG) + { + fprintf(stderr,"timeout !\n"); + SDL_FreeSurface(cir); + SDL_FreeSurface(fun); + return; + } + alltime++; + } +} + + +/* connect to a server */ +void zeRace_connect(char *host,int port) +{ + char *tmp; + int lag=0; + udpsock=SDLNet_UDP_Open(0); + if (udpsock==NULL) + { + fprintf(stderr,"SDLNet_UDP_Open: %s\n",SDLNet_GetError()); + zeRace_exit(); + } + SDLNet_ResolveHost(&packet->address,host,port); + tmp=packet->data; + strcpy(tmp,"connect"); + tmp+=strlen(tmp)+1; + strcpy(tmp,config.pseudo); + tmp+=strlen(tmp)+1; + SDLNet_Write16(config.color,tmp); + tmp+=2; + packet->len=(void *)tmp-(void *)packet->data; + SDLNet_UDP_Send(udpsock,-1,packet); + /* network loop */ + while (SDLNet_UDP_Recv(udpsock,packet) || lagdata; + if (strcmp(tmp,"track")==0) + { + struct _tracklist *loopcheck=tracklist; + int time; + char go; + 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; + if (strcmp(tracklist->name,tmp)!=0) + { + fprintf(stderr,"unknown track : %s\n",tmp); + zeRace_exit(); + } + tmp+=strlen(tmp)+1; + time=SDLNet_Read32(tmp); + tmp+=4; + network_speed=SDLNet_Read32(tmp); + zeRace_launch(time,go); + if (strcmp(packet->data,"finish")==0) SDL_Delay(5000); + lag=0; + } + SDL_Delay(7); + lag++; + } + SDLNet_UDP_Close(udpsock); + udpsock=NULL; +} + + +/* main program */ +int main(int argc,char *argv[]) +{ + if (argc!=4) { fprintf(stderr,"Usage : %s host port random\n host : host or ip of the server to connect to\n port : port number of the server to connect to\n random : frequency of random moves (0 = no random moves, 1 = only random, 1000 = 1/1000 random moves)\n",argv[0]); exit(1); } + aleas=atoi(argv[3]); + zeRace_init(); + zeRace_connect(argv[1],atoi(argv[2])); + zeRace_exit(); + return 0; +} diff --git a/bot.h b/bot.h new file mode 100644 index 0000000..22c3b7f --- /dev/null +++ b/bot.h @@ -0,0 +1,18 @@ +/* generic bot framework */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdl.h" +#include "car.h" +#include "tracklist.h" +#include "network.h" + +/* ia functions */ +char *bot_name(); +void bot_ia(char *trackname,struct _car *car,SDL_Surface *fun,int *ku,int *kd,int *kl,int *kr); diff --git a/bot_anticip.c b/bot_anticip.c new file mode 100644 index 0000000..22de8dd --- /dev/null +++ b/bot_anticip.c @@ -0,0 +1,121 @@ +/* + * zeRace "anticip" bot + * http://royale.zerezo.com/zerace/ + * + * Copyright (C) 2004 Antoine Jacquet + * Licensed under GPL + * + * This robot uses the idea described on this page : + * http://rars.sourceforge.net/selection/felix.html + * Thanks to Doug Eleveld + */ + +#include "bot.h" + +char *bot_name() +{ + return "Anticip"; +} + +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; + float o,m,s; + + /* adjust the properties depending of the track, this was "manually" optimized ;) */ + if (strcmp(trackname,"car")==0) + { + a1=190; + a2=180; + o=0.1; + m=0.1; + s=car->speed/3.3+0.4; + og=130; + } + else if (strcmp(trackname,"first")==0) + { + a1=240; + a2=230; + o=0.1; + m=0.1; + s=car->speed/3.3+0.3; + og=120; + } + else if (strcmp(trackname,"icy")==0) + { + a1=250; + a2=240; + o=0.3; + m=0.1; + s=car->speed/3.3+0.3; + og=120; + } + else if (strcmp(trackname,"hairpins")==0) + { + a1=220; + a2=210; + o=0.6; + m=0.1; + s=car->speed/3.3+0.4; + og=120; + } + else if (strcmp(trackname,"simple")==0) + { + a1=190; + a2=180; + o=0.2; + m=0.1; + s=car->speed/3.3+0.4; + og=1; + } + else if (strcmp(trackname,"loop")==0) + { + a1=150; + a2=90; + o=0.8; + m=0.1; + s=car->speed/3.3+0.4; + og=1; + } + /* some default values that may work on some tracks */ + else + { + a1=190; + a2=180; + o=0.2; + m=0.1; + s=car->speed/3.3+0.4; + og=1; + } + + /* should we accelerate or brake ? */ + c=getpixel(fun,car->x,car->y); + *ku=1,*kd=0; + for (l=0;lx-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 (gspeed>m) { *ku=0,*kd=1; break; } + } + + /* should we turn ? left or right ? */ + *kl=0; + *kr=0; + for (l=0;lx-cos(car->angle)*l*s; + y2=car->y-sin(car->angle)*l*s; + x3=car->x-cos(car->angle-o)*l*s; + y3=car->y-sin(car->angle-o)*l*s; + 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 (g>tg) { *kr=1; break; } else if (glapflag=0; @@ -13,11 +13,11 @@ void move_car(struct _car *car,int keys,SDL_Surface *fun) /* 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 )&0xff; + r=(c>>RSHIFT)&0xff; /* green layer (road quality) */ - g=(c>>8 )&0xff; - /* blue layer (unused) */ - b=(c>>16)&0xff; + g=(c>>GSHIFT)&0xff; + /* blue layer (grip) */ + b=(c>>BSHIFT)&0xff; if (keys & 8) /* up */ car->speed+=0.01*2*COEFF; diff --git a/network.h b/network.h index f7cb706..206cfe6 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.3" +#define VERSION "0.4" diff --git a/sdl.h b/sdl.h index 193d175..3eceb70 100644 --- a/sdl.h +++ b/sdl.h @@ -4,6 +4,19 @@ #include #include +/* endianness setup */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + #define RSHIFT 24 + #define GSHIFT 16 + #define BSHIFT 8 + #define ASHIFT 0 +#else + #define RSHIFT 0 + #define GSHIFT 8 + #define BSHIFT 16 + #define ASHIFT 24 +#endif + void print(SDL_Surface *dst,int x,int y,unsigned char *text); void readstring(SDL_Surface *dst,int x,int y,unsigned char *text,int limit); Uint32 getpixel(SDL_Surface *surface, int x, int y); diff --git a/server.c b/server.c index c6da730..047d985 100644 --- a/server.c +++ b/server.c @@ -54,14 +54,14 @@ void announce(char *name,int clients) printf("announcing server... "); fflush(stdout); - if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + if (SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); return; } tcpsock=SDLNet_TCP_Open(&ip); - if(!tcpsock) + if (!tcpsock) { fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError()); return; @@ -72,11 +72,12 @@ void announce(char *name,int clients) len=strlen(temp); result=SDLNet_TCP_Send(tcpsock,temp,len); - if(resultname); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); - memcpy(tmp,&network_speed,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write32(time,tmp); + tmp+=4; + SDLNet_Write32(network_speed,tmp); + tmp+=4; packet->len=(void *)tmp-(void *)packet->data; for (i=0;ix; clients[i].car.y=tracklist->y; clients[i].car.w=30; @@ -233,10 +235,10 @@ int main(int argc,char *argv[]) *tmp++=0; /* no startup countdown */ strcpy(tmp,tracklist->name); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); - memcpy(tmp,&network_speed,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write32(time,tmp); + tmp+=4; + SDLNet_Write32(network_speed,tmp); + tmp+=4; packet->len=(void *)tmp-(void *)packet->data; SDLNet_UDP_Send(udpsock,-1,packet); break; @@ -264,10 +266,11 @@ int main(int argc,char *argv[]) { int temp; tmp+=strlen(tmp)+1; - memcpy(&temp,tmp,sizeof(int)); - tmp+=sizeof(int); - if (clients[id].lasttime==temp) + temp=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) @@ -298,20 +301,26 @@ int main(int argc,char *argv[]) tmp=packet->data; strcpy(tmp,"positions"); tmp+=strlen(tmp)+1; - memcpy(tmp,&time,sizeof(int)); - tmp+=sizeof(int); /* for server time */ - tmp+=sizeof(int); /* for client time */ - tmp+=sizeof(int); /* for number of cars */ + SDLNet_Write32(time,tmp); + tmp+=4; /* for server time */ + tmp+=4; /* for client time */ + tmp+=2; /* for number of cars */ nb=0; for (j=0;jdata+strlen("positions")+1+sizeof(int)+sizeof(int),&nb,sizeof(int)); + SDLNet_Write16(nb,packet->data+strlen("positions")+1+4+4); + SDLNet_Write32(clients[i].lasttime,packet->data+strlen("positions")+1+4); packet->len=(void *)tmp-(void *)packet->data; - memcpy(packet->data+strlen("positions")+1+sizeof(int),&clients[i].lasttime,sizeof(int)); packet->address=clients[i].address; SDLNet_UDP_Send(udpsock,-1,packet); } @@ -329,7 +338,7 @@ int main(int argc,char *argv[]) tmp=packet->data; strcpy(tmp,"finish"); tmp+=strlen(tmp)+1; - tmp+=sizeof(int); /* space for number */ + tmp+=2; /* space for number */ nb=0; for (i=0;i<10;i++) { @@ -343,14 +352,14 @@ int main(int argc,char *argv[]) { sprintf(tmp,"%s : %d",clients[best_id].pseudo,best_sc); tmp+=strlen(tmp)+1; - memcpy(tmp,&clients[best_id].car.color,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write16(clients[best_id].car.color,tmp); + tmp+=2; clients[best_id].car.lap=-1; nb++; printf("top %d : %s - %d\n",nb,clients[best_id].pseudo,best_sc); } } - memcpy(packet->data+strlen("finish")+1,&nb,sizeof(int)); + SDLNet_Write16(nb,packet->data+strlen("finish")+1); packet->len=(void *)tmp-(void *)packet->data; for (i=0;inext; } diff --git a/sprites/boss.png b/sprites/boss.png new file mode 100644 index 0000000..d61eae7 Binary files /dev/null and b/sprites/boss.png differ diff --git a/tracks/car_function.png b/tracks/car_function.png index 1fd3062..8b6430a 100644 Binary files a/tracks/car_function.png and b/tracks/car_function.png differ diff --git a/tracks/hairpins_function.png b/tracks/hairpins_function.png index 9d9339b..10cb4d9 100644 Binary files a/tracks/hairpins_function.png and b/tracks/hairpins_function.png differ diff --git a/tracks/list.txt b/tracks/list.txt index a352376..d198f48 100644 --- a/tracks/list.txt +++ b/tracks/list.txt @@ -25,8 +25,8 @@ Royale 435 215 180 -1175 -Royale +1149 +mrhe hairpins Hairpins @@ -35,8 +35,8 @@ ICFP Programming Contest 505 665 0 -3158 -Voisin +3030 +Royale simple Simple @@ -45,5 +45,15 @@ ICFP Programming Contest 585 565 0 -1784 -Voisin +1766 +Royale + +loop +Loop +Royale +0.1 +678 +686 +0 +1614 +Royale diff --git a/tracks/loop.png b/tracks/loop.png new file mode 100644 index 0000000..f9dd0af Binary files /dev/null and b/tracks/loop.png differ diff --git a/tracks/loop_function.png b/tracks/loop_function.png new file mode 100644 index 0000000..3d486b9 Binary files /dev/null and b/tracks/loop_function.png differ diff --git a/zeRace.c b/zeRace.c index c88d6cf..6f787e0 100644 --- a/zeRace.c +++ b/zeRace.c @@ -1,5 +1,5 @@ /* - * zeRace 0.3, a funny retro racing game + * zeRace 0.4, a funny retro racing game * http://royale.zerezo.com/zerace/ * * Copyright (C) 2004 Antoine Jacquet @@ -33,6 +33,7 @@ #include "car.h" #include "tracklist.h" #include "network.h" +#include /* configuration constants */ #define COEFF 1 @@ -57,7 +58,8 @@ struct _config SDLKey left; SDLKey right; int color; -} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6}; + SDLKey boss; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6,SDLK_b}; /* full script for a lap */ struct _record @@ -133,14 +135,14 @@ void zeRace_check_version() printf("checking version... "); fflush(stdout); - if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + if (SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); return; } tcpsock=SDLNet_TCP_Open(&ip); - if(!tcpsock) + if (!tcpsock) { fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError()); return; @@ -148,7 +150,7 @@ void zeRace_check_version() len=strlen(request); result=SDLNet_TCP_Send(tcpsock,request,len); - if(resultnext!=loopcheck) + { + zeRace_download_file(tracklist->full); + zeRace_download_file(tracklist->function); + tracklist=tracklist->next; + } + srand(time(NULL)); if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) @@ -293,7 +365,7 @@ void zeRace_init() } atexit(SDL_Quit); - if(SDLNet_Init()==-1) + if (SDLNet_Init()==-1) { fprintf(stderr,"could not initialize SDLNet : %s\n",SDLNet_GetError()); zeRace_exit(); @@ -333,7 +405,7 @@ void zeRace_init() /* send the best time for this race to the web server */ -void zeRace_send_time(struct _record record/*float x,float y,float speed,float angle,int btime,char *bkeys*/) +void zeRace_send_time(struct _record record) { IPaddress ip; TCPsocket tcpsock; @@ -356,17 +428,20 @@ void zeRace_send_time(struct _record record/*float x,float y,float speed,float a char *msg9="&bkeys="; int len,result; + /* if the best time is small enought to save all keys, send it */ + if (record.time>=MAXRECORDKEYS) return; + printf("sending time... "); fflush(stdout); - if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + if (SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); return; } tcpsock=SDLNet_TCP_Open(&ip); - if(!tcpsock) + if (!tcpsock) { fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError()); return; @@ -377,7 +452,7 @@ void zeRace_send_time(struct _record record/*float x,float y,float speed,float a len=strlen(temp); result=SDLNet_TCP_Send(tcpsock,temp,len); - if(resultfull); fun=IMG_Load(tracklist->function); @@ -483,13 +573,6 @@ void zeRace_launch(int alltime,int go) switch (event.key.keysym.sym) { case SDLK_ESCAPE: - /* free memory */ - Mix_FreeMusic(light); - Mix_FreeMusic(engine); - Mix_FreeMusic(crash); - Mix_FreeMusic(slide); - /* if the best time is small enought to save all keys, send it */ - if (best.timedata,"positions")==0) { - /*struct _car netcar;*/ int servertime,clienttime,nb; - memcpy(&servertime,packet->data+strlen("positions")+1,sizeof(int)); - memcpy(&clienttime,packet->data+strlen("positions")+1+sizeof(int),sizeof(int)); - memcpy(&nb,packet->data+strlen("positions")+1+sizeof(int)+sizeof(int),sizeof(int)); + servertime=SDLNet_Read32(packet->data+strlen("positions")+1); + clienttime=SDLNet_Read32(packet->data+strlen("positions")+1+4); + nb=SDLNet_Read16(packet->data+strlen("positions")+1+4+4); if (clienttime>lastack) { memcpy(net.keys,net.keys+clienttime-lastack,net.time+1); @@ -547,19 +644,31 @@ void zeRace_launch(int alltime,int go) if (clienttime>servertime+5) delay+=DELAY; if (clienttimedata+strlen("positions")+1+sizeof(int)*3,sizeof(struct _car)*nb); + 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); + } lastack=clienttime; } - } else return; + } + else /* end of this network race */ + { + zeRace_send_time(best); + free_mem(); + return; + } if (strlen(net.keys)!=0) { tmp=packet->data; strcpy(tmp,"keys"); tmp+=strlen(tmp)+1; - memcpy(tmp,&lastack,sizeof(int)); - tmp+=sizeof(int); + SDLNet_Write32(lastack,tmp); + tmp+=4; strcpy(tmp,net.keys); tmp+=strlen(tmp)+1; packet->len=(void *)tmp-(void *)packet->data+10; @@ -664,6 +773,19 @@ void zeRace_launch(int alltime,int go) if (config.sound) Mix_PlayMusic(crash,1)==-1; } + /* game time */ + current.time++; + net.time++; + if (udpsock && net.time>MAX_LAG) + { + print(screen,WIDTH/2-strlen("Timeout !")*5,HEIGHT/2-10,"Timeout !"); + SDL_Flip(screen); + zeRace_send_time(best); + free_mem(); + return; + } + alltime++; + /* if we completed a lap */ if (car.lapflag) { @@ -684,16 +806,6 @@ void zeRace_launch(int alltime,int go) /* let the system breath */ SDL_Delay(delay); - /* game time */ - current.time++; - net.time++; - if (udpsock && net.time>MAX_LAG) - { - print(screen,WIDTH/2-strlen("Timeout !")*5,HEIGHT/2-10,"Timeout !"); - SDL_Flip(screen); - return; - } - alltime++; } } @@ -719,7 +831,7 @@ void zeRace_splash() print(screen,screen->w/2-strlen("zeRace " VERSION)*5,screen->h/2-splash->h/2-20,"zeRace " VERSION); SDL_FreeSurface(splash); SDL_Flip(screen); - /*SDL_Delay(2000);*/ + SDL_Delay(2000); } @@ -803,15 +915,15 @@ void zeRace_top10(char *buf) int i,nb,tmp; SDL_Rect pos; SDL_FillRect(screen,NULL,0x000000); - memcpy(&nb,buf,sizeof(int)); - buf+=sizeof(int); + nb=SDLNet_Read16(buf); + buf+=2; print(screen,WIDTH/2-16*5,HEIGHT/14,"* Race results *"); for (i=0;ilen=(void *)tmp-(void *)packet->data; SDLNet_UDP_Send(udpsock,-1,packet); /* network loop */ @@ -861,9 +973,9 @@ void zeRace_connect(char *host,int port) zeRace_exit(); } tmp+=strlen(tmp)+1; - memcpy(&time,tmp,sizeof(int)); - tmp+=sizeof(int); - memcpy(&network_speed,tmp,sizeof(int)); + time=SDLNet_Read32(tmp); + tmp+=4; + network_speed=SDLNet_Read32(tmp); zeRace_launch(time,go); if (strcmp(packet->data,"finish")==0) zeRace_top10(packet->data+strlen(packet->data)+1); lag=0; @@ -974,14 +1086,14 @@ void zeRace_internet() printf("dowloading list of servers... "); fflush(stdout); - if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + if (SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); return; } tcpsock=SDLNet_TCP_Open(&ip); - if(!tcpsock) + if (!tcpsock) { fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError()); return; @@ -989,7 +1101,7 @@ void zeRace_internet() len=strlen(request); result=SDLNet_TCP_Send(tcpsock,request,len); - if(result"); print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu"); SDL_Flip(screen); } @@ -1157,7 +1270,8 @@ void zeRace_config() if (config.color<0) config.color=11; if (config.color>11) config.color=0; break; - case 10: + case 10: config.boss=0; update(); config.boss=read_key(); break; + case 11: return; } update();