diff --git a/polymer/build/devcpp/Build.dev b/polymer/build/devcpp/Build.dev
index 6c9c7e729..4cd104380 100644
--- a/polymer/build/devcpp/Build.dev
+++ b/polymer/build/devcpp/Build.dev
@@ -6,13 +6,13 @@ Type=0
 Ver=1
 ObjFiles=
 Includes=..\include
-Libs=C:\sdks\msc\dx7\include
+Libs=C:\sdks\directx\dx7\include
 PrivateResource=Build_private.rc
-ResourceIncludes=..\
+ResourceIncludes=..\;..\include
 MakeIncludes=
-Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_
+Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_-fno-strict-aliasing_@@_
 CppCompiler=
-Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_
+Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_-lcomctl32_@@_
 IsCpp=0
 Icon=
 ExeOutput=..\devcpp
@@ -48,17 +48,8 @@ ProductVersion=
 AutoIncBuildNr=0
 
 [Unit1]
-FileName=..\src\bstub.c
-CompileCpp=0
-Folder=KenBuild Editor
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
-[Unit2]
 FileName=..\src\misc\buildres.rc
+CompileCpp=0
 Folder=KenBuild Editor
 Compile=1
 Link=0
@@ -66,3 +57,13 @@ Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
 
+[Unit2]
+FileName=..\testgame\bstub.c
+Folder=KenBuild Editor
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+CompileCpp=0
+
diff --git a/polymer/build/devcpp/Game.dev b/polymer/build/devcpp/Game.dev
index b4b498a11..003052106 100644
--- a/polymer/build/devcpp/Game.dev
+++ b/polymer/build/devcpp/Game.dev
@@ -5,14 +5,14 @@ UnitCount=5
 Type=0
 Ver=1
 ObjFiles=
-Includes=..\include;C:\sdks\fmodapi373win\api\inc
-Libs=C:\sdks\msc\dx7\include;C:\sdks\fmodapi373win\api\lib
+Includes=..\include;..\testgame;..\..\jfaud\inc
+Libs=C:\sdks\directx\dx7\include;..\..\jfaud
 PrivateResource=Game_private.rc
-ResourceIncludes=..\
+ResourceIncludes=..\;..\testgame
 MakeIncludes=
-Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_
+Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-funsigned-char_@@_-fno-strict-aliasing_@@_
 CppCompiler=
-Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_-lfmod_@@_
+Linker=libeditor.a_@@_libengine.a_@@_-ldxguid_@@_-lws2_32_@@_-lsupc++_@@_-lcomctl32_@@_-ljfaud_@@_-lwinmm_@@_
 IsCpp=0
 Icon=
 ExeOutput=..\devcpp
@@ -48,9 +48,9 @@ ProductVersion=
 AutoIncBuildNr=0
 
 [Unit3]
-FileName=..\src\sound.c
+FileName=..\testgame\startwin.game.c
 CompileCpp=0
-Folder=KenBuild Editor
+Folder=KenBuild Game
 Compile=1
 Link=1
 Priority=1000
@@ -58,13 +58,14 @@ OverrideBuildCmd=0
 BuildCmd=
 
 [Unit4]
-FileName=..\src\misc\gameres.rc
+FileName=..\testgame\jfaud_sound.cpp
 Folder=KenBuild Game
 Compile=1
-Link=0
+Link=1
 Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
+CompileCpp=0
 
 [Unit1]
 FileName=..\src\config.c
@@ -76,18 +77,8 @@ Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
 
-[Unit2]
-FileName=..\src\game.c
-CompileCpp=0
-Folder=KenBuild Editor
-Compile=1
-Link=1
-Priority=1000
-OverrideBuildCmd=0
-BuildCmd=
-
 [Unit5]
-FileName=..\src\gamestartwin.c
+FileName=..\testgame\game.c
 CompileCpp=0
 Folder=KenBuild Game
 Compile=1
@@ -96,3 +87,22 @@ Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
 
+[Unit6]
+FileName=..\testgame\game.c
+CompileCpp=0
+Folder=KenBuild Game
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\src\misc\gameres.rc
+Folder=KenBuild Game
+Compile=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/polymer/build/devcpp/engineinfo.c b/polymer/build/devcpp/engineinfo.c
deleted file mode 100644
index 71cd27509..000000000
--- a/polymer/build/devcpp/engineinfo.c
+++ /dev/null
@@ -1,5 +0,0 @@
-const char _engine_cflags[] = "Dev-C++ made this";
-const char _engine_libs[] = "Dev-C++ made this";
-const char _engine_uname[] = "Dev-C++";
-const char _engine_compiler[] = "Dev-C++";
-const char _engine_date[] = __DATE__ " " __TIME__;
diff --git a/polymer/build/devcpp/libEditor.dev b/polymer/build/devcpp/libEditor.dev
index c297369be..09185d6b4 100644
--- a/polymer/build/devcpp/libEditor.dev
+++ b/polymer/build/devcpp/libEditor.dev
@@ -48,9 +48,9 @@ ProductVersion=
 AutoIncBuildNr=0
 
 [Unit3]
-FileName=..\src\buildstartwin.c
+FileName=..\src\startwin.editor.c
 CompileCpp=0
-Folder=KenBuild Editor
+Folder=Build Editor library
 Compile=1
 Link=1
 Priority=1000
diff --git a/polymer/build/devcpp/libEngine.dev b/polymer/build/devcpp/libEngine.dev
index 2e9adace8..40a74b500 100644
--- a/polymer/build/devcpp/libEngine.dev
+++ b/polymer/build/devcpp/libEngine.dev
@@ -1,16 +1,16 @@
 [Project]
 FileName=libEngine.dev
 Name=Build Engine library
-UnitCount=15
+UnitCount=18
 Type=2
 Ver=1
 ObjFiles=
-Includes=..\include;..\src;C:\sdks\msc\dx7\include
+Includes=..\include;..\src;C:\sdks\directx\dx7\include
 Libs=
 PrivateResource=
 ResourceIncludes=
 MakeIncludes=
-Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-DKSFORBUILD_@@_-funsigned-char_@@_
+Compiler=-DRENDERTYPEWIN=1_@@_-DSUPERBUILD_@@_-DPOLYMOST_@@_-DUSE_OPENGL_@@_-DDYNAMIC_OPENGL_@@_-DNO_GCC_BUILTINS_@@_-DUNDERSCORES_@@_-DKSFORBUILD_@@_-funsigned-char_@@_-fno-strict-aliasing_@@_
 CppCompiler=
 Linker=
 IsCpp=0
@@ -196,3 +196,33 @@ Priority=1000
 OverrideBuildCmd=0
 BuildCmd=
 
+[Unit16]
+FileName=..\src\md4.c
+CompileCpp=0
+Folder=Build Engine library
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit17]
+FileName=..\src\lzf_d.c
+CompileCpp=0
+Folder=Build Engine library
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit18]
+FileName=..\src\lzf_c.c
+CompileCpp=0
+Folder=Build Engine library
+Compile=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h
index 857bb0a59..c0ed07520 100644
--- a/polymer/build/include/build.h
+++ b/polymer/build/include/build.h
@@ -355,6 +355,7 @@ OTHER VARIABLES:
             you call the loadboard function.
 ***************************************************************************/
 
+int    preinitengine(void);	// a partial setup of the engine used for launch windows
 int    initengine(void);
 void   uninitengine(void);
 void   initspritelists(void);
diff --git a/polymer/build/include/scriptfile.h b/polymer/build/include/scriptfile.h
index 01557f2f6..c27c46d2d 100644
--- a/polymer/build/include/scriptfile.h
+++ b/polymer/build/include/scriptfile.h
@@ -20,6 +20,7 @@ int scriptfile_getbraces(scriptfile *sf, char **braceend);
 scriptfile *scriptfile_fromfile(char *fn);
 scriptfile *scriptfile_fromstring(char *string);
 void scriptfile_close(scriptfile *sf);
+int scriptfile_eof(scriptfile *sf);
 
 int scriptfile_getsymbolvalue(char *name, int *val);
 int scriptfile_addsymbolvalue(char *name, int val);
diff --git a/polymer/build/src/engine.c b/polymer/build/src/engine.c
index 38a162a0f..0d38726e2 100644
--- a/polymer/build/src/engine.c
+++ b/polymer/build/src/engine.c
@@ -5454,13 +5454,38 @@ static void sighandler(int sig, const siginfo_t *info, void *ctx)
 }
 #endif
 
+//
+// preinitengine
+//
+static int preinitcalled = 0;
+int preinitengine(void)
+{
+	char *e;
+	if (initsystem()) exit(1);
+
+	if ((e = Bgetenv("BUILD_NOP6")) != NULL)
+		if (!Bstrcasecmp(e, "TRUE")) {
+			Bprintf("Disabling P6 optimizations.\n");
+			dommxoverlay = 0;
+		}
+	if (dommxoverlay) mmxoverlay();
+
+	validmodecnt = 0;
+	getvalidmodes();
+
+	initcrc32table();
+
+	preinitcalled = 1;
+	return 0;
+}
+
+
 //
 // initengine
 //
 int initengine(void)
 {
     long i, j;
-    char *e;
 
 #if !defined _WIN32 && defined DEBUGGINGAIDS
     struct sigaction sigact, oldact;
@@ -5469,16 +5494,11 @@ int initengine(void)
     sigact.sa_flags = SA_SIGINFO;
     sigaction(SIGFPE, &sigact, &oldact);
 #endif
-
-    if (initsystem()) exit(1);
-
-    if ((e = Bgetenv("BUILD_NOP6")) != NULL)
-        if (!Bstrcasecmp(e, "TRUE")) {
-            Bprintf("Disabling P6 optimizations.\n");
-            dommxoverlay = 0;
-        }
-    if (dommxoverlay) mmxoverlay();
-
+	if (!preinitcalled) {
+		i = preinitengine();
+		if (i) return i;
+	}
+	
     if (loadtables()) return 1;
 
     xyaspect = -1;
@@ -5518,8 +5538,6 @@ int initengine(void)
     clearbuf(&show2dwall[0],(long)((MAXWALLS+3)>>5),0L);
     automapping = 0;
 
-    validmodecnt = 0;
-
     pointhighlight = -1;
     linehighlight = -1;
     highlightcnt = 0;
@@ -5531,14 +5549,11 @@ int initengine(void)
     captureformat = 0;
 
     loadpalette();
-    getvalidmodes();
 #if defined(POLYMOST) && defined(USE_OPENGL)
     if (!hicfirstinit) hicinit();
     if (!mdinited) mdinit();
 #endif
 
-    initcrc32table();
-
     return 0;
 }
 
