From: Antoine Jacquet Date: Mon, 13 Sep 2004 22:00:00 +0000 (+0200) Subject: version 0.2 X-Git-Tag: v0.2 X-Git-Url: http://royale.zerezo.com/git/?p=zeRace;a=commitdiff_plain;h=866e35b81c26169886388f7c93dce52f2a42809f version 0.2 * code has been commented :) * game is now a bit slower (easier to play) * added configuration screen with more options (keys, color, etc) * best times are now shown in the track selection screen * last lap time is now shown on the screen during the race * fixed directions while going backwards * blue channel is now used for grip --- diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..ae96a29 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,13 @@ +Change log file for zeRace + +version 0.2 (2004-09-14) + * code has been commented :) + * game is now a bit slower (easier to play) + * added configuration screen with more options (keys, color, etc) + * best times are now shown in the track selection screen + * last lap time is now shown on the screen during the race + * fixed directions while going backwards + * blue channel is now used for grip + +version 0.1 (2004-09-07) + * initial release diff --git a/Makefile b/Makefile index c98d452..d999c0b 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ zeRace:zeRace.c sdl.o - gcc -o zeRace zeRace.c sdl.o `sdl-config --cflags --libs` -lSDL_image -lSDL_gfx -lSDL_net -lSDL_mixer + gcc -ansi -Wall -o zeRace zeRace.c sdl.o `sdl-config --cflags --libs` -lSDL_image -lSDL_gfx -lSDL_net -lSDL_mixer sdl.o:sdl.c sdl.h - gcc -c sdl.c `sdl-config --cflags` + gcc -ansi -Wall -c sdl.c `sdl-config --cflags` clean: - rm -f zeRace *.o + rm -f zeRace *.o *.cfg diff --git a/README b/README index 615337d..43fdabe 100644 --- a/README +++ b/README @@ -1,3 +1,3 @@ -zeRace 0.1 +zeRace 0.2 site: http://royale.zerezo.com/zerace/ -mail: royale@zerezo.com \ No newline at end of file +mail: royale@zerezo.com diff --git a/sdl.c b/sdl.c index 0661854..16bd1c6 100644 --- a/sdl.c +++ b/sdl.c @@ -1,14 +1,16 @@ +/* some useful functions for zeRace game */ + #include "sdl.h" SDL_Surface *font=NULL; +/* prints a message using the bitmap font */ void print(SDL_Surface *dst,int x,int y,unsigned char *text) { SDL_Rect srcpos,dstpos; + /* on the first call, load the font picture */ if (!font) if ((font=IMG_Load("sprites/font.png"))==NULL) - { - fprintf(stderr,"could not load font file\n",SDL_GetError()); - } + fprintf(stderr,"could not load font file\n"); while (*text!='\0') { if (*text>=' ' && *text<' '+16*10) @@ -24,6 +26,51 @@ void print(SDL_Surface *dst,int x,int y,unsigned char *text) } } +/* reads a string into the "text" variable */ +void readstring(SDL_Surface *dst,int x,int y,unsigned char *text,int limit) +{ + SDL_Event event; + int shift=0; + + SDL_EnableUNICODE(1); + for (;;) + { + while (SDL_PollEvent(&event)) switch (event.type) + { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + case SDLK_RETURN: + return; + case SDLK_LSHIFT: + case SDLK_RSHIFT: + shift=1; + break; + case SDLK_BACKSPACE: + if (strlen(text)) + { + text[strlen(text)-1]='\0'; + print(dst,x+strlen(text)*10,y," "); + } + break; + default: + if ((event.key.keysym.unicode & 0xff80)==0 && strlen(text)format, r, g, b ); - - /* How we draw the pixel depends on the bitdepth */ - switch(screen->format->BytesPerPixel) { - case 1: - ubuff8 = (Uint8*) screen->pixels; - ubuff8 += (y * screen->pitch) + x; - *ubuff8 = (Uint8) color; - break; - case 2: - ubuff16 = (Uint16*) screen->pixels; - ubuff16 += ((y * screen->pitch)>>2) + x; - *ubuff16 = (Uint16) color; - break; - case 3: - ubuff8 = (Uint8*) screen->pixels; - ubuff8 += (y * screen->pitch) + x; - - r = (color>>screen->format->Rshift)&0xFF; - g = (color>>screen->format->Gshift)&0xFF; - b = (color>>screen->format->Bshift)&0xFF; - - ubuff8[0] = r; - ubuff8[1] = g; - ubuff8[2] = b; - break; - - case 4: - ubuff32 = (Uint32*) screen->pixels; - ubuff32 += ((y*screen->pitch)>>2) + x; - *ubuff32 = color; - break; - - default: - fprintf(stderr, "Error: Unknown bitdepth!\n"); - } - - /* Unlock the screen if needed */ - if(SDL_MUSTLOCK(screen)) { - SDL_UnlockSurface(screen); - } -} diff --git a/sdl.h b/sdl.h index a613c93..193d175 100644 --- a/sdl.h +++ b/sdl.h @@ -1,7 +1,11 @@ +/* some useful functions for zeRace game */ + +#include #include #include 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); void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b); diff --git a/sprites/carA.png b/sprites/carA.png new file mode 100644 index 0000000..feeb257 Binary files /dev/null and b/sprites/carA.png differ diff --git a/sprites/carB.png b/sprites/carB.png new file mode 100644 index 0000000..4fe6e50 Binary files /dev/null and b/sprites/carB.png differ diff --git a/sprites/carC.png b/sprites/carC.png new file mode 100644 index 0000000..b7a3d90 Binary files /dev/null and b/sprites/carC.png differ diff --git a/sprites/carD.png b/sprites/carD.png new file mode 100644 index 0000000..17125e1 Binary files /dev/null and b/sprites/carD.png differ diff --git a/sprites/carE.png b/sprites/carE.png new file mode 100644 index 0000000..f59eb34 Binary files /dev/null and b/sprites/carE.png differ diff --git a/sprites/carF.png b/sprites/carF.png new file mode 100644 index 0000000..acdf7b6 Binary files /dev/null and b/sprites/carF.png differ diff --git a/sprites/car.png b/sprites/carG.png similarity index 76% rename from sprites/car.png rename to sprites/carG.png index 7b9d2ea..575161a 100644 Binary files a/sprites/car.png and b/sprites/carG.png differ diff --git a/sprites/carH.png b/sprites/carH.png new file mode 100644 index 0000000..4755652 Binary files /dev/null and b/sprites/carH.png differ diff --git a/sprites/carI.png b/sprites/carI.png new file mode 100644 index 0000000..2ecf329 Binary files /dev/null and b/sprites/carI.png differ diff --git a/sprites/carJ.png b/sprites/carJ.png new file mode 100644 index 0000000..54fb16f Binary files /dev/null and b/sprites/carJ.png differ diff --git a/sprites/carK.png b/sprites/carK.png new file mode 100644 index 0000000..97dc16b Binary files /dev/null and b/sprites/carK.png differ diff --git a/sprites/carL.png b/sprites/carL.png new file mode 100644 index 0000000..0ddec99 Binary files /dev/null and b/sprites/carL.png differ diff --git a/sprites/logo.jpg b/sprites/logo.jpg new file mode 100644 index 0000000..3ad0fcb Binary files /dev/null and b/sprites/logo.jpg differ diff --git a/tracks/car.txt b/tracks/car.txt deleted file mode 100644 index 0339620..0000000 --- a/tracks/car.txt +++ /dev/null @@ -1,6 +0,0 @@ -title : Car -author : ICFP Programming Contest -version : 0.1 -x : 435 -y : 640 -a : 180 diff --git a/tracks/first.txt b/tracks/first.txt deleted file mode 100644 index 57440f7..0000000 --- a/tracks/first.txt +++ /dev/null @@ -1,6 +0,0 @@ -title : First circuit for this game... -author : Royale -version : 0.1 -x : 420 -y : 200 -a : 180 diff --git a/tracks/first_function.png b/tracks/first_function.png index 03f5cc7..0feeea3 100644 Binary files a/tracks/first_function.png and b/tracks/first_function.png differ diff --git a/tracks/hairpins.txt b/tracks/hairpins.txt deleted file mode 100644 index b08f395..0000000 --- a/tracks/hairpins.txt +++ /dev/null @@ -1,6 +0,0 @@ -title : Hairpins -author : ICFP Programming Contest -version : 0.1 -x : 490 -y : 650 -a : 0 diff --git a/tracks/icy.png b/tracks/icy.png new file mode 100644 index 0000000..c5a5fc7 Binary files /dev/null and b/tracks/icy.png differ diff --git a/tracks/icy_function.png b/tracks/icy_function.png new file mode 100644 index 0000000..b7253ce Binary files /dev/null and b/tracks/icy_function.png differ diff --git a/tracks/list.txt b/tracks/list.txt new file mode 100644 index 0000000..6f6f0ac --- /dev/null +++ b/tracks/list.txt @@ -0,0 +1,49 @@ +car +Car +ICFP Programming Contest +0.1 +435 +640 +180 +10000 +? + +first +First circuit for this game... +Royale +0.1 +420 +200 +180 +10000 +? + +icy +Same as "First", but in winter ! +Royale +0.1 +420 +200 +180 +10000 +? + +hairpins +Hairpins +ICFP Programming Contest +0.1 +490 +650 +0 +10000 +? + +simple +Simple +ICFP Programming Contest +0.1 +570 +550 +0 +10000 +? diff --git a/tracks/simple.txt b/tracks/simple.txt deleted file mode 100644 index 68decf8..0000000 --- a/tracks/simple.txt +++ /dev/null @@ -1,6 +0,0 @@ -title : Simple -author : ICFP Programming Contest -version : 0.1 -x : 570 -y : 550 -a : 0 diff --git a/zeRace.c b/zeRace.c index 7bc2e33..ce90ba1 100644 --- a/zeRace.c +++ b/zeRace.c @@ -1,20 +1,46 @@ -#include +/* + * zeRace 0.2, a funny retro racing game + * http://royale.zerezo.com/zerace/ + * + * Copyright (C) 2004 Antoine Jacquet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include #include +#include +#include #include #include #include #include -#include +#include #include "sdl.h" -#define MAXLINELENGTH 1000 -#define VERSION "0.1" +/* configuration constants */ +#define COEFF 1 +#define DELAY 7 +#define MAXLINELENGTH 80 +#define VERSION "0.2" #define WIDTH 1024 #define HEIGHT 768 -/* global variables */ - -struct track +/* tracklist : double chained list */ +struct _tracklist { char *name; char *title; @@ -23,198 +49,288 @@ struct track char *full; char *function; int x,y,a; - struct track *prev; - struct track *next; + int best_time; + char *best_pseudo; + struct _tracklist *prev; + struct _tracklist *next; } *tracklist=NULL; -int fullscreen=0; -int sound=0; -char pseudo[MAXLINELENGTH]="anonymous"; -char url[MAXLINELENGTH]=""; +/* user setup */ +struct _config +{ + char pseudo[MAXLINELENGTH]; + char url[MAXLINELENGTH]; + int fullscreen; + int sound; + int tire; + SDLKey up; + SDLKey down; + SDLKey left; + SDLKey right; + char color; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6}; + +/* display and all directions for the car */ SDL_Surface *screen; SDL_Surface *cars[256]; + +/* read the user configuration file */ +void zeRace_read_config() +{ + FILE *fic; + if ((fic=fopen("zeRace.cfg","rt"))==NULL) + { + fprintf(stderr,"can't open config file \"zeRace.cfg\"\n"); + return; + } + fread(&config,sizeof(struct _config),1,fic); + fclose(fic); +} + + +/* save the user configuration file */ +void zeRace_save_config() +{ + FILE *fic; + if ((fic=fopen("zeRace.cfg","wt"))==NULL) + { + fprintf(stderr,"can't create config file \"zeRace.cfg\"\n"); + return; + } + fwrite(&config,sizeof(struct _config),1,fic); + fclose(fic); +} + + +/* exit the game and clean */ void zeRace_exit() { printf("quit\n"); - if (sound) Mix_CloseAudio(); + if (config.sound) Mix_CloseAudio(); SDLNet_Quit(); SDL_Quit(); - /* - save_config(); - zeRace_send_ghosts(); - close_sdl(); - */ + zeRace_save_config(); exit(0); } -void zeRace_read_config() +/* get available local tracks */ +void zeRace_get_tracks() { FILE *fic; char line[MAXLINELENGTH]; - char keyword[MAXLINELENGTH]; - char value[MAXLINELENGTH]; - int configlines=0; + 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() +{ + IPaddress ip; + TCPsocket tcpsock; + char *request= + "GET /zerace/version.php HTTP/1.0\n" + "Host: royale.zerezo.com\n" + "User-Agent: zeRace " VERSION "\n" + "\n"; + char response[1024],*tmp,*version; + int len,result; - if ((fic=fopen("zeRace.cfg","rt"))==NULL) + printf("checking version... "); + fflush(stdout); + + if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) { - fprintf(stderr,"can't open config file \"zeRace.cfg\"\n"); - exit(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; } - while (fgets(line,MAXLINELENGTH,fic)) + len=strlen(request); + result=SDLNet_TCP_Send(tcpsock,request,len); + if(result0) printf("new version available !\nhttp://royale.zerezo.com/zerace/\n"); } } + + SDLNet_TCP_Close(tcpsock); } -void zeRace_get_tracks() +/* get remote list of tracks */ +void zeRace_update_tracks() { - struct dirent **namelist; - int i; - unsigned char ext[5]; + IPaddress ip; + TCPsocket tcpsock; + char *request= + "GET /zerace/tracks.php HTTP/1.0\n" + "Host: royale.zerezo.com\n" + "User-Agent: zeRace " VERSION "\n" + "\n"; + char response[10240],*tmp; + int len,result; FILE *fic; - char *shortname=NULL; - char line[MAXLINELENGTH]; - int configlines; - struct track *tmp=NULL,*first=NULL; - DIR *dirp; - struct dirent *dp; + + printf("checking version and updating tracks... "); + fflush(stdout); - if ((dirp=opendir("tracks"))==NULL) { fprintf(stderr,"can't open \"tracks\" directory or no tracks\n"); return; } + if(SDLNet_ResolveHost(&ip,"royale.zerezo.com",80)==-1) + { + fprintf(stderr,"SDLNet_ResolveHost: %s\n",SDLNet_GetError()); + return; + } - while (dp=readdir(dirp)) if (strlen(dp->d_name)>4) + 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(resultd_name)-3); - strncpy(shortname,dp->d_name,strlen(dp->d_name)-4); - shortname[strlen(dp->d_name)-4]='\0'; - for (i=0;i<5;i++) ext[i]=tolower(dp->d_name[strlen(dp->d_name)-4+i]); - if (strcmp(".txt",ext)==0) + if ((fic=fopen("tracks/list.txt","wt"))==NULL) { - tmp=(struct track *)malloc(sizeof(struct track)); - if (first==NULL) first=tmp; - tmp->name=(char *)malloc(strlen(shortname)+1); - strcpy(tmp->name,shortname); - tmp->title=""; - tmp->author=""; - tmp->version=""; - tmp->x=10; - tmp->y=10; - tmp->a=0; - configlines=0; - sprintf(line,"tracks/%s.txt",shortname); - if ((fic=fopen(line,"rt"))==NULL) - { - fprintf(stderr,"can't open track file \"%s\"\n",line); - zeRace_exit(); - } - while (fgets(line,MAXLINELENGTH,fic)) - { - configlines++; - if (*line!=';' && *line!='#' && *line!='/' && *line!='-' && *line!='\n') - { - for (i=0;ititle=(char *)malloc(strlen(line+i+3)+1); - strcpy(tmp->title,line+i+3); - } - else - - if (strcmp("author",line)==0) - { - tmp->author=(char *)malloc(strlen(line+i+3)+1); - strcpy(tmp->author,line+i+3); - } - else - - if (strcmp("x",line)==0) - tmp->x=atoi(line+i+3); - else - - if (strcmp("y",line)==0) - tmp->y=atoi(line+i+3); - else - - if (strcmp("a",line)==0) - tmp->a=atoi(line+i+3); - else - - if (strcmp("version",line)==0) - { - tmp->version=(char *)malloc(strlen(line+i+3)+1); - strcpy(tmp->version,line+i+3); - } - - else { fprintf(stderr,"error in track file \"%s\" : \"%s\" is an unknown keyword (line %d)\n",shortname,line,configlines); exit(1); } - } - } - fclose(fic); - tmp->full=(char *)malloc(strlen(line)+20); - sprintf(tmp->full,"tracks/%s.png",shortname); - tmp->function=(char *)malloc(strlen(line)+30); - sprintf(tmp->function,"tracks/%s_function.png",shortname); - tmp->prev=tracklist; - if (tmp->prev) tmp->prev->next=tmp; - tracklist=tmp; + fprintf(stderr,"can't create track list\n"); + zeRace_exit(); } + len=SDLNet_TCP_Recv(tcpsock,response,10240); + tmp=response; + while (*tmp!='\n' || *(tmp+1)!='\r') tmp++; + tmp+=3; + fwrite(tmp,1,len+response-tmp,fic); + fclose(fic); + printf("done\n"); } - if (!tmp) { fprintf(stderr,"no circuits found !\n"); zeRace_exit(); } - while (tmp->prev) tmp=tmp->prev; - tmp->prev=tracklist; - tracklist->next=tmp; + + SDLNet_TCP_Close(tcpsock); } -void zeRace_init() +/* load the car sprite and rotate it for every angles */ +void zeRace_generate_cars() { + int i; SDL_Surface *car; - int i,flags; + 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;xw;x++) for (y=0;yh;y++) + { + 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 && x2w && y2>0 && y2h) + putpixel(cars[i],x,y,getpixel(car,x2,y2)); + } + } + SDL_FreeSurface(car); +} + + +/* initialize the game */ +void zeRace_init() +{ + int flags,i; + /* do a clean exit in case of emergency */ signal(SIGINT,zeRace_exit); signal(SIGTERM,zeRace_exit); + + /* read the user configuration file */ zeRace_read_config(); - //zeRace_check_version(); + + /* check for a newer available version */ + zeRace_check_version(); + + /* update the list of tracks */ + zeRace_update_tracks(); + + /* get the list of local tracks */ zeRace_get_tracks(); - //zeRace_get_ghosts(); srand(time(NULL)); @@ -232,7 +348,7 @@ void zeRace_init() } flags=SDL_HWSURFACE|SDL_ANYFORMAT; - if (fullscreen) flags|=SDL_FULLSCREEN; + if (config.fullscreen) flags|=SDL_FULLSCREEN; if ((screen=SDL_SetVideoMode(WIDTH,HEIGHT,32,flags))==NULL) { @@ -244,45 +360,30 @@ void zeRace_init() SDL_WM_SetCaption("zeRace " VERSION,"zeRace " VERSION); SDL_ShowCursor(SDL_DISABLE); - if (sound) if (Mix_OpenAudio(44100,MIX_DEFAULT_FORMAT,2,512)<0) + if (config.sound) if (Mix_OpenAudio(44100,MIX_DEFAULT_FORMAT,2,512)<0) { fprintf(stderr,"Mix_OpenAudio error\n"); zeRace_exit(); } - car=IMG_Load("sprites/car.png"); - for (i=0;i<256;i++) + /* 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) { - float x,y; - float tcos,tsin; - cars[i]=SDL_CreateRGBSurface(SDL_SWSURFACE,car->h*2,car->h*2,32,0x000000ff,0x0000ff00,0x00ff0000,0xff000000); - if(cars[i]==NULL) - { - fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError()); - exit(1); - } - tcos=cos(2*M_PI*i/256); - tsin=sin(2*M_PI*i/256); - for (x=0;xw;x++) for (y=0;yh;y++) - { - int x2,y2; - Uint32 col; - 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 && x2w && y2>0 && y2h) - putpixel(cars[i],x,y,getpixel(car,x2,y2)); - } - } + fprintf(stderr,"CreateRGBSurface failed: %s\n",SDL_GetError()); + zeRace_exit(); + }; + 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) { IPaddress ip; TCPsocket tcpsock; char *temp; char *msg1= - "POST /zerace/time.php HTTP/1.1\n" + "POST /zerace/time.php HTTP/1.0\n" "Host: royale.zerezo.com\n" "User-Agent: zeRace " VERSION "\n" "Content-Type: application/x-www-form-urlencoded\n" @@ -315,20 +416,41 @@ void zeRace_send_time(float x,float y,float speed,float angle,int btime,char *bk return; } - temp=(char *)malloc(strlen(msg1)+strlen(pseudo)+strlen(msg2)+strlen(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,pseudo,msg2,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(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); len=strlen(temp); result=SDLNet_TCP_Send(tcpsock,temp,len); if(result100) return; + temp[0]=q/10+'0'; + temp[1]=q%10+'0'; + temp[2]='"'; + temp[3]=r/100+'0'; + temp[4]=r%100/10+'0'; + temp[5]=r%10+'0'; + temp[6]='\0'; + print(screen,x,y,temp); +} + + +/* launch a new race */ void zeRace_launch() { SDL_Surface *cir,*fun; @@ -340,12 +462,10 @@ void zeRace_launch() float x,y,angle,speed; float sx,sy,sangle,sspeed; float bx,by,bangle,bspeed; - int c,r,v,b; - int temp; + int c,r,g,b; char keys[10000]; char bkeys[10000]; - char text[10]; - Mix_Music *light,*engine,*crash,*slide; + Mix_Music *light,*engine,*crash,*slide; int lastsound_time=-999,alltime=0,lastsound=0; cir=IMG_Load(tracklist->full); @@ -358,12 +478,13 @@ void zeRace_launch() lastcheck=0; time=0; - if (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"))) + 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"))) { fprintf(stderr,"Mix_LoadMUS error\n"); zeRace_exit(); } + /* startup countdown */ for (i=4;i>=-1;i--) { char startup[15]="sprites/?.png"; @@ -381,25 +502,29 @@ void zeRace_launch() SDL_BlitSurface(temp,NULL,screen,&pos); SDL_FreeSurface(temp); } - if (sound) if (i!=4) Mix_PlayMusic(light,1); + if (config.sound) if (i!=4) Mix_PlayMusic(light,1); SDL_Flip(screen); if (i!=-1) SDL_Delay(1000); } + /* main loop */ for (;;) - { + { + /* clear the old position */ size.w=cars[0]->w; size.h=cars[0]->h; pos.x=x; pos.y=y; 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) { x=ox; @@ -407,6 +532,7 @@ void zeRace_launch() speed=0; } + /* 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; @@ -414,58 +540,80 @@ void zeRace_launch() SDL_UpdateRect(screen,ox,oy,cars[i]->w,cars[i]->h); SDL_UpdateRect(screen,x,y,cars[i]->w,cars[i]->h); - if (kl) angle-=0.01; - if (kr) angle+=0.01; - if (ku) speed+=0.01*2; - if (kd) speed-=0.01; + /* 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; + /* play engine sound if no sound is currently playing */ if (lastsound_time+1000.5 || speed>2.0 && !ku) + /* if the car is fast or braking, it slides */ + if ((kd && speed>0.5) || (speed>2.0 && !ku)) { - + /* if the only sound is the engine, play the slide sound */ if (lastsound_time+100w/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); - if (kd) + /* display tires slide */ + if (config.tire) { - 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,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); + /* 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); + } } } - + + /* 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); - r=c&0x000000ff; - v=(c&0x0000ff00)>>8; - - if (v==0) + /* 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) { x=ox; y=oy; + /* play the crash sound */ if (lastsound_time+100title)*5,5*HEIGHT/6-20,tracklist->title); print(screen,WIDTH/2-(strlen(tracklist->author)+strlen("Author : "))*5,5*HEIGHT/6+0,"Author : "); print(screen,WIDTH/2-(strlen(tracklist->author)-strlen("Author : "))*5,5*HEIGHT/6+0,tracklist->author); - print(screen,WIDTH/2-(strlen(tracklist->version)+strlen("Version : "))*5,5*HEIGHT/6+20,"Version : "); - print(screen,WIDTH/2-(strlen(tracklist->version)-strlen("Version : "))*5,5*HEIGHT/6+20,tracklist->version); + print(screen,WIDTH/2-( strlen("Version : ")+strlen(tracklist->version))*5,5*HEIGHT/6+20,"Version : "); + print(screen,WIDTH/2-(-strlen("Version : ")+strlen(tracklist->version))*5,5*HEIGHT/6+20,tracklist->version); + print(screen,WIDTH/2-( strlen("Best time : ")+6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,"Best time : "); + print_time (WIDTH/2-(-strlen("Best time : ")+6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,tracklist->best_time); + print(screen,WIDTH/2-(-strlen("Best time : ")-6+strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40," by "); + print(screen,WIDTH/2-(-strlen("Best time : ")-6-strlen(" by ")+strlen(tracklist->best_pseudo))*5,5*HEIGHT/6+40,tracklist->best_pseudo); full=IMG_Load(tracklist->full); preview=(SDL_Surface *)zoomSurface(full,0.5,0.5,1); SDL_FreeSurface(full); @@ -611,22 +756,211 @@ void zeRace_menu() case SDL_KEYDOWN: switch (event.key.keysym.sym) { - case SDLK_ESCAPE: // escape - zeRace_exit(); - break; - case SDLK_RETURN: //enter - case SDLK_SPACE: //space + case SDLK_ESCAPE: + return; + case SDLK_RETURN: + case SDLK_SPACE: zeRace_launch(); update(); break; - case SDLK_LEFT: //left + case SDLK_LEFT: tracklist=tracklist->next; update(); break; - case SDLK_RIGHT: //right + case SDLK_RIGHT: tracklist=tracklist->prev; update(); break; + default: + break; + } + break; + } + } + SDL_Delay(10); + } +} + + +/* configuration screen */ +void zeRace_config() +{ + SDL_Event event; + int active=0; + #define CONFIG_OPTIONS 11 + + void update() + { + SDL_Rect pos; + SDL_FillRect(screen,NULL,0x000000); + 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 : "); + print(screen,40+10*strlen("Pseudo : "),HEIGHT/(CONFIG_OPTIONS+4)*3,config.pseudo); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*4,"Url : "); + print(screen,40+10*strlen("Url : "),HEIGHT/(CONFIG_OPTIONS+4)*4,config.url); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*5,"Fullscreen : "); + print(screen,40+10*strlen("Fullscreen : "),HEIGHT/(CONFIG_OPTIONS+4)*5,config.fullscreen?"Yes":"No"); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*6,"Sound : "); + print(screen,40+10*strlen("Sound : "),HEIGHT/(CONFIG_OPTIONS+4)*6,config.sound?"Yes":"No"); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*7,"Tire : "); + print(screen,40+10*strlen("Tire : "),HEIGHT/(CONFIG_OPTIONS+4)*7,config.tire?"Yes":"No"); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*8,"Accelerate key : "); + print(screen,40+10*strlen("Accelerate key : "),HEIGHT/(CONFIG_OPTIONS+4)*8,config.up?SDL_GetKeyName(config.up):""); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*9,"Brake key : "); + print(screen,40+10*strlen("Brake key : "),HEIGHT/(CONFIG_OPTIONS+4)*9,config.down?SDL_GetKeyName(config.down):""); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*10,"Turn left key : "); + print(screen,40+10*strlen("Turn left key : "),HEIGHT/(CONFIG_OPTIONS+4)*10,config.left?SDL_GetKeyName(config.left):""); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*11,"Turn right key : "); + print(screen,40+10*strlen("Turn right key : "),HEIGHT/(CONFIG_OPTIONS+4)*11,config.right?SDL_GetKeyName(config.right):""); + 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); + print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu"); + SDL_Flip(screen); + } + + int read_key() + { + for (;;) + { + while (SDL_PollEvent(&event)) switch (event.type) + { + case SDL_KEYDOWN: + return event.key.keysym.sym; + } + SDL_Delay(10); + } + } + + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); + 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: + SDL_EnableKeyRepeat(0,0); + return; + case SDLK_RETURN: + case SDLK_SPACE: + case SDLK_LEFT: + case SDLK_RIGHT: + switch (active) + { + case 0: readstring(screen,40+10*strlen("Pseudo : "),HEIGHT/(CONFIG_OPTIONS+4)*3,config.pseudo,MAXLINELENGTH); break; + case 1: readstring(screen,40+10*strlen("Url : "),HEIGHT/(CONFIG_OPTIONS+4)*4,config.url,MAXLINELENGTH); break;; + case 2: config.fullscreen=!config.fullscreen; break; + case 3: config.sound=!config.sound; break; + case 4: config.tire=!config.tire; break; + case 5: config.up=0; update(); config.up=read_key(); break; + case 6: config.down=0; update(); config.down=read_key(); break; + case 7: config.left=0; update(); config.left=read_key(); break; + 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; + zeRace_generate_cars(); + break; + case 10: + SDL_EnableKeyRepeat(0,0); + return; + } + update(); + break; + case SDLK_UP: + active--; if (active<0) active=CONFIG_OPTIONS-1; + update(); + break; + case SDLK_DOWN: + active++; if (active>CONFIG_OPTIONS-1) active=0; + update(); + break; + default: + break; + } + break; + } + } + SDL_Delay(10); + } +} + + +/* main menu */ +void zeRace_menu() +{ + SDL_Event event; + int active=0; + SDL_Surface *logo; + #define MENU_OPTIONS 3 + + void update() + { + SDL_Rect pos; + SDL_FillRect(screen,NULL,0x000000); + 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,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"); + SDL_Flip(screen); + } + + logo=IMG_Load("sprites/logo.jpg"); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL); + 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: + SDL_EnableKeyRepeat(0,0); + return; + case SDLK_RETURN: + case SDLK_SPACE: + case SDLK_LEFT: + case SDLK_RIGHT: + switch (active) + { + case 0: zeRace_select_track(); break; + case 1: zeRace_config(); break; + case 2: return; + } + update(); + break; + case SDLK_UP: + active--; if (active<0) active=MENU_OPTIONS-1; + update(); + break; + case SDLK_DOWN: + active++; if (active>MENU_OPTIONS-1) active=0; + update(); + break; + default: + break; } break; } @@ -636,6 +970,7 @@ void zeRace_menu() } +/* main program */ int main(int argc,char *argv[]) { zeRace_init(); diff --git a/zeRace.cfg b/zeRace.cfg deleted file mode 100644 index c3da5a4..0000000 --- a/zeRace.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# set this to your nickname to set your name in top list -# http://royale.zerezo.com/zerace/ -pseudo : anonymous - -# set this to add a link on your nickname -#url : mailto:royale@zerezo.com -#url : http://royale.zerezo.com/ - -# set to yes to enable fullscreen -fullscreen : no - -# set to no to turn off awful sounds -sound : no