TORCS  1.3.9
The Open Racing Car Simulator
grutil.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : grutil.cpp
4  created : Wed Nov 1 21:33:22 CET 2000
5  copyright : (C) 2000 by Eric Espie
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 #include <math.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <stdio.h>
24 #include <ctype.h>
25 #ifdef WIN32
26 #include <windows.h>
27 #endif
28 #include <GL/glut.h>
29 #include <plib/ssg.h>
30 
31 #include <tgfclient.h>
32 #include <portability.h>
33 
34 #include "grutil.h"
35 #include "grmultitexstate.h"
36 #include "grscene.h"
37 #include "grtexture.h"
38 
39 float grGammaValue = 1.8;
40 int grMipMap = 0;
41 
42 char *grFilePath; // Multiple path (';' separated) used to search for files.
43 char *grTexturePath = NULL; // Default ssg path.
44 
45 
46 int grGetFilename(const char *filename, char *filepath, char *buf, const int BUFSIZE)
47 {
48  char *c1, *c2;
49  int found = 0;
50  int lg;
51  int flen = strlen(filename);
52 
53  if (filepath) {
54  c1 = filepath;
55  c2 = c1;
56  while ((!found) && (c2 != NULL)) {
57  c2 = strchr(c1, ';');
58  if (c2 == NULL) {
59  snprintf(buf, BUFSIZE, "%s/%s", c1, filename);
60  } else {
61  lg = c2 - c1;
62  if (lg + flen + 2 < BUFSIZE) {
63  strncpy(buf, c1, lg);
64  buf[lg] = '/';
65  strcpy(buf + lg + 1, filename);
66  } else {
67  buf[0] = '\0';
68  }
69  }
70  if (ulFileExists(buf)) {
71  found = 1;
72  }
73  c1 = c2 + 1;
74  }
75  } else {
76  strncpy(buf, filename, BUFSIZE);
77  if (ulFileExists(buf)) {
78  found = 1;
79  }
80  }
81  if (!found) {
82  GfOut("File %s not found\n", filename);
83  GfOut("File Path was %s\n", filepath);
84  return 0;
85  }
86 
87  return 1;
88 }
89 
90 
91 bool grLoadPngTexture (const char *fname, ssgTextureInfo* info)
92 {
93  GLubyte *tex;
94  int w, h;
95  int mipmap = 1;
96 
97  TRACE_GL("Load: grLoadPngTexture start");
98 
99  tex = (GLubyte*)GfImgReadPng(fname, &w, &h, 2.0);
100  if (!tex) {
101  return false;
102  }
103 
104  if (info) {
105  info -> width = w;
106  info -> height = h;
107  info -> depth = 4;
108  info -> alpha = true;
109  }
110 
111  TRACE_GL("Load: grLoadPngTexture stop");
112 
113  // TODO: Check if tex is freed.
114  // Check/fix potential problems related to malloc/delete mixture
115  // (instead of malloc/free or new/delete).
116 
117  mipmap = doMipMap(fname, mipmap);
118 
119  GLubyte* tex2 = new GLubyte[w*h*4];
120  memcpy(tex2, tex, w*h*4);
121  free(tex);
122  tex = tex2;
123 
124  return grMakeMipMaps(tex, w, h, 4, mipmap);
125 }
126 
127 
128 
129 typedef struct stlist
130 {
131  struct stlist *next;
132  struct stlist *prev;
134  char *name;
135 } stlist;
136 
137 
138 static stlist * stateList = NULL;
139 
140 
141 static grManagedState * grGetState(char *img)
142 {
143  stlist *curr;
144 
145  curr = stateList;
146  while (curr != NULL) {
147  if (strcmp(curr->name, img) == 0) {
148  return curr->state;
149  }
150  curr = curr->next;
151  }
152  return NULL;
153 }
154 
155 
156 void grRemoveState(char* img)
157 {
158  stlist *curr;
159 
160  curr = stateList;
161  while (curr != NULL) {
162  if (strcmp(curr->name, img) == 0) {
163  if (curr->prev != 0) {
164  curr->prev->next = curr->next;
165  }
166  if (curr->next != 0) {
167  curr->next->prev = curr->prev;
168  }
169  if (curr == stateList) {
170  stateList = curr->next;
171  }
172 
173  free(curr->name);
174  free(curr);
175  break;
176  }
177  curr = curr->next;
178  }
179 }
180 
181 
182 void grShutdownState(void)
183 {
184  stlist *curr;
185  stlist *next;
186 
187  curr = stateList;
188  while (curr != NULL) {
189  next = curr->next;
190  printf("Still in list : %s\n", curr->name);
191  free(curr->name);
192  free(curr);
193  curr = next;
194  }
195  stateList = NULL;
196 }
197 
198 
199 static void grSetupState(grManagedState *st, char *buf)
200 {
201  st->enable(GL_LIGHTING);
202  st->enable(GL_TEXTURE_2D);
203  st->enable(GL_BLEND);
204  st->setColourMaterial(GL_AMBIENT_AND_DIFFUSE);
205 
206  stlist *curr = (stlist*)calloc(sizeof(stlist), 1);
207  curr->next = stateList;
208  if (stateList != NULL) {
209  stateList->prev = curr;
210  }
211  stateList = curr;
212  curr->state = st;
213  curr->name = strdup(buf);
214 
215  GfOut("Loading %s\n", buf);
216 }
217 
218 
219 ssgState * grSsgLoadTexState(const char *img)
220 {
221  const int BUFSIZE = 1024;
222  char buf[BUFSIZE];
223  const char *s;
224  grManagedState *st;
225 
226  // remove the directory
227  s = strrchr(img, '/');
228  if (s == NULL) {
229  s = img;
230  } else {
231  s++;
232  }
233 
234  if (!grGetFilename(s, grFilePath, buf, BUFSIZE)) {
235  GfOut("grSsgLoadTexState: File %s not found\n", s);
236  return NULL;
237  }
238 
239  st = grGetState(buf);
240  if (st != NULL) {
241  return (ssgState*)st;
242  }
243 
244  st = grStateFactory();
245  grSetupState(st, buf);
246  st->setTexture(buf);
247 
248  return (ssgState*)st;
249 }
250 
251 ssgState * grSsgEnvTexState(const char *img)
252 {
253  const int BUFSIZE = 1024;
254  char buf[BUFSIZE];
255  const char *s;
256  grManagedState *st;
257 
258  // remove the directory
259  s = strrchr(img, '/');
260  if (s == NULL) {
261  s = img;
262  } else {
263  s++;
264  }
265 
266  if (!grGetFilename(s, grFilePath, buf, BUFSIZE)) {
267  GfOut("grSsgLoadTexState: File %s not found\n", s);
268  return NULL;
269  }
270 
271  /*st = grGetState(buf);
272  if (st != NULL) {
273  return (ssgState*)st;
274  }*/
275 
276  st = new grMultiTexState();
277  grSetupState(st, buf);
278  st->setTexture(buf);
279 
280  return (ssgState*)st;
281 }
282 
283 ssgState *
284 grSsgLoadTexStateEx(const char *img, char *filepath, int wrap, int mipmap)
285 {
286  const int BUFSIZE = 1024;
287  char buf[BUFSIZE];
288  const char *s;
289  grManagedState *st;
290 
291  // remove the directory
292  s = strrchr(img, '/');
293  if (s == NULL) {
294  s = img;
295  } else {
296  s++;
297  }
298 
299  if (!grGetFilename(s, filepath, buf, BUFSIZE)) {
300  GfOut("File %s not found\n", s);
301  return NULL;
302  }
303 
304  st = grGetState(buf);
305  if (st != NULL) {
306  return (ssgState*)st;
307  }
308 
309  st = grStateFactory();
310  grSetupState(st, buf);
311  st->setTexture(buf, wrap, wrap, mipmap);
312 
313  return (ssgState*)st;
314 }
315 
316 
317 void grWriteTime(float *color, int font, int x, int y, tdble sec, int sgn)
318 {
319  const int BUFSIZE = 256;
320  char buf[BUFSIZE];
321  const char* sign;
322 
323  if (sec < 0.0) {
324  sec = -sec;
325  sign = "-";
326  } else {
327  if (sgn) {
328  sign = "+";
329  } else {
330  sign = " ";
331  }
332  }
333 
334  int h = (int)(sec / 3600.0);
335  sec -= 3600 * h;
336  int m = (int)(sec / 60.0);
337  sec -= 60 * m;
338  int s = (int)(sec);
339  sec -= s;
340  int c = (int)floor((sec) * 100.0);
341  if (h) {
342  (void)snprintf(buf, BUFSIZE, "%s%2.2d:%2.2d:%2.2d:%2.2d", sign,h,m,s,c);
343  } else if (m) {
344  (void)snprintf(buf, BUFSIZE, " %s%2.2d:%2.2d:%2.2d", sign,m,s,c);
345  } else {
346  (void)snprintf(buf, BUFSIZE, " %s%2.2d:%2.2d", sign,s,c);
347  }
348 
349  GfuiPrintString(buf, color, font, x, y, GFUI_ALIGN_HR_VB);
350 }
351 
352 
353 // TODO: more efficient solution, this one is slow.
354 float grGetHOT(float x, float y)
355 {
356  sgVec3 test_vec;
357  sgMat4 invmat;
358  sgMakeIdentMat4(invmat);
359 
360  invmat[3][0] = -x;
361  invmat[3][1] = -y;
362  invmat[3][2] = 0.0f ;
363 
364  test_vec [0] = 0;
365  test_vec [1] = 0;
366  test_vec [2] = 100000.0f;
367 
368  ssgHit *results;
369  int num_hits = ssgHOT (TheScene, test_vec, invmat, &results);
370  float hot = -1000000.0f;
371 
372  for (int i = 0; i < num_hits; i++) {
373  ssgHit *h = &results[i];
374 
375  float hgt = (h->plane[2] == 0.0 ? 0.0 : - h->plane[3] / h->plane[2]);
376 
377  if (hgt >= hot) {
378  hot = hgt;
379  }
380  }
381 
382  return hot;
383 }
384 
385 
386 
bool grLoadPngTexture(const char *fname, ssgTextureInfo *info)
Definition: grutil.cpp:91
ssgRoot * TheScene
Definition: grscene.cpp:66
static grManagedState * grGetState(char *img)
Definition: grutil.cpp:141
#define TRACE_GL(msg)
Definition: grutil.h:28
ssgState * grSsgEnvTexState(const char *img)
Definition: grutil.cpp:251
char * grFilePath
Definition: grutil.cpp:42
void grRemoveState(char *img)
Definition: grutil.cpp:156
static void grSetupState(grManagedState *st, char *buf)
Definition: grutil.cpp:199
struct stlist stlist
#define GFUI_ALIGN_HR_VB
Definition: tgfclient.h:75
bool doMipMap(const char *tfname, int mipmap)
Definition: grtexture.cpp:29
static stlist * stateList
Definition: grutil.cpp:138
The Gaming Framework API (client part).
char * grTexturePath
Definition: grutil.cpp:43
struct stlist * prev
Definition: grutil.cpp:132
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
unsigned char * GfImgReadPng(const char *filename, int *widthp, int *heightp, float screen_gamma)
Load an image from disk to a buffer in RGBA mode.
Definition: img.cpp:54
grManagedState * grStateFactory(void)
Definition: grtexture.h:73
#define GfOut
Definition: tgf.h:373
struct stlist * next
Definition: grutil.cpp:131
void GfuiPrintString(const char *text, float *fgColor, int font, int x, int y, int align)
Definition: guiobject.cpp:43
float grGetHOT(float x, float y)
Definition: grutil.cpp:354
char * name
Definition: grutil.cpp:134
static Vector y[4]
Definition: Convex.cpp:56
void grShutdownState(void)
Definition: grutil.cpp:182
ssgState * grSsgLoadTexState(const char *img)
Definition: grutil.cpp:219
virtual void setTexture(ssgTexture *tex)
Definition: grtexture.h:55
ssgState * grSsgLoadTexStateEx(const char *img, char *filepath, int wrap, int mipmap)
Definition: grutil.cpp:284
float grGammaValue
Definition: grutil.cpp:39
int grGetFilename(const char *filename, char *filepath, char *buf, const int BUFSIZE)
Definition: grutil.cpp:46
int sgn(Scalar x)
Definition: Basic.h:46
grManagedState * state
Definition: grutil.cpp:133
void grWriteTime(float *color, int font, int x, int y, tdble sec, int sgn)
Definition: grutil.cpp:317
bool grMakeMipMaps(GLubyte *image, int xsize, int ysize, int zsize, bool mipmap)
Definition: grtexture.cpp:213
int grMipMap
Definition: grutil.cpp:40
const T sign(const T &x)
Definition: MathFunctions.h:30