diff --git a/polymer/build/src/scriptfile.c b/polymer/build/src/scriptfile.c
index deb6b1d03..4fbded1b9 100644
--- a/polymer/build/src/scriptfile.c
+++ b/polymer/build/src/scriptfile.c
@@ -321,6 +321,12 @@ void scriptfile_close(scriptfile *sf)
     free(sf);
 }
 
+int scriptfile_eof(scriptfile *sf)
+{
+	skipoverws(sf);
+	if (sf->textptr >= sf->eof) return 1;
+	return 0;
+}
 
 #define SYMBTABSTARTSIZE 256
 static int symbtablength=0, symbtaballoclength=0;
diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile
index 69e258d41..013539acc 100644
--- a/polymer/eduke32/Makefile
+++ b/polymer/eduke32/Makefile
@@ -106,7 +106,7 @@ EDITOROBJS=$(OBJ)astub.$o
 ifeq ($(PLATFORM),WINDOWS)
 	OURCFLAGS+= -DUNDERSCORES -I$(DXROOT)/include
 	NASMFLAGS+= -DUNDERSCORES -f win32
-	GAMEOBJS+= $(OBJ)gameres.$o $(OBJ)winbits.$o $(OBJ)startwin.game.$o
+	GAMEOBJS+= $(OBJ)gameres.$o $(OBJ)winbits.$o $(OBJ)startwin.game.$o $(OBJ)startdlg.$o
 	EDITOROBJS+= $(OBJ)buildres.$o
 endif
 
@@ -121,7 +121,7 @@ ifeq ($(RENDERTYPE),SDL)
 
 	ifeq (1,$(HAVE_GTK2))
 		OURCFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0)
-        GAMEOBJS+= $(OBJ)game_banner.$o $(OBJ)startgtk.game.$o
+		GAMEOBJS+= $(OBJ)game_banner.$o $(OBJ)startgtk.game.$o $(OBJ)startdlg.$o
 		EDITOROBJS+= $(OBJ)editor_banner.$o
 	endif
 
diff --git a/polymer/eduke32/Makefile.deps b/polymer/eduke32/Makefile.deps
index dbfaf4126..f418cf433 100644
--- a/polymer/eduke32/Makefile.deps
+++ b/polymer/eduke32/Makefile.deps
@@ -27,9 +27,12 @@ $(OBJ)astub.$o: $(SRC)astub.c $(EINC)build.h $(EINC)pragmas.h $(EINC)compat.h $(
 $(OBJ)game_icon.$o: $(RSRC)game_icon.c
 $(OBJ)build_icon.$o: $(RSRC)build_icon.c
 
+$(OBJ)startdlg.$o: $(SRC)startdlg.c $(EINC)compat.h $(EINC)baselayer.h $(EINC)scriptfile.h $(EINC)cache1d.h $(EINC)crc32.h $(INC)startdlg.h
 $(OBJ)gameres.$o: $(SRC)misc/gameres.rc $(SRC)startwin.game.h $(RSRC)game.bmp $(RSRC)game_icon.ico
 $(OBJ)buildres.$o: $(SRC)misc/buildres.rc $(EINC)startwin.editor.h $(RSRC)build.bmp $(RSRC)build_icon.ico
-$(OBJ)startwin.game.$o: $(SRC)startwin.game.c $(duke3d_h) $(EINC)build.h $(EINC)winlayer.h $(EINC)compat.h
+$(OBJ)startwin.game.$o: $(SRC)startwin.game.c $(duke3d_h) $(EINC)build.h $(EINC)winlayer.h $(EINC)compat.h $(INC)startdlg.h
+$(OBJ)startgtk.game.$o: $(SRC)startgtk.game.c $(duke3d_h) $(EINC)dynamicgtk.h $(EINC)build.h $(EINC)baselayer.h $(EINC)compat.h
+
 
 # jMACT objects
 $(OBJ)animlib.$o: $(SRC)jmact/animlib.c $(SRC)jmact/types.h $(INC)develop.h $(SRC)jmact/util_lib.h $(SRC)jmact/animlib.h $(EINC)compat.h
diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c
index e5b3adaa3..ad92d2c69 100644
--- a/polymer/eduke32/source/game.c
+++ b/polymer/eduke32/source/game.c
@@ -127,7 +127,7 @@ void pitch_test( void );
 char restorepalette,screencapt,nomorelogohack;
 int sendmessagecommand = -1;
 
-static char *duke3dgrp = "duke3d.grp";  // JBF 20030925
+char *duke3dgrp = "duke3d.grp";  // JBF 20030925
 static char *duke3ddef = "duke3d.def";
 
 extern long lastvisinc;
@@ -7763,7 +7763,6 @@ void checkcommandline(int argc,char **argv)
             if (((*c == '/') || (*c == '-')) && (!firstnet))
             {
                 if (!Bstrcasecmp(c+1,"setup")) {
-                    CommandSetup = 1;
                     i++;
                     continue;
                 }
@@ -7927,23 +7926,12 @@ void checkcommandline(int argc,char **argv)
                 continue;
             }
 
-
-            if(*c == '?')
-            {
-                comlinehelp(argv);
-                exit(-1);
-            }
-
             if((*c == '/') || (*c == '-'))
             {
                 c++;
                 switch(*c)
                 {
-                default:
-                    //                      printf("Unknown command line parameter '%s'\n",argv[i]);
-                case '?':
-                    comlinehelp(argv);
-                    exit(0);
+                default: break;
                 case 'x':
                 case 'X':
                     c++;
@@ -8525,7 +8513,7 @@ void Startup(void)
 
     compilecons();
 
-    i = CONFIG_ReadSetup();
+    //    i = CONFIG_ReadSetup();
 
     if (initengine()) {
         wm_msgbox("Build Engine Initialisation Error",
@@ -8534,16 +8522,6 @@ void Startup(void)
         exit(1);
     }
 
-#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2)
-    if (i < 0 || (netparamcount == 0 && ForceSetup) || CommandSetup) {
-        if (quitevent | !startwin_run()) {
-            uninitengine();
-            freeconmem();
-            exit(0);
-        }
-    }
-#endif
-
     setupdynamictostatic();
 
     if (ud.multimode > 1) sanitizegametype();
@@ -8814,8 +8792,6 @@ void backtomenu(void)
 
 int shareware = 0;
 
-char *startwin_labeltext = "Starting EDuke32...";
-
 int load_script(char *szScript)
 {
     FILE* fp = fopenfrompath(szScript, "r");
@@ -8888,6 +8864,34 @@ void app_main(int argc,char **argv)
         duke3dgrp = getenv("DUKE3DGRP");
         initprintf("Using `%s' as main GRP file\n", duke3dgrp);
     }
+
+    for (i=1;i<argc;i++) {
+        if (argv[i][0] != '-' && argv[i][0] != '/') continue;
+        if (!Bstrcasecmp(argv[i]+1, "setup")) CommandSetup = TRUE;
+        else if (!Bstrcasecmp(argv[i]+1, "?")) {
+            comlinehelp(argv);
+            exit(0);
+        }
+    }
+
+    wm_setapptitle("EDuke32");
+    if (preinitengine()) {
+        wm_msgbox("Build Engine Initialisation Error",
+                  "There was a problem initialising the Build engine: %s", engineerrstr);
+        exit(1);
+    }
+
+    i = CONFIG_ReadSetup();
+
+#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2)
+    if (i < 0 || ForceSetup || CommandSetup) {
+        if (quitevent || !startwin_run()) {
+            uninitengine();
+            exit(0);
+        }
+    }
+#endif
+
     initgroupfile(duke3dgrp);
     i = kopen4load("DUKESW.BIN",1); // JBF 20030810
     if (i!=-1) {
diff --git a/polymer/eduke32/source/misc/gameres.rc b/polymer/eduke32/source/misc/gameres.rc
index 736573630..a7020b4fa 100644
--- a/polymer/eduke32/source/misc/gameres.rc
+++ b/polymer/eduke32/source/misc/gameres.rc
@@ -33,8 +33,6 @@ BEGIN
 	CONTROL "",               IDCSOUNDDRV, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_DISABLED | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 26, 110, 56
 	CONTROL "&MIDI device:",  -1, "STATIC", SS_LEFT | WS_CHILD | WS_DISABLED | WS_VISIBLE, 5, 44, 50, 8
 	CONTROL "",               IDCMIDIDEV, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_DISABLED | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 42, 110, 56
-	CONTROL "C&D drive:",     -1, "STATIC", SS_LEFT | WS_CHILD | WS_DISABLED | WS_VISIBLE, 5, 60, 50, 8
-	CONTROL "",               IDCCDADEV, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_DISABLED | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 58, 40, 56
 
 	CONTROL "Input devices:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 80, 50, 8
 	CONTROL "Mo&use",         IDCINPUTMOUSE, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 80, 49, 8
@@ -43,4 +41,13 @@ BEGIN
 	CONTROL "&Always show configuration on start", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
 END
 
+WIN_STARTWINPAGE_GAME DIALOGEX DISCARDABLE 20, 40, 279, 168
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg"
+BEGIN
+	CONTROL "&Game or addon:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 5, 100, 8
+	CONTROL "",                IDGDATA, "LISTBOX", LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS | LBS_SORT | WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP, 10, 15, 226, 50
+END
+
 1 24 "rsrc/manifest.game.xml"
diff --git a/polymer/eduke32/source/startdlg.c b/polymer/eduke32/source/startdlg.c
new file mode 100755
index 000000000..61942c063
--- /dev/null
+++ b/polymer/eduke32/source/startdlg.c
@@ -0,0 +1,180 @@
+#include "compat.h"
+#include "baselayer.h"
+
+#include "scriptfile.h"
+#include "cache1d.h"
+#include "crc32.h"
+
+#include "startdlg.h"
+
+struct grpfile grpfiles[numgrpfiles] = {
+                                           { "Registered Version 1.3d",	0xBBC9CE44, 26524524, NULL },
+                                           { "Registered Version 1.4",	0x00000000, 0, NULL },
+                                           { "Registered Version 1.5",	0xFD3DCFF1, 44356548, NULL },
+                                           { "Shareware Version",		0x983AD923, 11035779, NULL },
+                                           { "Mac Shareware Version",	0xC5F71561, 10444391, NULL },
+                                           { "Mac Registered Version",     0x00000000, 0, NULL },
+                                       };
+struct grpfile *foundgrps = NULL;
+
+#define GRPCACHEFILE "grpfiles.cache"
+static struct grpcache {
+    struct grpcache *next;
+    char name[BMAX_PATH+1];
+    int size;
+    int mtime;
+    int crcval;
+} *grpcache = NULL, *usedgrpcache = NULL;
+
+static int LoadGroupsCache(void)
+{
+    struct grpcache *fg;
+
+    int fsize, fmtime, fcrcval;
+    char *fname;
+
+    scriptfile *script;
+
+    script = scriptfile_fromfile(GRPCACHEFILE);
+    if (!script) return -1;
+
+    while (!scriptfile_eof(script)) {
+        if (scriptfile_getstring(script, &fname)) break;	// filename
+        if (scriptfile_getnumber(script, &fsize)) break;	// filesize
+        if (scriptfile_getnumber(script, &fmtime)) break;	// modification time
+        if (scriptfile_getnumber(script, &fcrcval)) break;	// crc checksum
+
+        fg = calloc(1, sizeof(struct grpcache));
+        fg->next = grpcache;
+        grpcache = fg;
+
+        strncpy(fg->name, fname, BMAX_PATH);
+        fg->size = fsize;
+        fg->mtime = fmtime;
+        fg->crcval = fcrcval;
+    }
+
+    scriptfile_close(script);
+    return 0;
+}
+
+static void FreeGroupsCache(void)
+{
+    struct grpcache *fg;
+
+    while (grpcache) {
+        fg = grpcache->next;
+        free(grpcache);
+        grpcache = fg;
+    }
+}
+
+int ScanGroups(void)
+{
+    CACHE1D_FIND_REC *srch, *sidx;
+    struct grpcache *fg, *fgg;
+    struct grpfile *grp;
+    char *fn;
+    struct Bstat st;
+
+    initprintf("Scanning for GRP files...\n");
+
+    LoadGroupsCache();
+
+    srch = klistpath("/", "*.grp", CACHE1D_FIND_FILE);
+
+    for (sidx = srch; sidx; sidx = sidx->next) {
+        for (fg = grpcache; fg; fg = fg->next) {
+            if (!Bstrcmp(fg->name, sidx->name)) break;
+        }
+
+        if (fg) {
+            if (findfrompath(sidx->name, &fn)) continue;	// failed to resolve the filename
+        if (Bstat(fn, &st)) { free(fn); continue; }	// failed to stat the file
+            free(fn);
+            if (fg->size == st.st_size && fg->mtime == st.st_mtime) {
+                grp = (struct grpfile *)calloc(1, sizeof(struct grpfile));
+                grp->name = strdup(sidx->name);
+                grp->crcval = fg->crcval;
+                grp->size = fg->size;
+                grp->next = foundgrps;
+                foundgrps = grp;
+
+                fgg = (struct grpcache *)calloc(1, sizeof(struct grpcache));
+                strcpy(fgg->name, fg->name);
+                fgg->size = fg->size;
+                fgg->mtime = fg->mtime;
+                fgg->crcval = fg->crcval;
+                fgg->next = usedgrpcache;
+                usedgrpcache = fgg;
+                continue;
+            }
+        }
+
+        {
+            int b, fh;
+            int crcval;
+            char buf[16*512];
+
+            fh = openfrompath(sidx->name, BO_RDONLY|BO_BINARY, BS_IREAD);
+            if (fh < 0) continue;
+            if (fstat(fh, &st)) continue;
+
+            initprintf(" Checksumming %s...", sidx->name);
+            crc32init((unsigned long *)&crcval);
+            do {
+                b = read(fh, buf, sizeof(buf));
+                if (b > 0) crc32block((unsigned long *)&crcval, buf, b);
+            } while (b == sizeof(buf));
+            crc32finish((unsigned long *)&crcval);
+            close(fh);
+            initprintf(" Done\n");
+
+            grp = (struct grpfile *)calloc(1, sizeof(struct grpfile));
+            grp->name = strdup(sidx->name);
+            grp->crcval = crcval;
+            grp->size = st.st_size;
+            grp->next = foundgrps;
+            foundgrps = grp;
+
+            fgg = (struct grpcache *)calloc(1, sizeof(struct grpcache));
+            strncpy(fgg->name, sidx->name, BMAX_PATH);
+            fgg->size = st.st_size;
+            fgg->mtime = st.st_mtime;
+            fgg->crcval = crcval;
+            fgg->next = usedgrpcache;
+            usedgrpcache = fgg;
+        }
+    }
+
+    klistfree(srch);
+    FreeGroupsCache();
+
+    if (usedgrpcache) {
+        FILE *fp;
+        fp = fopen(GRPCACHEFILE, "wt");
+        if (fp) {
+            for (fg = usedgrpcache; fg; fg=fgg) {
+                fgg = fg->next;
+                fprintf(fp, "\"%s\" %d %d %d\n", fg->name, fg->size, fg->mtime, fg->crcval);
+                free(fg);
+            }
+            fclose(fp);
+        }
+    }
+
+    return 0;
+}
+
+void FreeGroups(void)
+{
+    struct grpfile *fg;
+
+    while (foundgrps) {
+        fg = foundgrps->next;
+        free((char*)foundgrps->name);
+        free(foundgrps);
+        foundgrps = fg;
+    }
+}
+
diff --git a/polymer/eduke32/source/startdlg.h b/polymer/eduke32/source/startdlg.h
new file mode 100755
index 000000000..f15da2f08
--- /dev/null
+++ b/polymer/eduke32/source/startdlg.h
@@ -0,0 +1,12 @@
+// List of internally-known GRP files
+#define numgrpfiles 6
+struct grpfile {
+	const char *name;
+	int crcval;
+	int size;
+	struct grpfile *next;
+} grpfiles[numgrpfiles], *foundgrps;
+
+int ScanGroups(void);
+void FreeGroups(void);
+
diff --git a/polymer/eduke32/source/startgtk.game.c b/polymer/eduke32/source/startgtk.game.c
index 5f4bf241c..789017056 100755
--- a/polymer/eduke32/source/startgtk.game.c
+++ b/polymer/eduke32/source/startgtk.game.c
@@ -28,10 +28,10 @@
 #define TAB_MESSAGES 1
 
 static struct {
-	int fullscreen;
-	int xdim3d, ydim3d, bpp3d;
-	int forcesetup;
-	int usemouse, usejoy;
+    int fullscreen;
+    int xdim3d, ydim3d, bpp3d;
+    int forcesetup;
+    int usemouse, usejoy;
 } settings;
 
 extern int gtkenabled;
@@ -53,104 +53,104 @@ static int retval = -1, mode = TAB_MESSAGES;
 
 static GdkPixbuf *load_banner(void)
 {
-	extern const GdkPixdata startbanner_pixdata;
-	return gdk_pixbuf_from_pixdata(&startbanner_pixdata, FALSE, NULL);
+    extern const GdkPixdata startbanner_pixdata;
+    return gdk_pixbuf_from_pixdata(&startbanner_pixdata, FALSE, NULL);
 }
 
 static void SetPage(int n)
 {
-	if (!gtkenabled || !startwin) return;
-	mode = n;
-	gtk_notebook_set_current_page(GTK_NOTEBOOK(lookup_widget(startwin,"tabs")), n);
+    if (!gtkenabled || !startwin) return;
+    mode = n;
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(lookup_widget(startwin,"tabs")), n);
 
-	// each control in the config page vertical layout plus the start button should be made (in)sensitive
-	if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
-	gtk_widget_set_sensitive(lookup_widget(startwin,"startbutton"), n);
-	gtk_container_foreach(GTK_CONTAINER(lookup_widget(startwin,"configvlayout")),
-			(GtkCallback)gtk_widget_set_sensitive, (gpointer)n);
+    // each control in the config page vertical layout plus the start button should be made (in)sensitive
+    if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
+    gtk_widget_set_sensitive(lookup_widget(startwin,"startbutton"), n);
+    gtk_container_foreach(GTK_CONTAINER(lookup_widget(startwin,"configvlayout")),
+                          (GtkCallback)gtk_widget_set_sensitive, (gpointer)n);
 }
 
 static void on_vmode3dcombo_changed(GtkComboBox *, gpointer);
 static void PopulateForm(void)
 {
-	int mode3d, i;
-	GtkListStore *modes3d;
-	GtkTreeIter iter;
-	GtkComboBox *box3d;
-	char buf[64];
+    int mode3d, i;
+    GtkListStore *modes3d;
+    GtkTreeIter iter;
+    GtkComboBox *box3d;
+    char buf[64];
 
-	mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
-	if (mode3d < 0) {
-		int i, cd[] = { 32, 24, 16, 15, 8, 0 };
-		for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; }
-		for ( ; cd[i]; i++) {
-			mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
-			if (mode3d < 0) continue;
-			settings.bpp3d = cd[i];
-			break;
-		}
-	}
+    mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
+    if (mode3d < 0) {
+        int i, cd[] = { 32, 24, 16, 15, 8, 0 };
+        for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; }
+        for ( ; cd[i]; i++) {
+            mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
+            if (mode3d < 0) continue;
+            settings.bpp3d = cd[i];
+            break;
+        }
+    }
 
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"fullscreencheck")), settings.fullscreen);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"alwaysshowcheck")), settings.forcesetup);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"fullscreencheck")), settings.fullscreen);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"alwaysshowcheck")), settings.forcesetup);
 
