int lasttime;
struct _car car;
IPaddress address;
+ int dx,dy;
} clients [MAX_CLIENTS];
/* UDP stuff */
struct _tracklist *tracklist;
SDL_Surface *fun;
+SDL_Surface *cars[256];
/* return the id of a connected address */
}
+/* 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;x<cars[j]->w;x++) for (y=0;y<cars[j]->h;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 && x2<car->w && y2>0 && y2<car->h)
+ 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);
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);
fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError());
exit(2);
}
-
+
+ zeRace_generate_cars();
+
for (;;)
{
/* announce the server on internet if wanted */
/* look for type of message */
tmp=packet->data;
- /*printf("%s\n",tmp);*/
/* new connection ? */
if (strcmp(tmp,"connect")==0)
}
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;
+ }
}
}
}
clients[i].connected=0;
}
+ /* should we check for collisions ? */
+ if (col)
+ {
+ /* check for collisions */
+ for (i=0;i<MAX_CLIENTS;i++) clients[i].dx=clients[i].dy=0;
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected)
+ for (j=i+1;j<MAX_CLIENTS;j++) if (clients[j].connected)
+ if (i!=j)
+ if (abs(clients[i].car.x-clients[j].car.x)<30 && abs(clients[i].car.y-clients[j].car.y)<30)
+ {
+ int x1,y1,x2,y2;
+ for (x1=0;x1<30;x1++)
+ for (y1=0;y1<30;y1++)
+ if (getpixel(cars[(unsigned char)(256*clients[i].car.angle/2.0/M_PI)%256],x1,y1)!=0)
+ {
+ x2=x1+clients[i].car.x-clients[j].car.x;
+ y2=y1+clients[i].car.y-clients[j].car.y;
+ if (x2>0 && 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;i<MAX_CLIENTS;i++) if (clients[i].connected) if (clients[i].dx || clients[i].dy)
+ {
+ Uint32 c;
+ Uint8 g,t;
+ int dx=clients[i].dx;
+ int dy=clients[i].dy;
+ /* do not jump to much */
+ while (abs(dx)>5) 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.x<fun->w-cars[0]->w && clients[i].car.y>cars[0]->h && clients[i].car.y<fun->h-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;i<MAX_CLIENTS;i++) if (clients[i].connected)
{
tmp+=2;
SDLNet_Write16(clients[j].car.color,tmp);
tmp+=2;
+ SDLNet_Write16(clients[j].car.lights_brake,tmp);
+ tmp+=2;
+ SDLNet_Write16(clients[j].car.lights_backwards,tmp);
+ tmp+=2;
+ SDLNet_Write16(clients[j].car.lights_warning,tmp);
+ tmp+=2;
nb++;
}
SDLNet_Write16(nb,packet->data+strlen("positions")+1+4+4);
}
/* did someone finish the track ? */
+ for (i=0;i<MAX_CLIENTS;i++) { if (clients[i].car.lapflag==1) printf("client %d : %d laps\n",i,clients[i].car.lap); clients[i].car.lapflag=0; }
for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected && clients[i].car.lap==nb_laps) finish=1;
if (finish) break;
/*
- * zeRace 0.4, a funny retro racing game
+ * zeRace 0.5, a funny retro racing game
* http://royale.zerezo.com/zerace/
*
* Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
#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;
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
/* 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;
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;
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;
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();
int i,j;
SDL_Surface *car;
char temp[20]="sprites/carX.png";
- for (i=0;i<12;i++)
+ for (i=0;i<NB_CARS;i++)
{
temp[11]='A'+i;
/* load the car sprite */
{
float x,y;
float tcos,tsin;
- if ((cars[i][j]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,0xff<<RSHIFT,0xff<<GSHIFT,0xff<<BSHIFT,0xff<<ASHIFT))==NULL)
+ if ((cars[i][j]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,RMASK,GMASK,BMASK,AMASK))==NULL)
{
fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError());
zeRace_exit();
/* download missing files */
loopcheck=tracklist;
- while (tracklist->next!=loopcheck)
+ do
{
zeRace_download_file(tracklist->full);
zeRace_download_file(tracklist->function);
tracklist=tracklist->next;
- }
+ } while (tracklist!=loopcheck);
srand(time(NULL));
}
+/* 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;
int lastack=alltime;
struct _record net;
struct _car oldnetpos[MAX_CLIENTS],newnetpos[MAX_CLIENTS];
-
+ int l=80,o=15;
+
/* free memory */
void free_mem()
{
}
cir=IMG_Load(tracklist->full);
+ /* dark the track if it is night */
+ if (config.bynight)
+ {
+ for (pos.x=0;pos.x<screen->w;pos.x++)
+ for (pos.y=0;pos.y<screen->h;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;
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)
for (i=0;i<nb;i++)
{
newnetpos[i].w=newnetpos[i].h=30;
- newnetpos[i].x=SDLNet_Read16(packet->data+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);
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;
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;i<MAX_CLIENTS;i++) if (newnetpos[i].w)
{
pos.w=car.w;
pos.h=car.h;
SDL_BlitSurface(cars[newnetpos[i].color][(unsigned char)(256*newnetpos[i].angle/2.0/M_PI)%256],NULL,screen,&pos);
+
+ /* if the car is braking, display red lights */
+ if (newnetpos[i].lights_brake)
+ {
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3-sin(newnetpos[i].angle)*4,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3+cos(newnetpos[i].angle)*4,3,C_RED);
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3+sin(newnetpos[i].angle)*4,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3-cos(newnetpos[i].angle)*4,3,C_RED);
+ }
+
+ /* if the car is going backwards, display white lights */
+ if (newnetpos[i].lights_backwards)
+ {
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3-sin(newnetpos[i].angle)*4,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3+cos(newnetpos[i].angle)*4,3,C_WHITE);
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3+sin(newnetpos[i].angle)*4,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3-cos(newnetpos[i].angle)*4,3,C_WHITE);
+ }
+
+ /* if the car is stopped, then warning */
+ if (newnetpos[i].lights_warning && alltime/75%2)
+ {
+ lights(newnetpos[i].x-cos(newnetpos[i].angle)*car.w/3-sin(newnetpos[i].angle)*5,newnetpos[i].y-sin(newnetpos[i].angle)*car.h/3+cos(newnetpos[i].angle)*5,2,C_ORANGE);
+ lights(newnetpos[i].x-cos(newnetpos[i].angle)*car.w/3+sin(newnetpos[i].angle)*5,newnetpos[i].y-sin(newnetpos[i].angle)*car.h/3-cos(newnetpos[i].angle)*5,2,C_ORANGE);
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3-sin(newnetpos[i].angle)*5,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3+cos(newnetpos[i].angle)*5,2,C_ORANGE);
+ lights(newnetpos[i].x+cos(newnetpos[i].angle)*car.w/3+sin(newnetpos[i].angle)*5,newnetpos[i].y+sin(newnetpos[i].angle)*car.h/3-cos(newnetpos[i].angle)*5,2,C_ORANGE);
+ }
}
/* display the car at the new position */
pos.h=car.h;
SDL_BlitSurface(cars[config.color][(unsigned char)(256*car.angle/2.0/M_PI)%256],NULL,screen,&pos);
+ /* if the car is braking, display red lights */
+ if (car.lights_brake)
+ {
+ lights(car.x+cos(car.angle)*car.w/3-sin(car.angle)*4,car.y+sin(car.angle)*car.h/3+cos(car.angle)*4,3,C_RED);
+ lights(car.x+cos(car.angle)*car.w/3+sin(car.angle)*4,car.y+sin(car.angle)*car.h/3-cos(car.angle)*4,3,C_RED);
+ }
+
+ /* if the car is going backwards, display white lights */
+ if (car.lights_backwards)
+ {
+ lights(car.x+cos(car.angle)*car.w/3-sin(car.angle)*4,car.y+sin(car.angle)*car.h/3+cos(car.angle)*4,3,C_WHITE);
+ lights(car.x+cos(car.angle)*car.w/3+sin(car.angle)*4,car.y+sin(car.angle)*car.h/3-cos(car.angle)*4,3,C_WHITE);
+ }
+
+ /* if the car is stopped, then warning */
+ if (car.lights_warning && alltime/75%2)
+ {
+ lights(car.x-cos(car.angle)*car.w/3-sin(car.angle)*5,car.y-sin(car.angle)*car.h/3+cos(car.angle)*5,2,C_ORANGE);
+ lights(car.x-cos(car.angle)*car.w/3+sin(car.angle)*5,car.y-sin(car.angle)*car.h/3-cos(car.angle)*5,2,C_ORANGE);
+ lights(car.x+cos(car.angle)*car.w/3-sin(car.angle)*5,car.y+sin(car.angle)*car.h/3+cos(car.angle)*5,2,C_ORANGE);
+ lights(car.x+cos(car.angle)*car.w/3+sin(car.angle)*5,car.y+sin(car.angle)*car.h/3-cos(car.angle)*5,2,C_ORANGE);
+ }
+
+ /* display the lights */
+ if (config.bynight)
+ {
+ lights(car.x+cos(car.angle)*car.w/3-sin(car.angle)*3,car.y+sin(car.angle)*car.h/3+cos(car.angle)*4,2,C_RED);
+ lights(car.x+cos(car.angle)*car.w/3+sin(car.angle)*3,car.y+sin(car.angle)*car.h/3-cos(car.angle)*4,2,C_RED);
+ lights(car.x-cos(car.angle)*car.w/3-sin(car.angle)*4,car.y-sin(car.angle)*car.h/3+cos(car.angle)*4,3,C_YELLOW);
+ lights(car.x-cos(car.angle)*car.w/3+sin(car.angle)*4,car.y-sin(car.angle)*car.h/3-cos(car.angle)*4,3,C_YELLOW);
+ pos.x=car.x-cos(car.angle)*l-sin(car.angle)*o;
+ pos.y=car.y-sin(car.angle)*l+cos(car.angle)*o;
+ pos.x-=50;
+ pos.y-=50;
+ pos.w=100;
+ pos.h=100;
+ SDL_BlitSurface(hilight,NULL,screen,&pos);
+ pos.x=car.x-cos(car.angle)*l+sin(car.angle)*o;
+ pos.y=car.y-sin(car.angle)*l-cos(car.angle)*o;
+ pos.x-=50;
+ pos.y-=50;
+ pos.w=100;
+ pos.h=100;
+ SDL_BlitSurface(hilight,NULL,screen,&pos);
+ }
+
/* update display */
if (udpsock)
{
}
SDL_UpdateRect(screen,car.ox-car.w/2,car.oy-car.h/2,car.w,car.h);
SDL_UpdateRect(screen,car.x-car.w/2,car.y-car.h/2,car.w,car.h);
-
+
+ /* update the lights by night */
+ if (config.bynight)
+ {
+ 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);
+ 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+100<alltime)
{
/* display tires slide */
if (config.tire)
{
- putpixel(cir,car.x+cos(car.angle)*car.w/3-sin(car.angle)*4,car.y+sin(car.angle)*car.h/3+cos(car.angle)*4,0);
- putpixel(cir,car.x+cos(car.angle)*car.w/3+sin(car.angle)*4,car.y+sin(car.angle)*car.h/3-cos(car.angle)*4,0);
+ putpixel(cir,car.x+cos(car.angle)*car.w/3-sin(car.angle)*4,car.y+sin(car.angle)*car.h/3+cos(car.angle)*4,C_BLACK);
+ putpixel(cir,car.x+cos(car.angle)*car.w/3+sin(car.angle)*4,car.y+sin(car.angle)*car.h/3-cos(car.angle)*4,C_BLACK);
/* if we are braking the slide is larger */
if (kd)
{
- putpixel(cir,car.x+cos(car.angle)*car.w/3-sin(car.angle)*3,car.y+sin(car.angle)*car.h/3+cos(car.angle)*3,0);
- putpixel(cir,car.x+cos(car.angle)*car.w/3+sin(car.angle)*3,car.y+sin(car.angle)*car.h/3-cos(car.angle)*3,0);
+ putpixel(cir,car.x+cos(car.angle)*car.w/3-sin(car.angle)*3,car.y+sin(car.angle)*car.h/3+cos(car.angle)*3,C_BLACK);
+ putpixel(cir,car.x+cos(car.angle)*car.w/3+sin(car.angle)*3,car.y+sin(car.angle)*car.h/3-cos(car.angle)*3,C_BLACK);
}
}
}
}
alltime++;
- /* if we completed a lap */
- if (car.lapflag)
+ switch (car.lapflag)
{
- printf("time = %d\"%d\n",current.time*DELAY/1000,current.time*DELAY%1000);
- print(screen,0,0,"Last lap : ");
- print_time(110,0,current.time);
- SDL_UpdateRect(screen,0,0,170,19);
- /* if it is the first turn of the best turn, save it */
- if (best.time==-1 || current.time<best.time)
- memcpy(&best,¤t,sizeof(struct _record));
- /* reset turn variables */
- current.time=0;
- current.x=car.x;
- current.y=car.y;
- current.angle=car.angle;
- current.speed=car.speed;
+ /* if we completed a lap */
+ case 1:
+ printf("time = %d\"%d\n",current.time*DELAY/1000,current.time*DELAY%1000);
+ print(screen,0,0,"Last lap : ");
+ print_time(110,0,current.time);
+ SDL_UpdateRect(screen,0,0,200,19);
+ /* if it is the first turn of the best turn, save it */
+ if (best.time==-1 || current.time<best.time)
+ memcpy(&best,¤t,sizeof(struct _record));
+ /* reset turn variables */
+ current.time=0;
+ current.x=car.x;
+ current.y=car.y;
+ current.angle=car.angle;
+ current.speed=car.speed;
+ car.lapflag=0;
+ break;
+ /* if we completed an incomplete lap */
+ case 2:
+ print(screen,0,0,"Last lap : CANCELED ");
+ SDL_UpdateRect(screen,0,0,200,19);
+ /* reset turn variables */
+ current.time=0;
+ car.lapflag=0;
+ break;
+ /* if we miss a checkpoint */
+ case 3:
+ print(screen,0,0,"Checkpoint missed ! ");
+ SDL_UpdateRect(screen,0,0,200,19);
+ break;
+ /* if we validate a missed checkpoint */
+ case 4:
+ print(screen,0,0,"Checkpoint missed OK");
+ SDL_UpdateRect(screen,0,0,200,19);
+ break;
+ /* nothing */
+ default:
+ break;
}
/* let the system breath */
SDL_Rect pos;
char temp[20]="splashs/0.jpg";
- SDL_FillRect(screen,NULL,0x000000);
- temp[8]=rand()%3+'1';
+ SDL_FillRect(screen,NULL,C_BLACK);
+ temp[8]=rand()%5+'1';
splash=IMG_Load(temp);
pos.x=screen->w/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);
{
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 : ");
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);
{
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 *");
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);
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 : ");
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++)
{
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 : ");
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):"<press key>");
+ 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);
}
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();
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);