+void glutGameModeString(const char *string)
+{
+ const char *p = string;
+ unsigned int minb = 15, maxb = 32;
+ unsigned int minw = 0, maxw = -1;
+ unsigned int minh, maxh = -1;
+ unsigned int minf = 0, maxf = MAX_VSYNC;
+ char *endptr;
+ int count = -1, val;
+
+ ModePossible = 0;
+
+ if(DisplayMode & GLUT_INDEX)
+ minb = maxb = 8;
+
+ again:
+ count++;
+ if((val = strtol(p, &endptr, 10)) && *endptr=='x') {
+ maxw = minw = val;
+ p = endptr + 1;
+ maxh = minh = strtol(p, &endptr, 10);
+ p = endptr;
+ goto again;
+ }
+
+ if(*p == ':') {
+ minb = strtol(p+1, &endptr, 10);
+ p = endptr;
+ if(DisplayMode & GLUT_INDEX) {
+ if(minb != 8)
+ return;
+ } else
+ if(minb != 15 && minb != 16 && minb != 24 && minb != 32)
+ return;
+ maxb = minb;
+ goto again;
+ }
+
+ if(*p == '@') {
+ minf = strtol(p+1, &endptr, 10) - 5;
+ maxf = minf + 10;
+ p = endptr;
+ goto again;
+ }
+
+ if(count == 0)
+ while(*p) {
+ if(*p == ' ')
+ p++;
+ else
+ if(memcmp(p, "bpp", 3) == 0)
+ p = SetOpers(p+3, &minb, &maxb);
+ else
+ if(memcmp(p, "height", 6) == 0)
+ p = SetOpers(p+6, &minh, &maxh);
+ else
+ if(memcmp(p, "hertz", 5) == 0)
+ p = SetOpers(p+5, &minf, &maxf);
+ else
+ if(memcmp(p, "width", 5) == 0)
+ p = SetOpers(p+5, &minw, &maxw);
+ else
+ if(p = strchr(p, ' '))
+ p++;
+ else
+ break;
+ }
+
+ NormVarInfo = VarInfo;
+ if(!ParseFBModes(minw, maxw, minh, maxh, minf, maxf))
+ return;
+
+ GameVarInfo = VarInfo;
+ VarInfo = NormVarInfo;
+
+ /* determine optimal bitdepth, make sure we have enough video memory */
+ if(VarInfo.bits_per_pixel && VarInfo.bits_per_pixel <= maxb)
+ GameVarInfo.bits_per_pixel = VarInfo.bits_per_pixel;
+ else
+ GameVarInfo.bits_per_pixel = maxb;
+
+ while(FixedInfo.smem_len < GameVarInfo.xres * GameVarInfo.yres
+ * GameVarInfo.bits_per_pixel / 8) {
+ if(GameVarInfo.bits_per_pixel < minb)
+ return;
+ GameVarInfo.bits_per_pixel = ((GameVarInfo.bits_per_pixel+1)/8)*8-8;
+ }
+
+ ModePossible = 1;
+}
+