-	box3d = GTK_COMBO_BOX(lookup_widget(startwin,"vmode3dcombo"));
-	modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(box3d));
-	gtk_list_store_clear(modes3d);
+    box3d = GTK_COMBO_BOX(lookup_widget(startwin,"vmode3dcombo"));
+    modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(box3d));
+    gtk_list_store_clear(modes3d);
 
-	for (i=0; i<validmodecnt; i++) {
-		if (validmode[i].fs != settings.fullscreen) continue;
+    for (i=0; i<validmodecnt; i++) {
+        if (validmode[i].fs != settings.fullscreen) continue;
 
-		// all modes get added to the 3D mode list
-		Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
-		gtk_list_store_append(modes3d, &iter);
-		gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
-		if (i == mode3d) {
-			g_signal_handlers_block_by_func(box3d, on_vmode3dcombo_changed, NULL);
-			gtk_combo_box_set_active_iter(box3d, &iter);
-			g_signal_handlers_unblock_by_func(box3d, on_vmode3dcombo_changed, NULL);
-		}
-	}
+        // all modes get added to the 3D mode list
+        Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
+        gtk_list_store_append(modes3d, &iter);
+        gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
+        if (i == mode3d) {
+            g_signal_handlers_block_by_func(box3d, on_vmode3dcombo_changed, NULL);
+            gtk_combo_box_set_active_iter(box3d, &iter);
+            g_signal_handlers_unblock_by_func(box3d, on_vmode3dcombo_changed, NULL);
+        }
+    }
 
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputmousecheck")), settings.usemouse);
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputjoycheck")), settings.usejoy);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputmousecheck")), settings.usemouse);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputjoycheck")), settings.usejoy);
 }
 
 // -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
 
 static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
 {
-	GtkTreeModel *data;
-	GtkTreeIter iter;
-	int val;
-	if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
-	if (!(data = gtk_combo_box_get_model(combobox))) return;
-	gtk_tree_model_get(data, &iter, 1, &val, -1);
-	settings.xdim3d = validmode[val].xdim;
-	settings.ydim3d = validmode[val].ydim;
+    GtkTreeModel *data;
+    GtkTreeIter iter;
+    int val;
+    if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
+    if (!(data = gtk_combo_box_get_model(combobox))) return;
+    gtk_tree_model_get(data, &iter, 1, &val, -1);
+    settings.xdim3d = validmode[val].xdim;
+    settings.ydim3d = validmode[val].ydim;
 }
 
 static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	settings.fullscreen = (gtk_toggle_button_get_active(togglebutton) == TRUE);
