--- /dev/null
+/* zeRace dedicated server */
+
+#include <SDL_net.h>
+#include "network.h"
+#include "car.h"
+#include "tracklist.h"
+
+/* each client has his data */
+struct _clients
+{
+ char pseudo[MAXLINELENGTH];
+ int connected;
+ int lasttime;
+ struct _car car;
+ IPaddress address;
+} clients [MAX_CLIENTS];
+
+/* UDP stuff */
+UDPsocket udpsock;
+UDPpacket *packet;
+
+struct _tracklist *tracklist;
+SDL_Surface *fun;
+
+
+/* return the id of a connected address */
+int lookup(IPaddress address)
+{
+ int i;
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected && clients[i].address.host==address.host && clients[i].address.port==address.port) return i;
+ return -1;
+}
+
+
+/* announce the server on internet */
+void announce(char *name,int clients)
+{
+ IPaddress ip;
+ TCPsocket tcpsock;
+ char *temp;
+ char *msg1=
+ "POST /zerace/announce.php HTTP/1.0\n"
+ "Host: royale.zerezo.com\n"
+ "User-Agent: zeRace dedicated server " VERSION "\n"
+ "Content-Type: application/x-www-form-urlencoded\n"
+ "Content-Length: 99999\n"
+ "\n"
+ "version=" VERSION
+ "&port=" PORT
+ "&name=";
+ char *msg2="&clients=";
+ int len,result;
+
+ printf("announcing server... ");
+ fflush(stdout);
+
+ 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)
+ {
+ fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError());
+ return;
+ }
+
+ temp=(char *)malloc(strlen(msg1)+strlen(name)+strlen(msg2)+10);
+ sprintf(temp,"%s%s%s%d\n",msg1,name,msg2,clients);
+
+ len=strlen(temp);
+ result=SDLNet_TCP_Send(tcpsock,temp,len);
+ if(result<len)
+ fprintf(stderr,"SDLNet_TCP_Send: %s\n", SDLNet_GetError());
+ else
+ printf("done\n");
+
+ SDLNet_TCP_Close(tcpsock);
+}
+
+
+/* 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;
+
+ if (argc!=5)
+ {
+ fprintf(stderr,
+ "usage: %s 'server_name' nb_laps network_speed (public|private)\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"
+ ,argv[0]
+ );
+ exit(1);
+ }
+ printf("server_name : %s\n",argv[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]));
+
+ if (!zeRace_get_tracks(&tracklist)) exit(1);
+
+ if (SDL_Init(0)==-1)
+ {
+ fprintf(stderr,"SDL_Init: %s\n",SDL_GetError());
+ exit(1);
+ };
+ if (SDLNet_Init()==-1)
+ {
+ fprintf(stderr,"SDLNet_Init: %s\n",SDLNet_GetError());
+ exit(2);
+ }
+
+ udpsock=SDLNet_UDP_Open(atoi(PORT));
+ if (!udpsock)
+ {
+ fprintf(stderr,"SDLNet_UDP_Open: %s\n",SDLNet_GetError());
+ exit(2);
+ }
+
+ packet=SDLNet_AllocPacket(1024);
+ if (!packet)
+ {
+ fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError());
+ exit(2);
+ }
+
+ for (;;)
+ {
+ /* announce the server on internet if wanted */
+ nb=0;
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected) nb++;
+ if (pub) announce(argv[1],nb);
+
+ /* load new track */
+ printf("loading track \"%s\"\n",tracklist->name);
+ fun=IMG_Load(tracklist->function);
+
+ /* reset clients variables */
+ for (i=0;i<MAX_CLIENTS;i++)
+ {
+ clients[i].lasttime=time;
+ clients[i].car.x=tracklist->x;
+ clients[i].car.y=tracklist->y;
+ clients[i].car.w=30;
+ clients[i].car.h=30;
+ clients[i].car.angle=tracklist->a*2*M_PI/360;
+ clients[i].car.speed=0;
+ clients[i].car.lap=0;
+ clients[i].car.lastcheck=0;
+ }
+
+ /* tell the clients */
+ tmp=packet->data;
+ strcpy(tmp,"track");
+ tmp+=strlen(tmp)+1;
+ *tmp++=1; /* 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);
+ packet->len=(void *)tmp-(void *)packet->data;
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected)
+ {
+ packet->address=clients[i].address;
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ }
+
+ /* wait for everybody startup */
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected) break;
+ if (i!=MAX_CLIENTS) SDL_Delay(5000);
+
+ printf("go\n");
+
+ /* main race loop */
+ for (;;)
+ {
+ int finish=0;
+
+ /* read all available packets */
+ while (SDLNet_UDP_Recv(udpsock,packet))
+ {
+ /* return the local id based on the address */
+ id=lookup(packet->address);
+
+ /* look for type of message */
+ tmp=packet->data;
+ /*printf("%s\n",tmp);*/
+
+ /* new connection ? */
+ if (strcmp(tmp,"connect")==0)
+ {
+ /* allready connected ? */
+ if (id!=-1 && clients[id].connected)
+ {
+ /* should not happen */
+ printf("client %d allready connected\n",id);
+ }
+ else
+ for (i=0;i<MAX_CLIENTS;i++) if (!clients[i].connected)
+ {
+ clients[i].address=packet->address;
+ clients[i].connected=1;
+ clients[i].lasttime=time;
+ memset(&clients[i].car,0,sizeof(struct _car));
+ tmp+=strlen(tmp)+1;
+ strcpy(clients[i].pseudo,tmp);
+ tmp+=strlen(tmp)+1;
+ memcpy(&clients[i].car.color,tmp,sizeof(int));
+ clients[i].car.x=tracklist->x;
+ clients[i].car.y=tracklist->y;
+ clients[i].car.w=30;
+ clients[i].car.h=30;
+ clients[i].car.angle=tracklist->a*2*M_PI/360;
+ clients[i].car.speed=0;
+ clients[i].car.lap=0;
+ clients[i].car.lastcheck=0;
+ memcpy(ip,&packet->address.host,4);
+ printf("client %d connected at %d : %d.%d.%d.%d:%d (pseudo : %s, color : %d)\n",i,time,ip[0],ip[1],ip[2],ip[3],packet->address.port,clients[i].pseudo,clients[i].car.color);
+ tmp=packet->data;
+ strcpy(tmp,"track");
+ tmp+=strlen(tmp)+1;
+ *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);
+ packet->len=(void *)tmp-(void *)packet->data;
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ break;
+ }
+ }
+ else
+
+ /* disconnection ? */
+ if (strcmp(tmp,"disconnect")==0 && id!=-1)
+ {
+ clients[id].connected=0;
+ printf("client %d disconnected\n",id);
+ }
+ else
+
+ /* keys message ? */
+ if (strcmp(tmp,"keys")==0)
+ {
+ if (id==-1 || !clients[id].connected)
+ {
+ /* should not happen */
+ printf("discarded \"keys\" message\n");
+ }
+ else
+ {
+ int temp;
+ tmp+=strlen(tmp)+1;
+ memcpy(&temp,tmp,sizeof(int));
+ tmp+=sizeof(int);
+ if (clients[id].lasttime==temp)
+ {
+ /* 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 for timeouts */
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected && clients[i].lasttime+MAX_LAG<time)
+ {
+ printf("client %d timeout at %d\n",i,time);
+ packet->address=clients[i].address;
+ strcpy(packet->data,"disconnected");
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ clients[i].connected=0;
+ }
+
+ /* send update to clients */
+ if (time%network_speed==0) for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected)
+ {
+ 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 */
+ nb=0;
+ for (j=0;j<MAX_CLIENTS;j++) if (j!=i && clients[j].connected)
+ {
+ memcpy(tmp,&clients[j].car,sizeof(struct _car));
+ tmp+=sizeof(struct _car);
+ nb++;
+ }
+ memcpy(packet->data+strlen("positions")+1+sizeof(int)+sizeof(int),&nb,sizeof(int));
+ 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);
+ }
+
+ /* did someone finish the track ? */
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected && clients[i].car.lap==nb_laps) finish=1;
+ if (finish) break;
+
+ /* wait like clients */
+ SDL_Delay(7);
+ time++;
+ }
+
+ /* send the top 10 screen */
+ tmp=packet->data;
+ strcpy(tmp,"finish");
+ tmp+=strlen(tmp)+1;
+ tmp+=sizeof(int); /* space for number */
+ nb=0;
+ for (i=0;i<10;i++)
+ {
+ int best_sc=-1,best_id;
+ for (j=0;j<MAX_CLIENTS;j++) if (clients[j].connected && clients[j].car.lap*32+clients[j].car.lastcheck>best_sc)
+ {
+ best_sc=clients[j].car.lap*32+clients[j].car.lastcheck;
+ best_id=j;
+ }
+ if (best_sc!=-1)
+ {
+ 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);
+ 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));
+ packet->len=(void *)tmp-(void *)packet->data;
+ for (i=0;i<MAX_CLIENTS;i++) if (clients[i].connected)
+ {
+ packet->address=clients[i].address;
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ }
+ SDL_Delay(5000);
+
+ tracklist=tracklist->next;
+ }
+
+ return 0;
+}
/*
- * zeRace 0.2, a funny retro racing game
+ * zeRace 0.3, a funny retro racing game
* http://royale.zerezo.com/zerace/
*
* Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
#include <SDL_mixer.h>
#include <SDL_rotozoom.h>
#include "sdl.h"
+#include "car.h"
+#include "tracklist.h"
+#include "network.h"
/* configuration constants */
#define COEFF 1
#define DELAY 7
-#define MAXLINELENGTH 80
-#define VERSION "0.2"
#define WIDTH 1024
#define HEIGHT 768
+#define MAXRECORDKEYS 9999
-/* tracklist : double chained list */
-struct _tracklist
-{
- char *name;
- char *title;
- char *author;
- char *version;
- char *full;
- char *function;
- int x,y,a;
- int best_time;
- char *best_pseudo;
- struct _tracklist *prev;
- struct _tracklist *next;
-} *tracklist=NULL;
+/* tracklist */
+struct _tracklist *tracklist;
/* user setup */
struct _config
SDLKey down;
SDLKey left;
SDLKey right;
- char color;
+ 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;
+};
+
/* display and all directions for the car */
SDL_Surface *screen;
-SDL_Surface *cars[256];
+SDL_Surface *cars[12][256];
+
+/* network stuff */
+UDPsocket udpsock=NULL;
+UDPpacket *packet;
+int network_speed=1;
/* read the user configuration file */
}
-/* get available local tracks */
-void zeRace_get_tracks()
-{
- FILE *fic;
- char line[MAXLINELENGTH];
- struct _tracklist *tmp=NULL,*first=NULL;
-
- if ((fic=fopen("tracks/list.txt","rt"))==NULL)
- {
- fprintf(stderr,"can't open track list\n");
- zeRace_exit();
- }
- while (!feof(fic))
- {
- tmp=(struct _tracklist *)malloc(sizeof(struct _tracklist));
- if (first==NULL) first=tmp;
- fgets(line,MAXLINELENGTH,fic);
- tmp->name=(char *)malloc(strlen(line)+1);
- strcpy(tmp->name,line);
- tmp->name[strlen(tmp->name)-1]='\0';
- fgets(line,MAXLINELENGTH,fic);
- tmp->title=(char *)malloc(strlen(line)+1);
- strcpy(tmp->title,line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->author=(char *)malloc(strlen(line)+1);
- strcpy(tmp->author,line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->version=(char *)malloc(strlen(line)+1);
- strcpy(tmp->version,line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->x=atoi(line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->y=atoi(line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->a=atoi(line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->best_time=atoi(line);
- fgets(line,MAXLINELENGTH,fic);
- tmp->best_pseudo=(char *)malloc(strlen(line)+1);
- strcpy(tmp->best_pseudo,line);
- tmp->full=(char *)malloc(strlen(line)+20);
- sprintf(tmp->full,"tracks/%s.png",tmp->name);
- tmp->function=(char *)malloc(strlen(line)+30);
- sprintf(tmp->function,"tracks/%s_function.png",tmp->name);
- tmp->prev=tracklist;
- if (tmp->prev) tmp->prev->next=tmp;
- tracklist=tmp;
- /* skip one line */
- fgets(line,MAXLINELENGTH,fic);
- }
- fclose(fic);
- if (!tmp) { fprintf(stderr,"no circuits found !\n"); zeRace_exit(); }
- while (tmp->prev) tmp=tmp->prev;
- tmp->prev=tracklist;
- tracklist->next=tmp;
-}
-
-
/* check for a newer version online to warn the user */
void zeRace_check_version()
{
/* load the car sprite and rotate it for every angles */
void zeRace_generate_cars()
{
- int i;
+ int i,j;
SDL_Surface *car;
char temp[20]="sprites/carX.png";
- temp[11]='A'+config.color;
- /* load the car sprite */
- car=IMG_Load(temp);
- /* and rotate it for all available angles */
- for (i=0;i<256;i++)
- {
- float x,y;
- float tcos,tsin;
- tcos=cos(2*M_PI*i/256);
- tsin=sin(2*M_PI*i/256);
- for (x=0;x<cars[i]->w;x++) for (y=0;y<cars[i]->h;y++)
+ for (i=0;i<12;i++)
+ {
+ temp[11]='A'+i;
+ /* load the car sprite */
+ car=IMG_Load(temp);
+ /* and rotate it for all available angles */
+ for (j=0;j<256;j++)
{
- int x2,y2;
- x2=(x-cars[i]->w/2.0)*tcos+(y-cars[i]->h/2.0)*tsin+car->w/2.0;
- y2=(x-cars[i]->w/2.0)*tsin-(y-cars[i]->h/2.0)*tcos+car->h/2.0;
- if (x2>0 && x2<car->w && y2>0 && y2<car->h)
- putpixel(cars[i],x,y,getpixel(car,x2,y2));
+ float x,y;
+ float tcos,tsin;
+ if ((cars[i][j]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,0x000000ff,0x0000ff00,0x00ff0000,0xff000000))==NULL)
+ {
+ fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError());
+ zeRace_exit();
+ };
+ tcos=cos(2*M_PI*j/256);
+ tsin=sin(2*M_PI*j/256);
+ for (x=0;x<cars[i][j]->w;x++) for (y=0;y<cars[i][j]->h;y++)
+ {
+ int x2,y2;
+ x2=(x-cars[i][j]->w/2.0)*tcos+(y-cars[i][j]->h/2.0)*tsin+car->w/2.0;
+ y2=(x-cars[i][j]->w/2.0)*tsin-(y-cars[i][j]->h/2.0)*tcos+car->h/2.0;
+ if (x2>0 && x2<car->w && y2>0 && y2<car->h)
+ putpixel(cars[i][j],x,y,getpixel(car,x2,y2));
+ }
}
+ SDL_FreeSurface(car);
}
- SDL_FreeSurface(car);
}
/* initialize the game */
void zeRace_init()
{
- int flags,i;
+ int flags;
/* do a clean exit in case of emergency */
signal(SIGINT,zeRace_exit);
zeRace_update_tracks();
/* get the list of local tracks */
- zeRace_get_tracks();
+ if (!zeRace_get_tracks(&tracklist)) zeRace_exit();
srand(time(NULL));
zeRace_exit();
}
+ packet=SDLNet_AllocPacket(1024);
+ if (!packet)
+ {
+ fprintf(stderr,"SDLNet_AllocPacket: %s\n",SDLNet_GetError());
+ zeRace_exit();
+ }
+
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
+
flags=SDL_HWSURFACE|SDL_ANYFORMAT;
if (config.fullscreen) flags|=SDL_FULLSCREEN;
zeRace_exit();
}
- /* allocate memory for car sprites */
- for (i=0;i<256;i++) if ((cars[i]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,0x000000ff,0x0000ff00,0x00ff0000,0xff000000))==NULL)
- {
- fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError());
- zeRace_exit();
- };
+ /* pre-calculate car sprites */
zeRace_generate_cars();
}
/* send the best time for this race to the web server */
-void zeRace_send_time(float x,float y,float speed,float angle,int btime,char *bkeys)
+void zeRace_send_time(struct _record record/*float x,float y,float speed,float angle,int btime,char *bkeys*/)
{
IPaddress ip;
TCPsocket tcpsock;
return;
}
- temp=(char *)malloc(strlen(msg1)+strlen(config.pseudo)+strlen(msg2)+strlen(config.url)+strlen(msg3)+strlen(tracklist->name)+strlen(msg4)+10+strlen(msg5)+10+strlen(msg6)+10+strlen(msg7)+10+strlen(msg8)+10+strlen(msg9)+strlen(bkeys)+100);
- sprintf(temp,"%s%s%s%s%s%s%s%d%s%f%s%f%s%f%s%f%s%s\n",msg1,config.pseudo,msg2,config.url,msg3,tracklist->name,msg4,btime,msg5,x,msg6,y,msg7,speed,msg8,angle,msg9,bkeys);
+ temp=(char *)malloc(strlen(msg1)+strlen(config.pseudo)+strlen(msg2)+strlen(config.url)+strlen(msg3)+strlen(tracklist->name)+strlen(msg4)+10+strlen(msg5)+10+strlen(msg6)+10+strlen(msg7)+10+strlen(msg8)+10+strlen(msg9)+strlen(record.keys)+100);
+ sprintf(temp,"%s%s%s%s%s%s%s%d%s%f%s%f%s%f%s%f%s%s\n",msg1,config.pseudo,msg2,config.url,msg3,tracklist->name,msg4,record.time,msg5,record.x,msg6,record.y,msg7,record.speed,msg8,record.angle,msg9,record.keys);
len=strlen(temp);
result=SDLNet_TCP_Send(tcpsock,temp,len);
/* launch a new race */
-void zeRace_launch()
+void zeRace_launch(int alltime,int go)
{
SDL_Surface *cir,*fun;
- SDL_Rect pos,size;
+ SDL_Rect pos;
SDL_Event event;
- int ku=0,kd=0,kl=0,kr=0;
- int i,time=0,lastcheck=0,btime=10000;
- float ox,oy;
- float x,y,angle,speed;
- float sx,sy,sangle,sspeed;
- float bx,by,bangle,bspeed;
- int c,r,g,b;
- char keys[10000];
- char bkeys[10000];
+ int ku=0,kd=0,kl=0,kr=0,i;
+ struct _car car;
+ struct _record current,best;
Mix_Music *light,*engine,*crash,*slide;
- int lastsound_time=-999,alltime=0,lastsound=0;
+ int lastsound_time=-999,lastsound=0;
+ int delay=DELAY;
+ int lastack=alltime;
+ struct _record net;
+ struct _car oldnetpos[MAX_CLIENTS],newnetpos[MAX_CLIENTS];
cir=IMG_Load(tracklist->full);
fun=IMG_Load(tracklist->function);
- sspeed=speed=0;
- sangle=angle=(tracklist->a*2*M_PI/360);
- sx=x=tracklist->x;
- sy=y=tracklist->y;
- lastcheck=0;
- time=0;
+ 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.w=cars[0][0]->w;
+ car.h=cars[0][0]->h;
+ current.time=0;
+ best.time=MAXRECORDKEYS;
+ net.time=0;
+ memset(oldnetpos,0,MAX_CLIENTS*sizeof(struct _car));
+ memset(newnetpos,0,MAX_CLIENTS*sizeof(struct _car));
if (config.sound) if (!(light=Mix_LoadMUS("sounds/light.wav")) || !(engine=Mix_LoadMUS("sounds/engine.wav")) || !(crash=Mix_LoadMUS("sounds/crash.wav")) || !(slide=Mix_LoadMUS("sounds/slide.wav")))
{
char startup[15]="sprites/?.png";
SDL_Surface *temp;
startup[8]='0'+i;
- pos.x=x;
- pos.y=y;
+ pos.x=car.x-car.w/2;
+ pos.y=car.y-car.h/2;
SDL_BlitSurface(cir,NULL,screen,NULL);
- SDL_BlitSurface(cars[(unsigned char)(256*angle/2.0/M_PI)%256],NULL,screen,&pos);
+ SDL_BlitSurface(cars[config.color][(unsigned char)(256*car.angle/2.0/M_PI)%256],NULL,screen,&pos);
if (i!=4 && i!=-1)
{
temp=IMG_Load(startup);
}
if (config.sound) if (i!=4) Mix_PlayMusic(light,1);
SDL_Flip(screen);
+ if (!go) break;
if (i!=-1) SDL_Delay(1000);
}
/* main loop */
for (;;)
{
+ /* look for user interaction */
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ zeRace_exit();
+ break;
+ case SDL_KEYDOWN:
+ 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.time<MAXRECORDKEYS) zeRace_send_time(best);
+ if (udpsock)
+ {
+ print(screen,WIDTH/2-strlen("Disconnecting !")*5,HEIGHT/2-10,"Disconnecting !");
+ strcpy(packet->data,"disconnect");
+ packet->len=strlen(packet->data)+1;
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ SDL_Flip(screen);
+ }
+ return;
+ default:
+ i=event.key.keysym.sym;
+ if (i==config.up) ku=1;
+ if (i==config.down) kd=1;
+ if (i==config.left) kl=1;
+ if (i==config.right) kr=1;
+ break;
+ }
+ break;
+ case SDL_KEYUP:
+ i=event.key.keysym.sym;
+ if (i==config.up) ku=0;
+ if (i==config.down) kd=0;
+ if (i==config.left) kl=0;
+ if (i==config.right) kr=0;
+ break;
+ }
+ }
+
+ /* save pressed keys to validate best time */
+ if (current.time<MAXRECORDKEYS) current.keys[current.time]=(ku<<3 | kd<<2 | kl<<1 | kr)+'A';
+ current.keys[current.time+1]='\0';
+ /* and to send to server if needed */
+ 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)
+ {
+ /*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));
+ if (clienttime>lastack)
+ {
+ memcpy(net.keys,net.keys+clienttime-lastack,net.time+1);
+ net.time-=clienttime-lastack;
+ if (clienttime>servertime+5) delay+=DELAY;
+ if (clienttime<servertime-5) delay-=DELAY;
+ if (delay<0) delay=0;
+ /* printf("servertime = %d clienttime = %d lastack = %d nb = %d delay = %d net.time = %d\n",servertime,clienttime,lastack,nb,delay,net.time); */
+ for (i=0;i<MAX_CLIENTS;i++) newnetpos[i].w=0;
+ memcpy(newnetpos,packet->data+strlen("positions")+1+sizeof(int)*3,sizeof(struct _car)*nb);
+ lastack=clienttime;
+ }
+ } else return;
+ if (strlen(net.keys)!=0)
+ {
+ tmp=packet->data;
+ strcpy(tmp,"keys");
+ tmp+=strlen(tmp)+1;
+ memcpy(tmp,&lastack,sizeof(int));
+ tmp+=sizeof(int);
+ 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);
+ };
+ }
+ }
+
+ /* clear the old network position */
+ if (udpsock) for (i=0;i<MAX_CLIENTS;i++) if (oldnetpos[i].w)
+ {
+ pos.x=oldnetpos[i].x-car.w/2;
+ pos.y=oldnetpos[i].y-car.h/2;
+ pos.w=car.w;
+ pos.h=car.h;
+ SDL_BlitSurface(cir,&pos,screen,&pos);
+ }
+
/* clear the old position */
- size.w=cars[0]->w;
- size.h=cars[0]->h;
- pos.x=x;
- pos.y=y;
+ pos.x=car.ox-car.w/2;
+ pos.y=car.oy-car.h/2;
+ pos.w=car.w;
+ pos.h=car.h;
SDL_BlitSurface(cir,&pos,screen,&pos);
- /* save the old position and compute the new one */
- ox=x;
- oy=y;
- speed*=0.995;
- x=x-cos(angle)*speed;
- y=y-sin(angle)*speed;
-
- /* collision with the border of the screen */
- if (x<0 || x>screen->w-cars[0]->w || y<0 || y>screen->h-cars[0]->h)
+ /* display the network car at the new position */
+ if (udpsock) for (i=0;i<MAX_CLIENTS;i++) if (newnetpos[i].w)
{
- x=ox;
- y=oy;
- speed=0;
+ pos.x=newnetpos[i].x-car.w/2;
+ pos.y=newnetpos[i].y-car.h/2;
+ 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);
}
- /* display the car at the new position and update display */
- pos.x=x;
- pos.y=y;
- i=(unsigned char)(256*angle/2.0/M_PI)%256;
- SDL_BlitSurface(cars[i],NULL,screen,&pos);
- SDL_UpdateRect(screen,ox,oy,cars[i]->w,cars[i]->h);
- SDL_UpdateRect(screen,x,y,cars[i]->w,cars[i]->h);
+ /* display the car at the new position */
+ pos.x=car.x-car.w/2;
+ pos.y=car.y-car.h/2;
+ pos.w=car.w;
+ pos.h=car.h;
+ SDL_BlitSurface(cars[config.color][(unsigned char)(256*car.angle/2.0/M_PI)%256],NULL,screen,&pos);
- /* accelerate, brake and turn depending on the pressed keys */
- if (kl) { if (speed<0) angle+=0.01*(255-b)/255*COEFF; else angle-=0.01*(255-b)/255*COEFF; }
- if (kr) { if (speed<0) angle-=0.01*(255-b)/255*COEFF; else angle+=0.01*(255-b)/255*COEFF; }
- if (ku) speed+=0.01*2*COEFF;
- if (kd) speed-=0.01*COEFF;
+ /* update display */
+ if (udpsock)
+ {
+ for (i=0;i<MAX_CLIENTS;i++)
+ {
+ if (oldnetpos[i].w) SDL_UpdateRect(screen,oldnetpos[i].x-car.w/2,oldnetpos[i].y-car.h/2,car.w,car.h);
+ if (newnetpos[i].w) SDL_UpdateRect(screen,newnetpos[i].x-car.w/2,newnetpos[i].y-car.h/2,car.w,car.h);
+ }
+ memcpy(oldnetpos,newnetpos,MAX_CLIENTS*sizeof(struct _car));
+ }
+ 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);
+
+ 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)
}
/* if the car is fast or braking, it slides */
- if ((kd && speed>0.5) || (speed>2.0 && !ku))
+ if ((kd && car.speed>0.5) || (car.speed>2.0 && !ku))
{
/* if the only sound is the engine, play the slide sound */
if (lastsound_time+100<alltime || lastsound<1)
/* display tires slide */
if (config.tire)
{
- putpixel(cir,x+cars[i]->w/2+cos(angle)*cars[i]->w/3-sin(angle)*2,y+cars[i]->h/2+sin(angle)*cars[i]->h/3+cos(angle)*2,0);
- putpixel(cir,x+cars[i]->w/2+cos(angle)*cars[i]->w/3+sin(angle)*5,y+cars[i]->h/2+sin(angle)*cars[i]->h/3-cos(angle)*5,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,0);
/* if we are braking the slide is larger */
if (kd)
{
- putpixel(cir,x+cars[i]->w/2+cos(angle)*cars[i]->w/3-sin(angle)*3,y+cars[i]->h/2+sin(angle)*cars[i]->h/3+cos(angle)*3,0);
- putpixel(cir,x+cars[i]->w/2+cos(angle)*cars[i]->w/3+sin(angle)*4,y+cars[i]->h/2+sin(angle)*cars[i]->h/3-cos(angle)*4,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,0);
}
}
}
- /* get the pixel color under the center of car in the function map */
- c=getpixel(fun,x+cars[i]->w/2,y+cars[i]->h/2);
- /* red layer (checkpoints) */
- r=(c )&0xff;
- /* green layer (road quality) */
- g=(c>>8 )&0xff;
- /* blue layer (unused) */
- b=(c>>16)&0xff;
-
- /* if it is a wall we move back to the last position */
- if (g==0)
+ /* if we crashed */
+ if (car.crashflag && (lastsound_time+100<alltime || lastsound<2))
{
- x=ox;
- y=oy;
- /* play the crash sound */
- if (lastsound_time+100<alltime || lastsound<2)
- {
- lastsound=2;
- lastsound_time=alltime;
- if (config.sound) Mix_PlayMusic(crash,1)==-1;
- }
+ lastsound=2;
+ lastsound_time=alltime;
+ if (config.sound) Mix_PlayMusic(crash,1)==-1;
}
- /* update the speed depending on the road quality */
- speed-=speed*(255-g)/1000;
- /* if we are on the next checkpoint, validate it (no missing allowed) */
- if (r/8==lastcheck+1) lastcheck++;
- /* if we validate all and start over, we complete a turn */
- if (r/8==0 && lastcheck==31)
+ /* if we completed a lap */
+ if (car.lapflag)
{
- printf("time = %d\"%d\n",time*DELAY/1000,time*DELAY%1000);
+ printf("time = %d\"%d\n",current.time*DELAY/1000,current.time*DELAY%1000);
print(screen,0,0,"Last lap : ");
- print_time(110,0,time);
+ 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 (btime==-1 || time<btime)
- {
- btime=time;
- bx=sx;
- by=sy;
- bangle=sangle;
- bspeed=sspeed;
- keys[time]='\0';
- memcpy(bkeys,keys,btime);
- }
+ if (best.time==-1 || current.time<best.time)
+ memcpy(&best,¤t,sizeof(struct _record));
/* reset turn variables */
- lastcheck=0;
- time=0;
- sx=x;
- sy=y;
- sangle=angle;
- sspeed=speed;
- }
-
- /* look for user interaction */
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- case SDL_QUIT:
- zeRace_exit();
- break;
- case SDL_KEYDOWN:
- 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 (btime<10000) zeRace_send_time(bx,by,bspeed,bangle,btime,bkeys);
- return;
- default:
- i=event.key.keysym.sym;
- if (i==config.up) ku=1;
- if (i==config.down) kd=1;
- if (i==config.left) kl=1;
- if (i==config.right) kr=1;
- break;
- }
- break;
- case SDL_KEYUP:
- i=event.key.keysym.sym;
- if (i==config.up) ku=0;
- if (i==config.down) kd=0;
- if (i==config.left) kl=0;
- if (i==config.right) kr=0;
- break;
- }
+ current.time=0;
+ current.x=car.x;
+ current.y=car.y;
+ current.angle=car.angle;
+ current.speed=car.speed;
}
/* let the system breath */
- SDL_Delay(DELAY);
- /* save pressed keys to validate best time */
- if (time<btime) keys[time]=(ku<<3 | kd<<2 | kl<<1 | kr)+'A';
+ SDL_Delay(delay);
/* game time */
- 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++;
}
}
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);*/
}
/* menu loop to select track */
-void zeRace_select_track()
+void zeRace_local()
{
SDL_Event event;
return;
case SDLK_RETURN:
case SDLK_SPACE:
- zeRace_launch();
+ zeRace_launch(0,1);
update();
break;
case SDLK_LEFT:
}
+/* top 10 screen */
+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);
+ print(screen,WIDTH/2-16*5,HEIGHT/14,"* Race results *");
+ for (i=0;i<nb;i++)
+ {
+ print(screen,150,(i+3)*HEIGHT/14,buf);
+ buf+=strlen(buf)+1;
+ memcpy(&tmp,buf,sizeof(int));
+ buf+=sizeof(int);
+ pos.x=110;
+ pos.y=(i+3)*HEIGHT/14-8;
+ SDL_BlitSurface(cars[tmp][0],NULL,screen,&pos);
+ }
+ SDL_Flip(screen);
+ SDL_Delay(5000);
+}
+
+
+/* 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;
+ memcpy(tmp,&config.color,sizeof(int));
+ tmp+=sizeof(int);
+ packet->len=(void *)tmp-(void *)packet->data;
+ SDLNet_UDP_Send(udpsock,-1,packet);
+ /* network loop */
+ while (SDLNet_UDP_Recv(udpsock,packet) || lag<MAX_LAG)
+ {
+ tmp=packet->data;
+ 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;
+ memcpy(&time,tmp,sizeof(int));
+ tmp+=sizeof(int);
+ memcpy(&network_speed,tmp,sizeof(int));
+ zeRace_launch(time,go);
+ if (strcmp(packet->data,"finish")==0) zeRace_top10(packet->data+strlen(packet->data)+1);
+ lag=0;
+ }
+ SDL_Delay(7);
+ lag++;
+ }
+ SDLNet_UDP_Close(udpsock);
+ udpsock=NULL;
+}
+
+
+/* network game */
+void zeRace_network()
+{
+ SDL_Event event;
+ int active=0;
+ char server[MAXLINELENGTH]="localhost";
+ char port[6]=PORT;
+ #define NETWORK_OPTIONS 4
+
+ void update()
+ {
+ SDL_FillRect(screen,NULL,0x000000);
+ 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 : ");
+ print(screen,400+10*strlen("Server : "),HEIGHT/(NETWORK_OPTIONS+4)*3,server);
+ print(screen,400,HEIGHT/(NETWORK_OPTIONS+4)*4,"Port : ");
+ print(screen,400+10*strlen("Port : "),HEIGHT/(NETWORK_OPTIONS+4)*4,port);
+ print(screen,400,HEIGHT/(NETWORK_OPTIONS+4)*(NETWORK_OPTIONS+1),"Connect");
+ print(screen,400,HEIGHT/(NETWORK_OPTIONS+4)*(NETWORK_OPTIONS+2),"Back to main menu");
+ SDL_Flip(screen);
+ }
+
+ update();
+ for (;;)
+ {
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ zeRace_exit();
+ break;
+ case SDL_KEYDOWN:
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_ESCAPE:
+ return;
+ case SDLK_RETURN:
+ case SDLK_SPACE:
+ case SDLK_LEFT:
+ case SDLK_RIGHT:
+ switch (active)
+ {
+ case 0: readstring(screen,400+10*strlen("Server : "),HEIGHT/(NETWORK_OPTIONS+4)*3,server,MAXLINELENGTH); break;
+ case 1: readstring(screen,400+10*strlen("Port : "),HEIGHT/(NETWORK_OPTIONS+4)*4,port,5); break;;
+ case 2:
+ zeRace_connect(server,atoi(port));
+ break;
+ case 3:
+ return;
+ }
+ update();
+ break;
+ case SDLK_UP:
+ active--; if (active<0) active=NETWORK_OPTIONS-1;
+ update();
+ break;
+ case SDLK_DOWN:
+ active++; if (active>NETWORK_OPTIONS-1) active=0;
+ update();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ SDL_Delay(10);
+ }
+}
+
+
+/* internet game */
+void zeRace_internet()
+{
+ IPaddress ip;
+ TCPsocket tcpsock;
+ char *request=
+ "GET /zerace/servers.php HTTP/1.0\n"
+ "Host: royale.zerezo.com\n"
+ "User-Agent: zeRace " VERSION "\n"
+ "\n";
+ char response[10240],*tmp;
+ int len,result,i;
+ struct _server
+ {
+ char name[MAXLINELENGTH];
+ char ip[16];
+ char port[6];
+ } servers[10];
+ SDL_Event event;
+ int active=0;
+ #define INTERNET_OPTIONS 11
+
+ printf("dowloading list of servers... ");
+ fflush(stdout);
+
+ 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)
+ {
+ fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError());
+ return;
+ }
+
+ len=strlen(request);
+ result=SDLNet_TCP_Send(tcpsock,request,len);
+ if(result<len)
+ fprintf(stderr,"SDLNet_TCP_Send: %s\n",SDLNet_GetError());
+ else
+ {
+ len=SDLNet_TCP_Recv(tcpsock,response,10240);
+ tmp=response;
+ for (tmp=response;tmp<response+10240;tmp++) if (*tmp=='\n') *tmp='\0';
+ tmp=response;
+ while (*tmp!='\0' || *(tmp+1)!='\r') tmp++;
+ tmp+=3;
+ printf("%s\n",tmp);
+ for (i=0;i<10;i++)
+ {
+ strcpy(servers[i].name,tmp);
+ tmp+=strlen(tmp)+1;
+ strcpy(servers[i].ip,tmp);
+ tmp+=strlen(tmp)+1;
+ strcpy(servers[i].port,tmp);
+ tmp+=strlen(tmp)+1;
+ }
+ printf("done\n");
+ }
+
+ SDLNet_TCP_Close(tcpsock);
+
+ void update()
+ {
+ int i;
+ SDL_FillRect(screen,NULL,0x000000);
+ 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++)
+ print(screen,400,HEIGHT/(INTERNET_OPTIONS+4)*(i+3),servers[i].name);
+ print(screen,400,HEIGHT/(INTERNET_OPTIONS+4)*(INTERNET_OPTIONS+2),"Back to main menu");
+ SDL_Flip(screen);
+ }
+
+ update();
+ for (;;)
+ {
+ while (SDL_PollEvent(&event))
+ {
+ switch (event.type)
+ {
+ case SDL_QUIT:
+ zeRace_exit();
+ break;
+ case SDL_KEYDOWN:
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_ESCAPE:
+ return;
+ case SDLK_RETURN:
+ case SDLK_SPACE:
+ case SDLK_LEFT:
+ case SDLK_RIGHT:
+ if (active==INTERNET_OPTIONS-1)
+ return;
+ else
+ zeRace_connect(servers[active].ip,atoi(servers[active].port));
+ update();
+ break;
+ case SDLK_UP:
+ active--; if (active<0) active=INTERNET_OPTIONS-1;
+ update();
+ break;
+ case SDLK_DOWN:
+ active++; if (active>INTERNET_OPTIONS-1) active=0;
+ update();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ SDL_Delay(10);
+ }
+}
+
+
/* configuration screen */
void zeRace_config()
{
print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*12,"Color : ");
pos.x=123;
pos.y=HEIGHT/(CONFIG_OPTIONS+4)*12-7;
- SDL_BlitSurface(cars[0],NULL,screen,&pos);
+ SDL_BlitSurface(cars[config.color][0],NULL,screen,&pos);
print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu");
SDL_Flip(screen);
}
}
}
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
update();
for (;;)
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
- SDL_EnableKeyRepeat(0,0);
return;
case SDLK_RETURN:
case SDLK_SPACE:
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;
- zeRace_generate_cars();
break;
case 10:
- SDL_EnableKeyRepeat(0,0);
return;
}
update();
SDL_Event event;
int active=0;
SDL_Surface *logo;
- #define MENU_OPTIONS 3
+ #define MENU_OPTIONS 5
void update()
{
pos.x=WIDTH/2-logo->w/2;
pos.y=HEIGHT/6-logo->h/2;
SDL_BlitSurface(logo,NULL,screen,&pos);
- print(screen,650,HEIGHT/(MENU_OPTIONS+4)*2,"version " VERSION);
+ print(screen,650,HEIGHT/6+logo->h/3,"version " VERSION);
print(screen,420,HEIGHT/(MENU_OPTIONS+4)*(3+active),">");
print(screen,440,HEIGHT/(MENU_OPTIONS+4)*3,"Local game");
- /* print(screen,440,HEIGHT/(MENU_OPTIONS+4)*4,"Network game"); */
- print(screen,440,HEIGHT/(MENU_OPTIONS+4)*4,"Configuration");
- print(screen,440,HEIGHT/(MENU_OPTIONS+4)*5,"Exit game");
+ print(screen,440,HEIGHT/(MENU_OPTIONS+4)*4,"Network game");
+ print(screen,440,HEIGHT/(MENU_OPTIONS+4)*5,"Internet game");
+ print(screen,440,HEIGHT/(MENU_OPTIONS+4)*6,"Configuration");
+ print(screen,440,HEIGHT/(MENU_OPTIONS+4)*7,"Exit game");
SDL_Flip(screen);
}
logo=IMG_Load("sprites/logo.jpg");
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
update();
for (;;)
{
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
- SDL_EnableKeyRepeat(0,0);
return;
case SDLK_RETURN:
case SDLK_SPACE:
case SDLK_RIGHT:
switch (active)
{
- case 0: zeRace_select_track(); break;
- case 1: zeRace_config(); break;
- case 2: return;
+ case 0: zeRace_local(); break;
+ case 1: zeRace_network(); break;
+ case 2: zeRace_internet(); break;
+ case 3: zeRace_config(); break;
+ case 4: return;
}
update();
break;