/***************************************************************************
file : nfsperf.cpp
created : Tue Aug 5 23:20:23 CEST 2003
copyright : (C) 2003 by Eric Espié
email : eric.espie@torcs.org
version : $Id: mainnfsperf.cpp,v 1.2 2005/02/01 15:08:12 berniw Exp $
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/** @file
@author Eric Espie
@version $Id: mainnfsperf.cpp,v 1.2 2005/02/01 15:08:12 berniw Exp $
*/
#ifdef WIN32
#include
#include
#endif
#include
#include
#ifndef WIN32
#include
#endif
#include
char *catfile = NULL;
char *infile = "carp.txt";
char *outfile = "carp.xml";
char *gears[] = {"r", "n", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
void usage(void)
{
fprintf(stderr, "Car Specifications Converter $Revision: 1.2 $ \n");
fprintf(stderr, "Usage: nfsperf [-c category.xml] [-i ] [-o output carp.xml]\n");
fprintf(stderr, " -c category.xml : car category description\n");
fprintf(stderr, " -i input carp.txt : input NFS carp.txt\n");
fprintf(stderr, " -o output carp.xml : converted parameters\n");
}
void init_args(int argc, char **argv)
{
#ifdef WIN32
int i;
#else
int c;
#endif
#ifndef WIN32
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"help", 0, 0, 0},
{"version", 1, 0, 0}
};
c = getopt_long(argc, argv, "c:i:o:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
switch (option_index) {
case 0:
usage();
exit(0);
break;
case 1:
printf("Car Specifications Converter $Revision: 1.2 $ \n");
exit(0);
break;
default:
usage();
exit(1);
}
break;
case 'h':
usage();
exit(0);
break;
case 'c':
catfile = strdup(optarg);
break;
case 'i':
infile = strdup(optarg);
break;
case 'o':
outfile = strdup(optarg);
break;
default:
usage();
exit(1);
break;
}
}
#else
i = 1;
while (i < argc) {
if (strncmp(argv[i], "-h", 2) == 0) {
usage();
exit(0);
}
if (strncmp(argv[i], "-v", 2) == 0) {
printf("Car Specifications Converter $Revision: 1.2 $ \n");
exit(0);
}
if (strncmp(argv[i], "-c", 2) == 0) {
if (i + 1 < argc) {
catfile = strdup(argv[++i]);
} else {
usage();
exit(0);
}
} else if (strncmp(argv[i], "-i", 2) == 0) {
if (i + 1 < argc) {
infile = strdup(argv[++i]);
} else {
usage();
exit(0);
}
} else if (strncmp(argv[i], "-o", 2) == 0) {
if (i + 1 < argc) {
outfile = strdup(argv[++i]);
} else {
usage();
exit(0);
}
} else {
usage();
exit(0);
}
i++;
}
#endif
}
int main (int argc, char **argv)
{
FILE *fin;
void *param;
char buf[1024];
char path[1024];
char *s;
char *end;
int i;
int idx;
int vald;
tdble valf;
init_args (argc, argv);
fin = fopen (infile, "rb");
if (!fin) {
perror (infile);
exit (1);
}
if (catfile) {
param = GfParmReadFile (catfile, GFPARM_RMODE_STD);
} else {
param = GfParmReadFile (outfile, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
GfParmClean(param);
}
/* Main parser */
while (fgets (buf, sizeof (buf), fin)) {
s = strrchr (buf, '(');
if (!s) {
printf ("Syntax error: \"%s\"\n", buf);
exit (1);
}
idx = strtol (s + 1, NULL, 0);
switch (idx) {
case 2: /* mass [kg] */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
GfParmSetNum (param, "Car", "mass", "kg", valf);
break;
case 4: /* gear shift delay (ticks) */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%d", &vald);
valf = 0.025f * (tdble)vald;
GfParmSetNum (param, "Gearbox", "shift time", "s", valf);
break;
case 8: /* gear ratios (size 8) */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
s = buf;
i = 0;
while (s) {
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%f", &valf);
if (i == 0) {
valf = -valf;
} else if (i == 1) {
i++;
s = end;
continue;
}
sprintf (path, "Gearbox/gears/%s", gears [i++]);
GfParmSetNum (param, path, "ratio", NULL, valf);
s = end;
}
break;
case 9: /* gear efficiency (size 8) */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
s = buf;
i = 0;
while (s) {
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%f", &valf);
sprintf (path, "Gearbox/gears/%s", gears [i++]);
GfParmSetNum (param, path, "efficiency", NULL, valf);
s = end;
}
break;
case 10: /* torque curve (size 21) in 500 rpm increments */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
s = buf;
i = 0;
while (s) {
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%f", &valf);
sprintf (path, "Engine/data points/%d", i + 1);
GfParmSetNum (param, path, "rpm", "rpm", 500.0f * i);
GfParmSetNum (param, path, "Tq", "N.m", valf);
s = end;
i++;
}
break;
case 11: /* final gear */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
GfParmSetNum (param, "Rear Differential", "ratio", NULL, valf);
break;
case 12: /* engine minimum rpm */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%d", &vald);
valf = (tdble)vald;
GfParmSetNum (param, "Engine", "tickover", "rpm", valf);
break;
case 13: /* engine redline in rpm */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%d", &vald);
valf = (tdble)vald;
GfParmSetNum (param, "Engine", "revs limiter", "rpm", valf);
GfParmSetNum (param, "Engine", "revs maxi", "rpm", valf + 1000.0f);
break;
case 16: /* front drive ratio */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
if (valf != 0) {
if (valf == 1.0) {
GfParmSetStr (param, "Drivetrain", "type", "FWD");
GfParmSetStr (param, "Rear Differential", "type", "NONE");
GfParmSetStr (param, "Front Differential", "type", "FREE");
GfParmSetNum (param, "Front Differential", "ratio", NULL, valf);
} else {
GfParmSetStr (param, "Drivetrain", "type", "4WD");
GfParmSetStr (param, "Front Differential", "type", "FREE");
GfParmSetStr (param, "Central Differential", "type", "VISCOUS COUPLER");
GfParmSetNum (param, "Central Differential", "min torque bias", NULL, MAX (valf - 1.0f, 0.1f));
GfParmSetNum (param, "Central Differential", "max torque bias", NULL, MIN (valf + 1.0f, 0.9f));
valf = GfParmGetNum (param, "Rear Differential", "ratio", NULL, 3.5);
GfParmSetNum (param, "Central Differential", "ratio", NULL, valf);
GfParmSetNum (param, "Rear Differential", "ratio", NULL, 1.0);
GfParmSetNum (param, "Front Differential", "ratio", NULL, 1.0);
}
}
break;
case 19: /* front bias brake ratio */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
GfParmSetNum (param, "Brake System", "front-rear brake repartition", NULL, valf);
break;
case 25: /* front grip bias */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
GfParmSetNum (param, "Front Right Wheel", "mu", NULL, valf * 3.0f);
GfParmSetNum (param, "Front Left Wheel", "mu", NULL, valf * 3.0f);
GfParmSetNum (param, "Rear Right Wheel", "mu", NULL, (1.0f - valf) * 3.0f);
GfParmSetNum (param, "Rear Left Wheel", "mu", NULL, (1.0f - valf) * 3.0f);
break;
case 31: /* aerodynamic downforce multiplier */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
sscanf (buf, "%f", &valf);
GfParmSetNum (param, "Aerodynamics", "front Clift", NULL, valf * 120.0f);
GfParmSetNum (param, "Aerodynamics", "rear Clift", NULL, valf * 100.0f);
break;
case 35: /* tire specs front */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
s = buf;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Front Right Wheel", "tire width", "mm", (tdble)vald);
GfParmSetNum (param, "Front Left Wheel", "tire width", "mm", (tdble)vald);
s = end;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Front Right Wheel", "tire height-width ratio", "%", (tdble)vald);
GfParmSetNum (param, "Front Left Wheel", "tire height-width ratio", "%", (tdble)vald);
s = end;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Front Right Wheel", "rim diameter", "in", (tdble)vald);
GfParmSetNum (param, "Front Left Wheel", "rim diameter", "in", (tdble)vald);
s = end;
break;
case 36: /* tire specs rear */
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
s = buf;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Rear Right Wheel", "tire width", "mm", (tdble)vald);
GfParmSetNum (param, "Rear Left Wheel", "tire width", "mm", (tdble)vald);
s = end;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Rear Right Wheel", "tire height-width ratio", "%", (tdble)vald);
GfParmSetNum (param, "Rear Left Wheel", "tire height-width ratio", "%", (tdble)vald);
s = end;
end = strchr (s, ',');
if (end) {
*end = 0;
end++;
}
sscanf (s, "%d", &vald);
GfParmSetNum (param, "Rear Right Wheel", "rim diameter", "in", (tdble)vald);
GfParmSetNum (param, "Rear Left Wheel", "rim diameter", "in", (tdble)vald);
s = end;
break;
default:
if (!fgets (buf, sizeof (buf), fin)) {
exit (1);
}
break;
}
}
GfParmWriteFile (outfile, param, "car");
return 0;
}