-	PopulateForm();
+    settings.fullscreen = (gtk_toggle_button_get_active(togglebutton) == TRUE);
+    PopulateForm();
 }
 
 static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	settings.forcesetup = (gtk_toggle_button_get_active(togglebutton) == TRUE);
+    settings.forcesetup = (gtk_toggle_button_get_active(togglebutton) == TRUE);
 }
 
 static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
 {
-	if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
-	else quitevent++;
+    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
+    else quitevent++;
 }
 
 static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
 {
-	retval = 1;
-	gtk_main_quit();
+    retval = 1;
+    gtk_main_quit();
 }
 
 static void on_sounddrvcombo_changed(GtkComboBox *combobox, gpointer user_data)
@@ -159,466 +159,464 @@ static void on_sounddrvcombo_changed(GtkComboBox *combobox, gpointer user_data)
 
 static void on_inputmousecheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	settings.usemouse = (gtk_toggle_button_get_active(togglebutton) == TRUE);
+    settings.usemouse = (gtk_toggle_button_get_active(togglebutton) == TRUE);
 }
 
 static void on_inputjoycheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	settings.usejoy = (gtk_toggle_button_get_active(togglebutton) == TRUE);
+    settings.usejoy = (gtk_toggle_button_get_active(togglebutton) == TRUE);
 }
 
 static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
 {
-	if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
-	else quitevent++;
-	return TRUE;	// FALSE would let the event go through. we want the game to decide when to close
+    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
+    else quitevent++;
+    return TRUE;	// FALSE would let the event go through. we want the game to decide when to close
 }
 
 
 static GtkWidget *create_window(void)
 {
-  GtkWidget *startwin;
-  GtkWidget *hlayout;
-  GtkWidget *banner;
-  GtkWidget *vlayout;
-  GtkWidget *tabs;
-  GtkWidget *configvlayout;
-  GtkWidget *configlayout;
-  GtkWidget *fullscreencheck;
-  GtkWidget *vmode3dlabel;
-  GtkWidget *inputdevlabel;
-  GtkWidget *sounddrvlabel;
-  GtkWidget *sounddrvcombo;
-  GtkWidget *inputmousecheck;
-  GtkWidget *inputjoycheck;
-  GtkWidget *vmode3dcombo;
-  GtkWidget *alwaysshowcheck;
-  GtkWidget *configtab;
-  GtkWidget *messagesscroll;
-  GtkWidget *messagestext;
-  GtkWidget *messagestab;
-  GtkWidget *buttons;
-  GtkWidget *cancelbutton;
-  GtkWidget *cancelbuttonalign;
-  GtkWidget *cancelbuttonlayout;
-  GtkWidget *cancelbuttonicon;
-  GtkWidget *cancelbuttonlabel;
-  GtkWidget *startbutton;
-  GtkWidget *startbuttonalign;
-  GtkWidget *startbuttonlayout;
-  GtkWidget *startbuttonicon;
-  GtkWidget *startbuttonlabel;
-  GtkAccelGroup *accel_group;
+    GtkWidget *startwin;
+    GtkWidget *hlayout;
+    GtkWidget *banner;
+    GtkWidget *vlayout;
+    GtkWidget *tabs;
+    GtkWidget *configvlayout;
+    GtkWidget *configlayout;
+    GtkWidget *fullscreencheck;
+    GtkWidget *vmode3dlabel;
+    GtkWidget *inputdevlabel;
+    GtkWidget *sounddrvlabel;
+    GtkWidget *sounddrvcombo;
+    GtkWidget *inputmousecheck;
+    GtkWidget *inputjoycheck;
+    GtkWidget *vmode3dcombo;
+    GtkWidget *alwaysshowcheck;
+    GtkWidget *configtab;
+    GtkWidget *messagesscroll;
+    GtkWidget *messagestext;
+    GtkWidget *messagestab;
+    GtkWidget *buttons;
+    GtkWidget *cancelbutton;
+    GtkWidget *cancelbuttonalign;
+    GtkWidget *cancelbuttonlayout;
+    GtkWidget *cancelbuttonicon;
+    GtkWidget *cancelbuttonlabel;
+    GtkWidget *startbutton;
+    GtkWidget *startbuttonalign;
+    GtkWidget *startbuttonlayout;
+    GtkWidget *startbuttonicon;
+    GtkWidget *startbuttonlabel;
+    GtkAccelGroup *accel_group;
 
-  accel_group = gtk_accel_group_new ();
+    accel_group = gtk_accel_group_new ();
 
-  // Basic window
-  startwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_title (GTK_WINDOW (startwin), apptitle);	// NOTE: use global app title
-  gtk_window_set_position (GTK_WINDOW (startwin), GTK_WIN_POS_CENTER);
-  gtk_window_set_resizable (GTK_WINDOW (startwin), FALSE);
-  gtk_window_set_type_hint (GTK_WINDOW (startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
+    // Basic window
+    startwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title (GTK_WINDOW (startwin), apptitle);	// NOTE: use global app title
+    gtk_window_set_position (GTK_WINDOW (startwin), GTK_WIN_POS_CENTER);
+    gtk_window_set_resizable (GTK_WINDOW (startwin), FALSE);
+    gtk_window_set_type_hint (GTK_WINDOW (startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
 
-  // Horizontal layout of banner and controls
-  hlayout = gtk_hbox_new (FALSE, 0);
-  gtk_widget_show (hlayout);
-  gtk_container_add (GTK_CONTAINER (startwin), hlayout);
+    // Horizontal layout of banner and controls
+    hlayout = gtk_hbox_new (FALSE, 0);
+    gtk_widget_show (hlayout);
+    gtk_container_add (GTK_CONTAINER (startwin), hlayout);
 
-  // Banner
-  {
-	GdkPixbuf *pixbuf = load_banner();
-	banner = gtk_image_new_from_pixbuf(pixbuf);
-	g_object_unref((gpointer)pixbuf);
-  }
-  gtk_widget_show (banner);
-  gtk_box_pack_start (GTK_BOX (hlayout), banner, FALSE, FALSE, 0);
-  gtk_misc_set_alignment (GTK_MISC (banner), 0.5, 0);
+    // Banner
+    {
+        GdkPixbuf *pixbuf = load_banner();
+        banner = gtk_image_new_from_pixbuf(pixbuf);
+        g_object_unref((gpointer)pixbuf);
+    }
+    gtk_widget_show (banner);
+    gtk_box_pack_start (GTK_BOX (hlayout), banner, FALSE, FALSE, 0);
+    gtk_misc_set_alignment (GTK_MISC (banner), 0.5, 0);
 
-  // Vertical layout of tab control and start+cancel buttons
-  vlayout = gtk_vbox_new (FALSE, 0);
-  gtk_widget_show (vlayout);
-  gtk_box_pack_start (GTK_BOX (hlayout), vlayout, TRUE, TRUE, 0);
+    // Vertical layout of tab control and start+cancel buttons
+    vlayout = gtk_vbox_new (FALSE, 0);
+    gtk_widget_show (vlayout);
+    gtk_box_pack_start (GTK_BOX (hlayout), vlayout, TRUE, TRUE, 0);
 
-  // Tab control
-  tabs = gtk_notebook_new ();
-  gtk_widget_show (tabs);
-  gtk_box_pack_start (GTK_BOX (vlayout), tabs, TRUE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (tabs), 4);
+    // Tab control
+    tabs = gtk_notebook_new ();
+    gtk_widget_show (tabs);
+    gtk_box_pack_start (GTK_BOX (vlayout), tabs, TRUE, TRUE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (tabs), 4);
 
-  // Vertical layout of config page main body
-  configvlayout = gtk_vbox_new (FALSE, 0);
-  gtk_widget_show (configvlayout);
-  gtk_container_add (GTK_CONTAINER (tabs), configvlayout);
+    // Vertical layout of config page main body
+    configvlayout = gtk_vbox_new (FALSE, 0);
+    gtk_widget_show (configvlayout);
+    gtk_container_add (GTK_CONTAINER (tabs), configvlayout);
 
-  // Fixed-position layout of config page controls
-  configlayout = gtk_fixed_new ();
-  gtk_widget_show (configlayout);
-  gtk_box_pack_start (GTK_BOX (configvlayout), configlayout, TRUE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (configlayout), 6);
+    // Fixed-position layout of config page controls
+    configlayout = gtk_fixed_new ();
+    gtk_widget_show (configlayout);
+    gtk_box_pack_start (GTK_BOX (configvlayout), configlayout, TRUE, TRUE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (configlayout), 6);
 
-  // Fullscreen checkbox
-  fullscreencheck = gtk_check_button_new_with_mnemonic ("_Fullscreen");
-  gtk_widget_show (fullscreencheck);
-  gtk_fixed_put (GTK_FIXED (configlayout), fullscreencheck, 248, 0);
-  gtk_widget_set_size_request (fullscreencheck, 85, 29);
-  gtk_widget_add_accelerator (fullscreencheck, "grab_focus", accel_group,
-                              GDK_F, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+    // Fullscreen checkbox
+    fullscreencheck = gtk_check_button_new_with_mnemonic ("_Fullscreen");
+    gtk_widget_show (fullscreencheck);
+    gtk_fixed_put (GTK_FIXED (configlayout), fullscreencheck, 248, 0);
+    gtk_widget_set_size_request (fullscreencheck, 85, 29);
+    gtk_widget_add_accelerator (fullscreencheck, "grab_focus", accel_group,
+                                GDK_F, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  // 3D video mode label
-  vmode3dlabel = gtk_label_new_with_mnemonic ("_Video mode:");
-  gtk_widget_show (vmode3dlabel);
-  gtk_fixed_put (GTK_FIXED (configlayout), vmode3dlabel, 0, 0);
-  gtk_widget_set_size_request (vmode3dlabel, 88, 29);
-  gtk_misc_set_alignment (GTK_MISC (vmode3dlabel), 0, 0.5);
+    // 3D video mode label
+    vmode3dlabel = gtk_label_new_with_mnemonic ("_Video mode:");
+    gtk_widget_show (vmode3dlabel);
+    gtk_fixed_put (GTK_FIXED (configlayout), vmode3dlabel, 0, 0);
+    gtk_widget_set_size_request (vmode3dlabel, 88, 29);
+    gtk_misc_set_alignment (GTK_MISC (vmode3dlabel), 0, 0.5);
 
-  inputdevlabel = gtk_label_new ("Input devices:");
-  gtk_widget_show (inputdevlabel);
-  gtk_fixed_put (GTK_FIXED (configlayout), inputdevlabel, 0, 120);
-  gtk_widget_set_size_request (inputdevlabel, 88, 20);
-  gtk_misc_set_alignment (GTK_MISC (inputdevlabel), 0, 0.5);
+    inputdevlabel = gtk_label_new ("Input devices:");
+    gtk_widget_show (inputdevlabel);
+    gtk_fixed_put (GTK_FIXED (configlayout), inputdevlabel, 0, 120);
+    gtk_widget_set_size_request (inputdevlabel, 88, 20);
+    gtk_misc_set_alignment (GTK_MISC (inputdevlabel), 0, 0.5);
 
-  sounddrvlabel = gtk_label_new_with_mnemonic ("S_ound driver:");
-  gtk_widget_show (sounddrvlabel);
-  gtk_fixed_put (GTK_FIXED (configlayout), sounddrvlabel, 0, 40);
-  gtk_widget_set_size_request (sounddrvlabel, 88, 29);
-  gtk_misc_set_alignment (GTK_MISC (sounddrvlabel), 0, 0.5);
+    sounddrvlabel = gtk_label_new_with_mnemonic ("S_ound driver:");
+    gtk_widget_show (sounddrvlabel);
+    gtk_fixed_put (GTK_FIXED (configlayout), sounddrvlabel, 0, 40);
+    gtk_widget_set_size_request (sounddrvlabel, 88, 29);
+    gtk_misc_set_alignment (GTK_MISC (sounddrvlabel), 0, 0.5);
 
-  sounddrvcombo = gtk_combo_box_new_text ();
-  gtk_widget_show (sounddrvcombo);
-  gtk_fixed_put (GTK_FIXED (configlayout), sounddrvcombo, 88, 40);
-  gtk_widget_set_size_request (sounddrvcombo, 31, 30);
-  gtk_widget_add_accelerator (sounddrvcombo, "grab_focus", accel_group,
-                              GDK_O, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+    sounddrvcombo = gtk_combo_box_new_text ();
+    gtk_widget_show (sounddrvcombo);
+    gtk_fixed_put (GTK_FIXED (configlayout), sounddrvcombo, 88, 40);
+    gtk_widget_set_size_request (sounddrvcombo, 31, 30);
+    gtk_widget_add_accelerator (sounddrvcombo, "grab_focus", accel_group,
+                                GDK_O, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  inputmousecheck = gtk_check_button_new_with_mnemonic ("Mo_use");
-  gtk_widget_show (inputmousecheck);
-  gtk_fixed_put (GTK_FIXED (configlayout), inputmousecheck, 88, 120);
-  gtk_widget_set_size_request (inputmousecheck, 80, 20);
-  gtk_widget_add_accelerator (inputmousecheck, "grab_focus", accel_group,
-                              GDK_U, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+    inputmousecheck = gtk_check_button_new_with_mnemonic ("Mo_use");
+    gtk_widget_show (inputmousecheck);
+    gtk_fixed_put (GTK_FIXED (configlayout), inputmousecheck, 88, 120);
+    gtk_widget_set_size_request (inputmousecheck, 80, 20);
+    gtk_widget_add_accelerator (inputmousecheck, "grab_focus", accel_group,
+                                GDK_U, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  inputjoycheck = gtk_check_button_new_with_mnemonic ("_Joystick");
-  gtk_widget_show (inputjoycheck);
-  gtk_fixed_put (GTK_FIXED (configlayout), inputjoycheck, 168, 120);
-  gtk_widget_set_size_request (inputjoycheck, 80, 20);
-  gtk_widget_add_accelerator (inputjoycheck, "grab_focus", accel_group,
-                              GDK_J, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+    inputjoycheck = gtk_check_button_new_with_mnemonic ("_Joystick");
+    gtk_widget_show (inputjoycheck);
+    gtk_fixed_put (GTK_FIXED (configlayout), inputjoycheck, 168, 120);
+    gtk_widget_set_size_request (inputjoycheck, 80, 20);
+    gtk_widget_add_accelerator (inputjoycheck, "grab_focus", accel_group,
+                                GDK_J, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  // 3D video mode combo
-  {
-	GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
-	GtkCellRenderer *cell;
+    // 3D video mode combo
+    {
+        GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
+        GtkCellRenderer *cell;
 
-	vmode3dcombo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(list));
-	g_object_unref(G_OBJECT(list));
+        vmode3dcombo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(list));
+        g_object_unref(G_OBJECT(list));
 
-	cell = gtk_cell_renderer_text_new();
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(vmode3dcombo), cell, FALSE);
-	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(vmode3dcombo), cell, "text", 0, NULL);
-  }
-  gtk_widget_show (vmode3dcombo);
-  gtk_fixed_put (GTK_FIXED (configlayout), vmode3dcombo, 88, 0);
-  gtk_widget_set_size_request (vmode3dcombo, 150, 29);
-  gtk_widget_add_accelerator (vmode3dcombo, "grab_focus", accel_group,
-                              GDK_V, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+        cell = gtk_cell_renderer_text_new();
+        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(vmode3dcombo), cell, FALSE);
+        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(vmode3dcombo), cell, "text", 0, NULL);
+    }
+    gtk_widget_show (vmode3dcombo);
+    gtk_fixed_put (GTK_FIXED (configlayout), vmode3dcombo, 88, 0);
+    gtk_widget_set_size_request (vmode3dcombo, 150, 29);
+    gtk_widget_add_accelerator (vmode3dcombo, "grab_focus", accel_group,
+                                GDK_V, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  // Always show config checkbox
-  alwaysshowcheck = gtk_check_button_new_with_mnemonic ("_Always show configuration on start");
-  gtk_widget_show (alwaysshowcheck);
-  gtk_box_pack_start (GTK_BOX (configvlayout), alwaysshowcheck, FALSE, FALSE, 0);
-  gtk_widget_add_accelerator (alwaysshowcheck, "grab_focus", accel_group,
-                              GDK_A, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
+    // Always show config checkbox
+    alwaysshowcheck = gtk_check_button_new_with_mnemonic ("_Always show configuration on start");
+    gtk_widget_show (alwaysshowcheck);
+    gtk_box_pack_start (GTK_BOX (configvlayout), alwaysshowcheck, FALSE, FALSE, 0);
+    gtk_widget_add_accelerator (alwaysshowcheck, "grab_focus", accel_group,
+                                GDK_A, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
 
-  // Configuration tab
-  configtab = gtk_label_new ("Configuration");
-  gtk_widget_show (configtab);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 0), configtab);
+    // Configuration tab
+    configtab = gtk_label_new ("Configuration");
+    gtk_widget_show (configtab);
+    gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 0), configtab);
 
-  // Messages scrollable area
-  messagesscroll = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_show (messagesscroll);
-  gtk_container_add (GTK_CONTAINER (tabs), messagesscroll);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+    // Messages scrollable area
+    messagesscroll = gtk_scrolled_window_new (NULL, NULL);
+    gtk_widget_show (messagesscroll);
+    gtk_container_add (GTK_CONTAINER (tabs), messagesscroll);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
 
-  // Messages text area
-  messagestext = gtk_text_view_new ();
-  gtk_widget_show (messagestext);
-  gtk_container_add (GTK_CONTAINER (messagesscroll), messagestext);
-  gtk_text_view_set_editable (GTK_TEXT_VIEW (messagestext), FALSE);
-  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (messagestext), GTK_WRAP_WORD);
-  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (messagestext), FALSE);
-  gtk_text_view_set_left_margin (GTK_TEXT_VIEW (messagestext), 2);
-  gtk_text_view_set_right_margin (GTK_TEXT_VIEW (messagestext), 2);
+    // Messages text area
+    messagestext = gtk_text_view_new ();
+    gtk_widget_show (messagestext);
+    gtk_container_add (GTK_CONTAINER (messagesscroll), messagestext);
+    gtk_text_view_set_editable (GTK_TEXT_VIEW (messagestext), FALSE);
+    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (messagestext), GTK_WRAP_WORD);
+    gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (messagestext), FALSE);
+    gtk_text_view_set_left_margin (GTK_TEXT_VIEW (messagestext), 2);
+    gtk_text_view_set_right_margin (GTK_TEXT_VIEW (messagestext), 2);
 
-  // Messages tab
-  messagestab = gtk_label_new ("Messages");
-  gtk_widget_show (messagestab);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 1), messagestab);
+    // Messages tab
+    messagestab = gtk_label_new ("Messages");
+    gtk_widget_show (messagestab);
+    gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 1), messagestab);
 
