TORCS  1.3.9
The Open Racing Car Simulator
gui.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  gui.cpp -- gui
3  -------------------
4  created : Fri Aug 13 22:01:33 CEST 1999
5  copyright : (C) 1999 by Eric Espie
6  email : torcs@free.fr
7  version : $Id$
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <time.h>
29 
30 #include <tgfclient.h>
31 #include "gui.h"
32 
33 #include <portability.h>
34 
35 tGfuiScreen *GfuiScreen; /* current screen */
36 static int GfuiMouseVisible = 1;
38 
39 int GfuiMouseHW = 0;
40 
42 
43 static int ScrW, ScrH, ViewW, ViewH;
44 
46 static double LastTimeClick;
47 #define REPEAT1 1.0
48 #define REPEAT2 0.2
49 
50 static void
52 {
53  const int BUFSIZE = 1024;
54  char buf[BUFSIZE];
55 
56  void *hdle;
57  int i, j;
59  const char *clr[GFUI_COLORNB] = {
66  };
67 
68  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
70 
71  for (i = 0; i < GFUI_COLORNB; i++) {
72  for (j = 0; j < 4; j++) {
73  snprintf(buf, BUFSIZE, "%s/%s/%s", GFSCR_SECT_MENUCOL, GFSCR_LIST_COLORS, clr[i]);
74  GfuiColor[i][j] = GfParmGetNum(hdle, buf, rgba[j], (char*)NULL, 1.0);
75  }
76  }
77 
78  GfParmReleaseHandle(hdle);
79 
80  /* Remove the X11/Windows cursor */
81  if (!GfuiMouseHW) {
82  glutSetCursor(GLUT_CURSOR_NONE);
83  }
84 
85  GfuiMouseVisible = 1;
86 }
87 
88 
89 void
90 gfuiInit(void)
91 {
93  gfuiHelpInit();
94  gfuiLabelInit();
96  gfuiColorInit();
97  gfuiLoadFonts();
98 
99 /* glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF); */
100 }
101 
102 
107 void
109 {
110 }
111 
115 void
116 GfuiIdle(void)
117 {
118  double curtime = GfTimeClock();
119 
120  if ((curtime - LastTimeClick) > DelayRepeat) {
122  LastTimeClick = curtime;
123  if (GfuiScreen->mouse == 1) {
124  /* button down */
125  gfuiUpdateFocus();
126  gfuiMouseAction((void*)0);
127  glutPostRedisplay();
128  }
129  }
130 }
131 
135 void
137 {
138  tGfuiObject *curObj;
139 
140  glDisable(GL_DEPTH_TEST);
141  glDisable(GL_LIGHTING);
142  glDisable(GL_TEXTURE_2D);
143  glDisable(GL_CULL_FACE);
144  glDisable(GL_ALPHA_TEST);
145  glEnable(GL_BLEND);
146  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
147 
148  GfScrGetSize(&ScrW, &ScrH, &ViewW, &ViewH);
149 
150  glViewport((ScrW-ViewW) / 2, (ScrH-ViewH) / 2, ViewW, ViewH);
151  glMatrixMode(GL_PROJECTION);
152  glLoadIdentity();
153  gluOrtho2D(0, GfuiScreen->width, 0, GfuiScreen->height);
154  glMatrixMode(GL_MODELVIEW);
155  glLoadIdentity();
156 
157  if (GfuiScreen->bgColor[3] != 0.0) {
158  glClearColor(GfuiScreen->bgColor[0],
159  GfuiScreen->bgColor[1],
160  GfuiScreen->bgColor[2],
161  GfuiScreen->bgColor[3]);
162  glClear(GL_COLOR_BUFFER_BIT);
163  }
164 
165  if (glIsTexture(GfuiScreen->bgImage) == GL_TRUE) {
166  GLfloat tx1 = 0.0f, tx2 = 1.0f, ty1 = 0.0f, ty2 = 1.0f;
167 
168  // All background images are 16:10 images which are stored as quadratic images.
169  // Compute texture coordinates to ensure proper unskewed/unstretched display of
170  // image content.
171  tdble rfactor = (16.0f*ViewH)/(10.0f*ViewW);
172  if (rfactor >= 1.0f) {
173  // Aspect ratio of view is smaller than 16:10, "cut off" sides
174  tdble tdx = (1.0f-1.0f/rfactor)/2.0f;
175  tx1 += tdx;
176  tx2 -= tdx;
177  } else {
178  // Aspect ratio of view is larger than 16:10, "cut off" top and bottom
179  tdble tdy = (1.0f-rfactor)/2.0f;
180  ty1 += tdy;
181  ty2 -= tdy;
182  }
183 
184  glDisable(GL_BLEND);
185  glEnable(GL_TEXTURE_2D);
186  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
187  glColor3f(0.0, 0.0, 1.0);
188  glBindTexture(GL_TEXTURE_2D, GfuiScreen->bgImage);
189  glBegin(GL_QUADS);
190  glTexCoord2f(tx1, ty1); glVertex3f(0.0, 0.0, 0.0);
191  glTexCoord2f(tx1, ty2); glVertex3f(0.0, GfuiScreen->height, 0.0);
192  glTexCoord2f(tx2, ty2); glVertex3f(GfuiScreen->width, GfuiScreen->height, 0.0);
193  glTexCoord2f(tx2, ty1); glVertex3f(GfuiScreen->width, 0.0, 0.0);
194  glEnd();
195  glDisable(GL_TEXTURE_2D);
196  glEnable(GL_BLEND);
197  }
198 
199  curObj = GfuiScreen->objects;
200  if (curObj) {
201  do {
202  curObj = curObj->next;
203  GfuiDraw(curObj);
204  } while (curObj != GfuiScreen->objects);
205  }
206 
208  GfuiDrawCursor();
209  }
210 
211  glDisable(GL_BLEND);
212  glutSwapBuffers();
213 }
214 
219 void
221 {
223 }
224 
229 void
231 {
233 }
234 
240 void
242 {
243  GfuiMouseHW = 1;
244 }
245 
246 static void
247 gfuiKeyboard(unsigned char key, int /* x */, int /* y */)
248 {
249  tGfuiKey *curKey;
250  int modifier;
251  tGfuiObject *obj;
252 
253  modifier = glutGetModifiers();
254 
255  /* user preempt key */
256  if (GfuiScreen->onKeyAction && GfuiScreen->onKeyAction(key, modifier, GFUI_KEY_DOWN)) {
257  return;
258  }
259 
260  /* now see the user's defined keys */
261  if (GfuiScreen->userKeys != NULL) {
262  curKey = GfuiScreen->userKeys;
263  do {
264  curKey = curKey->next;
265  if ((curKey->key == key) && ((curKey->modifier == 0) || (curKey->modifier & modifier) != 0)) {
266  if (curKey->onPress) curKey->onPress(curKey->userData);
267  break;
268  }
269  } while (curKey != GfuiScreen->userKeys);
270  }
271 
272  obj = GfuiScreen->hasFocus;
273  if (obj != NULL) {
274  switch (obj->widget) {
275  case GFUI_EDITBOX:
276  gfuiEditboxKey(obj, (int)key, modifier);
277  break;
278  }
279  }
280  glutPostRedisplay();
281 }
282 
283 static void
284 gfuiSpecial(int key, int /* x */, int /* y */)
285 {
286  tGfuiKey *curKey;
287  int modifier;
288  tGfuiObject *obj;
289 
290  modifier = glutGetModifiers();
291 
292  /* user preempt key */
293  if (GfuiScreen->onSKeyAction && GfuiScreen->onSKeyAction(key, modifier, GFUI_KEY_DOWN)) {
294  return;
295  }
296 
297  /* now see the user's defined keys */
298  if (GfuiScreen->userSpecKeys != NULL) {
299  curKey = GfuiScreen->userSpecKeys;
300  do {
301  curKey = curKey->next;
302  if ((curKey->specialkey == key) && ((curKey->modifier == 0) || (curKey->modifier & modifier) != 0)) {
303  if (curKey->onPress) curKey->onPress(curKey->userData);
304  break;
305  }
306  } while (curKey != GfuiScreen->userSpecKeys);
307  }
308 
309  obj = GfuiScreen->hasFocus;
310  if (obj != NULL) {
311  switch (obj->widget) {
312  case GFUI_EDITBOX:
313  gfuiEditboxKey(obj, key + 256, modifier);
314  break;
315  }
316  }
317  glutPostRedisplay();
318 }
319 
320 static void
321 gfuiKeyboardUp(unsigned char key, int /* x */, int /* y */)
322 {
323  tGfuiKey *curKey;
324  int modifier;
325 
326  modifier = glutGetModifiers();
327 
328  /* user preempt key */
329  if (GfuiScreen->onKeyAction && GfuiScreen->onKeyAction(key, modifier, GFUI_KEY_UP)) {
330  return;
331  }
332 
333  /* now see the user's defined keys */
334  if (GfuiScreen->userKeys != NULL) {
335  curKey = GfuiScreen->userKeys;
336  do {
337  curKey = curKey->next;
338  if ((curKey->key == key) && ((curKey->modifier == 0) || (curKey->modifier & modifier) != 0)) {
339  if (curKey->onRelease) curKey->onRelease(curKey->userData);
340  break;
341  }
342  } while (curKey != GfuiScreen->userKeys);
343  }
344 
345  glutPostRedisplay();
346 }
347 
348 static void
349 gfuiSpecialUp(int key, int /* x */, int /* y */)
350 {
351  tGfuiKey *curKey;
352  int modifier;
353 
354  modifier = glutGetModifiers();
355 
356  /* user preempt key */
357  if (GfuiScreen->onSKeyAction && GfuiScreen->onSKeyAction(key, modifier, GFUI_KEY_UP)) {
358  return;
359  }
360 
361  /* now see the user's defined keys */
362  if (GfuiScreen->userSpecKeys != NULL) {
363  curKey = GfuiScreen->userSpecKeys;
364  do {
365  curKey = curKey->next;
366  if ((curKey->specialkey == key) && ((curKey->modifier == 0) || (curKey->modifier & modifier) != 0)) {
367  if (curKey->onRelease) curKey->onRelease(curKey->userData);
368  break;
369  }
370  } while (curKey != GfuiScreen->userSpecKeys);
371  }
372 
373  glutPostRedisplay();
374 }
375 
381 {
382  return &GfuiMouse;
383 }
384 
391 void GfuiMouseSetPos(int x, int y)
392 {
393  glutWarpPointer(x, y);
394 }
395 
396 
397 static void
398 gfuiMouse(int button, int state, int x, int y)
399 {
400  // Check array range of button array!
401  if (button > -1 && button < 3) {
402  GfuiMouse.X = (x - (ScrW - ViewW)/2) * (int)GfuiScreen->width / ViewW;
403  GfuiMouse.Y = (ViewH - y + (ScrH - ViewH)/2) * (int)GfuiScreen->height / ViewH;
404 
405  GfuiMouse.button[button] = 1 - state;
406 
409  if (state == GLUT_DOWN) {
410  if (button == GLUT_RIGHT_BUTTON) {
411  GfuiScreen->mouse = 0;
412  /* GfuiMouseVisible = 1 - GfuiMouseVisible; */
413  gfuiUpdateFocus();
414  } else {
415  GfuiScreen->mouse = 1;
416  gfuiUpdateFocus();
417  gfuiMouseAction((void*)0);
418  }
419  } else {
420  GfuiScreen->mouse = 0;
421  gfuiUpdateFocus();
422  if (button != GLUT_RIGHT_BUTTON) {
423  gfuiMouseAction((void*)1);
424  }
425  }
426  glutPostRedisplay();
427  }
428 }
429 
430 static void
431 gfuiMotion(int x, int y)
432 {
433  GfuiMouse.X = (x - (ScrW - ViewW)/2) * (int)GfuiScreen->width / ViewW;
434  GfuiMouse.Y = (ViewH - y + (ScrH - ViewH)/2) * (int)GfuiScreen->height / ViewH;
435  gfuiUpdateFocus();
436  gfuiMouseAction((void*)(1 - GfuiScreen->mouse));
437  glutPostRedisplay();
439 }
440 
441 static void
442 gfuiPassiveMotion(int x, int y)
443 {
444  GfuiMouse.X = (x - (ScrW - ViewW)/2) * (int)GfuiScreen->width / ViewW;
445  GfuiMouse.Y = (ViewH - y + (ScrH - ViewH)/2) * (int)GfuiScreen->height / ViewH;
446  gfuiUpdateFocus();
447  glutPostRedisplay();
448 }
449 
455 int
456 GfuiScreenIsActive(void *screen)
457 {
458  return (GfuiScreen == screen);
459 }
460 
466 void
467 GfuiScreenActivate(void *screen)
468 {
470 
471  GfuiScreen = (tGfuiScreen*)screen;
472 
473  glutKeyboardFunc(gfuiKeyboard);
474  glutSpecialFunc(gfuiSpecial);
475  glutKeyboardUpFunc(gfuiKeyboardUp);
476  glutSpecialUpFunc(gfuiSpecialUp);
477  glutMouseFunc(gfuiMouse);
478  glutMotionFunc(gfuiMotion);
479  glutPassiveMotionFunc(gfuiPassiveMotion);
480  glutIdleFunc((void(*)(void))NULL);
481 
482  if (GfuiScreen->onlyCallback == 0) {
483  if (GfuiScreen->hasFocus == NULL) {
484  gfuiSelectNext(NULL);
485  }
486  glutDisplayFunc(GfuiDisplay);
487  } else {
488  glutDisplayFunc(GfuiDisplayNothing);
489  }
490 
492 
493  if (GfuiScreen->onlyCallback == 0) {
494  GfuiDisplay();
495  glutPostRedisplay();
496  }
497 }
498 
499 
505 void
506 GfuiScreenReplace(void *screen)
507 {
508  tGfuiScreen *oldScreen = GfuiScreen;
509 
510  if (oldScreen) {
511  GfuiScreenRelease(oldScreen);
512  }
513  GfuiScreenActivate(screen);
514 }
515 
519 void
521 {
523 
524  GfuiScreen = (tGfuiScreen*)NULL;
525 
526  glutKeyboardFunc((void(*)(unsigned char,int,int))NULL);
527  glutSpecialFunc((void(*)(int,int,int))NULL);
528  glutKeyboardUpFunc((void(*)(unsigned char,int,int))NULL);
529  glutSpecialUpFunc((void(*)(int,int,int))NULL);
530  glutMouseFunc((void(*)(int,int,int,int))NULL);
531  glutMotionFunc((void(*)(int,int))NULL);
532  glutPassiveMotionFunc((void(*)(int,int))NULL);
533  glutIdleFunc((void(*)(void))NULL);
534  glutDisplayFunc(GfuiDisplayNothing);
535 }
536 
542 void *
544 {
545  tGfuiScreen *screen;
546 
547  screen = (tGfuiScreen*)calloc(1, sizeof(tGfuiScreen));
548 
549  screen->width = 640.0;
550  screen->height = 480.0;
551 
552  screen->bgColor = (float*)calloc(4, sizeof(float));
553  int i;
554  for(i = 0; i < 4; i++) {
555  screen->bgColor[i] = GfuiColor[GFUI_BGCOLOR][i];
556  }
557 
558  screen->mouseColor[0] = &(GfuiColor[GFUI_MOUSECOLOR1][0]);
559  screen->mouseColor[1] = &(GfuiColor[GFUI_MOUSECOLOR2][0]);
560  screen->mouseAllowed = 1;
561 
562  return (void*)screen;
563 }
564 
577 void *
578 GfuiScreenCreateEx(float *bgColor,
579  void *userDataOnActivate, tfuiCallback onActivate,
580  void *userDataOnDeactivate, tfuiCallback onDeactivate,
581  int mouseAllowed)
582 {
583  int i;
584  tGfuiScreen *screen;
585 
586  screen = (tGfuiScreen*)calloc(1, sizeof(tGfuiScreen));
587 
588  screen->width = 640.0;
589  screen->height = 480.0;
590 
591  screen->bgColor = (float*)calloc(4, sizeof(float));
592  for(i = 0; i < 4; i++) {
593  if (bgColor != NULL) {
594  screen->bgColor[i] = bgColor[i];
595  } else {
596  screen->bgColor[i] = GfuiColor[GFUI_BGCOLOR][i];
597  }
598  }
599 
600  screen->mouseColor[0] = &(GfuiColor[GFUI_MOUSECOLOR1][0]);
601  screen->mouseColor[1] = &(GfuiColor[GFUI_MOUSECOLOR2][0]);
602  screen->onActivate = onActivate;
603  screen->userActData = userDataOnActivate;
604  screen->onDeactivate = onDeactivate;
605  screen->userDeactData = userDataOnDeactivate;
606 
607  screen->mouseAllowed = mouseAllowed;
608 
609  return (void*)screen;
610 }
611 
617 void
619 {
620  tGfuiObject *curObject;
621  tGfuiObject *nextObject;
622  tGfuiKey *curKey;
623  tGfuiKey *nextKey;
624  tGfuiScreen *screen = (tGfuiScreen*)scr;
625 
626  if (GfuiScreen == screen) {
628  }
629 
630  if (glIsTexture(screen->bgImage) == GL_TRUE) {
631  glDeleteTextures(1, &screen->bgImage);
632  }
633 
634  if (screen->bgColor != NULL) {
635  free(screen->bgColor);
636  screen->bgColor = NULL;
637  }
638 
639  curObject = screen->objects;
640  if (curObject != NULL) {
641  do {
642  nextObject = curObject->next;
643  gfuiReleaseObject(curObject);
644  curObject = nextObject;
645  } while (curObject != screen->objects);
646  }
647 
648  curKey = screen->userKeys;
649  if (curKey != NULL) {
650  do {
651  nextKey = curKey->next;
652  free(curKey->name);
653  free(curKey->descr);
654  free(curKey);
655  curKey = nextKey;
656  } while (curKey != screen->userKeys);
657  }
658  curKey = screen->userSpecKeys;
659  if (curKey != NULL) {
660  do {
661  nextKey = curKey->next;
662  free(curKey->name);
663  free(curKey->descr);
664  free(curKey);
665  curKey = nextKey;
666  } while (curKey != screen->userSpecKeys);
667  }
668  free(screen);
669 }
670 
678 void *
679 GfuiHookCreate(void *userDataOnActivate, tfuiCallback onActivate)
680 {
681  tGfuiScreen *screen;
682 
683  screen = (tGfuiScreen*)calloc(1, sizeof(tGfuiScreen));
684  screen->onActivate = onActivate;
685  screen->userActData = userDataOnActivate;
686  screen->onlyCallback = 1;
687 
688  return (void*)screen;
689 }
690 
695 void
696 GfuiHookRelease(void *hook)
697 {
698  free(hook);
699 }
700 
701 void
703 {
704  tGfuiScreen *screen = (tGfuiScreen*)scr;
705 
706  screen->onKeyAction = onKeyAction;
707 }
708 
709 
710 void
712 {
713  tGfuiScreen *screen = (tGfuiScreen*)scr;
714 
715  screen->onSKeyAction = onSKeyAction;
716 }
717 
718 void
720 {
722 }
723 
724 
725 void
727 {
729 }
730 
731 
741 void
742 GfuiAddKey(void *scr, unsigned char key, const char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
743 {
744  tGfuiKey *curKey;
745  tGfuiScreen *screen = (tGfuiScreen*)scr;
746  const int BUFSIZE = 16;
747  char buf[BUFSIZE];
748 
749  curKey = (tGfuiKey*)calloc(1, sizeof(tGfuiKey));
750  curKey->key = key;
751  curKey->userData = userData;
752  curKey->onPress = onKeyPressed;
753 
754  if (descr == NULL) {
755  curKey->descr = strdup("");
756  } else {
757  curKey->descr = strdup(descr);
758  }
759 
760  switch(key){
761  case 8:
762  curKey->name = strdup("backspace");
763  break;
764  case 9:
765  curKey->name = strdup("tab");
766  break;
767  case 13:
768  curKey->name = strdup("enter");
769  break;
770  case 27:
771  curKey->name = strdup("esc");
772  break;
773  case ' ':
774  curKey->name = strdup("space");
775  break;
776  default:
777  snprintf(buf, BUFSIZE, "%c", key);
778  curKey->name = strdup(buf);
779  break;
780  }
781 
782  if (screen->userKeys == NULL) {
783  screen->userKeys = curKey;
784  curKey->next = curKey;
785  } else {
786  curKey->next = screen->userKeys->next;
787  screen->userKeys->next = curKey;
788  }
789 }
790 
799 void
800 GfuiRegisterKey(unsigned char key, char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
801 {
802  GfuiAddKey(GfuiScreen, key, descr, userData, onKeyPressed, onKeyReleased);
803 }
804 
815 void
816 GfuiAddSKey(void *scr, int key, const char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
817 {
818  tGfuiKey *curKey;
819  tGfuiScreen *screen = (tGfuiScreen*)scr;
820 
821  curKey = (tGfuiKey*)calloc(1, sizeof(tGfuiKey));
822  curKey->specialkey = key;
823  curKey->userData = userData;
824  curKey->onPress = onKeyPressed;
825 
826  if (descr == NULL) {
827  curKey->descr = strdup("");
828  } else {
829  curKey->descr = strdup(descr);
830  }
831 
832  switch(key) {
833  case GLUT_KEY_F1:
834  curKey->name = strdup("F1");
835  break;
836  case GLUT_KEY_F2:
837  curKey->name = strdup("F2");
838  break;
839  case GLUT_KEY_F3:
840  curKey->name = strdup("F3");
841  break;
842  case GLUT_KEY_F4:
843  curKey->name = strdup("F4");
844  break;
845  case GLUT_KEY_F5:
846  curKey->name = strdup("F5");
847  break;
848  case GLUT_KEY_F6:
849  curKey->name = strdup("F6");
850  break;
851  case GLUT_KEY_F7:
852  curKey->name = strdup("F7");
853  break;
854  case GLUT_KEY_F8:
855  curKey->name = strdup("F8");
856  break;
857  case GLUT_KEY_F9:
858  curKey->name = strdup("F9");
859  break;
860  case GLUT_KEY_F10:
861  curKey->name = strdup("F10");
862  break;
863  case GLUT_KEY_F11:
864  curKey->name = strdup("F11");
865  break;
866  case GLUT_KEY_F12:
867  curKey->name = strdup("F12");
868  break;
869  case GLUT_KEY_LEFT:
870  curKey->name = strdup("Left Arrow");
871  break;
872  case GLUT_KEY_UP:
873  curKey->name = strdup("Up Arrow");
874  break;
875  case GLUT_KEY_RIGHT:
876  curKey->name = strdup("Right Arrow");
877  break;
878  case GLUT_KEY_DOWN:
879  curKey->name = strdup("Down Arrow");
880  break;
881  case GLUT_KEY_PAGE_UP:
882  curKey->name = strdup("Page Up");
883  break;
884  case GLUT_KEY_PAGE_DOWN:
885  curKey->name = strdup("Page Down");
886  break;
887  case GLUT_KEY_HOME:
888  curKey->name = strdup("Home");
889  break;
890  case GLUT_KEY_END:
891  curKey->name = strdup("End");
892  break;
893  case GLUT_KEY_INSERT:
894  curKey->name = strdup("Insert");
895  break;
896  }
897 
898 
899  if (screen->userSpecKeys == NULL) {
900  screen->userSpecKeys = curKey;
901  curKey->next = curKey;
902  } else {
903  curKey->next = screen->userSpecKeys->next;
904  screen->userSpecKeys->next = curKey;
905  screen->userSpecKeys = curKey;
906  }
907 }
908 
912 void
913 GfuiScreenShot(void * /* notused */)
914 {
915  unsigned char *img;
916  const int BUFSIZE = 1024;
917  char buf[BUFSIZE];
918  struct tm *stm;
919  time_t t;
920  int sw, sh, vw, vh;
921  char path[BUFSIZE];
922 
923  snprintf(path, BUFSIZE, "%sscreenshots", GetLocalDir());
924  // Ensure that screenshot directory exists.
925  if (GfCreateDir(path) == GF_DIR_CREATED) {
926 
927  GfScrGetSize(&sw, &sh, &vw, &vh);
928  img = (unsigned char*)malloc(vw * vh * 3);
929  if (img == NULL) {
930  return;
931  }
932 
933  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
934  glPixelStorei(GL_PACK_ALIGNMENT, 1);
935  glReadBuffer(GL_FRONT);
936  glReadPixels((sw-vw)/2, (sh-vh)/2, vw, vh, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
937 
938  t = time(NULL);
939  stm = localtime(&t);
940  snprintf(buf, BUFSIZE, "%s/torcs-%4d%02d%02d%02d%02d%02d.png",
941  path,
942  stm->tm_year+1900,
943  stm->tm_mon+1,
944  stm->tm_mday,
945  stm->tm_hour,
946  stm->tm_min,
947  stm->tm_sec);
948  GfImgWritePng(img, buf, vw, vh);
949 
950  free(img);
951  }
952 }
953 
960 void
961 GfuiScreenAddBgImg(void *scr, const char *filename)
962 {
963  tGfuiScreen *screen = (tGfuiScreen*)scr;
964  void *handle;
965  float screen_gamma;
966  GLbyte *tex;
967  int w,h;
968  const int BUFSIZE = 1024;
969  char buf[BUFSIZE];
970 
971  if (glIsTexture(screen->bgImage) == GL_TRUE) {
972  glDeleteTextures(1, &screen->bgImage);
973  }
974 
975  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
977  screen_gamma = (float)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_GAMMA, (char*)NULL, 2.0);
978  tex = (GLbyte*)GfImgReadPng(filename, &w, &h, screen_gamma);
979  if (!tex) {
980  GfParmReleaseHandle(handle);
981  return;
982  }
983 
984  glGenTextures(1, &screen->bgImage);
985  glBindTexture(GL_TEXTURE_2D, screen->bgImage);
986  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
987  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
988  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)(tex));
989  free(tex);
990  GfParmReleaseHandle(handle);
991 }
992 
993 
#define GFSCR_SECT_MENUCOL
#define GFSCR_ELT_BTNDISABLED
GLuint bgImage
Definition: gui.h:240
Definition: gui.h:222
void GfuiMouseShow(void)
Show the mouse cursor.
Definition: gui.cpp:230
#define GFUI_MOUSECOLOR2
Definition: gui.h:40
tfuiCallback onPress
Definition: gui.h:230
#define GFSCR_ELT_HELPCOLOR2
#define GFSCR_ATT_GAMMA
void gfuiInit(void)
Definition: gui.cpp:90
void * userDeactData
Definition: gui.h:252
void GfuiScreenReplace(void *screen)
Activate a screen and make it current plus release the current screen.
Definition: gui.cpp:506
void * GfParmReadFile(const char *file, int mode)
Read parameter set from file and return handle to parameter set.
Definition: params.cpp:1157
int GfImgWritePng(unsigned char *img, const char *filename, int width, int height)
Write a buffer to a png image on disk.
Definition: img.cpp:201
static void gfuiKeyboardUp(unsigned char key, int, int)
Definition: gui.cpp:321
static void gfuiPassiveMotion(int x, int y)
Definition: gui.cpp:442
#define GFPARM_RMODE_STD
if handle already openned return it
Definition: tgf.h:265
#define GFSCR_ATTR_BLUE
void GfuiMouseSetPos(int x, int y)
Set the mouse position.
Definition: gui.cpp:391
float * bgColor
Definition: gui.h:239
float width
Definition: gui.h:238
#define GFSCR_ATTR_ALPHA
char * GetLocalDir(void)
Definition: tgf.cpp:231
void GfParmReleaseHandle(void *parmHandle)
Release given parameter set handle parmHandle.
Definition: params.cpp:1834
#define GFSCR_CONF_FILE
void GfuiKeyEventRegisterCurrent(tfuiKeyCallback onKeyAction)
Definition: gui.cpp:719
int mouseAllowed
Definition: gui.h:261
void GfuiAddKey(void *scr, unsigned char key, const char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
Add a Keyboard callback to a screen.
Definition: gui.cpp:742
int GfCreateDir(char *path)
Create directory for given path recursively, so all missing parent directories are created as well...
Definition: tgf.cpp:309
unsigned char key
Definition: gui.h:224
void GfuiDisplay(void)
Display function for the GUI to be called during redisplay of glut.
Definition: gui.cpp:136
void GfuiScreenRelease(void *scr)
Release the given screen.
Definition: gui.cpp:618
static int ViewH
Definition: gui.cpp:43
int mouse
Definition: gui.h:260
int(* tfuiSKeyCallback)(int key, int modifier, int state)
return 1 to prevent normal key computing
Definition: tgfclient.h:108
static tdble DelayRepeat
Definition: gui.cpp:45
void gfuiObjectInit(void)
Definition: guiobject.cpp:27
void GfuiScreenAddBgImg(void *scr, const char *filename)
Add an image background to a screen.
Definition: gui.cpp:961
#define GFSCR_ELT_BGSCROLLIST
static int ViewW
Definition: gui.cpp:43
#define GFSCR_ELT_BGBTNFOCUS
void gfuiEditboxKey(tGfuiObject *obj, int key, int modifier)
Definition: guiedit.cpp:270
static void gfuiMouse(int button, int state, int x, int y)
Definition: gui.cpp:398
int(* tfuiKeyCallback)(unsigned char key, int modifier, int state)
return 1 to prevent normal key computing
Definition: tgfclient.h:107
void GfuiIdle(void)
Idle function for the GUI to be called during Idle loop of glut.
Definition: gui.cpp:116
tfuiCallback onRelease
Definition: gui.h:231
static void gfuiKeyboard(unsigned char key, int, int)
Definition: gui.cpp:247
struct GfuiKey * next
Definition: gui.h:232
#define GFSCR_SECT_PROP
void GfuiSKeyEventRegister(void *scr, tfuiSKeyCallback onSKeyAction)
Definition: gui.cpp:711
#define GFSCR_LIST_COLORS
void GfuiSKeyEventRegisterCurrent(tfuiSKeyCallback onSKeyAction)
Definition: gui.cpp:726
The Gaming Framework API (client part).
void GfuiKeyEventRegister(void *scr, tfuiKeyCallback onKeyAction)
Definition: gui.cpp:702
#define GFSCR_ELT_BGBTNDISABLED
void GfuiRegisterKey(unsigned char key, char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
Add a Keyboard callback to the current screen.
Definition: gui.cpp:800
#define GFSCR_ELT_MOUSECOLOR1
void * userData
Definition: gui.h:229
#define GFUI_EDITBOX
Definition: tgfclient.h:66
#define GFSCR_ELT_MOUSECOLOR2
void GfuiDisplayNothing(void)
Dummy display function for glut.
Definition: gui.cpp:108
float * mouseColor[2]
Definition: gui.h:262
void GfuiMouseSetHWPresent(void)
Force the hardware mouse pointer.
Definition: gui.cpp:241
void * GfuiScreenCreateEx(float *bgColor, void *userDataOnActivate, tfuiCallback onActivate, void *userDataOnDeactivate, tfuiCallback onDeactivate, int mouseAllowed)
Create a screen.
Definition: gui.cpp:578
void gfuiReleaseObject(tGfuiObject *curObject)
Definition: guiobject.cpp:520
int button[3]
Definition: tgfclient.h:148
static void gfuiSpecial(int key, int, int)
Definition: gui.cpp:284
void gfuiHelpInit(void)
Definition: guihelp.cpp:38
#define GFSCR_ATTR_GREEN
#define GFSCR_ELT_EDITCURSORCLR
float tdble
Floating point type used in TORCS.
Definition: tgf.h:48
static void onActivate(void *)
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
int modifier
Definition: gui.h:228
#define GFUI_KEY_UP
Definition: tgfclient.h:84
tMouseInfo GfuiMouse
Definition: gui.cpp:37
#define GFUI_MOUSECOLOR1
Definition: gui.h:39
void * userActData
Definition: gui.h:250
static double LastTimeClick
Definition: gui.cpp:46
static int ScrW
Definition: gui.cpp:43
tfuiKeyCallback onKeyAction
Definition: gui.h:256
tMouseInfo * GfuiMouseInfo(void)
Get the mouse information (position and buttons)
Definition: gui.cpp:380
#define GFSCR_ELT_TIPCOLOR
static int GfuiMouseVisible
Definition: gui.cpp:36
int GfuiScreenIsActive(void *screen)
Tell if the screen is active or not.
Definition: gui.cpp:456
tfuiSKeyCallback onSKeyAction
Definition: gui.h:257
void gfuiButtonInit(void)
Definition: guibutton.cpp:36
#define GFSCR_ELT_LABELCOLOR
void * GfuiHookCreate(void *userDataOnActivate, tfuiCallback onActivate)
Create a callback hook.
Definition: gui.cpp:679
#define GFSCR_ELT_HELPCOLOR1
tGfuiScreen * GfuiScreen
Definition: gui.cpp:35
void(* tfuiCallback)(void *)
Definition: tgfclient.h:105
int specialkey
Definition: gui.h:227
void GfuiMouseHide(void)
Hide the mouse cursor.
Definition: gui.cpp:220
void GfuiScreenActivate(void *screen)
Activate a screen and make it current.
Definition: gui.cpp:467
struct GfuiObject * next
Definition: gui.h:217
void GfuiAddSKey(void *scr, int key, const char *descr, void *userData, tfuiCallback onKeyPressed, tfuiCallback onKeyReleased)
Add a Special Keyboard shortcut to the screen.
Definition: gui.cpp:816
int onlyCallback
Definition: gui.h:268
static int ScrH
Definition: gui.cpp:43
void gfuiLabelInit(void)
Definition: guilabel.cpp:35
static void gfuiMotion(int x, int y)
Definition: gui.cpp:431
char * descr
Definition: gui.h:226
void GfuiDraw(tGfuiObject *obj)
Definition: guiobject.cpp:114
float height
Definition: gui.h:238
void GfScrGetSize(int *scrw, int *scrh, int *vieww, int *viewh)
Get the screen and viewport sizes.
Definition: screen.cpp:471
tdble GfParmGetNum(void *handle, const char *path, const char *key, const char *unit, tdble deflt)
Get a numerical parameter from the parameter set handle.
Definition: params.cpp:2392
double GfTimeClock(void)
Get the time in seconds.
Definition: os.cpp:50
#define REPEAT2
Definition: gui.cpp:48
float GfuiColor[GFUI_COLORNB][4]
Definition: gui.cpp:41
tfuiCallback onActivate
Definition: gui.h:251
#define GFSCR_ELT_BGCOLOR
#define GFSCR_ELT_BTNCLICK
void GfuiScreenShot(void *)
Save a screen shot in png format.
Definition: gui.cpp:913
#define GFSCR_ELT_BTNFOCUS
static Vector y[4]
Definition: Convex.cpp:56
void gfuiLoadFonts(void)
Definition: guifont.cpp:65
#define GFSCR_ELT_BGBTNCLICK
#define GFUI_COLORNB
Definition: gui.h:24
#define GFSCR_ATTR_RED
tGfuiObject * hasFocus
Definition: gui.h:244
#define GFSCR_ELT_SELSCROLLIST
void * GfuiScreenCreate(void)
Create a new screen.
Definition: gui.cpp:543
int GfuiMouseHW
Definition: gui.cpp:39
tfuiCallback onDeactivate
Definition: gui.h:253
tGfuiObject * objects
Definition: gui.h:243
#define REPEAT1
Definition: gui.cpp:47
static void gfuiColorInit(void)
Definition: gui.cpp:51
static int onKeyAction(unsigned char key, int, int state)
void GfuiDrawCursor()
Definition: guiobject.cpp:76
tGfuiKey * userKeys
Definition: gui.h:248
void gfuiMouseAction(void *action)
Definition: guiobject.cpp:456
#define GFSCR_ELT_BGSELSCROLLIST
#define GFUI_BGCOLOR
Definition: gui.h:27
tGfuiKey * userSpecKeys
Definition: gui.h:249
#define GFSCR_ELT_SCROLLIST
void GfuiHookRelease(void *hook)
Release the given hook.
Definition: gui.cpp:696
#define GFSCR_ELT_BGBTNENABLED
int widget
Definition: gui.h:199
#define GFSCR_ELT_BTNENABLED
void GfuiScreenDeactivate(void)
Deactivate the current screen.
Definition: gui.cpp:520
#define GFPARM_RMODE_CREAT
Create the file if doesn&#39;t exist.
Definition: tgf.h:267
static void gfuiSpecialUp(int key, int, int)
Definition: gui.cpp:349
#define GFUI_KEY_DOWN
Definition: tgfclient.h:85
static int onSKeyAction(int key, int, int state)
#define GF_DIR_CREATED
Definition: tgf.h:623
char * name
Definition: gui.h:225
void gfuiUpdateFocus()
Definition: guiobject.cpp:277
void gfuiSelectNext(void *)
Definition: guiobject.cpp:311
#define GFSCR_ELT_TITLECOLOR