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