-  // Dialogue box buttons layout
-  buttons = gtk_hbutton_box_new ();
-  gtk_widget_show (buttons);
-  gtk_box_pack_start (GTK_BOX (vlayout), buttons, FALSE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (buttons), 3);
-  gtk_button_box_set_layout (GTK_BUTTON_BOX (buttons), GTK_BUTTONBOX_END);
+    // Dialogue box buttons layout
+    buttons = gtk_hbutton_box_new ();
+    gtk_widget_show (buttons);
+    gtk_box_pack_start (GTK_BOX (vlayout), buttons, FALSE, TRUE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER (buttons), 3);
+    gtk_button_box_set_layout (GTK_BUTTON_BOX (buttons), GTK_BUTTONBOX_END);
 
-  // Cancel button
-  cancelbutton = gtk_button_new ();
-  gtk_widget_show (cancelbutton);
-  gtk_container_add (GTK_CONTAINER (buttons), cancelbutton);
-  GTK_WIDGET_SET_FLAGS (cancelbutton, GTK_CAN_DEFAULT);
-  gtk_widget_add_accelerator (cancelbutton, "grab_focus", accel_group,
-                              GDK_C, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
-  gtk_widget_add_accelerator (cancelbutton, "clicked", accel_group,
-                              GDK_Escape, 0,
-                              GTK_ACCEL_VISIBLE);
+    // Cancel button
+    cancelbutton = gtk_button_new ();
+    gtk_widget_show (cancelbutton);
+    gtk_container_add (GTK_CONTAINER (buttons), cancelbutton);
+    GTK_WIDGET_SET_FLAGS (cancelbutton, GTK_CAN_DEFAULT);
+    gtk_widget_add_accelerator (cancelbutton, "grab_focus", accel_group,
+                                GDK_C, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
+    gtk_widget_add_accelerator (cancelbutton, "clicked", accel_group,
+                                GDK_Escape, 0,
+                                GTK_ACCEL_VISIBLE);
 
-  cancelbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
-  gtk_widget_show (cancelbuttonalign);
-  gtk_container_add (GTK_CONTAINER (cancelbutton), cancelbuttonalign);
+    cancelbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
+    gtk_widget_show (cancelbuttonalign);
+    gtk_container_add (GTK_CONTAINER (cancelbutton), cancelbuttonalign);
 
-  cancelbuttonlayout = gtk_hbox_new (FALSE, 2);
-  gtk_widget_show (cancelbuttonlayout);
-  gtk_container_add (GTK_CONTAINER (cancelbuttonalign), cancelbuttonlayout);
+    cancelbuttonlayout = gtk_hbox_new (FALSE, 2);
+    gtk_widget_show (cancelbuttonlayout);
+    gtk_container_add (GTK_CONTAINER (cancelbuttonalign), cancelbuttonlayout);
 
-  cancelbuttonicon = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON);
-  gtk_widget_show (cancelbuttonicon);
-  gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonicon, FALSE, FALSE, 0);
+    cancelbuttonicon = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON);
+    gtk_widget_show (cancelbuttonicon);
+    gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonicon, FALSE, FALSE, 0);
 
