TORCS  1.3.9
The Open Racing Car Simulator
screen.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  screen.cpp -- screen init
3  -------------------
4  created : Fri Aug 13 22:29:56 CEST 1999
5  copyright : (C) 1999-2024 by Eric Espie, Bernhard Wymann
6  email : berniw@bluewin.ch
7 ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
23 #include <stdio.h>
24 #ifdef WIN32
25 #include <windows.h>
26 #endif
27 #include <GL/glut.h>
28 #include <math.h>
29 #ifndef WIN32
30 #include <unistd.h>
31 #else
32 #include <process.h>
33 #endif /* WIN32 */
34 
35 #include <tgfclient.h>
36 #include <portability.h>
38 #include <portability.h>
39 
40 #include "gui.h"
41 #include "fg_gm.h"
42 #include "glfeatures.h"
43 
44 //#ifndef WIN32
45 //#define USE_RANDR_EXT
46 //#endif // WIN32
47 
48 #ifdef USE_RANDR_EXT
49 #include <GL/glx.h>
50 #include <X11/Xlib.h>
51 #include <X11/Xatom.h>
52 #include <X11/keysym.h>
53 #include <X11/extensions/Xrandr.h>
54 #endif // USE_RANDR_EXT
55 
56 static int GfScrWidth;
57 static int GfScrHeight;
58 static int GfViewWidth;
59 static int GfViewHeight;
60 static int GfScrCenX;
61 static int GfScrCenY;
62 
63 static void *scrHandle = NULL;
64 
65 static int usedGM = 0;
66 #if !defined(FREEGLUT) && !defined(WIN32)
67 static int usedFG = 0;
68 #endif
69 
70 #ifdef USE_RANDR_EXT
71 static char **Res = NULL;
72 static int nbRes = 0;
73 #else // USE_RANDR_EXT
74 static char *Res[] = {
75  "640x480",
76  "800x600",
77  "1024x768",
78  "1152x768",
79  "1152x864",
80  "1200x854",
81  "1200x960",
82  "1280x720",
83  "1280x1024",
84  "1400x900",
85  "1600x900",
86  "1600x1200",
87  "1680x1050",
88  "1920x1080",
89  "2560x1080",
90  "3840x1080",
91  "1920x1200",
92  "2560x1440",
93  "3440x1440",
94  "5120x1440",
95  "4096x2160",
96  "5040x2160",
97  "8192x2160",
98  "320x200"
99 };
100 static const int nbRes = sizeof(Res) / sizeof(Res[0]);
101 #endif // USE_RANDR_EXT
102 
103 static const char *Mode[] = {"Full-screen mode", "Window mode"};
105 static const char *Depthlist[] = {"24", "32", "16"};
106 
107 //static const int nbRes = sizeof(Res) / sizeof(Res[0]);
108 static const int nbMode = sizeof(Mode) / sizeof(Mode[0]);
109 static const int nbVInit = sizeof(VInit) / sizeof(VInit[0]);
110 static const int nbDepth = sizeof(Depthlist) / sizeof(Depthlist[0]);
111 
112 static int curRes = 0;
113 static int curMode = 0;
114 static int curDepth = 0;
115 static int curVInit = 0;
116 
117 static int curMaxFreq = 75;
118 #ifdef WIN32
119 static int MaxFreqId;
120 #endif
121 
122 static int ResLabelId;
123 static int DepthLabelId;
124 static int ModeLabelId;
125 static int VInitLabelId;
126 
127 static float LabelColor[] = {1.0, 0.0, 1.0, 1.0};
128 
129 
130 void
132 {
133 #ifdef USE_RANDR_EXT
134  // Get display, screen and root window handles.
135  const char *displayname = getenv("DISPLAY");
136  if (displayname == NULL) {
137  displayname = strdup(":0.0");
138  }
139 
140  Display *display = XOpenDisplay(displayname);
141 
142  if( display != NULL) {
143  // If we have a display fill in the resolutions advertised by Xrandr.
144  int screen = DefaultScreen(display);
145  Window root = RootWindow(display, screen);
146 
147  XRRScreenConfiguration *screenconfig = XRRGetScreenInfo (display, root);
148  if (screenconfig != NULL) {
149  int i, j, nsize;
150  XRRScreenSize *sizes = XRRConfigSizes(screenconfig, &nsize);
151 
152  if (nsize > 0) {
153  // Check if 320x200, 640x480, 800x600 are available, construct a mode wish list.
154  int check_resx[] = {320, 640, 800};
155  int check_resy[] = {240, 480, 600};
156  bool mode_in_list[] = {false, false, false};
157  int add_modes = sizeof(check_resx)/sizeof(check_resx[0]);
158 
159  for (i = 0; i < nsize; i++) {
160  for (j = 0; j < 3; j++) {
161  if ((mode_in_list[j] == false) && (sizes[i].width == check_resx[j])) {
162  if (sizes[i].height == check_resy[j]) {
163  // Mode already in list.
164  mode_in_list[j] = true;
165  add_modes--;
166  }
167  }
168  }
169  }
170 
171  const int bufsize = 20;
172  char buffer[bufsize];
173  Res = (char**) malloc(sizeof(char *)*(nsize+add_modes));
174  int resx[nsize+add_modes];
175  int resy[nsize+add_modes];
176  for (i = 0; i < nsize+add_modes; i++) {
177  if (i < nsize) {
178  // Add mode from screenconfig (system).
179  snprintf(buffer, bufsize, "%dx%d", sizes[i].width, sizes[i].height);
180  Res[i] = strndup(buffer, bufsize);
181  resx[i] = sizes[i].width;
182  resy[i] = sizes[i].height;
183  } else {
184  // Add mode from wish list.
185  unsigned int j;
186  for (j = 0; j < sizeof(check_resx)/sizeof(check_resx[0]); j++) {
187  if (mode_in_list[j] == false) {
188  mode_in_list[j] = true;
189  snprintf(buffer, bufsize, "%dx%d", check_resx[j], check_resy[j]);
190  Res[i] = strndup(buffer, bufsize);
191  resx[i] = check_resx[j];
192  resy[i] = check_resy[j];
193  break;
194  }
195  }
196  }
197 
198  // Stupid sorting (not much elements, don't worry).
199  int j;
200  for (j = i; j > 0; j--) {
201  if ((resx[j] < resx[j-1]) ||
202  (resx[j] == resx[j-1] && resy[j] < resy[j-1]))
203  {
204  int tx, ty;
205  char *tc;
206  tx = resx[j-1];
207  ty = resy[j-1];
208  resx[j-1] = resx[j];
209  resy[j-1] = resy[j];
210  resx[j] = tx;
211  resy[j] = ty;
212  tc = Res[j-1];
213  Res[j-1] = Res[j];
214  Res[j] = tc;
215  } else {
216  break;
217  }
218  }
219  }
220 
221  nbRes = nsize + add_modes;
222  }
223 
224  XRRFreeScreenConfigInfo(screenconfig);
225  }
226  XCloseDisplay(display);
227  }
228 
229  if (Res == NULL || nbRes == 0) {
230  // We failed to get a handle to the display, so fill in some defaults.
231  GfOut("Failed to initialize resolutions for display '%s'", XDisplayName(displayname));
232  nbRes = 8;
233  Res = (char **) malloc(sizeof(char *)*nbRes);
234  Res[0] = strdup("640x480");
235  Res[1] = strdup("800x600");
236  Res[2] = strdup("1024x768");
237  Res[3] = strdup("1152x864");
238  Res[4] = strdup("1200x960");
239  Res[5] = strdup("1280x1024");
240  Res[6] = strdup("1600x1200");
241  Res[7] = strdup("320x200");
242  }
243 #endif // USE_RANDR_EXT
244 }
245 
246 static void Reshape(int width, int height)
247 {
248  glViewport( (width-GfViewWidth)/2, (height-GfViewHeight)/2, GfViewWidth, GfViewHeight);
249  glMatrixMode( GL_PROJECTION );
250  glLoadIdentity();
251  glOrtho( 0.0, 640.0, 0.0, 480.0, -1.0, 1.0 );
252  glMatrixMode( GL_MODELVIEW );
253  glLoadIdentity();
254 
255  GfScrWidth = width;
256  GfScrHeight = height;
257  GfScrCenX = width / 2;
258  GfScrCenY = height / 2;
259 }
260 
261 void GfScrInit(int argc, char *argv[])
262 {
263  int Window;
264  int xw, yw;
265  int winX, winY;
266  void *handle;
267  int fullscreen;
268  int maxfreq;
269  int i, depth;
270  const int BUFSIZE = 1024;
271  char buf[BUFSIZE];
272 
273  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
275  xw = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_X, (char*)NULL, 640);
276  yw = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_Y, (char*)NULL, 480);
277  winX = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, xw);
278  winY = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, yw);
279  depth = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, 32);
280  maxfreq = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_MAXREFRESH, (char*)NULL, 160);
281  GfViewWidth = xw;
282  GfViewHeight = yw;
283  GfScrCenX = xw / 2;
284  GfScrCenY = yw / 2;
285 
286  // The fullscreen hack must be run before glutInit, such that glut gets the right screen size, etc.
287  const char* fscr = GfParmGetStr(handle, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
288  fullscreen = 0;
289 #if !defined(FREEGLUT) && !defined(WIN32)
290  if (strcmp(fscr, GFSCR_VAL_YES) == 0) { // Resize the screen
291  GfOut ("Freeglut not detected...\n");
292  for (i = maxfreq; i > 59; i--) {
293  snprintf(buf, BUFSIZE, "%dx%d:%d@%d", winX, winY, depth, i);
294  GfOut("Trying %s mode\n", buf);
295  fglutGameModeString(buf);
296  if (fglutEnterGameMode()) {
297  GfOut("OK done for %s\n", buf);
298  usedFG = 1;
299  break;
300  }
301  }
302  }
303 #endif
304 
306 
307  glutInit(&argc, argv);
308 
309  // Depending on "video mode init" setting try to get the best mode or try to get a mode in a safe way...
310  // This is a workaround for driver/glut/glx bug, which lie about the capabilites of the visual.
311 
312  if (strcmp(vinit, GFSCR_VAL_VINIT_BEST) == 0) {
313 
314  // Try to get "best" videomode, z-buffer >= 24bit, visual with alpha channel,
315  // antialiasing support.
316 
317  int visualDepthBits = 24;
318  bool visualSupportsMultisample = true;
319  bool visualSupportsAlpha = true;
320 
321  glutInitDisplayString("rgba double depth>=24 samples alpha");
322 
323  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
324  // Failed, try without antialiasing support.
325  visualDepthBits = 24;
326  visualSupportsMultisample = false;
327  visualSupportsAlpha = true;
328  glutInitDisplayString("rgba double depth>=24 alpha");
329  }
330 
331  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
332  // Failed, try without alpha channel.
333  visualDepthBits = 24;
334  visualSupportsMultisample = true;
335  visualSupportsAlpha = false;
336  glutInitDisplayString("rgb double depth>=24 samples");
337  }
338 
339  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
340  // Failed, try without antialiasing and alpha support.
341  visualDepthBits = 24;
342  visualSupportsMultisample = false;
343  visualSupportsAlpha = false;
344  glutInitDisplayString("rgb double depth>=24");
345  }
346 
347  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
348  // Failed, try without 24 bit z-Buffer and without antialiasing.
349  visualDepthBits = 16;
350  visualSupportsMultisample = false;
351  visualSupportsAlpha = true;
352  glutInitDisplayString("rgba double depth>=16 alpha");
353  }
354 
355  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
356  // Failed, try without 24 bit z-Buffer, without antialiasing and without alpha.
357  visualDepthBits = 16;
358  visualSupportsMultisample = false;
359  visualSupportsAlpha = false;
360  glutInitDisplayString("rgb double depth>=16");
361  }
362 
363  printf("Visual Properties Report\n");
364  printf("------------------------\n");
365 
366  if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)) {
367  // All failed.
368  printf("The minimum display requirements are not fulfilled.\n");
369  printf("We need a double buffered RGB visual with a 16 bit depth buffer at least.\n");
370  // Try fallback as last resort.
371  printf("Trying generic initialization, fallback.\n");
372  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
373  } else {
374  // We have got a mode, report the properties.
375  printf("z-buffer depth: %d (%s)\n", visualDepthBits, visualDepthBits < 24 ? "bad" : "good");
376  printf("multisampling : %s\n", visualSupportsMultisample ? "available" : "no");
377  printf("alpha bits : %s\n", visualSupportsAlpha ? "available" : "no");
378  if (visualDepthBits < 24) {
379  // Show a hint if the z-buffer depth is not optimal.
380  printf("The z-buffer resolution is below 24 bit, you will experience rendering\n");
381  printf("artefacts. Try to improve the setup of your graphics board or look\n");
382  printf("for an alternate driver.\n");
383  }
384  }
385  } else {
386  // Compatibility mode.
387  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
388  printf("Visual Properties Report\n");
389  printf("------------------------\n");
390  printf("Compatibility mode, properties unknown.\n");
391  }
392 
393 
394  if (strcmp(fscr, GFSCR_VAL_YES) == 0) {
395  for (i = maxfreq; i > 59; i--) {
396  snprintf(buf, BUFSIZE, "%dx%d:%d@%d", winX, winY, depth, i);
397  glutGameModeString(buf);
398  GfOut("2 - Trying %s mode\n", buf);
399  if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
400  GfOut("2- %s mode Possible\n", buf);
401  glutEnterGameMode();
402  if (glutGameModeGet(GLUT_GAME_MODE_DISPLAY_CHANGED)) {
403  GfOut("Use GameMode %s\n", buf);
404  usedGM = 1;
405  fullscreen = 1;
406  break;
407  } else {
408  glutLeaveGameMode();
409  }
410  }
411  }
412  }
413 
414  if (!fullscreen) {
415  /* Give an initial size and position so user doesn't have to place window */
416  glutInitWindowPosition(0, 0);
417  glutInitWindowSize(winX, winY);
418  Window = glutCreateWindow(argv[0]);
419  if (!Window) {
420  printf("Error, couldn't open window\n");
421  GfScrShutdown();
422  exit(1);
423  }
424  }
425 
426  if ((strcmp(fscr, GFSCR_VAL_YES) == 0) && (!fullscreen)) {
427  /* glutVideoResize(0, 0, winX, winY); */
428  glutFullScreen();
429  }
430 
431  GfParmReleaseHandle(handle);
432 
433  glutReshapeFunc( Reshape );
434 
435  checkGLFeatures();
436 }
437 
442 void GfScrShutdown(void)
443 {
444  if (usedGM) {
445  glutLeaveGameMode();
446  }
447 #if !defined(FREEGLUT) && !defined(WIN32)
448  if (usedFG) {
450  }
451 #endif
452 
453 #ifdef USE_RANDR_EXT
454  int i;
455  for (i = 0; i < nbRes; i++) {
456  free(Res[i]);
457  }
458  free(Res);
459 #endif // USE_RANDR_EXT
460 }
461 
462 
471 void GfScrGetSize(int *scrw, int *scrh, int *vieww, int *viewh)
472 {
473  *scrw = GfScrWidth;
474  *scrh = GfScrHeight;
475  *vieww = GfViewWidth;
476  *viewh = GfViewHeight;
477 }
478 
479 static void
481 {
482  int x, y, bpp;
483 
484  sscanf(Res[curRes], "%dx%d", &x, &y);
485  sscanf(Depthlist[curDepth], "%d", &bpp);
486 
487  const int BUFSIZE = 1024;
488  char buf[BUFSIZE];
489  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
490  void *paramHdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
491 
492  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_X, (char*)NULL, x);
493  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_Y, (char*)NULL, y);
494  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, x);
495  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, y);
496  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, bpp);
497  GfParmSetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_MAXREFRESH, (char*)NULL, curMaxFreq);
498 
500 
501  if (curMode == 0) {
502  GfParmSetStr(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, "yes");
503  } else {
504  GfParmSetStr(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, "no");
505  }
506  GfParmWriteFile(NULL, paramHdle, "Screen");
507  GfParmReleaseHandle(paramHdle);
508 }
509 
510 
511 void
512 GfScrReinit(void * /* dummy */)
513 {
514  int retcode = 0;
515  static const int CMDSIZE = 1024;
516  char cmd[CMDSIZE];
517 
518  stopMenuMusic();
519 
520 #ifndef WIN32
521  const char *arg[8];
522  int curArg;
523 #endif
524 
525  saveParams();
526 
527 #ifdef WIN32
528  snprintf(cmd, CMDSIZE, "%swtorcs.exe", GetLibDir());
529  int i;
530  for (i = 0; i < CMDSIZE && cmd[i] != NULL; i++) {
531  if (cmd[i] == '/') {
532  cmd[i] = '\\';
533  }
534  }
535 
536  char cmdarg[CMDSIZE];
537  snprintf(cmdarg, CMDSIZE, "\"%swtorcs.exe\"", GetLibDir());
538  for (i = 0; i < CMDSIZE && cmdarg[i] != NULL; i++) {
539  if (cmdarg[i] == '/') {
540  cmdarg[i] = '\\';
541  }
542  }
543 
544  retcode = execlp(cmd, cmdarg, (const char *)NULL);
545 #else
546  GfScrShutdown();
547 
548  snprintf (cmd, CMDSIZE, "%storcs-bin", GetLibDir ());
549  memset (arg, 0, sizeof (arg));
550  curArg = 0;
551  if (GfuiMouseHW) {
552  arg[curArg++] = "-m";
553  }
554 
555  if (strlen(GetLocalDir ())) {
556  arg[curArg++] = "-l";
557  arg[curArg++] = GetLocalDir();
558  }
559 
560  if (strlen(GetLibDir ())) {
561  arg[curArg++] = "-L";
562  arg[curArg++] = GetLibDir ();
563  }
564 
565  if (strlen(GetDataDir ())) {
566  arg[curArg++] = "-D";
567  arg[curArg++] = GetDataDir ();
568  }
569 
570  switch (curArg) {
571  case 0:
572  retcode = execlp (cmd, cmd, (const char *)NULL);
573  break;
574  case 1:
575  retcode = execlp (cmd, cmd, arg[0], (const char *)NULL);
576  break;
577  case 2:
578  retcode = execlp (cmd, cmd, arg[0], arg[1], (const char *)NULL);
579  break;
580  case 3:
581  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], (const char *)NULL);
582  break;
583  case 4:
584  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], arg[3], (const char *)NULL);
585  break;
586  case 5:
587  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], arg[3], arg[4], (const char *)NULL);
588  break;
589  case 6:
590  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], (const char *)NULL);
591  break;
592  case 7:
593  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], (const char *)NULL);
594  break;
595  case 8:
596  retcode = execlp (cmd, cmd, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], (const char *)NULL);
597  break;
598  }
599 
600 
601 #endif
602  if (retcode) {
603  perror("torcs");
604  exit(1);
605  }
606 }
607 
608 static void
610 {
614 #ifdef WIN32
615  const int BUFSIZE = 1024;
616  char buf[BUFSIZE];
617 
618  snprintf(buf, BUFSIZE, "%d", curMaxFreq);
619  GfuiEditboxSetString(scrHandle, MaxFreqId, buf);
620 #endif
622 }
623 
624 static void
625 ResPrevNext(void *vdelta)
626 {
627  long delta = (long)vdelta;
628  curRes += (int)delta;
629  if (curRes < 0) {
630  curRes = nbRes - 1;
631  } else {
632  if (curRes >= nbRes) {
633  curRes = 0;
634  }
635  }
636  updateLabelText();
637 }
638 
639 static void
640 DepthPrevNext(void *vdelta)
641 {
642  long delta = (long)vdelta;
643 
644  curDepth += (int)delta;
645  if (curDepth < 0) {
646  curDepth = nbDepth - 1;
647  } else {
648  if (curDepth >= nbDepth) {
649  curDepth = 0;
650  }
651  }
652  updateLabelText();
653 }
654 
655 static void
656 ModePrevNext(void *vdelta)
657 {
658  long delta = (long)vdelta;
659 
660  curMode += (int)delta;
661  if (curMode < 0) {
662  curMode = nbMode - 1;
663  } else {
664  if (curMode >= nbMode) {
665  curMode = 0;
666  }
667  }
668  updateLabelText();
669 }
670 
671 
672 static void
673 VInitPrevNext(void *vdelta)
674 {
675  long delta = (long)vdelta;
676 
677  curVInit += (int)delta;
678  if (curVInit < 0) {
679  curVInit = nbVInit - 1;
680  } else {
681  if (curVInit >= nbVInit) {
682  curVInit = 0;
683  }
684  }
685  updateLabelText();
686 }
687 
688 
689 static void
691 {
692  int x, y, bpp;
693  int i;
694  const int BUFSIZE = 1024;
695  char buf[BUFSIZE];
696 
697  snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GFSCR_CONF_FILE);
698  void *paramHdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
699 
700  x = (int)GfParmGetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_X, NULL, 640);
701  y = (int)GfParmGetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_Y, NULL, 480);
702 
703  snprintf(buf, BUFSIZE, "%dx%d", x, y);
704  for (i = 0; i < nbRes; i++) {
705  if (!strcmp(buf, Res[i])) {
706  curRes = i;
707  break;
708  }
709  }
710 
711  if (!strcmp("yes", GfParmGetStr(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, "yes"))) {
712  curMode = 0;
713  } else {
714  curMode = 1;
715  }
716 
717  curVInit = 0;
719  for (i = 0; i < nbVInit; i++) {
720  if (strcmp(VInit[i], tmp) == 0) {
721  curVInit = i;
722  break;
723  }
724  }
725 
726  bpp = (int)GfParmGetNum(paramHdle, GFSCR_SECT_PROP, GFSCR_ATT_BPP, NULL, 24);
727  snprintf(buf, BUFSIZE, "%d", bpp);
728  for (i = 0; i < nbDepth; i++) {
729  if (!strcmp(buf, Depthlist[i])) {
730  curDepth = i;
731  break;
732  }
733  }
734 
736  GfParmReleaseHandle(paramHdle);
737 }
738 
739 #ifdef WIN32
740 static void
741 ChangeMaxFreq(void * /* dummy */)
742 {
743  char *val;
744  const int BUFSIZE = 1024;
745  char buf[BUFSIZE];
746 
747  val = GfuiEditboxGetString(scrHandle, MaxFreqId);
748  curMaxFreq = (int)strtol(val, (char **)NULL, 0);
749  snprintf(buf, BUFSIZE, "%d", curMaxFreq);
750  GfuiEditboxSetString(scrHandle, MaxFreqId, buf);
751 }
752 #endif
753 
754 static void
755 onActivate(void * /* dummy */)
756 {
757  initFromConf();
758  updateLabelText();
759 }
760 
761 
766 void *
767 GfScrMenuInit(void *precMenu)
768 {
769  int y, x1, x2;
770 
771 #ifndef WIN32
772  const int yoffset1 = 30, yoffset2 = 60;
773 #else // WIN32
774  const int yoffset1 = 30, yoffset2 = 40;
775 #endif // WIN32
776 
777  if (scrHandle) return scrHandle;
778 
779  scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, onActivate, NULL, (tfuiCallback)NULL, 1);
780  GfuiTitleCreate(scrHandle, "Screen configuration", 0);
781  GfuiScreenAddBgImg(scrHandle, "data/img/splash-graphic.png");
782 
783  x1 = 200;
784  x2 = 440;
785  y = 400;
787  "Screen Resolution",
789  320, y, GFUI_ALIGN_HC_VB,
790  0);
791 
792  y -= yoffset1; //30;
794  "data/img/arrow-left.png",
795  "data/img/arrow-left.png",
796  "data/img/arrow-left.png",
797  "data/img/arrow-left-pushed.png",
798  x1, y, GFUI_ALIGN_HC_VB, 0,
799  (void*)-1, ResPrevNext,
800  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
801  GfuiAddSKey(scrHandle, GLUT_KEY_LEFT, "Previous Resolution", (void*)-1, ResPrevNext, NULL);
802 
804  "",
806  320, y, GFUI_ALIGN_HC_VB,
807  30);
809 
811  "data/img/arrow-right.png",
812  "data/img/arrow-right.png",
813  "data/img/arrow-right.png",
814  "data/img/arrow-right-pushed.png",
815  x2, y, GFUI_ALIGN_HC_VB, 0,
816  (void*)1, ResPrevNext,
817  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
818  GfuiAddSKey(scrHandle, GLUT_KEY_RIGHT, "Next Resolution", (void*)1, ResPrevNext, NULL);
819 
820  y -= yoffset2; //60;
822  "Color Depth",
824  320, y, GFUI_ALIGN_HC_VB,
825  0);
826  y -= yoffset1; //30;
828  "data/img/arrow-left.png",
829  "data/img/arrow-left.png",
830  "data/img/arrow-left.png",
831  "data/img/arrow-left-pushed.png",
832  x1, y, GFUI_ALIGN_HC_VB, 0,
833  (void*)-1, DepthPrevNext,
834  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
835 
837  "",
839  320, y, GFUI_ALIGN_HC_VB,
840  30);
842 
844  "data/img/arrow-right.png",
845  "data/img/arrow-right.png",
846  "data/img/arrow-right.png",
847  "data/img/arrow-right-pushed.png",
848  x2, y, GFUI_ALIGN_HC_VB, 0,
849  (void*)1, DepthPrevNext,
850  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
851 
852  y -= yoffset2; //60;
854  "Display Mode",
856  320, y, GFUI_ALIGN_HC_VB,
857  0);
858 
859  y -= yoffset1; //30;
861  "data/img/arrow-left.png",
862  "data/img/arrow-left.png",
863  "data/img/arrow-left.png",
864  "data/img/arrow-left-pushed.png",
865  x1, y, GFUI_ALIGN_HC_VB, 0,
866  (void*)-1, ModePrevNext,
867  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
868 
870  "",
872  320, y, GFUI_ALIGN_HC_VB,
873  30);
875 
877  "data/img/arrow-right.png",
878  "data/img/arrow-right.png",
879  "data/img/arrow-right.png",
880  "data/img/arrow-right-pushed.png",
881  x2, y, GFUI_ALIGN_HC_VB, 0,
882  (void*)1, ModePrevNext,
883  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
884  GfuiAddKey(scrHandle, 'f', "Display Mode", (void*)1, ModePrevNext, NULL);
885 
886 #ifdef WIN32
887  y -= yoffset2; //60;
889  "Max Frequency",
891  320, y, GFUI_ALIGN_HC_VB,
892  0);
893  y -= yoffset1; //30;
895  275, y, 0, 8, NULL, (tfuiCallback)NULL, ChangeMaxFreq);
896 #endif
897 
898  y -= yoffset2; //60;
900  "Video Mode Initialization",
902  320, y, GFUI_ALIGN_HC_VB,
903  0);
904  y -= yoffset1; //30;
906  "data/img/arrow-left.png",
907  "data/img/arrow-left.png",
908  "data/img/arrow-left.png",
909  "data/img/arrow-left-pushed.png",
910  x1, y, GFUI_ALIGN_HC_VB, 0,
911  (void*)-1, VInitPrevNext,
912  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
913 
915  "",
917  320, y, GFUI_ALIGN_HC_VB,
918  30);
920 
922  "data/img/arrow-right.png",
923  "data/img/arrow-right.png",
924  "data/img/arrow-right.png",
925  "data/img/arrow-right-pushed.png",
926  x2, y, GFUI_ALIGN_HC_VB, 0,
927  (void*)1, VInitPrevNext,
928  NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
929 
930 
931  GfuiAddKey(scrHandle, 13, "Apply Mode", NULL, GfScrReinit, NULL);
933  NULL, GfScrReinit, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
934 
935  GfuiAddKey(scrHandle, 27, "Cancel", precMenu, GfuiScreenActivate, NULL);
937  precMenu, GfuiScreenActivate, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
938 
939  return scrHandle;
940 }
941 
942 
943 
944 int GfuiGlutExtensionSupported(const char *str)
945 {
946  return glutExtensionSupported(str);
947 }
void gfScreenInit(void)
Definition: screen.cpp:131
int GfParmSetStr(void *handle, const char *path, const char *key, const char *val)
Set a string parameter in the parameter set handle.
Definition: params.cpp:2477
static void DepthPrevNext(void *vdelta)
Definition: screen.cpp:640
char * GfuiEditboxGetString(void *scr, int id)
Get the string.
Definition: guiedit.cpp:358
void * GfScrMenuInit(void *precMenu)
Create and activate the video options menu screen.
Definition: screen.cpp:767
#define GFUI_MOUSE_UP
Definition: tgfclient.h:80
static int curMode
Definition: screen.cpp:113
void fglutLeaveGameMode(void)
Definition: fg_gm.cpp:530
void * GfParmReadFile(const char *file, int mode)
Read parameter set from file and return handle to parameter set.
Definition: params.cpp:1157
static int GfScrHeight
Definition: screen.cpp:57
static int scrh
Definition: mouseconfig.cpp:50
int GfuiButtonCreate(void *scr, const char *text, int font, int x, int y, int width, int align, int mouse, void *userDataOnPush, tfuiCallback onPush, void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
Add a button to a screen.
Definition: guibutton.cpp:248
#define GFPARM_RMODE_STD
if handle already openned return it
Definition: tgf.h:265
static void updateLabelText(void)
Definition: screen.cpp:609
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
static int VInitLabelId
Definition: screen.cpp:125
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 GfuiLabelCreate(void *scr, const char *text, int font, int x, int y, int align, int maxlen)
Add a label to a screen.
Definition: guilabel.cpp:142
static void onActivate(void *)
Definition: screen.cpp:755
static char * Res[]
Definition: screen.cpp:74
#define GFSCR_ATT_VINIT
int GfuiEditboxCreate(void *scr, const char *text, int font, int x, int y, int width, int maxlen, void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost, int margin)
Add a editbox to a screen.
Definition: guiedit.cpp:57
void GfuiScreenAddBgImg(void *scr, const char *filename)
Add an image background to a screen.
Definition: gui.cpp:961
void checkGLFeatures(void)
Definition: glfeatures.cpp:152
static const int nbMode
Definition: screen.cpp:108
int GfParmWriteFile(const char *file, void *parmHandle, const char *name)
Write parameter set into file.
Definition: params.cpp:1610
static void ResPrevNext(void *vdelta)
Definition: screen.cpp:625
#define GFSCR_ATT_FSCR
#define GFSCR_VAL_VINIT_BEST
#define GFSCR_SECT_PROP
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition: params.cpp:2311
#define GFUI_FONT_LARGE_C
Definition: tgfclient.h:172
static void saveParams(void)
Definition: screen.cpp:480
#define GFSCR_ATT_MAXREFRESH
The Gaming Framework API (client part).
static char * strndup(const char *str, int len)
Definition: portability.h:39
#define GFSCR_VAL_VINIT_COMPATIBLE
#define GFUI_FONT_LARGE
Definition: tgfclient.h:168
static int GfViewWidth
Definition: screen.cpp:58
static int curRes
Definition: screen.cpp:112
void fglutGameModeString(const char *string)
Definition: fg_gm.cpp:469
void * GfuiScreenCreateEx(float *bgColor, void *userDataOnActivate, tfuiCallback onActivate, void *userDataOnDeactivate, tfuiCallback onDeactivate, int mouseAllowed)
Create a screen.
Definition: gui.cpp:578
static const char * Mode[]
Definition: screen.cpp:103
#define GFSCR_ATT_X
static int ModeLabelId
Definition: screen.cpp:124
void GfuiEditboxSetString(void *scr, int id, const char *text)
Set a new string.
Definition: guiedit.cpp:383
void GfuiLabelSetText(void *scr, int id, const char *text)
Change the text of a label.
Definition: guilabel.cpp:212
static int scrw
Definition: mouseconfig.cpp:50
char * GetLibDir(void)
Definition: tgf.cpp:244
static int GfScrCenX
Definition: screen.cpp:60
static const char * VInit[]
Definition: screen.cpp:104
char * GetDataDir(void)
Definition: tgf.cpp:257
#define GFSCR_ATT_WIN_X
static void initFromConf(void)
Definition: screen.cpp:690
int fglutEnterGameMode(void)
Definition: fg_gm.cpp:502
#define GfOut
Definition: tgf.h:373
static int ResLabelId
Definition: screen.cpp:122
static void * scrHandle
Definition: screen.cpp:63
#define GFSCR_ATT_WIN_Y
static int GfScrWidth
Definition: screen.cpp:56
void GfuiLabelSetColor(void *scr, int id, float *color)
Change the color of a label.
Definition: guilabel.cpp:239
static void ModePrevNext(void *vdelta)
Definition: screen.cpp:656
#define GFSCR_VAL_YES
static int curDepth
Definition: screen.cpp:114
void(* tfuiCallback)(void *)
Definition: tgfclient.h:105
void GfScrInit(int argc, char *argv[])
Definition: screen.cpp:261
void GfuiScreenActivate(void *screen)
Activate a screen and make it current.
Definition: gui.cpp:467
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
static int DepthLabelId
Definition: screen.cpp:123
static float LabelColor[]
Definition: screen.cpp:127
int GfParmSetNum(void *handle, const char *path, const char *key, const char *unit, tdble val)
Set a numerical parameter in the parameter set handle.
Definition: params.cpp:2586
#define GFUI_ALIGN_HC_VB
Definition: tgfclient.h:72
static int usedFG
Definition: screen.cpp:67
static int GfScrCenY
Definition: screen.cpp:61
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
static Vector y[4]
Definition: Convex.cpp:56
int GfuiTitleCreate(void *scr, const char *text, int maxlen)
Add a Title to the screen.
Definition: guilabel.cpp:170
static void Reshape(int width, int height)
Definition: screen.cpp:246
static const int nbDepth
Definition: screen.cpp:110
int GfuiGrButtonCreate(void *scr, const char *disabled, const char *enabled, const char *focused, const char *pushed, int x, int y, int align, int mouse, void *userDataOnPush, tfuiCallback onPush, void *userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost)
Add a graphical button to a screen.
Definition: guibutton.cpp:62
int GfuiMouseHW
Definition: gui.cpp:39
static const int nbVInit
Definition: screen.cpp:109
#define GFUI_FONT_MEDIUM_C
Definition: tgfclient.h:173
static int curVInit
Definition: screen.cpp:115
static int usedGM
Definition: screen.cpp:65
static int GfViewHeight
Definition: screen.cpp:59
static int curMaxFreq
Definition: screen.cpp:117
#define GFSCR_ATT_BPP
void GfScrShutdown(void)
Shutdown the screen.
Definition: screen.cpp:442
#define GFSCR_VAL_NO
void stopMenuMusic()
Definition: musicplayer.cpp:90
static const char * Depthlist[]
Definition: screen.cpp:105
void GfScrReinit(void *)
Definition: screen.cpp:512
int GfuiGlutExtensionSupported(const char *str)
Definition: screen.cpp:944
#define GFPARM_RMODE_CREAT
Create the file if doesn&#39;t exist.
Definition: tgf.h:267
static const int nbRes
Definition: screen.cpp:100
#define GFSCR_ATT_Y
static void VInitPrevNext(void *vdelta)
Definition: screen.cpp:673