TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 file : main.cpp
4 created : Sat Sep 2 10:40:47 CEST 2000
5 copyright : (C) 2000-2014 by Patrice & Eric Espie, Bernhard Wymann
6 email : torcs@free.fr
7 version : $Id$
8
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#ifdef WIN32
21#include <windows.h>
22#include <stdlib.h>
23#include <shlobj.h>
24#endif
25#include <GL/glut.h>
26#include <tgfclient.h>
27#include <client.h>
28#include <portability.h>
29#include <raceinit.h>
30
31#include "windowsspec.h"
32
33
34// replace '\' with '/'
35static void convertDelimiter(char* buf, const int bufsize)
36{
37 int i;
38 for (i = 0; i < bufsize && buf[i] != '\0'; i++) {
39 if (buf[i] == '\\') {
40 buf[i] = '/';
41 }
42 }
43}
44
45
46static void copyFileIfNotExists(const char* filepath)
47{
48 static const int BUFSIZE = 1024;
49 char target[BUFSIZE];
50 snprintf(target, BUFSIZE, "%s%s", GetLocalDir(), filepath);
51 target[BUFSIZE-1] = '\0';
52
53 DWORD attr = GetFileAttributes(target);
54 DWORD error = GetLastError();
55 if (
56 attr == INVALID_FILE_ATTRIBUTES &&
57 (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND)
58 ) {
59 if (GfCreateDirForFile(target) == GF_DIR_CREATED) {
60 char source[BUFSIZE];
61 snprintf(source, BUFSIZE, "%s%s", GetDataDir(), filepath);
62 source[BUFSIZE-1] = '\0';
63 if (SUCCEEDED(CopyFile(source, target, TRUE))) {
64 GfOut("Copy success: %s\n", target);
65 } else {
66 GfError("Copy failed: %s\n", target);
67 }
68 } else {
69 GfError("Target directory creation failed: %s\n", target);
70 }
71 }
72}
73
74
75// Check/prepare expected files in LocalDir
76static void prepareLocalDir()
77{
78 const char* file[] = {
79 "drivers/human/car.xml",
80 "drivers/human/human.xml",
81 "drivers/human/preferences.xml",
82 "config/graph.xml",
83 "config/raceengine.xml",
84 "config/screen.xml",
85 "config/sound.xml",
86 "config/style.xsl"
87 };
88
89 int i;
90 for (i = 0; i < sizeof(file)/sizeof(file[0]); i++) {
91 copyFileIfNotExists(file[i]);
92 }
93
94 // Copy race manager configurations
95 static const int BUFSIZE = 1024;
96 char path[BUFSIZE];
97
98 const char* racemanpath = "config/raceman";
99 tFList *racemanList = GfDirGetListFiltered(racemanpath, "xml");
100 tFList* racemanCur = racemanList;
101
102 if (racemanList) {
103 do {
104 snprintf(path, BUFSIZE, "%s/%s", racemanpath, racemanCur->name);
105 path[BUFSIZE-1] = '\0';
107 racemanCur = racemanCur->next;
108 } while (racemanCur != racemanList);
109 }
110
111 GfDirFreeList(racemanList, NULL, true, true);
112}
113
114
115// Try to set the users local application data directory
116static void setUserLocalDir(char* buf, const int bufsize)
117{
118 TCHAR szLocalAppDataPath[MAX_PATH];
119 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szLocalAppDataPath))) {
120 convertDelimiter(szLocalAppDataPath, MAX_PATH);
121 snprintf(buf, bufsize, "%s/torcs/", szLocalAppDataPath);
122 if (GfCreateDir(buf) == GF_DIR_CREATED) {
123 SetLocalDir(buf);
125 }
126 }
127}
128
129
130static void init_args(int argc, char **argv, const char** raceconfig)
131{
132 int i = 1;
133
134 while (i < argc) {
135 if ((strncmp(argv[i], "-s", 2) == 0) || (strncmp(argv[i], "/s", 2) == 0)) {
136 i++;
138 } else if ((strncmp(argv[i], "-r", 2) == 0) || (strncmp(argv[i], "/r", 2) == 0)) {
139 i++;
140 *raceconfig = "";
141 if (i < argc) {
142 convertDelimiter(argv[i], strlen(argv[i]));
143 *raceconfig = argv[i];
144 i++;
145 }
146
147 if ((strlen(*raceconfig) == 0) || (strstr(*raceconfig, ".xml") == 0)) {
148 printf("Please specify a race configuration xml when using -r\n");
149 exit(1);
150 }
151 } else {
152 i++; // Ignore unknown arguments
153 }
154 }
155
156 static const int BUFSIZE = 1024;
157 char buf[BUFSIZE];
158 strncpy(buf, argv[0], BUFSIZE);
159 buf[BUFSIZE-1] = '\0'; // Guarantee zero termination for next operation.
160 char *end = strrchr(buf, '\\');
161
162 // Did we find the last '\' and do we get a complete path?
163 if (end != NULL && buf[1] == ':') {
164 end++;
165 *(end) = '\0';
166 convertDelimiter(buf, BUFSIZE);
167
168 // Set fallback for local directory
169 SetLocalDir(buf);
170 // Set library and data directory
171 SetDataDir(buf);
172 SetLibDir("");
173 setUserLocalDir(buf, BUFSIZE);
174 } else {
175 if (_fullpath(buf, argv[0], BUFSIZE) != NULL &&
176 (strcmp(argv[0], "wtorcs") == 0 ||
177 strcmp(argv[0], "wtorcs.exe") == 0)
178 )
179 {
180 end = strrchr(buf, '\\');
181 end++;
182 *(end) = '\0';
183 convertDelimiter(buf, BUFSIZE);
184
185 // Set fallback for local directory
186 SetLocalDir(buf);
187 // Set library and data directory
188 SetDataDir(buf);
189 SetLibDir("");
190 setUserLocalDir(buf, BUFSIZE);
191 } else {
192 printf("Run wtorcs.exe either from the GUI or from the directory which contains wtorcs.exe\n");
193 exit(1);
194 }
195 }
196}
197
198/*
199 * Function
200 * main
201 *
202 * Description
203 * Win32 entry point of TORCS
204 *
205 * Parameters
206 *
207 *
208 * Return
209 *
210 *
211 * Remarks
212 *
213 */
214int
215main(int argc, char *argv[])
216{
217 const char* raceconfig = "";
218
219 WindowsSpecInit(); /* init specific windows functions */
220 init_args(argc, argv, &raceconfig);
221
222 if (strlen(raceconfig) == 0) {
223 GfScrInit(argc, argv); /* init screen */
224 TorcsEntry(); /* launch TORCS */
225 glutMainLoop(); /* event loop of glut */
226 } else {
227 // Run race from console, no Window, no OpenGL/OpenAL etc.
228 // Thought for blind scripted AI training
229 ReRunRaceOnConsole(raceconfig);
230 }
231
232 return 0; /* just for the compiler, never reached */
233}
234
void TorcsEntry(void)
Definition entry.cpp:46
tFList * GfDirGetListFiltered(const char *dir, const char *suffix)
Get the list of files with matching suffix of a given directory.
Definition directory.cpp:59
void GfDirFreeList(tFList *list, tfDirfreeUserData freeUserData, bool freename, bool freedispname)
Free a directory list.
Definition directory.cpp:75
int main(int argc, char *argv[])
Definition main.cpp:124
static void init_args(int argc, char **argv, const char **raceconfig)
Definition main.cpp:33
void ReRunRaceOnConsole(const char *raceconfig)
Definition raceinit.cpp:156
void GfScrInit(int argc, char *argv[])
Definition screen.cpp:284
struct FList * next
Next entry.
Definition tgf.h:230
char * name
File name.
Definition tgf.h:232
void SetDataDir(char *buf)
Definition tgf.cpp:262
void SetSingleTextureMode(void)
Definition tgf.cpp:278
void SetLocalDir(char *buf)
Definition tgf.cpp:236
int GfCreateDir(char *path)
Create directory for given path recursively, so all missing parent directories are created as well.
Definition tgf.cpp:308
char * GetDataDir(void)
Definition tgf.cpp:256
int GfCreateDirForFile(const char *filenameandpath)
Create directory for given file path recursively, so all missing parent directories are created as we...
Definition tgf.cpp:368
char * GetLocalDir(void)
Definition tgf.cpp:230
void SetLibDir(char *buf)
Definition tgf.cpp:249
#define GfOut
Definition tgf.h:372
#define GF_DIR_CREATED
Definition tgf.h:622
struct FList tFList
List of (DLL) files for a Directory.
#define GfError
Definition tgf.h:350
static void convertDelimiter(char *buf, const int bufsize)
Definition main.cpp:35
static void setUserLocalDir(char *buf, const int bufsize)
Definition main.cpp:116
static void copyFileIfNotExists(const char *filepath)
Definition main.cpp:46
static void prepareLocalDir()
Definition main.cpp:76