-  cancelbuttonlabel = gtk_label_new_with_mnemonic ("_Cancel");
-  gtk_widget_show (cancelbuttonlabel);
-  gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonlabel, FALSE, FALSE, 0);
+    cancelbuttonlabel = gtk_label_new_with_mnemonic ("_Cancel");
+    gtk_widget_show (cancelbuttonlabel);
+    gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonlabel, FALSE, FALSE, 0);
 
-  // Start button
-  startbutton = gtk_button_new ();
-  gtk_widget_show (startbutton);
-  gtk_container_add (GTK_CONTAINER (buttons), startbutton);
-  GTK_WIDGET_SET_FLAGS (startbutton, GTK_CAN_DEFAULT);
-  gtk_widget_add_accelerator (startbutton, "grab_focus", accel_group,
-                              GDK_S, GDK_MOD1_MASK,
-                              GTK_ACCEL_VISIBLE);
-  gtk_widget_add_accelerator (startbutton, "clicked", accel_group,
-                              GDK_Return, 0,
-                              GTK_ACCEL_VISIBLE);
+    // Start button
+    startbutton = gtk_button_new ();
+    gtk_widget_show (startbutton);
+    gtk_container_add (GTK_CONTAINER (buttons), startbutton);
+    GTK_WIDGET_SET_FLAGS (startbutton, GTK_CAN_DEFAULT);
+    gtk_widget_add_accelerator (startbutton, "grab_focus", accel_group,
+                                GDK_S, GDK_MOD1_MASK,
+                                GTK_ACCEL_VISIBLE);
+    gtk_widget_add_accelerator (startbutton, "clicked", accel_group,
+                                GDK_Return, 0,
+                                GTK_ACCEL_VISIBLE);
 
-  startbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
-  gtk_widget_show (startbuttonalign);
-  gtk_container_add (GTK_CONTAINER (startbutton), startbuttonalign);
+    startbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
+    gtk_widget_show (startbuttonalign);
+    gtk_container_add (GTK_CONTAINER (startbutton), startbuttonalign);
 
-  startbuttonlayout = gtk_hbox_new (FALSE, 2);
-  gtk_widget_show (startbuttonlayout);
-  gtk_container_add (GTK_CONTAINER (startbuttonalign), startbuttonlayout);
+    startbuttonlayout = gtk_hbox_new (FALSE, 2);
+    gtk_widget_show (startbuttonlayout);
+    gtk_container_add (GTK_CONTAINER (startbuttonalign), startbuttonlayout);
 
-  startbuttonicon = gtk_image_new_from_stock ("gtk-execute", GTK_ICON_SIZE_BUTTON);
-  gtk_widget_show (startbuttonicon);
-  gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonicon, FALSE, FALSE, 0);
+    startbuttonicon = gtk_image_new_from_stock ("gtk-execute", GTK_ICON_SIZE_BUTTON);
+    gtk_widget_show (startbuttonicon);
+    gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonicon, FALSE, FALSE, 0);
 
-  startbuttonlabel = gtk_label_new_with_mnemonic ("_Start");
-  gtk_widget_show (startbuttonlabel);
-  gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonlabel, FALSE, FALSE, 0);
+    startbuttonlabel = gtk_label_new_with_mnemonic ("_Start");
+    gtk_widget_show (startbuttonlabel);
+    gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonlabel, FALSE, FALSE, 0);
 
-  // Wire up the signals
-  g_signal_connect ((gpointer) startwin, "delete_event",
-                    G_CALLBACK (on_startwin_delete_event),
-                    NULL);
-  g_signal_connect ((gpointer) fullscreencheck, "toggled",
-                    G_CALLBACK (on_fullscreencheck_toggled),
-                    NULL);
-  g_signal_connect ((gpointer) sounddrvcombo, "changed",
-                    G_CALLBACK (on_sounddrvcombo_changed),
-                    NULL);
-  g_signal_connect ((gpointer) inputmousecheck, "toggled",
-                    G_CALLBACK (on_inputmousecheck_toggled),
-                    NULL);
-  g_signal_connect ((gpointer) inputjoycheck, "toggled",
-                    G_CALLBACK (on_inputjoycheck_toggled),
-                    NULL);
-  g_signal_connect ((gpointer) vmode3dcombo, "changed",
-                    G_CALLBACK (on_vmode3dcombo_changed),
-                    NULL);
-  g_signal_connect ((gpointer) alwaysshowcheck, "toggled",
-                    G_CALLBACK (on_alwaysshowcheck_toggled),
-                    NULL);
-  g_signal_connect ((gpointer) cancelbutton, "clicked",
-                    G_CALLBACK (on_cancelbutton_clicked),
-                    NULL);
-  g_signal_connect ((gpointer) startbutton, "clicked",
-                    G_CALLBACK (on_startbutton_clicked),
-                    NULL);
+    // Wire up the signals
+    g_signal_connect ((gpointer) startwin, "delete_event",
+                      G_CALLBACK (on_startwin_delete_event),
+                      NULL);
+    g_signal_connect ((gpointer) fullscreencheck, "toggled",
+                      G_CALLBACK (on_fullscreencheck_toggled),
+                      NULL);
+    g_signal_connect ((gpointer) sounddrvcombo, "changed",
+                      G_CALLBACK (on_sounddrvcombo_changed),
+                      NULL);
+    g_signal_connect ((gpointer) inputmousecheck, "toggled",
+                      G_CALLBACK (on_inputmousecheck_toggled),
+                      NULL);
+    g_signal_connect ((gpointer) inputjoycheck, "toggled",
+                      G_CALLBACK (on_inputjoycheck_toggled),
+                      NULL);
+    g_signal_connect ((gpointer) vmode3dcombo, "changed",
+                      G_CALLBACK (on_vmode3dcombo_changed),
+                      NULL);
+    g_signal_connect ((gpointer) alwaysshowcheck, "toggled",
+                      G_CALLBACK (on_alwaysshowcheck_toggled),
+                      NULL);
+    g_signal_connect ((gpointer) cancelbutton, "clicked",
+                      G_CALLBACK (on_cancelbutton_clicked),
+                      NULL);
+    g_signal_connect ((gpointer) startbutton, "clicked",
+                      G_CALLBACK (on_startbutton_clicked),
+                      NULL);
 
-  // Associate labels with their controls
-  gtk_label_set_mnemonic_widget (GTK_LABEL (vmode3dlabel), vmode3dcombo);
-  gtk_label_set_mnemonic_widget (GTK_LABEL (sounddrvlabel), sounddrvcombo);
+    // Associate labels with their controls
+    gtk_label_set_mnemonic_widget (GTK_LABEL (vmode3dlabel), vmode3dcombo);
+    gtk_label_set_mnemonic_widget (GTK_LABEL (sounddrvlabel), sounddrvcombo);
 
