From: Antoine Jacquet Date: Mon, 19 Mar 2007 23:00:00 +0000 (+0100) Subject: version 0.7 X-Git-Tag: v0.7 X-Git-Url: http://royale.zerezo.com/git/?a=commitdiff_plain;ds=inline;p=zeRace version 0.7 * added a new bot based on checkpoints * option to disable internet accesses --- diff --git a/CHANGELOG b/CHANGELOG index 430e1f4..9afa5c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ Change log file for zeRace +version 0.7 (2007-03-20) + * added a new bot based on checkpoints + * option to disable internet accesses + version 0.6 (2007-02-24) * added some tracks from pyRacerz (thank you Julien) * fixed network initialization issue for Win32 diff --git a/Makefile b/Makefile index b899460..ec34343 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=gcc SDLCONFIG=sdl-config -all:zeRace server bot_anticip +all:zeRace server bot_anticip bot_checkpoint optimize_checkpoint zeRace:zeRace.c network.h sdl.o car.o tracklist.o $(ICON) $(CC) -o zeRace$(EXT) zeRace.c sdl.o car.o tracklist.o $(ICON) `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_mixer -lSDL_image -lSDL_gfx -L. @@ -12,6 +12,12 @@ server:server.c network.h sdl.o car.o tracklist.o bot_anticip:bot_anticip.c bot.o sdl.o car.o tracklist.o $(CC) -o bot_anticip$(EXT) bot_anticip.c bot.o sdl.o car.o tracklist.o `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_image -L. +bot_checkpoint:bot_checkpoint.c bot.o sdl.o car.o tracklist.o + $(CC) -o bot_checkpoint$(EXT) bot_checkpoint.c bot.o sdl.o car.o tracklist.o `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_image -L. + +optimize_checkpoint:bot_checkpoint.c sdl.o car.o tracklist.o + $(CC) -O2 -DOPTIMIZE -o optimize_checkpoint$(EXT) bot_checkpoint.c sdl.o car.o tracklist.o `$(SDLCONFIG) --cflags --libs` -lSDL_net -lSDL_image -L. + sdl.o:sdl.c sdl.h $(CC) -c sdl.c `$(SDLCONFIG) --cflags` @@ -28,4 +34,4 @@ icon.o:icon.rc $(WINDRES) -i icon.rc -o icon.o clean: - rm -f zeRace server bot_anticip *.exe *.o *.cfg + rm -f zeRace server bot_anticip bot_checkpoint optimize_checkpoint *.exe *.o *.cfg diff --git a/README b/README index 10f9f9e..d8273bf 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -zeRace 0.6 +zeRace 0.7 site: http://royale.zerezo.com/zerace/ mail: royale@zerezo.com diff --git a/bot_checkpoint.c b/bot_checkpoint.c new file mode 100644 index 0000000..1d7a5a6 --- /dev/null +++ b/bot_checkpoint.c @@ -0,0 +1,355 @@ +/* + * zeRace "checkpoint" bot + optimizer + * http://royale.zerezo.com/zerace/ + * + * Copyright (C) 2006 Antoine Jacquet + * Licensed under GPL + * + * This robot uses a static database of checkpoint. + * It will not be able to race on an unknown track. + * + * If you want to train it for a new track, you will need to add some manual + * checkpoints to the list. + * + * You can then use the optimizer to find better checkpoints. + * An example: ./optimize formula 5 10000 4 + * Will optimize the track "formula" using 10000 races of 5 laps. + * At each loop, it will move each checkpoint of 4 pixel or less. + * The optimizer will output new values for checkpoints you should copy/paste. + */ + +#define sqr(x) ((x)*(x)) +#define MAX_STUCK 100 +#define LOOPS 1000 +#define LAPS 5 +#define INIT_PRECISION 50 +#define TIMEOUT 19999 +#define TOLERANCE_DISTANCE 30.0 + +#include +#include "bot.h" + +typedef struct { + int x; + int y; +} coord; + +char dummy[99]; + +struct { + char *trackname; + float max_speed_angle; + coord *checkpoint; +} db[] = { + /* dummy entry used for new tracks */ dummy, 0.5, (coord[]){ -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, -1,-1, }, + /* 7373 */ "bio", 0.59, (coord[]){ 890,683, 502,526, 277,599, 72,530, 45,302, 298,232, 781,192, 826,185, 916,324, 970,548, -1,-1, }, + /* 4700 */ "car", 0.40, (coord[]){ 781,664, 877,617, 883,479, 522,242, 291,237, 111,449, 149,580, 234,661, -1,-1, }, + /* 5572 */ "city", 0.65, (coord[]){ 49,266, 122,198, 259,174, 349,183, 377,211, 453,229, 749,308, 917,487, 681,595, 546,574, 417,596, 233,571, 128,486, 45,414, -1,-1, }, + /* 13338 */ "desert", 0.40, (coord[]){ 561,378, 382,338, 285,415, 367,522, 440,594, 377,697, 103,289, 136,154, 258,66, 366,57, 588,50, 729,126, 821,308, 897,525, 777,649, 720,495, -1,-1, }, + /* 5792 */ "first", 0.65, (coord[]){ 500,240, 762,150, 988,418, 916,544, 712,590, 556,663, 225,646, 115,339, -1,-1, }, + /* 6602 */ "formula", 0.60, (coord[]){ 682,577, 968,495, 964,255, 762,232, 722,421, 554,610, 215,520, 160,448, 266,252, -1,-1, }, + /* 21470 */ "hairpins", 0.50, (coord[]){ 353,604, 182,617, 68,516, 195,501, 217,381, 159,342, 119,346, 103,207, 250,97, 334,123, 346,259, 446,309, 492,104, 588,37, 632,93, 791,140, 862,136, 971,271, 806,200, 722,262, 802,446, 838,460, 865,593, 838,697, 698,595, 637,491, 487,504, 481,470, 570,550, 549,665, -1,-1, }, + /* 8581 */ "http", 0.58, (coord[]){ 635,88, 689,98, 796,232, 776,292, 773,364, 792,408, 809,521, 665,693, 622,710, 518,696, 476,663, 408,689, 344,461, 431,366, 338,224, 245,303, 110,216, 297,118, 404,83, 473,97, 528,47, -1,-1, }, + /* 5854 */ "icy", 0.67, (coord[]){ 792,164, 951,255, 873,535, 710,593, 616,635, 547,667, 235,657, 116,353, 329,202, -1,-1, }, + /* 13889 */ "kart", 1.16, (coord[]){ 132,657, 38,387, 109,171, 332,215, 472,276, 512,201, 834,108, 957,343, 274,336, 275,512, 900,560, 918,694, -1,-1, }, + /* 9063 */ "loop", 0.61, (coord[]){ 412,720, 207,659, 68,442, 115,183, 397,132, 523,281, 855,331, 892,276, 839,106, 712,182, 651,208, 658,473, 855,542, 915,630, 719,702, 638,700, -1,-1, }, + /* 13333 */ "simple", 0.61, (coord[]){ 362,629, 169,663, 78,608, 143,151, 396,375, 420,288, 416,206, 601,131, 652,273, 922,440, 962,541, -1,-1, }, + /* 12926 */ "wave", 0.57, (coord[]){ 733,381, 916,512, 884,633, 732,540, 872,281, 822,132, 722,137, 647,163, 586,177, 616,173, 573,202, 475,173, 443,206, 405,189, 301,140, 287,169, 155,291, 560,593, 446,681, 334,636, 203,572, 151,525, 676,413, -1,-1, }, + /* end entry */ NULL, 0, NULL, +}; + +char *bot_name() +{ + return "Checkpoint"; +} + +int current_track = 0; +int next_checkpoint = 0; + +void bot_ia(char *trackname, struct _car *car, SDL_Surface * fun, int *ku, int *kd, int *kl, int *kr) +{ + int i; + float dx, dy, da; + float angle = 0, distance; + + /* if the track has changed */ + if (strcmp(db[current_track].trackname, trackname) != 0) + { + current_track = -1; + + /* find the good track in the db */ + for (i = 0; db[i].trackname != NULL; i++) if (strcmp(db[i].trackname, trackname) == 0) current_track = i; + + /* we did not find the track in the database */ + if (current_track == -1) + { + /* we won't be able to drive this race ... */ + fprintf(stderr, "Unknown track: %s\n", trackname); + exit(1); + } + next_checkpoint = 0; + } + + /* compute delta x/y */ + dx = db[current_track].checkpoint[next_checkpoint].x - car->x; + dy = db[current_track].checkpoint[next_checkpoint].y - car->y; + + /* compute the angle of the next checkpoint */ + if (dy > 0) + angle = 3.0 * M_PI / 2 - atan(dx/dy); + if (dy < 0) + angle = 1.0 * M_PI / 2 - atan(dx/dy); + + /* compute the distance of the next checkpoint */ + distance = sqrt( sqr(dx) + sqr(dy) ); + + /* compute the angle difference */ + da = angle - car->angle; + + /* keep it between -pi and pi */ + while (da < -M_PI) da += 2 * M_PI; + while (da > +M_PI) da -= 2 * M_PI; + + /* compute steering */ + if (da < 0) *kl = 1; else *kl = 0; + if (da > 0) *kr = 1; else *kr = 0; + + /* we try to go as fast as possible */ + *ku = 1; + *kd = 0; + + /* if the angle and speed are to big */ + if (car->speed > 0) + /* formula should be based on speed, angle diff... and distance? */ + if (sqrt(1 + car->speed) * sqr(da) > db[current_track].max_speed_angle) + { + /* we should brake! */ + *ku = 0; + *kd = 1; + } + + /* if we are close enought of the checkpoint, jump to the next one */ + if (distance < TOLERANCE_DISTANCE) + { + next_checkpoint++; + if (db[current_track].checkpoint[next_checkpoint].x == -1) next_checkpoint = 0; + } + + /* debug */ + if (0) + printf("debug: x=%.2f y=%.2f a=%.0f s=%.2f | kl=%d kr=%d ku=%d kd=%d | c=%d a=%.0f d=%.2f dx/dy=%.0f/%.0f da=%.2f\n", + car->x, car->y, 180/M_PI*car->angle, car->speed, *kl, *kr, *ku, *kd, next_checkpoint, 180/M_PI*angle, distance, dx, dy, da); +} + +#ifdef OPTIMIZE + +/* if the bot is called from command line, we run the track optimizer */ +int main(int argc, char *argv[]) +{ + struct _tracklist *tracklist, *loopcheck; + SDL_Surface *fun; + int loop, lap, ctime, btime = TIMEOUT, tr, nb, i, j, precision, stuck = 0, found = 0; + int ku, kd, kl, kr; + struct _car car; + coord backup[99]; + float backup_msa; + + /* check parameters */ + if (argc != 2) + { + fprintf(stderr, + "Usage : %s track\n" + " track: the name of the track you want to optimize.\n" + "Look at the source code for more details...\n" + ,argv[0]); + exit(1); + } + + /* randomize */ + srand(time(NULL)); + precision = INIT_PRECISION; + + /* load tracklist */ + if (!zeRace_get_tracks(&tracklist)) + { + fprintf(stderr, "Unable to load tracks!\n"); + exit(1); + } + + /* pick up the good track */ + loopcheck = tracklist; + do if (strcmp(tracklist->name, argv[1]) == 0) break; else tracklist = tracklist->next; while (tracklist != loopcheck); + + /* if it is not found, display an error message */ + if (strcmp(tracklist->name, argv[1]) != 0) + { + fprintf(stderr, "Unable to load track %s\n", argv[1]); + exit(1); + } + + /* load the image */ + fun = IMG_Load(tracklist->function); + + /* find the good track in the db */ + for (tr = 0; db[tr].trackname != NULL; tr++) if (strcmp(db[tr].trackname, argv[1]) == 0) break; + + /* we did not find the track in the database */ + if (db[tr].trackname == NULL) + { + printf("trying to create some checkpoints... "); fflush(stdout); + tr = 0; + strcpy(db[tr].trackname, argv[1]); + /* try to suggest some checkpoints */ + for (i = 1; i < 32; i += 1) + { + int x,y, xx = 0,yy = 0, n = 0; + + for (x = 0; x < fun->w; x += 5) + for ( y = 0; y < fun->h; y += 5) + { + Uint32 c; + Uint8 r,g,b; + /* get the pixel color under the center of car in the function map */ + c = getpixel(fun, x, y); + /* red layer (checkpoints) */ + /* green layer (road quality) */ + /* blue layer (grip) */ + SDL_GetRGB(c, fun->format, &r, &g, &b); + if (g == 255 && r/8 == i) + { + xx += x; + yy += y; + n++; + } + } + + db[tr].checkpoint[i-1].x = xx/n; + db[tr].checkpoint[i-1].y = yy/n; + } + printf("done\n"); + } + + /* while we can continue to optimize better */ + while (precision > 0 || found) + { + /* start again ? */ + if (precision == 0) + { + printf("starting again...\n"); + precision = INIT_PRECISION; + found = 0; + } + + /* check for close checkpoints */ + nb = 0; + for (i = 0; db[tr].checkpoint[i+1].x != -1; i++) + /* if the checkpoints are close */ + if (sqrt( sqr(db[tr].checkpoint[i].x - db[tr].checkpoint[i+1].x) + sqr(db[tr].checkpoint[i].y - db[tr].checkpoint[i+1].y)) < TOLERANCE_DISTANCE) + { + nb++; + /* we remove one from the list */ + for (j = i+1; db[tr].checkpoint[j].x != -1; j++) + { + db[tr].checkpoint[j].x = db[tr].checkpoint[j+1].x; + db[tr].checkpoint[j].y = db[tr].checkpoint[j+1].y; + } + db[tr].checkpoint[j].x = -1; + } + if (nb) printf("removing %d checkpoints...\n", nb); + + /* count the checkpoints */ + for (nb = 0; db[tr].checkpoint[nb].x != -1; nb++); + + /* copy the current checkpoints */ + memcpy(backup, db[tr].checkpoint, nb * 2 * sizeof(coord)); + backup_msa = db[tr].max_speed_angle; + + /* try with this precision */ + printf("trying with %d pixel precision...\n", precision); + + /* do X optimization races (loops) */ + for (loop = 0; loop < LOOPS; loop++) + { + /* init parameters */ + car.speed = 0; + car.angle = tracklist->a * 2 * M_PI / 360; + car.ox = car.x = tracklist->x; + car.oy = car.y = tracklist->y; + car.lastcheck = 0; + car.w = 30; + car.h = 30; + ctime = 0; + car.lapflag = 0; + lap = 0; + next_checkpoint = 0; + + /* do X laps */ + while (1) + { + bot_ia(argv[1], &car, fun, &ku, &kd, &kl, &kr); + move_car(&car, (ku<<3 | kd<<2 | kl<<1 | kr), fun); + + /* if we did a full lap, count it */ + if (car.lapflag == 1) + { + lap++; + /* we did all the lap, exit */ + if (lap == LAPS) break; + car.lapflag = 0; + } + + /* check if we are "stuck" */ + if (car.speed < 0.01) stuck++; else stuck = 0; + + /* if we missed a checkpoint or too long, exit */ + if (car.lapflag != 0 || ctime > TIMEOUT || stuck > MAX_STUCK) + { + ctime = TIMEOUT; + break; + } + + ctime++; + } + + /* check if it is the best ? */ + if (ctime < btime) + { + btime = ctime; + printf("new record: %d!!!\n", btime); + /* print the best table found */ + printf("/* %d */ \"%s\", %.2f, (coord[]){ ", btime, argv[1], db[current_track].max_speed_angle); + for (i = 0; i <= nb; i++) + printf("%d,%d, ", db[tr].checkpoint[i].x, db[tr].checkpoint[i].y); + printf("},\n"); + found = 1; + } + /* restore previous version */ + else + { + memcpy(db[tr].checkpoint, backup, nb * 2 * sizeof(coord)); + db[tr].max_speed_angle = backup_msa; + } + + /* backup the new version */ + memcpy(backup, db[tr].checkpoint, nb * 2 * sizeof(coord)); + backup_msa = db[tr].max_speed_angle; + + /* do some change to the checkpoint table */ + db[tr].max_speed_angle += ( rand() % (2 * precision + 1) - precision ) / 100.0; + for (i = 0; i < nb; i++) + { + db[tr].checkpoint[i].x += rand() % (2 * precision + 1) - precision; + db[tr].checkpoint[i].y += rand() % (2 * precision + 1) - precision; + } + } + + /* restore the best version */ + memcpy(db[tr].checkpoint, backup, nb * 2 * sizeof(coord)); + db[tr].max_speed_angle = backup_msa; + + /* try to find better... */ + precision = precision/2; + } +} + +#endif diff --git a/local-server-with-bots.bat b/local-server-with-bots.bat index 9ce4dff..3040259 100755 --- a/local-server-with-bots.bat +++ b/local-server-with-bots.bat @@ -2,22 +2,25 @@ echo Launching server... start server.exe "My private server" 5 1 private col ping localhost -n 2 > NUL -echo Launching bot(0)... +echo Launching anticip(0)... start bot_anticip.exe localhost 3600 0 ping localhost -n 2 > NUL -echo Launching bot(5)... +echo Launching anticip(5)... start bot_anticip.exe localhost 3600 5 ping localhost -n 2 > NUL -echo Launching bot(10)... +echo Launching anticip(10)... start bot_anticip.exe localhost 3600 10 ping localhost -n 2 > NUL -echo Launching bot(15)... -start bot_anticip.exe localhost 3600 15 +echo Launching checkpoint(0)... +start bot_checkpoint.exe localhost 3600 0 ping localhost -n 2 > NUL -echo Launching bot(20)... -start bot_anticip.exe localhost 3600 20 -ping localhost -n 2 > NUL -echo A local server has been launched with 5 bots. +echo Launching checkpoint(5)... +start bot_checkpoint.exe localhost 3600 5 +ping localhost -n 2 > NUL +echo Launching checkpoint(10)... +start bot_checkpoint.exe localhost 3600 10 +ping localhost -n 2 > NUL +echo A local server has been launched with 6 bots. echo You can now join it with zeRace in the network menu. echo When you have finished, you can terminate the server with the task manager. echo. diff --git a/local-server-with-bots.sh b/local-server-with-bots.sh index 5b89fcd..28d2e5f 100755 --- a/local-server-with-bots.sh +++ b/local-server-with-bots.sh @@ -1,22 +1,25 @@ echo 'Launching server...' ./server "My private server" 5 1 private col &>/dev/null & sleep 1 -echo 'Launching bot(0)...' +echo 'Launching anticip(0)...' ./bot_anticip localhost 3600 0 &>/dev/null & sleep 1 -echo 'Launching bot(5)...' +echo 'Launching anticip(5)...' ./bot_anticip localhost 3600 5 &>/dev/null & sleep 1 -echo 'Launching bot(10)...' +echo 'Launching anticip(10)...' ./bot_anticip localhost 3600 10 &>/dev/null & sleep 1 -echo 'Launching bot(15)...' -./bot_anticip localhost 3600 15 &>/dev/null & +echo 'Launching checkpoint(0)...' +./bot_checkpoint localhost 3600 0 &>/dev/null & sleep 1 -echo 'Launching bot(20)...' -./bot_anticip localhost 3600 20 &>/dev/null & +echo 'Launching checkpoint(5)...' +./bot_checkpoint localhost 3600 5 &>/dev/null & sleep 1 -echo A local server has been launched with 5 bots. +echo 'Launching checkpoint(10)...' +./bot_checkpoint localhost 3600 10 &>/dev/null & +sleep 1 +echo A local server has been launched with 6 bots. echo You can now join it with zeRace in the network menu. echo When you have finished, you can terminate the server. echo \ No newline at end of file diff --git a/network.h b/network.h index 93ed5a9..ce9a7d2 100644 --- a/network.h +++ b/network.h @@ -4,4 +4,4 @@ #define MAX_LAG 500 #define MAX_CLIENTS 32 #define PORT "3600" -#define VERSION "0.6" +#define VERSION "0.7" diff --git a/server.c b/server.c index a2ccbcd..6c410cc 100644 --- a/server.c +++ b/server.c @@ -128,7 +128,7 @@ int main(int argc,char *argv[]) if (argc!=6) { fprintf(stderr, - "usage: %s 'server_name' nb_laps network_speed (public|private) (col|nocol)\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" diff --git a/tracks/formula.png b/tracks/formula.png index 0fcc252..f4ae991 100644 Binary files a/tracks/formula.png and b/tracks/formula.png differ diff --git a/tracks/list.txt b/tracks/list.txt index 8b8f813..0aaeb33 100644 --- a/tracks/list.txt +++ b/tracks/list.txt @@ -15,8 +15,8 @@ Royale 435 215 180 -996 -inz +995 +Royale icy Same as "First", but in winter ! @@ -25,8 +25,8 @@ Royale 435 215 180 -1130 -Julien +1132 +Royale hairpins Hairpins @@ -35,8 +35,8 @@ ICFP Programming Contest 505 665 0 -2239 -Julien +3029 +inz simple Simple @@ -45,8 +45,8 @@ ICFP Programming Contest 585 565 0 -1548 -ukero +1720 +inz loop Loop @@ -55,8 +55,8 @@ Royale 678 686 0 -1363 -Julien +1535 +Royale bio Bio @@ -65,7 +65,7 @@ Jujucece 930 500 270 -1310 +1126 Royale city @@ -75,8 +75,8 @@ Jujucece 106 358 90 -595 -anonymous +899 +Royale desert Desert @@ -85,8 +85,8 @@ Jujucece 680 487 80 -1888 -anonymous +1538 +Royale http HTTP @@ -95,8 +95,8 @@ Jujucece 520 70 180 -941 -anonymous +1418 +Royale kart Kart @@ -105,7 +105,7 @@ Jujucece 370 725 0 -2025 +1888 Royale wave @@ -115,8 +115,8 @@ Jujucece 630 380 180 -1860 -anonymous +1839 +Royale formula Formula @@ -125,5 +125,5 @@ Ju 350 330 220 -790 -FRD +1269 +inz diff --git a/zeRace.c b/zeRace.c index b371de4..9277dd3 100644 --- a/zeRace.c +++ b/zeRace.c @@ -1,5 +1,5 @@ /* - * zeRace 0.6, a funny retro racing game + * zeRace 0.7, a funny retro racing game * http://royale.zerezo.com/zerace/ * * Copyright (C) 2004 Antoine Jacquet @@ -69,7 +69,8 @@ struct _config int color; SDLKey boss; int bynight; -} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6,SDLK_b,0}; + int internet; +} config = {"anonymous","",0,0,1,SDLK_UP,SDLK_DOWN,SDLK_LEFT,SDLK_RIGHT,6,SDLK_b,0,1}; /* full script for a lap */ struct _record @@ -142,6 +143,8 @@ void zeRace_check_version() char response[1024],*tmp,*version; int len,result; + if (!config.internet) return; + printf("checking version... "); fflush(stdout); @@ -198,6 +201,8 @@ void zeRace_update_tracks() int len,result; FILE *fic; + if (!config.internet) return; + printf("checking version and updating tracks... "); fflush(stdout); @@ -249,6 +254,8 @@ void zeRace_download_file(char *file) FILE *fic; struct stat buf; + if (!config.internet) return; + if (stat(file,&buf)<0) { printf("downloading file \"%s\" : ",file); @@ -440,6 +447,8 @@ void zeRace_send_time(struct _record *record) char *msg9="&bkeys="; int len,result; + if (!config.internet) return; + /* if the best time is small enought to save all keys, send it */ if (record->time>=MAXRECORDKEYS) return; @@ -1295,6 +1304,8 @@ void zeRace_internet() int active=0; #define INTERNET_OPTIONS 11 + if (!config.internet) return; + printf("dowloading list of servers... "); fflush(stdout); @@ -1398,7 +1409,7 @@ void zeRace_config() { SDL_Event event; int active=0; - #define CONFIG_OPTIONS 13 + #define CONFIG_OPTIONS 14 void update() { @@ -1432,6 +1443,8 @@ void zeRace_config() print(screen,40+10*strlen("Boss key : "),HEIGHT/(CONFIG_OPTIONS+4)*13,config.boss?SDL_GetKeyName(config.boss):""); 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)*15,"Internet : "); + print(screen,40+10*strlen("Internet : "),HEIGHT/(CONFIG_OPTIONS+4)*15,config.internet?"Yes":"No"); print(screen,40,HEIGHT/(CONFIG_OPTIONS+4)*(CONFIG_OPTIONS+2),"Back to main menu"); SDL_Flip(screen); } @@ -1486,7 +1499,8 @@ void zeRace_config() break; case 10: config.boss=0; update(); config.boss=read_key(); break; case 11: config.bynight=!config.bynight; break; - case 12: + case 12: config.internet=!config.internet; break; + case 13: return; } update();