1 /***************************************************************************
2
3 file : racegl.cpp
4 created : Sat Nov 16 18:22:00 CET 2002
5 copyright : (C) 2002-2013 by Eric Espie, Bernhard Wymann
6 email : eric.espie@torcs.org
7 version : $Id: racegl.cpp,v 1.7.2.4 2013/09/01 10:24:23 berniw Exp $
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 /** @file
21
22 @author <a href=mailto:eric.espie@torcs.org>Eric Espie</a>
23 @version $Id: racegl.cpp,v 1.7.2.4 2013/09/01 10:24:23 berniw Exp $
24 */
25 #include <stdlib.h>
26 #include <stdio.h>
27
28 #include <tgfclient.h>
29 #include <raceman.h>
30 #include <robot.h>
31
32 #include "racemain.h"
33 #include "raceinit.h"
34 #include "racestate.h"
35 #include "raceengine.h"
36
37 #include "racegl.h"
38
39 static void *reScreenHandle = 0;
40 static void *reHookHandle = 0;
41 static int rePauseId;
42 static int reMsgId;
43 static int reBigMsgId;
44
45 static float bgcolor[4] = {0.0, 0.0, 0.0, 0.0};
46 static float white[4] = {1.0, 1.0, 1.0, 1.0};
47 static float red[4] = {1.0, 0.0, 0.0, 1.0};
48
49 static void
reDisplay(void)50 reDisplay(void)
51 {
52 ReStateManage();
53 }
54
55 static void
reScreenActivate(void *)56 reScreenActivate(void * /* dummy */)
57 {
58 glutDisplayFunc(reDisplay);
59
60 if ((ReInfo->s->_raceState & RM_RACE_PAUSED) == 0) {
61 ReStart(); /* resynchro */
62 }
63 glutPostRedisplay();
64 }
65
66 static void
ReBoardInfo(void *)67 ReBoardInfo(void * /* vboard */)
68 {
69 if (ReInfo->s->_raceState & RM_RACE_PAUSED) {
70 ReInfo->s->_raceState &= ~RM_RACE_PAUSED;
71 ReStart();
72 GfuiVisibilitySet(reScreenHandle, rePauseId, 0);
73 } else {
74 ReInfo->s->_raceState |= RM_RACE_PAUSED;
75 ReStop();
76 GfuiVisibilitySet(reScreenHandle, rePauseId, 1);
77 }
78 }
79
80 static void
reSkipPreStart(void *)81 reSkipPreStart(void * /* dummy */)
82 {
83 if (ReInfo->s->currentTime < -1.0) {
84 ReInfo->s->currentTime = -1.0;
85 ReInfo->_reLastTime = -1.0;
86 }
87 }
88
89 static void
reMovieCapture(void *)90 reMovieCapture(void * /* dummy */)
91 {
92 tRmMovieCapture *capture = &(ReInfo->movieCapture);
93
94 if (!capture->enabled || (ReInfo->_displayMode == RM_DISP_MODE_NONE)) {
95 GfOut("Video Capture Mode Not Enabled\n");
96 return;
97 }
98
99 capture->state = 1 - capture->state;
100 if (capture->state) {
101 GfOut("Video Capture Mode On\n");
102 capture->currentFrame = 0;
103 capture->currentCapture++;
104 capture->lastFrame = GfTimeClock() - capture->deltaFrame;
105 ReInfo->_displayMode = RM_DISP_MODE_CAPTURE;
106 } else {
107 GfOut("Video Capture Mode Off\n");
108 ReInfo->_displayMode = RM_DISP_MODE_NORMAL;
109 ReStart();
110 }
111
112 }
113
114
115
116 static void
reAddKeys(void)117 reAddKeys(void)
118 {
119 GfuiAddSKey(reScreenHandle, GLUT_KEY_F1, "Help", reScreenHandle, GfuiHelpScreen, NULL);
120 GfuiAddSKey(reScreenHandle, GLUT_KEY_F12, "Screen Shot", NULL, GfuiScreenShot, NULL);
121
122
123 GfuiAddKey(reScreenHandle, '-', "Slow Time", (void*)0, ReTimeMod, NULL);
124 GfuiAddKey(reScreenHandle, '+', "Accelerate Time", (void*)1, ReTimeMod, NULL);
125 GfuiAddKey(reScreenHandle, '.', "Real Time", (void*)2, ReTimeMod, NULL);
126 GfuiAddKey(reScreenHandle, 'p', "Pause Race", (void*)0, ReBoardInfo, NULL);
127 GfuiAddKey(reScreenHandle, 27, "Stop Current Race", (void*)RE_STATE_RACE_STOP, ReStateApply, NULL);
128 /* GfuiAddKey(reScreenHandle, 'q', "Exit of TORCS", (void*)RE_STATE_EXIT, ReStateApply, NULL); */
129 GfuiAddKey(reScreenHandle, ' ', "Skip Pre Start", (void*)0, reSkipPreStart, NULL);
130 #ifdef DEBUG
131 //GfuiAddKey(reScreenHandle, '0', "One step simulation", (void*)1, reOneStep, NULL);
132 #endif
133 GfuiAddKey(reScreenHandle, 'c', "Movie Capture", (void*)0, reMovieCapture, NULL);
134
135 }
136
137
138 void
ReSetRaceMsg(const char * msg)139 ReSetRaceMsg(const char *msg)
140 {
141 static char *curMsg = 0;
142
143 if (curMsg) free(curMsg);
144
145 if (msg) {
146 curMsg = strdup(msg);
147 GfuiLabelSetText(reScreenHandle, reMsgId, curMsg);
148 } else {
149 curMsg = 0;
150 GfuiLabelSetText(reScreenHandle, reMsgId, "");
151 }
152 }
153
154 void
ReSetRaceBigMsg(const char * msg)155 ReSetRaceBigMsg(const char *msg)
156 {
157 static char *curMsg = 0;
158
159 if (curMsg) free(curMsg);
160
161 if (msg) {
162 curMsg = strdup(msg);
163 GfuiLabelSetText(reScreenHandle, reBigMsgId, curMsg);
164 } else {
165 curMsg = 0;
166 GfuiLabelSetText(reScreenHandle, reBigMsgId, "");
167 }
168 }
169
170 void *
ReScreenInit(void)171 ReScreenInit(void)
172 {
173
174 ReScreenShutdown();
175
176 reScreenHandle = GfuiScreenCreateEx(bgcolor, 0, reScreenActivate, 0, 0, 0);
177
178 reAddKeys();
179
180 reMsgId = GfuiLabelCreateEx(reScreenHandle,
181 "",
182 red,
183 GFUI_FONT_LARGE_C,
184 320,
185 400,
186 GFUI_ALIGN_HC_VB,
187 42);
188
189 rePauseId = GfuiLabelCreateEx(reScreenHandle,
190 "P A U S E",
191 red,
192 GFUI_FONT_BIG_C,
193 320,
194 420,
195 GFUI_ALIGN_HC_VB,
196 0);
197
198 reBigMsgId = GfuiLabelCreateEx(reScreenHandle,
199 "",
200 red,
201 GFUI_FONT_BIG_C,
202 320,
203 360,
204 GFUI_ALIGN_HC_VB,
205 32);
206
207 GfuiVisibilitySet(reScreenHandle, rePauseId, 0);
208
209 return reScreenHandle;
210 }
211
212
213 void
ReScreenShutdown(void)214 ReScreenShutdown(void)
215 {
216 if (reScreenHandle) {
217 GfuiScreenRelease(reScreenHandle);
218 reScreenHandle = 0;
219 }
220 }
221
222
223 static void
reHookActivate(void *)224 reHookActivate(void * /* dummy */)
225 {
226 ReStateManage();
227 }
228
229 void *
ReHookInit(void)230 ReHookInit(void)
231 {
232 if (reHookHandle) {
233 return reHookHandle;
234 }
235
236 reHookHandle = GfuiHookCreate(0, reHookActivate);
237
238 return reHookHandle;
239 }
240
241
242 void
ReHookShutdown(void)243 ReHookShutdown(void)
244 {
245 if (reHookHandle) {
246 GfuiHookRelease(reHookHandle);
247 reHookHandle = 0;
248 }
249 }
250
251 /**************************************************************************/
252
253 /*
254 * Result only screen
255 */
256 #define LINES 21
257
258 static float *reColor[] = {white, red};
259
260 static void *reResScreenHdle = 0;
261 static int reResTitleId;
262 static int reResMsgId[LINES];
263 static int reResMsgClr[LINES];
264 static char *reResMsg[LINES];
265 static int reCurLine;
266
267 static void
reAddResKeys(void)268 reAddResKeys(void)
269 {
270 GfuiAddSKey(reResScreenHdle, GLUT_KEY_F1, "Help", reScreenHandle, GfuiHelpScreen, NULL);
271 GfuiAddSKey(reResScreenHdle, GLUT_KEY_F12, "Screen Shot", NULL, GfuiScreenShot, NULL);
272
273 GfuiAddKey(reResScreenHdle, 27, "Stop Current Race", (void*)RE_STATE_RACE_STOP, ReStateApply, NULL);
274 /* GfuiAddKey(reResScreenHdle, 'q', "Exit of TORCS", (void*)RE_STATE_EXIT, ReStateApply, NULL); */
275 }
276
277 static void
reResScreenActivate(void *)278 reResScreenActivate(void * /* dummy */)
279 {
280 glutDisplayFunc(reDisplay);
281 GfuiDisplay();
282 glutPostRedisplay();
283 }
284
285
286 static void
reContDisplay(void)287 reContDisplay(void)
288 {
289 GfuiDisplay();
290 glutPostRedisplay();
291 }
292
293
294 static void
reResCont(void *)295 reResCont(void * /* dummy */)
296 {
297 ReStateManage();
298 }
299
300 static void
reResScreenShutdown(void *)301 reResScreenShutdown(void * /* dummy */)
302 {
303 int i;
304
305 for (i = 1; i < LINES; i++) {
306 FREEZ(reResMsg[i]);
307 }
308 }
309
310 void *
ReResScreenInit(void)311 ReResScreenInit(void)
312 {
313 int i;
314 int y, dy;
315 static const char *title[3] = {"Practice", "Qualifications", "Race"};
316
317 if (reResScreenHdle) {
318 GfuiScreenRelease(reResScreenHdle);
319 }
320
321 reResScreenHdle = GfuiScreenCreateEx(bgcolor, 0, reResScreenActivate, 0, reResScreenShutdown, 0);
322
323 GfuiTitleCreate(reResScreenHdle, title[ReInfo->s->_raceType], strlen(title[ReInfo->s->_raceType]));
324
325 const char* img = GfParmGetStr(ReInfo->params, RM_SECT_HEADER, RM_ATTR_RUNIMG, 0);
326 if (img) {
327 GfuiScreenAddBgImg(reResScreenHdle, img);
328 }
329
330 reAddResKeys();
331
332 reResTitleId = GfuiLabelCreateEx(reResScreenHdle,
333 "",
334 red,
335 GFUI_FONT_LARGE_C,
336 320, 420,
337 GFUI_ALIGN_HC_VB, 50);
338
339 y = 400;
340 dy = 378 / LINES;
341 for (i = 0; i < LINES; i++) {
342 FREEZ(reResMsg[i]);
343 reResMsgClr[i] = 0;
344 reResMsgId[i] = GfuiLabelCreateEx(reResScreenHdle,
345 "",
346 white,
347 GFUI_FONT_MEDIUM_C,
348 20, y,
349 GFUI_ALIGN_HL_VB, 120);
350 y -= dy;
351 }
352
353 reCurLine = 0;
354 return reResScreenHdle;
355 }
356
357 void
ReResScreenSetTitle(char * title)358 ReResScreenSetTitle(char *title)
359 {
360 if (reResScreenHdle) {
361 GfuiLabelSetText(reResScreenHdle, reResTitleId, title);
362 }
363 }
364
365 void
ReResScreenAddText(char * text)366 ReResScreenAddText(char *text)
367 {
368 int i;
369
370 if (reCurLine == LINES) {
371 free(reResMsg[0]);
372 for (i = 1; i < LINES; i++) {
373 reResMsg[i - 1] = reResMsg[i];
374 GfuiLabelSetText(reResScreenHdle, reResMsgId[i - 1], reResMsg[i]);
375 }
376 reCurLine--;
377 }
378 reResMsg[reCurLine] = strdup(text);
379 GfuiLabelSetText(reResScreenHdle, reResMsgId[reCurLine], reResMsg[reCurLine]);
380 reCurLine++;
381 }
382
383 void
ReResScreenSetText(const char * text,int line,int clr)384 ReResScreenSetText(const char *text, int line, int clr)
385 {
386 if (line < LINES) {
387 FREEZ(reResMsg[line]);
388 reResMsg[line] = strdup(text);
389 if ((clr >= 0) && (clr < 2)) {
390 reResMsgClr[line] = clr;
391 } else {
392 reResMsgClr[line] = 0;
393 }
394 GfuiLabelSetText(reResScreenHdle, reResMsgId[line], reResMsg[line]);
395 GfuiLabelSetColor(reResScreenHdle, reResMsgId[line], reColor[reResMsgClr[line]]);
396 }
397 }
398
399 int
ReResGetLines(void)400 ReResGetLines(void)
401 {
402 return LINES;
403 }
404
405 void
ReResEraseScreen(void)406 ReResEraseScreen(void)
407 {
408 int i;
409
410 for (i = 0; i < LINES; i++) {
411 ReResScreenSetText("", i, 0);
412 }
413 }
414
415
416 void
ReResScreenRemoveText(int line)417 ReResScreenRemoveText(int line)
418 {
419 if (line < LINES) {
420 FREEZ(reResMsg[line]);
421 GfuiLabelSetText(reResScreenHdle, reResMsgId[line], "");
422 }
423 }
424
425 void
ReResShowCont(void)426 ReResShowCont(void)
427 {
428
429 GfuiButtonCreate(reResScreenHdle,
430 "Continue",
431 GFUI_FONT_LARGE_C,
432 320, 15, GFUI_BTNSZ,
433 GFUI_ALIGN_HC_VB,
434 0, 0, reResCont,
435 NULL, (tfuiCallback)NULL,
436 (tfuiCallback)NULL);
437 GfuiAddKey(reResScreenHdle, 13, "Continue", 0, reResCont, NULL);
438 GfuiAddKey(reResScreenHdle, 27, "Continue", 0, reResCont, NULL);
439
440 glutDisplayFunc(reContDisplay);
441 glutPostRedisplay();
442 }
443
444