-  /* Store pointers to all widgets, for use by lookup_widget(). */
-  GLADE_HOOKUP_OBJECT_NO_REF (startwin, startwin, "startwin");
-  GLADE_HOOKUP_OBJECT (startwin, hlayout, "hlayout");
-  GLADE_HOOKUP_OBJECT (startwin, banner, "banner");
-  GLADE_HOOKUP_OBJECT (startwin, vlayout, "vlayout");
-  GLADE_HOOKUP_OBJECT (startwin, tabs, "tabs");
-  GLADE_HOOKUP_OBJECT (startwin, configvlayout, "configvlayout");
-  GLADE_HOOKUP_OBJECT (startwin, configlayout, "configlayout");
-  GLADE_HOOKUP_OBJECT (startwin, fullscreencheck, "fullscreencheck");
-  GLADE_HOOKUP_OBJECT (startwin, vmode3dlabel, "vmode3dlabel");
-  GLADE_HOOKUP_OBJECT (startwin, inputdevlabel, "inputdevlabel");
-  GLADE_HOOKUP_OBJECT (startwin, sounddrvlabel, "sounddrvlabel");
-  GLADE_HOOKUP_OBJECT (startwin, sounddrvcombo, "sounddrvcombo");
-  GLADE_HOOKUP_OBJECT (startwin, inputmousecheck, "inputmousecheck");
-  GLADE_HOOKUP_OBJECT (startwin, inputjoycheck, "inputjoycheck");
-  GLADE_HOOKUP_OBJECT (startwin, vmode3dcombo, "vmode3dcombo");
-  GLADE_HOOKUP_OBJECT (startwin, alwaysshowcheck, "alwaysshowcheck");
-  GLADE_HOOKUP_OBJECT (startwin, configtab, "configtab");
-  GLADE_HOOKUP_OBJECT (startwin, messagesscroll, "messagesscroll");
-  GLADE_HOOKUP_OBJECT (startwin, messagestext, "messagestext");
-  GLADE_HOOKUP_OBJECT (startwin, messagestab, "messagestab");
-  GLADE_HOOKUP_OBJECT (startwin, buttons, "buttons");
-  GLADE_HOOKUP_OBJECT (startwin, cancelbutton, "cancelbutton");
-  GLADE_HOOKUP_OBJECT (startwin, cancelbuttonalign, "cancelbuttonalign");
-  GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlayout, "cancelbuttonlayout");
-  GLADE_HOOKUP_OBJECT (startwin, cancelbuttonicon, "cancelbuttonicon");
-  GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlabel, "cancelbuttonlabel");
-  GLADE_HOOKUP_OBJECT (startwin, startbutton, "startbutton");
-  GLADE_HOOKUP_OBJECT (startwin, startbuttonalign, "startbuttonalign");
-  GLADE_HOOKUP_OBJECT (startwin, startbuttonlayout, "startbuttonlayout");
-  GLADE_HOOKUP_OBJECT (startwin, startbuttonicon, "startbuttonicon");
-  GLADE_HOOKUP_OBJECT (startwin, startbuttonlabel, "startbuttonlabel");
+    /* Store pointers to all widgets, for use by lookup_widget(). */
+    GLADE_HOOKUP_OBJECT_NO_REF (startwin, startwin, "startwin");
+    GLADE_HOOKUP_OBJECT (startwin, hlayout, "hlayout");
+    GLADE_HOOKUP_OBJECT (startwin, banner, "banner");
+    GLADE_HOOKUP_OBJECT (startwin, vlayout, "vlayout");
+    GLADE_HOOKUP_OBJECT (startwin, tabs, "tabs");
+    GLADE_HOOKUP_OBJECT (startwin, configvlayout, "configvlayout");
+    GLADE_HOOKUP_OBJECT (startwin, configlayout, "configlayout");
+    GLADE_HOOKUP_OBJECT (startwin, fullscreencheck, "fullscreencheck");
+    GLADE_HOOKUP_OBJECT (startwin, vmode3dlabel, "vmode3dlabel");
+    GLADE_HOOKUP_OBJECT (startwin, inputdevlabel, "inputdevlabel");
+    GLADE_HOOKUP_OBJECT (startwin, sounddrvlabel, "sounddrvlabel");
+    GLADE_HOOKUP_OBJECT (startwin, sounddrvcombo, "sounddrvcombo");
+    GLADE_HOOKUP_OBJECT (startwin, inputmousecheck, "inputmousecheck");
+    GLADE_HOOKUP_OBJECT (startwin, inputjoycheck, "inputjoycheck");
+    GLADE_HOOKUP_OBJECT (startwin, vmode3dcombo, "vmode3dcombo");
+    GLADE_HOOKUP_OBJECT (startwin, alwaysshowcheck, "alwaysshowcheck");
+    GLADE_HOOKUP_OBJECT (startwin, configtab, "configtab");
+    GLADE_HOOKUP_OBJECT (startwin, messagesscroll, "messagesscroll");
+    GLADE_HOOKUP_OBJECT (startwin, messagestext, "messagestext");
+    GLADE_HOOKUP_OBJECT (startwin, messagestab, "messagestab");
+    GLADE_HOOKUP_OBJECT (startwin, buttons, "buttons");
+    GLADE_HOOKUP_OBJECT (startwin, cancelbutton, "cancelbutton");
+    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonalign, "cancelbuttonalign");
+    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlayout, "cancelbuttonlayout");
+    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonicon, "cancelbuttonicon");
+    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlabel, "cancelbuttonlabel");
+    GLADE_HOOKUP_OBJECT (startwin, startbutton, "startbutton");
+    GLADE_HOOKUP_OBJECT (startwin, startbuttonalign, "startbuttonalign");
+    GLADE_HOOKUP_OBJECT (startwin, startbuttonlayout, "startbuttonlayout");
+    GLADE_HOOKUP_OBJECT (startwin, startbuttonicon, "startbuttonicon");
+    GLADE_HOOKUP_OBJECT (startwin, startbuttonlabel, "startbuttonlabel");
 
-  gtk_window_add_accel_group (GTK_WINDOW (startwin), accel_group);
+    gtk_window_add_accel_group (GTK_WINDOW (startwin), accel_group);
 
-  return startwin;
+    return startwin;
 }
 
 // -- BUILD ENTRY POINTS ------------------------------------------------------
 
 int startwin_open(void)
 {
-	if (!gtkenabled) return 0;
-	if (startwin) return 1;
+    if (!gtkenabled) return 0;
+    if (startwin) return 1;
 
-	startwin = create_window();
-	if (startwin) {
-		SetPage(TAB_MESSAGES);
-		gtk_widget_show(startwin);
-		gtk_main_iteration_do(FALSE);
-		return 0;
-	}
-  	return -1;
+    startwin = create_window();
+    if (startwin) {
+        SetPage(TAB_MESSAGES);
+        gtk_widget_show(startwin);
+        gtk_main_iteration_do(FALSE);
+        return 0;
+    }
+    return -1;
 }
 
 int startwin_close(void)
 {
-	if (!gtkenabled) return 0;
-	if (!startwin) return 1;
-	gtk_widget_destroy (startwin);
-	startwin = NULL;
-	return 0;
+    if (!gtkenabled) return 0;
+    if (!startwin) return 1;
+    gtk_widget_destroy (startwin);
+    startwin = NULL;
+    return 0;
 }
 
 int startwin_puts(const char *str)
 {
-	GtkWidget *textview;
-	GtkTextBuffer *textbuffer;
-	GtkTextIter enditer;
-	GtkTextMark *mark;
-	const char *aptr, *bptr;
+    GtkWidget *textview;
+    GtkTextBuffer *textbuffer;
+    GtkTextIter enditer;
+    GtkTextMark *mark;
+    const char *aptr, *bptr;
 
-	if (!gtkenabled || !str) return 0;
-	if (!startwin) return 1;
-	if (!(textview = lookup_widget(startwin, "messagestext"))) return -1;
-	textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+    if (!gtkenabled || !str) return 0;
+    if (!startwin) return 1;
+    if (!(textview = lookup_widget(startwin, "messagestext"))) return -1;
+    textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
 
-	gtk_text_buffer_get_end_iter(textbuffer, &enditer);
-	for (aptr = bptr = str; *aptr != 0; ) {
-		switch (*bptr) {
-			case '\b':
-				if (bptr > aptr)
-					gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
+    gtk_text_buffer_get_end_iter(textbuffer, &enditer);
+    for (aptr = bptr = str; *aptr != 0; ) {
+        switch (*bptr) {
+        case '\b':
+            if (bptr > aptr)
+                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
 #if GTK_CHECK_VERSION(2,6,0)
-				gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
+            gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
 #else
-				{
-				GtkTextIter iter2 = enditer;
-				gtk_text_iter_backward_cursor_position(&iter2);
-				//FIXME: this seems be deleting one too many chars somewhere!
-				if (!gtk_text_iter_equal(&iter2, &enditer))
-					gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
-				}
+            {
+                GtkTextIter iter2 = enditer;
+                gtk_text_iter_backward_cursor_position(&iter2);
+                //FIXME: this seems be deleting one too many chars somewhere!
+                if (!gtk_text_iter_equal(&iter2, &enditer))
+                    gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
+            }
 #endif
-				aptr = ++bptr;
-				break;
-			case 0:
-				if (bptr > aptr)
-					gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
-				aptr = bptr;
-				break;
-			case '\r':	// FIXME
-			default:
-				bptr++;
-				break;
-		}
-	}
+            aptr = ++bptr;
+            break;
+        case 0:
+            if (bptr > aptr)
+                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
+            aptr = bptr;
+            break;
+        case '\r':	// FIXME
+        default:
+            bptr++;
+            break;
+        }
+    }
 
-	mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
-	gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
-	gtk_text_buffer_delete_mark(textbuffer, mark);
+    mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
+    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
+    gtk_text_buffer_delete_mark(textbuffer, mark);
 
-	return 0;
+    return 0;
 }
 
 int startwin_settitle(const char *title)
 {
-	if (!gtkenabled) return 0;
-	if (!startwin) return 1;
-	gtk_window_set_title (GTK_WINDOW (startwin), title);
-	return 0;
+    if (!gtkenabled) return 0;
+    if (!startwin) return 1;
+    gtk_window_set_title (GTK_WINDOW (startwin), title);
+    return 0;
 }
 
 int startwin_idle(void *s)
 {
-	if (!gtkenabled) return 0;
-	//if (!startwin) return 1;
-  	gtk_main_iteration_do (FALSE);
-  	return 0;
+    if (!gtkenabled) return 0;
+    //if (!startwin) return 1;
+    gtk_main_iteration_do (FALSE);
+    return 0;
 }
 
-extern int xdimgame, ydimgame, bppgame, forcesetup;
-
 int startwin_run(void)
 {
-	if (!gtkenabled) return 0;
-	if (!startwin) return 1;
+    if (!gtkenabled) return 0;
+    if (!startwin) return 1;
 
-	SetPage(TAB_CONFIG);
+    SetPage(TAB_CONFIG);
 
-	settings.fullscreen = ScreenMode;
-	settings.xdim3d = ScreenWidth;
-	settings.ydim3d = ScreenHeight;
-	settings.bpp3d = ScreenBPP;
-	settings.forcesetup = ForceSetup;
-	settings.usemouse = UseMouse;
-	settings.usejoy = UseJoystick;
-	PopulateForm();
-	
-	gtk_main();
-	
-	SetPage(TAB_MESSAGES);
-	if (retval) {
-		ScreenMode = settings.fullscreen;
-		ScreenWidth = settings.xdim3d;
-		ScreenHeight = settings.ydim3d;
-		ScreenBPP = settings.bpp3d;
-		ForceSetup = settings.forcesetup;
-		UseMouse = settings.usemouse;
-		UseJoystick = settings.usejoy;
-	}
+    settings.fullscreen = ScreenMode;
+    settings.xdim3d = ScreenWidth;
+    settings.ydim3d = ScreenHeight;
+    settings.bpp3d = ScreenBPP;
+    settings.forcesetup = ForceSetup;
+    settings.usemouse = UseMouse;
+    settings.usejoy = UseJoystick;
+    PopulateForm();
 
-	return retval;
+    gtk_main();
+
+    SetPage(TAB_MESSAGES);
+    if (retval) {
+        ScreenMode = settings.fullscreen;
+        ScreenWidth = settings.xdim3d;
+        ScreenHeight = settings.ydim3d;
+        ScreenBPP = settings.bpp3d;
+        ForceSetup = settings.forcesetup;
+        UseMouse = settings.usemouse;
+        UseJoystick = settings.usejoy;
+    }
+
+    return retval;
 }
 
diff --git a/polymer/eduke32/source/startwin.game.c b/polymer/eduke32/source/startwin.game.c
index dafeb0650..65e9616f8 100755
--- a/polymer/eduke32/source/startwin.game.c
+++ b/polymer/eduke32/source/startwin.game.c
@@ -8,6 +8,8 @@
 #include "winlayer.h"
 #include "compat.h"
 
+#include "startdlg.h"
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <windowsx.h>
@@ -18,56 +20,79 @@
 #include "startwin.game.h"
 
 #define TAB_CONFIG 0
-#define TAB_MESSAGES 1
+#define TAB_GAME 1
+#define TAB_MESSAGES 2
 
 static struct {
     int fullscreen;
     int xdim, ydim, bpp;
     int forcesetup;
     int usemouse, usejoy;
+    char selectedgrp[BMAX_PATH+1];
 } settings;
 
 static HWND startupdlg = NULL;
-static HWND pages[2] = { NULL, NULL};
+static HWND pages[3] = { NULL, NULL, NULL };
 static int done = -1, mode = TAB_CONFIG;
 
