Add all the functionality from the win32 startup window to the GTK version

This commit is contained in:
Magnus Norddahl 2022-12-05 02:04:06 +01:00 committed by Christoph Oelckers
parent 24d27a6746
commit 7ae07d614e
2 changed files with 376 additions and 184 deletions

View File

@ -69,7 +69,7 @@
#ifndef NO_GTK
bool I_GtkAvailable ();
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags);
void I_ShowFatalError_Gtk(const char* errortext);
#elif defined(__APPLE__)
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
@ -297,7 +297,7 @@ void I_PrintStr(const char *cp)
if (StartWindow) RedrawProgressBar(ProgressBarCurPos,ProgressBarMaxPos);
}
int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int&)
int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags)
{
int i;
@ -361,7 +361,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int&
#ifndef NO_GTK
if (I_GtkAvailable())
{
return I_PickIWad_Gtk (wads, numwads, showwin, defaultiwad);
return I_PickIWad_Gtk (wads, numwads, showwin, defaultiwad, autoloadflags);
}
#endif

View File

@ -64,6 +64,8 @@ typedef enum
#include "printf.h"
EXTERN_CVAR (Bool, queryiwad);
EXTERN_CVAR (Int, vid_preferbackend);
EXTERN_CVAR (Bool, vid_fullscreen);
namespace Gtk {
@ -95,6 +97,9 @@ DYN_GTK_SYM(gtk_button_box_set_layout);
DYN_GTK_SYM(gtk_button_new_with_label);
DYN_GTK_SYM(gtk_cell_renderer_text_new);
DYN_GTK_SYM(gtk_check_button_new_with_label);
DYN_GTK_SYM(gtk_radio_button_new_with_label);
DYN_GTK_SYM(gtk_radio_button_new_with_label_from_widget);
DYN_GTK_SYM(gtk_radio_button_get_type);
DYN_GTK_SYM(gtk_container_add);
DYN_GTK_SYM(gtk_container_get_type);
DYN_GTK_SYM(gtk_container_set_border_width);
@ -190,137 +195,133 @@ static void ClickedOK(GtkButton *button, gpointer func_data)
gtk_main_quit();
}
static int PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
class ZUIWidget
{
GtkWidget *window;
GtkWidget *vbox = nullptr;
GtkWidget *hbox = nullptr;
GtkWidget *bbox = nullptr;
GtkWidget *widget;
GtkWidget *tree;
GtkWidget *check;
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *selection;
GtkTreeIter iter, defiter;
int close_style = 0;
int i;
char caption[100];
public:
virtual ~ZUIWidget() = default;
// Create the dialog window.
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
mysnprintf(caption, countof(caption), GAMENAME " %s: Select an IWAD to use", GetVersionString());
gtk_window_set_title (GTK_WINDOW(window), caption);
gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_gravity (GTK_WINDOW(window), GDK_GRAVITY_CENTER);
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
g_signal_connect (window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect (window, "key_press_event", G_CALLBACK(CheckEscape), NULL);
GtkWidget *widget = nullptr;
};
// Create the vbox container.
if (gtk_box_new) // Gtk3
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
else if (gtk_vbox_new) // Gtk2
vbox = gtk_vbox_new (FALSE, 10);
gtk_container_add (GTK_CONTAINER(window), vbox);
// Create the top label.
widget = gtk_label_new (GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:");
gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0);
if (gtk_widget_set_halign && gtk_widget_set_valign) // Gtk3
class ZUIWindow : public ZUIWidget
{
public:
ZUIWindow(const char* title)
{
gtk_widget_set_halign (widget, GTK_ALIGN_START);
gtk_widget_set_valign (widget, GTK_ALIGN_START);
widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(widget), title);
gtk_window_set_position (GTK_WINDOW(widget), GTK_WIN_POS_CENTER);
gtk_window_set_gravity (GTK_WINDOW(widget), GDK_GRAVITY_CENTER);
gtk_container_set_border_width (GTK_CONTAINER(widget), 15);
g_signal_connect (widget, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect (widget, "key_press_event", G_CALLBACK(CheckEscape), NULL);
}
else if (gtk_misc_set_alignment && gtk_misc_get_type) // Gtk2
gtk_misc_set_alignment (GTK_MISC(widget), 0, 0);
// Create a list store with all the found IWADs.
store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
for (i = 0; i < numwads; ++i)
~ZUIWindow()
{
const char *filepart = strrchr (wads[i].Path, '/');
if (filepart == NULL)
filepart = wads[i].Path;
else
filepart++;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, filepart,
1, wads[i].Name.GetChars(),
2, i,
-1);
if (i == defaultiwad)
if (GTK_IS_WINDOW(widget))
{
defiter = iter;
gtk_widget_destroy (widget);
// If we don't do this, then the X window might not actually disappear.
while (g_main_context_iteration (NULL, FALSE)) {}
}
}
// Create the tree view control to show the list.
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("IWAD", renderer, "text", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Game", renderer, "text", 1, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column);
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(tree), true, true, 0);
g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(DoubleClickChecker), &close_style);
g_signal_connect(G_OBJECT(tree), "key_press_event", G_CALLBACK(AllowDefault), window);
void AddWidget(ZUIWidget* child)
{
gtk_container_add (GTK_CONTAINER(widget), child->widget);
}
// Select the default IWAD.
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
gtk_tree_selection_select_iter (selection, &defiter);
void RunModal()
{
gtk_widget_show_all (widget);
gtk_main ();
}
};
// Create the hbox for the bottom row.
if (gtk_box_new) // Gtk3
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
else if (gtk_hbox_new) // Gtk2
hbox = gtk_hbox_new (FALSE, 0);
class ZUIVBox : public ZUIWidget
{
public:
ZUIVBox()
{
if (gtk_box_new) // Gtk3
widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
else if (gtk_vbox_new) // Gtk2
widget = gtk_vbox_new (FALSE, 10);
}
gtk_box_pack_end (GTK_BOX(vbox), hbox, false, false, 0);
void PackStart(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_start (GTK_BOX(widget), child->widget, expand, fill, padding);
}
// Create the "Don't ask" checkbox.
check = gtk_check_button_new_with_label ("Don't ask me this again");
gtk_box_pack_start (GTK_BOX(hbox), check, false, false, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check), !showwin);
void PackEnd(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_end (GTK_BOX(widget), child->widget, expand, fill, padding);
}
};
// Create the OK/Cancel button box.
if (gtk_button_box_new) // Gtk3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
else if (gtk_hbutton_box_new) // Gtk2
bbox = gtk_hbutton_box_new ();
class ZUILabel : public ZUIWidget
{
public:
ZUILabel(const char* text)
{
widget = gtk_label_new (text);
gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
gtk_box_set_spacing (GTK_BOX(bbox), 10);
gtk_box_pack_end (GTK_BOX(hbox), bbox, false, false, 0);
if (gtk_widget_set_halign && gtk_widget_set_valign) // Gtk3
{
gtk_widget_set_halign (widget, GTK_ALIGN_START);
gtk_widget_set_valign (widget, GTK_ALIGN_START);
}
else if (gtk_misc_set_alignment && gtk_misc_get_type) // Gtk2
gtk_misc_set_alignment (GTK_MISC(widget), 0, 0);
}
};
// Create the OK button.
widget = gtk_button_new_with_label ("OK");
class ZUIListView : public ZUIWidget
{
public:
ZUIListView(WadStuff *wads, int numwads, int defaultiwad)
{
// Create a list store with all the found IWADs.
store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
for (int i = 0; i < numwads; ++i)
{
const char *filepart = strrchr (wads[i].Path, '/');
if (filepart == NULL)
filepart = wads[i].Path;
else
filepart++;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, filepart,
1, wads[i].Name.GetChars(),
2, i,
-1);
if (i == defaultiwad)
{
defiter = iter;
}
}
gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0);
// Create the tree view control to show the list.
widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("IWAD", renderer, "text", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(widget), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Game", renderer, "text", 1, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(widget), column);
gtk_widget_set_can_default (widget, true);
// Select the default IWAD.
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(widget));
gtk_tree_selection_select_iter (selection, &defiter);
}
gtk_widget_grab_default (widget);
g_signal_connect (widget, "clicked", G_CALLBACK(ClickedOK), &close_style);
g_signal_connect (widget, "activate", G_CALLBACK(ClickedOK), &close_style);
// Create the cancel button.
widget = gtk_button_new_with_label ("Cancel");
gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0);
g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window);
// Finally we can show everything.
gtk_widget_show_all (window);
gtk_main ();
if (close_style == 1)
int GetSelectedIndex()
{
GtkTreeModel *model;
GValue value = { 0, { {0} } };
@ -328,96 +329,287 @@ static int PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
// Find out which IWAD was selected.
gtk_tree_selection_get_selected (selection, &model, &iter);
gtk_tree_model_get_value (GTK_TREE_MODEL(model), &iter, 2, &value);
i = g_value_get_int (&value);
int i = g_value_get_int (&value);
g_value_unset (&value);
return i;
}
void ConnectButtonPress(int *close_style)
{
g_signal_connect(G_OBJECT(widget), "button_press_event", G_CALLBACK(DoubleClickChecker), &close_style);
}
void ConnectKeyPress(ZUIWindow* window)
{
g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK(AllowDefault), window->widget);
}
GtkListStore *store = nullptr;
GtkCellRenderer *renderer = nullptr;
GtkTreeViewColumn *column = nullptr;
GtkTreeSelection *selection = nullptr;
GtkTreeIter iter, defiter;
};
class ZUIHBox : public ZUIWidget
{
public:
ZUIHBox()
{
// Create the hbox for the bottom row.
if (gtk_box_new) // Gtk3
widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
else if (gtk_hbox_new) // Gtk2
widget = gtk_hbox_new (FALSE, 0);
}
void PackStart(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_start (GTK_BOX(widget), child->widget, expand, fill, padding);
}
void PackEnd(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_end (GTK_BOX(widget), child->widget, expand, fill, padding);
}
};
class ZUICheckButton : public ZUIWidget
{
public:
ZUICheckButton(const char* text)
{
widget = gtk_check_button_new_with_label (text);
}
void SetChecked(bool value)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), value);
}
int GetChecked()
{
return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
}
};
class ZUIRadioButton : public ZUIWidget
{
public:
ZUIRadioButton(const char* text)
{
widget = gtk_radio_button_new_with_label (nullptr, text);
}
ZUIRadioButton(ZUIRadioButton* group, const char* text)
{
widget = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(group->widget), text);
}
void SetChecked(bool value)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget), value);
}
int GetChecked()
{
return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget));
}
};
class ZUIButtonBox : public ZUIWidget
{
public:
ZUIButtonBox()
{
if (gtk_button_box_new) // Gtk3
widget = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
else if (gtk_hbutton_box_new) // Gtk2
widget = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX(widget), GTK_BUTTONBOX_END);
gtk_box_set_spacing (GTK_BOX(widget), 10);
}
void PackStart(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_start (GTK_BOX(widget), child->widget, expand, fill, padding);
}
void PackEnd(ZUIWidget* child, bool expand, bool fill, int padding)
{
gtk_box_pack_end (GTK_BOX(widget), child->widget, expand, fill, padding);
}
};
class ZUIButton : public ZUIWidget
{
public:
ZUIButton(const char* text, bool defaultButton)
{
widget = gtk_button_new_with_label (text);
if (defaultButton)
{
gtk_widget_set_can_default (widget, true);
}
}
void GrabDefault()
{
gtk_widget_grab_default (widget);
}
void ConnectClickedOK(int *close_style)
{
g_signal_connect (widget, "clicked", G_CALLBACK(ClickedOK), close_style);
g_signal_connect (widget, "activate", G_CALLBACK(ClickedOK), close_style);
}
void ConnectClickedExit(ZUIWindow* window)
{
g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window->widget);
}
};
static int PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags)
{
char caption[100];
mysnprintf(caption, countof(caption), GAMENAME " %s: Select an IWAD to use", GetVersionString());
ZUIWindow window(caption);
ZUIVBox vbox;
ZUILabel label(GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:");
ZUIListView listview(wads, numwads, defaultiwad);
ZUIHBox hboxOptions;
ZUIVBox vboxVideo;
ZUILabel videoSettings("Video settings");
ZUIRadioButton opengl("OpenGL");
ZUIRadioButton vulkan(&opengl, "Vulkan");
ZUIRadioButton openglES(&opengl, "OpenGL ES");
ZUICheckButton fullscreen("Full screen");
ZUIVBox vboxMisc;
ZUICheckButton noautoload("Disable autoload");
ZUICheckButton dontAskAgain("Don't ask me this again");
ZUIVBox vboxExtra;
ZUILabel extraGraphics("Extra graphics");
ZUICheckButton lights("Lights");
ZUICheckButton brightmaps("Brightmaps");
ZUICheckButton widescreen("Widescreen");
ZUIHBox hboxButtons;
ZUIButtonBox bbox;
ZUIButton playButton("Play Game!", true);
ZUIButton exitButton("Exit", false);
window.AddWidget(&vbox);
vbox.PackStart(&label, false, false, 0);
vbox.PackStart(&listview, true, true, 0);
vbox.PackEnd(&hboxButtons, false, false, 0);
vbox.PackEnd(&hboxOptions, false, false, 0);
hboxOptions.PackStart(&vboxVideo, false, false, 15);
hboxOptions.PackStart(&vboxMisc, true, false, 15);
hboxOptions.PackStart(&vboxExtra, false, false, 15);
vboxVideo.PackStart(&videoSettings, false, false, 0);
vboxVideo.PackStart(&opengl, false, false, 0);
vboxVideo.PackStart(&vulkan, false, false, 0);
vboxVideo.PackStart(&openglES, false, false, 0);
vboxVideo.PackStart(&fullscreen, false, false, 15);
vboxMisc.PackStart(&noautoload, false, false, 0);
vboxMisc.PackStart(&dontAskAgain, false, false, 0);
vboxExtra.PackStart(&extraGraphics, false, false, 0);
vboxExtra.PackStart(&lights, false, false, 0);
vboxExtra.PackStart(&brightmaps, false, false, 0);
vboxExtra.PackStart(&widescreen, false, false, 0);
hboxButtons.PackStart(&bbox, true, true, 0);
bbox.PackStart(&playButton, false, false, 0);
bbox.PackEnd(&exitButton, false, false, 0);
dontAskAgain.SetChecked(!showwin);
switch (vid_preferbackend)
{
case 0: opengl.SetChecked(true); break;
case 1: vulkan.SetChecked(true); break;
case 2: openglES.SetChecked(true); break;
default: break;
}
if (vid_fullscreen) fullscreen.SetChecked(true);
if (autoloadflags & 1) noautoload.SetChecked(true);
if (autoloadflags & 2) lights.SetChecked(true);
if (autoloadflags & 4) brightmaps.SetChecked(true);
if (autoloadflags & 8) widescreen.SetChecked(true);
int close_style = 0;
listview.ConnectButtonPress(&close_style);
listview.ConnectKeyPress(&window);
playButton.ConnectClickedOK(&close_style);
exitButton.ConnectClickedExit(&window);
playButton.GrabDefault();
window.RunModal();
if (close_style == 1)
{
int i = listview.GetSelectedIndex();
// Set state of queryiwad based on the checkbox.
queryiwad = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(check));
queryiwad = !dontAskAgain.GetChecked();
if (opengl.GetChecked()) vid_preferbackend = 0;
if (vulkan.GetChecked()) vid_preferbackend = 1;
if (openglES.GetChecked()) vid_preferbackend = 2;
vid_fullscreen = fullscreen.GetChecked();
autoloadflags = 0;
if (noautoload.GetChecked()) autoloadflags |= 1;
if (lights.GetChecked()) autoloadflags |= 2;
if (brightmaps.GetChecked()) autoloadflags |= 4;
if (widescreen.GetChecked()) autoloadflags |= 8;
return i;
}
else
{
i = -1;
return -1;
}
if (GTK_IS_WINDOW(window))
{
gtk_widget_destroy (window);
// If we don't do this, then the X window might not actually disappear.
while (g_main_context_iteration (NULL, FALSE)) {}
}
return i;
}
static void ShowError(const char* errortext)
{
GtkWidget *window;
GtkWidget *widget;
GtkWidget *vbox = nullptr;
GtkWidget *bbox = nullptr;
ZUIWindow window("Fatal error");
ZUIVBox vbox;
ZUILabel label(errortext);
ZUIButtonBox bbox;
ZUIButton exitButton("Exit", true);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "Fatal error");
gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_gravity (GTK_WINDOW(window), GDK_GRAVITY_CENTER);
gtk_window_set_resizable (GTK_WINDOW(window), false);
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
g_signal_connect (window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect (window, "key_press_event", G_CALLBACK(CheckEscape), NULL);
window.AddWidget(&vbox);
vbox.PackStart(&label, true, true, 0);
vbox.PackEnd(&bbox, false, false, 0);
bbox.PackEnd(&exitButton, false, false, 0);
// Create the vbox container.
if (gtk_box_new) // Gtk3
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
else if (gtk_vbox_new) // Gtk2
vbox = gtk_vbox_new (FALSE, 10);
exitButton.ConnectClickedExit(&window);
gtk_container_add (GTK_CONTAINER(window), vbox);
// Create the label.
widget = gtk_label_new ((const gchar *) errortext);
gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0);
if (gtk_widget_set_halign && gtk_widget_set_valign) // Gtk3
{
gtk_widget_set_halign (widget, GTK_ALIGN_START);
gtk_widget_set_valign (widget, GTK_ALIGN_START);
}
else if (gtk_misc_set_alignment && gtk_misc_get_type) // Gtk2
gtk_misc_set_alignment (GTK_MISC(widget), 0, 0);
// Create the Exit button box.
if (gtk_button_box_new) // Gtk3
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
else if (gtk_hbutton_box_new) // Gtk2
bbox = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
gtk_box_set_spacing (GTK_BOX(bbox), 10);
gtk_box_pack_end (GTK_BOX(vbox), bbox, false, false, 0);
// Create the cancel button.
widget = gtk_button_new_with_label ("Exit");
gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0);
g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window);
// Finally we can show everything.
gtk_widget_show_all (window);
gtk_main ();
if (GTK_IS_WINDOW(window))
{
gtk_widget_destroy (window);
// If we don't do this, then the X window might not actually disappear.
while (g_main_context_iteration (NULL, FALSE)) {}
}
exitButton.GrabDefault();
window.RunModal();
}
} // namespace Gtk
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags)
{
return Gtk::PickIWad (wads, numwads, showwin, defaultiwad);
return Gtk::PickIWad (wads, numwads, showwin, defaultiwad, autoloadflags);
}
void I_ShowFatalError_Gtk(const char* errortext) {