2 * zeRace 0.2, a funny retro racing game
3 * http://royale.zerezo.com/zerace/
5 * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <SDL_image.h>
30 #include <SDL_mixer.h>
31 #include <SDL_rotozoom.h>
34 /* configuration constants */
37 #define MAXLINELENGTH 80
42 /* tracklist : double chained list */
54 struct _tracklist *prev;
55 struct _tracklist *next;
61 char pseudo[MAXLINELENGTH];
62 char url[MAXLINELENGTH];
71 } config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6};
73 /* display and all directions for the car */
75 SDL_Surface *cars[256];
78 /* read the user configuration file */
79 void zeRace_read_config()
82 if ((fic=fopen("zeRace.cfg","rt"))==NULL)
84 fprintf(stderr,"can't open config file \"zeRace.cfg\"\n");
87 fread(&config,sizeof(struct _config),1,fic);
92 /* save the user configuration file */
93 void zeRace_save_config()
96 if ((fic=fopen("zeRace.cfg","wt"))==NULL)
98 fprintf(stderr,"can't create config file \"zeRace.cfg\"\n");
101 fwrite(&config,sizeof(struct _config),1,fic);
106 /* exit the game and clean */
110 if (config.sound) Mix_CloseAudio();
113 zeRace_save_config();
118 /* get available local tracks */
119 void zeRace_get_tracks()
122 char line[MAXLINELENGTH];
123 struct _tracklist *tmp=NULL,*first=NULL;
125 if ((fic=fopen("tracks/list.txt","rt"))==NULL)
127 fprintf(stderr,"can't open track list\n");
132 tmp=(struct _tracklist *)malloc(sizeof(struct _tracklist));
133 if (first==NULL) first=tmp;
134 fgets(line,MAXLINELENGTH,fic);
135 tmp->name=(char *)malloc(strlen(line)+1);
136 strcpy(tmp->name,line);
137 tmp->name[strlen(tmp->name)-1]='\0';
138 fgets(line,MAXLINELENGTH,fic);
139 tmp->title=(char *)malloc(strlen(line)+1);
140 strcpy(tmp->title,line);
141 fgets(line,MAXLINELENGTH,fic);
142 tmp->author=(char *)malloc(strlen(line)+1);
143 strcpy(tmp->author,line);
144 fgets(line,MAXLINELENGTH,fic);
145 tmp->version=(char *)malloc(strlen(line)+1);
146 strcpy(tmp->version,line);
147 fgets(line,MAXLINELENGTH,fic);
149 fgets(line,MAXLINELENGTH,fic);
151 fgets(line,MAXLINELENGTH,fic);
153 fgets(line,MAXLINELENGTH,fic);
154 tmp->best_time=atoi(line);
155 fgets(line,MAXLINELENGTH,fic);
156 tmp->best_pseudo=(char *)malloc(strlen(line)+1);
157 strcpy(tmp->best_pseudo,line);
158 tmp->full=(char *)malloc(strlen(line)+20);
159 sprintf(tmp->full,"tracks/%s.png",tmp->name);
160 tmp->function=(char *)malloc(strlen(line)+30);
161 sprintf(tmp->function,"tracks/%s_function.png",tmp->name);
163 if (tmp->prev) tmp->prev->next=tmp;
166 fgets(line,MAXLINELENGTH,fic);
169 if (!tmp) { fprintf(stderr,"no circuits found !\n"); zeRace_exit(); }
170 while (tmp->prev) tmp=tmp->prev;
176 /* check for a newer version online to warn the user */
177 void zeRace_check_version()
182 "GET /zerace/version.php HTTP/1.0\n"
183 "Host: royale.zerezo.com\n"
184 "User-Agent: zeRace " VERSION "\n"
186 char response[1024],*tmp,*version;
189 printf("checking version... ");
192 if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1)
194 fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError());
198 tcpsock=SDLNet_TCP_Open(&ip);
201 fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError());
206 result=SDLNet_TCP_Send(tcpsock,request,len);
208 fprintf(stderr,"SDLNet_TCP_Send: %s\n",SDLNet_GetError());
212 len=SDLNet_TCP_Recv(tcpsock,response,1024);
214 fprintf(stderr,"SDLNet_TCP_Recv: %s\n",SDLNet_GetError());
218 while (*tmp++!='\0') if (strncmp(tmp,"version=",8)==0)
221 while (*tmp!='\n') tmp++;
223 if (strcmp(version,VERSION)>0) printf("new version available !\nhttp://royale.zerezo.com/zerace/\n");
227 SDLNet_TCP_Close(tcpsock);
231 /* get remote list of tracks */
232 void zeRace_update_tracks()
237 "GET /zerace/tracks.php HTTP/1.0\n"
238 "Host: royale.zerezo.com\n"
239 "User-Agent: zeRace " VERSION "\n"
241 char response[10240],*tmp;
245 printf("checking version and updating tracks... ");
248 if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1)
250 fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError());
254 tcpsock=SDLNet_TCP_Open(&ip);
257 fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError());
262 result=SDLNet_TCP_Send(tcpsock,request,len);
264 fprintf(stderr,"SDLNet_TCP_Send: %s\n",SDLNet_GetError());
267 if ((fic=fopen("tracks/list.txt","wt"))==NULL)
269 fprintf(stderr,"can't create track list\n");
272 len=SDLNet_TCP_Recv(tcpsock,response,10240);
274 while (*tmp!='\n' || *(tmp+1)!='\r') tmp++;
276 fwrite(tmp,1,len+response-tmp,fic);
281 SDLNet_TCP_Close(tcpsock);
285 /* load the car sprite and rotate it for every angles */
286 void zeRace_generate_cars()
290 char temp[20]="sprites/carX.png";
291 temp[11]='A'+config.color;
292 /* load the car sprite */
294 /* and rotate it for all available angles */
299 tcos=cos(2*M_PI*i/256);
300 tsin=sin(2*M_PI*i/256);
301 for (x=0;x<cars[i]->w;x++) for (y=0;y<cars[i]->h;y++)
304 x2=(x-cars[i]->w/2.0)*tcos+(y-cars[i]->h/2.0)*tsin+car->w/2.0;
305 y2=(x-cars[i]->w/2.0)*tsin-(y-cars[i]->h/2.0)*tcos+car->h/2.0;
306 if (x2>0 && x2<car->w && y2>0 && y2<car->h)
307 putpixel(cars[i],x,y,getpixel(car,x2,y2));
310 SDL_FreeSurface(car);
314 /* initialize the game */
319 /* do a clean exit in case of emergency */
320 signal(SIGINT,zeRace_exit);
321 signal(SIGTERM,zeRace_exit);
323 /* read the user configuration file */
324 zeRace_read_config();
326 /* check for a newer available version */
327 zeRace_check_version();
329 /* update the list of tracks */
330 zeRace_update_tracks();
332 /* get the list of local tracks */
337 if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0)
339 fprintf(stderr,"could not initialize SDL : %s\n",SDL_GetError());
344 if(SDLNet_Init()==-1)
346 fprintf(stderr,"could not initialize SDLNet : %s\n",SDLNet_GetError());
350 flags=SDL_HWSURFACE|SDL_ANYFORMAT;
351 if (config.fullscreen) flags|=SDL_FULLSCREEN;
353 if ((screen=SDL_SetVideoMode(WIDTH,HEIGHT,32,flags))==NULL)
355 fprintf(stderr,"could not create a surface : %s\n",SDL_GetError());
359 SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"),NULL);
360 SDL_WM_SetCaption("zeRace " VERSION,"zeRace " VERSION);
361 SDL_ShowCursor(SDL_DISABLE);
363 if (config.sound) if (Mix_OpenAudio(44100,MIX_DEFAULT_FORMAT,2,512)<0)
365 fprintf(stderr,"Mix_OpenAudio error\n");
369 /* allocate memory for car sprites */
370 for (i=0;i<256;i++) if ((cars[i]=SDL_CreateRGBSurface(SDL_SWSURFACE,30,30,32,0x000000ff,0x0000ff00,0x00ff0000,0xff000000))==NULL)
372 fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError());
375 zeRace_generate_cars();
379 /* send the best time for this race to the web server */
380 void zeRace_send_time(float x,float y,float speed,float angle,int btime,char *bkeys)
386 "POST /zerace/time.php HTTP/1.0\n"
387 "Host: royale.zerezo.com\n"
388 "User-Agent: zeRace " VERSION "\n"
389 "Content-Type: application/x-www-form-urlencoded\n"
390 "Content-Length: 99999\n"
394 char *msg3="&track=";
395 char *msg4="&btime=";
398 char *msg7="&speed=";
399 char *msg8="&angle=";
400 char *msg9="&bkeys=";
403 printf("sending time... ");
406 if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1)
408 fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError());
412 tcpsock=SDLNet_TCP_Open(&ip);
415 fprintf(stderr,"SDLNet_TCP_Open: %s\n",SDLNet_GetError());
419 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);
420 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);
423 result=SDLNet_TCP_Send(tcpsock,temp,len);
425 fprintf(stderr,"SDLNet_TCP_Send: %s\n", SDLNet_GetError());
429 SDLNet_TCP_Close(tcpsock);
433 /* print a time for a lap */
434 void print_time(int x,int y,int time)
446 temp[4]=r%100/10+'0';
449 print(screen,x,y,temp);
453 /* launch a new race */
456 SDL_Surface *cir,*fun;
459 int ku=0,kd=0,kl=0,kr=0;
460 int i,time=0,lastcheck=0,btime=10000;
462 float x,y,angle,speed;
463 float sx,sy,sangle,sspeed;
464 float bx,by,bangle,bspeed;
468 Mix_Music *light,*engine,*crash,*slide;
469 int lastsound_time=-999,alltime=0,lastsound=0;
471 cir=IMG_Load(tracklist->full);
472 fun=IMG_Load(tracklist->function);
475 sangle=angle=(tracklist->a*2*M_PI/360);
481 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")))
483 fprintf(stderr,"Mix_LoadMUS error\n");
487 /* startup countdown */
490 char startup[15]="sprites/?.png";
495 SDL_BlitSurface(cir,NULL,screen,NULL);
496 SDL_BlitSurface(cars[(unsigned char)(256*angle/2.0/M_PI)%256],NULL,screen,&pos);
499 temp=IMG_Load(startup);
500 pos.x=screen->w/2-temp->w/2;
501 pos.y=screen->h/2-temp->h/2;
502 SDL_BlitSurface(temp,NULL,screen,&pos);
503 SDL_FreeSurface(temp);
505 if (config.sound) if (i!=4) Mix_PlayMusic(light,1);
507 if (i!=-1) SDL_Delay(1000);
513 /* clear the old position */
518 SDL_BlitSurface(cir,&pos,screen,&pos);
520 /* save the old position and compute the new one */
524 x=x-cos(angle)*speed;
525 y=y-sin(angle)*speed;
527 /* collision with the border of the screen */
528 if (x<0 || x>screen->w-cars[0]->w || y<0 || y>screen->h-cars[0]->h)
535 /* display the car at the new position and update display */
538 i=(unsigned char)(256*angle/2.0/M_PI)%256;
539 SDL_BlitSurface(cars[i],NULL,screen,&pos);
540 SDL_UpdateRect(screen,ox,oy,cars[i]->w,cars[i]->h);
541 SDL_UpdateRect(screen,x,y,cars[i]->w,cars[i]->h);
543 /* accelerate, brake and turn depending on the pressed keys */
544 if (kl) { if (speed<0) angle+=0.01*(255-b)/255*COEFF; else angle-=0.01*(255-b)/255*COEFF; }
545 if (kr) { if (speed<0) angle-=0.01*(255-b)/255*COEFF; else angle+=0.01*(255-b)/255*COEFF; }
546 if (ku) speed+=0.01*2*COEFF;
547 if (kd) speed-=0.01*COEFF;
549 /* play engine sound if no sound is currently playing */
550 if (lastsound_time+100<alltime)
553 lastsound_time=alltime;
554 if (config.sound) Mix_PlayMusic(engine,1);
557 /* if the car is fast or braking, it slides */
558 if ((kd && speed>0.5) || (speed>2.0 && !ku))
560 /* if the only sound is the engine, play the slide sound */
561 if (lastsound_time+100<alltime || lastsound<1)
564 lastsound_time=alltime;
565 if (config.sound) Mix_PlayMusic(slide,1)==-1;
568 /* display tires slide */
571 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);
572 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);
573 /* if we are braking the slide is larger */
576 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);
577 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);
582 /* get the pixel color under the center of car in the function map */
583 c=getpixel(fun,x+cars[i]->w/2,y+cars[i]->h/2);
584 /* red layer (checkpoints) */
586 /* green layer (road quality) */
588 /* blue layer (unused) */
591 /* if it is a wall we move back to the last position */
596 /* play the crash sound */
597 if (lastsound_time+100<alltime || lastsound<2)
600 lastsound_time=alltime;
601 if (config.sound) Mix_PlayMusic(crash,1)==-1;
604 /* update the speed depending on the road quality */
605 speed-=speed*(255-g)/1000;
607 /* if we are on the next checkpoint, validate it (no missing allowed) */
608 if (r/8==lastcheck+1) lastcheck++;
609 /* if we validate all and start over, we complete a turn */
610 if (r/8==0 && lastcheck==31)
612 printf("time = %d\"%d\n",time*DELAY/1000,time*DELAY%1000);
613 print(screen,0,0,"Last lap : ");
614 print_time(110,0,time);
615 SDL_UpdateRect(screen,0,0,170,19);
616 /* if it is the first turn of the best turn, save it */
617 if (btime==-1 || time<btime)
625 memcpy(bkeys,keys,btime);
627 /* reset turn variables */
636 /* look for user interaction */
637 while (SDL_PollEvent(&event))
645 switch (event.key.keysym.sym)
649 Mix_FreeMusic(light);
650 Mix_FreeMusic(engine);
651 Mix_FreeMusic(crash);
652 Mix_FreeMusic(slide);
653 /* if the best time is small enought to save all keys, send it */
654 if (btime<10000) zeRace_send_time(bx,by,bspeed,bangle,btime,bkeys);
657 i=event.key.keysym.sym;
658 if (i==config.up) ku=1;
659 if (i==config.down) kd=1;
660 if (i==config.left) kl=1;
661 if (i==config.right) kr=1;
666 i=event.key.keysym.sym;
667 if (i==config.up) ku=0;
668 if (i==config.down) kd=0;
669 if (i==config.left) kl=0;
670 if (i==config.right) kr=0;
675 /* let the system breath */
677 /* save pressed keys to validate best time */
678 if (time<btime) keys[time]=(ku<<3 | kd<<2 | kl<<1 | kr)+'A';
686 /* display a random splash screen at startup */
691 char temp[20]="splashs/0.jpg";
693 SDL_FillRect(screen,NULL,0x000000);
694 temp[8]=rand()%3+'1';
695 splash=IMG_Load(temp);
696 pos.x=screen->w/2-splash->w/2-1;
698 pos.y=screen->h/2-splash->h/2-1;
700 SDL_FillRect(screen,&pos,0xffffff);
701 pos.x=screen->w/2-splash->w/2;
702 pos.y=screen->h/2-splash->h/2;
703 SDL_BlitSurface(splash,NULL,screen,&pos);
704 print(screen,screen->w/2-strlen("zeRace " VERSION)*5,screen->h/2-splash->h/2-20,"zeRace " VERSION);
705 SDL_FreeSurface(splash);
711 /* menu loop to select track */
712 void zeRace_select_track()
718 SDL_Surface *full,*preview;
720 SDL_FillRect(screen,NULL,0x000000);
721 print(screen,WIDTH/2-28*5,HEIGHT/6,"* Please choose your race *");
722 print(screen,WIDTH/2-strlen(tracklist->title)*5,5*HEIGHT/6-20,tracklist->title);
723 print(screen,WIDTH/2-(strlen(tracklist->author)+strlen("Author : "))*5,5*HEIGHT/6+0,"Author : ");
724 print(screen,WIDTH/2-(strlen(tracklist->author)-strlen("Author : "))*5,5*HEIGHT/6+0,tracklist->author);
725 print(screen,WIDTH/2-( strlen("Version : ")+strlen(tracklist->version))*5,5*HEIGHT/6+20,"Version : ");
726 print(screen,WIDTH/2-(-strlen("Version : ")+strlen(tracklist->version))*5,5*HEIGHT/6+20,tracklist->version);
727 print(screen,WIDTH/2-( strlen("Best time : ")+6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,"Best time : ");
728 print_time (WIDTH/2-(-strlen("Best time : ")+6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,tracklist->best_time);
729 print(screen,WIDTH/2-(-strlen("Best time : ")-6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40," by ");
730 print(screen,WIDTH/2-(-strlen("Best time : ")-6-strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,tracklist->best_pseudo);
731 full=IMG_Load(tracklist->full);
732 preview=(SDL_Surface *)zoomSurface(full,0.5,0.5,1);
733 SDL_FreeSurface(full);
734 pos.x=WIDTH/2-preview->w/2-1;
736 pos.y=screen->h/2-preview->h/2-1;
738 SDL_FillRect(screen,&pos,0xffffff);
739 pos.x=WIDTH/2-preview->w/2;
740 pos.y=screen->h/2-preview->h/2;
741 SDL_BlitSurface(preview,NULL,screen,&pos);
742 SDL_FreeSurface(preview);
749 while (SDL_PollEvent(&event))
757 switch (event.key.keysym.sym)
767 tracklist=tracklist->next;
771 tracklist=tracklist->prev;
785 /* configuration screen */
790 #define CONFIG_OPTIONS 11
795 SDL_FillRect(screen,NULL,0x000000);
796 print(screen,20,HEIGHT/(CONFIG_OPTIONS+4)*(3+active),">");
797 print(screen,WIDTH/2-24*5,HEIGHT/(CONFIG_OPTIONS+4),"* Configuration screen *");
798 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*3,"Pseudo : ");
799 print(screen,40+10*strlen("Pseudo : "),HEIGHT/(CONFIG_OPTIONS+4)*3,config.pseudo);
800 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*4,"Url : ");
801 print(screen,40+10*strlen("Url : "),HEIGHT/(CONFIG_OPTIONS+4)*4,config.url);
802 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*5,"Fullscreen : ");
803 print(screen,40+10*strlen("Fullscreen : "),HEIGHT/(CONFIG_OPTIONS+4)*5,config.fullscreen?"Yes":"No");
804 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*6,"Sound : ");
805 print(screen,40+10*strlen("Sound : "),HEIGHT/(CONFIG_OPTIONS+4)*6,config.sound?"Yes":"No");
806 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*7,"Tire : ");
807 print(screen,40+10*strlen("Tire : "),HEIGHT/(CONFIG_OPTIONS+4)*7,config.tire?"Yes":"No");
808 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*8,"Accelerate key : ");
809 print(screen,40+10*strlen("Accelerate key : "),HEIGHT/(CONFIG_OPTIONS+4)*8,config.up?SDL_GetKeyName(config.up):"<press key>");
810 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*9,"Brake key : ");
811 print(screen,40+10*strlen("Brake key : "),HEIGHT/(CONFIG_OPTIONS+4)*9,config.down?SDL_GetKeyName(config.down):"<press key>");
812 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*10,"Turn left key : ");
813 print(screen,40+10*strlen("Turn left key : "),HEIGHT/(CONFIG_OPTIONS+4)*10,config.left?SDL_GetKeyName(config.left):"<press key>");
814 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*11,"Turn right key : ");
815 print(screen,40+10*strlen("Turn right key : "),HEIGHT/(CONFIG_OPTIONS+4)*11,config.right?SDL_GetKeyName(config.right):"<press key>");
816 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*12,"Color : ");
818 pos.y=HEIGHT/(CONFIG_OPTIONS+4)*12-7;
819 SDL_BlitSurface(cars[0],NULL,screen,&pos);
820 print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu");
828 while (SDL_PollEvent(&event)) switch (event.type)
831 return event.key.keysym.sym;
837 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
841 while (SDL_PollEvent(&event))
849 switch (event.key.keysym.sym)
852 SDL_EnableKeyRepeat(0,0);
860 case 0: readstring(screen,40+10*strlen("Pseudo : "),HEIGHT/(CONFIG_OPTIONS+4)*3,config.pseudo,MAXLINELENGTH); break;
861 case 1: readstring(screen,40+10*strlen("Url : "),HEIGHT/(CONFIG_OPTIONS+4)*4,config.url,MAXLINELENGTH); break;;
862 case 2: config.fullscreen=!config.fullscreen; break;
863 case 3: config.sound=!config.sound; break;
864 case 4: config.tire=!config.tire; break;
865 case 5: config.up=0; update(); config.up=read_key(); break;
866 case 6: config.down=0; update(); config.down=read_key(); break;
867 case 7: config.left=0; update(); config.left=read_key(); break;
868 case 8: config.right=0; update(); config.right=read_key(); break;
870 if (event.key.keysym.sym==SDLK_LEFT) config.color--; else config.color++;
871 if (config.color<0) config.color=11;
872 if (config.color>11) config.color=0;
873 zeRace_generate_cars();
876 SDL_EnableKeyRepeat(0,0);
882 active--; if (active<0) active=CONFIG_OPTIONS-1;
886 active++; if (active>CONFIG_OPTIONS-1) active=0;
906 #define MENU_OPTIONS 3
911 SDL_FillRect(screen,NULL,0x000000);
912 pos.x=WIDTH/2-logo->w/2;
913 pos.y=HEIGHT/6-logo->h/2;
914 SDL_BlitSurface(logo,NULL,screen,&pos);
915 print(screen,650,HEIGHT/(MENU_OPTIONS+4)*2,"version " VERSION);
916 print(screen,420,HEIGHT/(MENU_OPTIONS+4)*(3+active),">");
917 print(screen,440,HEIGHT/(MENU_OPTIONS+4)*3,"Local game");
918 /* print(screen,440,HEIGHT/(MENU_OPTIONS+4)*4,"Network game"); */
919 print(screen,440,HEIGHT/(MENU_OPTIONS+4)*4,"Configuration");
920 print(screen,440,HEIGHT/(MENU_OPTIONS+4)*5,"Exit game");
924 logo=IMG_Load("sprites/logo.jpg");
925 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
929 while (SDL_PollEvent(&event))
937 switch (event.key.keysym.sym)
940 SDL_EnableKeyRepeat(0,0);
948 case 0: zeRace_select_track(); break;
949 case 1: zeRace_config(); break;
955 active--; if (active<0) active=MENU_OPTIONS-1;
959 active++; if (active>MENU_OPTIONS-1) active=0;
974 int main(int argc,char *argv[])