-static void PopulateForm(void)
+static void PopulateForm(int pgs)
 {
-    int i,j;
-    char buf[64];
-    int mode;
     HWND hwnd;
+    if (pgs & (1<<TAB_CONFIG)) {
+        int i,j;
+        char buf[64];
+        int mode;
 
-    hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
+        hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
 
-    mode = checkvideomode(&settings.xdim, &settings.ydim, settings.bpp, settings.fullscreen, 1);
-    if (mode < 0) {
-        int cd[] = { 32, 24, 16, 15, 8, 0 };
-        for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp) i++; else break; }
-        for ( ; cd[i]; i++) {
-            mode = checkvideomode(&settings.xdim, &settings.ydim, cd[i], settings.fullscreen, 1);
-            if (mode < 0) continue;
-            settings.bpp = cd[i];
-            break;
+        mode = checkvideomode(&settings.xdim, &settings.ydim, settings.bpp, settings.fullscreen, 1);
+        if (mode < 0) {
+            int cd[] = { 32, 24, 16, 15, 8, 0 };
+            for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp) i++; else break; }
+            for ( ; cd[i]; i++) {
+                mode = checkvideomode(&settings.xdim, &settings.ydim, cd[i], settings.fullscreen, 1);
+                if (mode < 0) continue;
+                settings.bpp = cd[i];
+                break;
+            }
+        }
+
+        Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), (settings.fullscreen ? BST_CHECKED : BST_UNCHECKED));
+        Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCALWAYSSHOW), (settings.forcesetup ? BST_CHECKED : BST_UNCHECKED));
+
+        ComboBox_ResetContent(hwnd);
+        for (i=0; i<validmodecnt; i++) {
+            if (validmode[i].fs != settings.fullscreen) continue;
+
+            // all modes get added to the 3D mode list
+            Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
+            j = ComboBox_AddString(hwnd, buf);
+            ComboBox_SetItemData(hwnd, j, i);
+            if (i == mode) ComboBox_SetCurSel(hwnd, j);
+        }
+
+        Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), (settings.usemouse ? BST_CHECKED : BST_UNCHECKED));
+        Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), (settings.usejoy ? BST_CHECKED : BST_UNCHECKED));
+    }
+
+    if (pgs & (1<<TAB_GAME)) {
+        struct grpfile *fg;
+        int i, j;
+        char buf[128+BMAX_PATH];
+
+        hwnd = GetDlgItem(pages[TAB_GAME], IDGDATA);
+
+        for (fg = foundgrps; fg; fg=fg->next) {
+            for (i = 0; i<numgrpfiles; i++)
+                if (fg->crcval == grpfiles[i].crcval) break;
+            if (i == numgrpfiles) continue;	// unrecognised grp file
+
+            Bsprintf(buf, "%s\t%s", grpfiles[i].name, fg->name);
+            j = ListBox_AddString(hwnd, buf);
+            ListBox_SetItemData(hwnd, j, (LPARAM)fg);
+            if (!Bstrcasecmp(fg->name, settings.selectedgrp)) ListBox_SetCurSel(hwnd, j);
         }
     }
-
-    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), (settings.fullscreen ? BST_CHECKED : BST_UNCHECKED));
-    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCALWAYSSHOW), (settings.forcesetup ? BST_CHECKED : BST_UNCHECKED));
-
-    ComboBox_ResetContent(hwnd);
-    for (i=0; i<validmodecnt; i++) {
-        if (validmode[i].fs != settings.fullscreen) continue;
-
-        // all modes get added to the 3D mode list
-        Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
-        j = ComboBox_AddString(hwnd, buf);
-        ComboBox_SetItemData(hwnd, j, i);
-        if (i == mode) ComboBox_SetCurSel(hwnd, j);
-    }
-
-    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), (settings.usemouse ? BST_CHECKED : BST_UNCHECKED));
-    Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), (settings.usejoy ? BST_CHECKED : BST_UNCHECKED));
 }
 
 static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -77,7 +102,7 @@ static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
         switch (LOWORD(wParam)) {
         case IDCFULLSCREEN:
             settings.fullscreen = !settings.fullscreen;
-            PopulateForm();
+            PopulateForm(1<<TAB_CONFIG);
             return TRUE;
         case IDCVMODE:
             if (HIWORD(wParam) == CBN_SELCHANGE) {
@@ -108,6 +133,26 @@ static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
     return FALSE;
 }
 
+static INT_PTR CALLBACK GamePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    switch (uMsg) {
+    case WM_COMMAND:
+        switch (LOWORD(wParam)) {
+        case IDGDATA: {
+                int i;
+                i = ListBox_GetCurSel((HWND)lParam);
+                if (i != CB_ERR) i = ListBox_GetItemData((HWND)lParam, i);
+                if (i != CB_ERR) strcpy(settings.selectedgrp, ((struct grpfile*)i)->name);
+                return TRUE;
+            }
+        default: break;
+        }
+        break;
+    default: break;
+    }
+    return FALSE;
+}
+
 
 
 static void SetPage(int n)
@@ -132,6 +177,8 @@ static void EnableConfig(int n)
     EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCVMODE), n);
     EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), n);
     EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), n);
+
+    EnableWindow(GetDlgItem(pages[TAB_GAME], IDGDATA), n);
 }
 
 static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -208,10 +255,13 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
                 ZeroMemory(&tab, sizeof(tab));
                 tab.mask = TCIF_TEXT;
                 tab.pszText = TEXT("Configuration");
-                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tab);
+                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)TAB_CONFIG, (LPARAM)&tab);
+                tab.mask = TCIF_TEXT;
+                tab.pszText = TEXT("Game");
+                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)TAB_GAME, (LPARAM)&tab);
                 tab.mask = TCIF_TEXT;
                 tab.pszText = TEXT("Messages");
-                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tab);
+                SendMessage(hwnd, TCM_INSERTITEM, (WPARAM)TAB_MESSAGES, (LPARAM)&tab);
 
                 // Work out the position and size of the area inside the tab control for the pages
                 ZeroMemory(&r, sizeof(r));
@@ -225,8 +275,11 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
                 // Create the pages and position them in the tab control, but hide them
                 pages[TAB_CONFIG] = CreateDialog((HINSTANCE)win_gethinstance(),
                                                  MAKEINTRESOURCE(WIN_STARTWINPAGE_CONFIG), hwndDlg, ConfigPageProc);
+                pages[TAB_GAME] = CreateDialog((HINSTANCE)win_gethinstance(),
+                                               MAKEINTRESOURCE(WIN_STARTWINPAGE_GAME), hwndDlg, GamePageProc);
                 pages[TAB_MESSAGES] = GetDlgItem(hwndDlg, WIN_STARTWIN_MESSAGES);
                 SetWindowPos(pages[TAB_CONFIG], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
+                SetWindowPos(pages[TAB_GAME], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
                 SetWindowPos(pages[TAB_MESSAGES], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
 
                 // Tell the editfield acting as the console to exclude the width of the scrollbar
@@ -235,7 +288,14 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
                 r.left = r.top = 0;
                 SendMessage(pages[TAB_MESSAGES], EM_SETRECTNP,0,(LPARAM)&r);
 
+                // Set a tab stop in the game data listbox
+                {
+                    DWORD tabs[1] = { 150 };
+                    ListBox_SetTabStops(GetDlgItem(pages[TAB_GAME], IDGDATA), 1, tabs);
+                }
+
                 SetFocus(GetDlgItem(hwndDlg, WIN_STARTWIN_START));
+                SetWindowText(hwndDlg, apptitle);
             }
             return FALSE;
         }
@@ -261,8 +321,8 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
         }
 
     case WM_CLOSE:
-		if (mode == TAB_CONFIG) done = 0;
-		else quitevent++;
+        if (mode == TAB_CONFIG) done = 0;
+        else quitevent++;
         return TRUE;
 
     case WM_DESTROY:
@@ -271,6 +331,11 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
             hbmp = NULL;
         }
 
+        if (pages[TAB_GAME]) {
+            DestroyWindow(pages[TAB_GAME]);
+            pages[TAB_GAME] = NULL;
+        }
+
         if (pages[TAB_CONFIG]) {
             DestroyWindow(pages[TAB_CONFIG]);
             pages[TAB_CONFIG] = NULL;
@@ -281,10 +346,10 @@ static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
 
     case WM_COMMAND:
         switch (LOWORD(wParam)) {
-		case WIN_STARTWIN_CANCEL:
-			if (mode == TAB_CONFIG) done = 0;
-			else quitevent++;
-			return TRUE;
+        case WIN_STARTWIN_CANCEL:
+            if (mode == TAB_CONFIG) done = 0;
+            else quitevent++;
+            return TRUE;
         case WIN_STARTWIN_START: done = 1; return TRUE;
         }
         return FALSE;
@@ -390,6 +455,8 @@ int startwin_idle(void *v)
     return 0;
 }
 
+extern char *duke3dgrp;
+
 int startwin_run(void)
 {
     MSG msg;
@@ -397,6 +464,8 @@ int startwin_run(void)
 
     done = -1;
 
+    ScanGroups();
+
     SetPage(TAB_CONFIG);
     EnableConfig(1);
 
@@ -407,7 +476,8 @@ int startwin_run(void)
     settings.forcesetup = ForceSetup;
     settings.usemouse = UseMouse;
     settings.usejoy = UseJoystick;
-    PopulateForm();
+    strncpy(settings.selectedgrp, duke3dgrp, BMAX_PATH);
+    PopulateForm(-1);
 
     while (done < 0) {
         switch (GetMessage(&msg, NULL, 0,0)) {
@@ -431,6 +501,7 @@ int startwin_run(void)
         ForceSetup = settings.forcesetup;
         UseMouse = settings.usemouse;
         UseJoystick = settings.usejoy;
+        duke3dgrp = settings.selectedgrp;
     }
 
     return done;
diff --git a/polymer/eduke32/source/startwin.game.h b/polymer/eduke32/source/startwin.game.h
index 446a9b087..fd2cacc6c 100755
--- a/polymer/eduke32/source/startwin.game.h
+++ b/polymer/eduke32/source/startwin.game.h
@@ -1,6 +1,7 @@
 // resource ids
 #define WIN_STARTWIN		1000
 #define WIN_STARTWINPAGE_CONFIG 2000
+#define WIN_STARTWINPAGE_GAME	3000
 #define WIN_STARTWIN_BITMAP	100	// banner bitmap
 #define WIN_STARTWIN_TABCTL	101
 #define WIN_STARTWIN_CANCEL	IDCANCEL
@@ -21,3 +22,6 @@
 #define IDCINPUTJOY	106
 #define IDCALWAYSSHOW	107
 
+// game page
+#define IDGDATA		100
+