Subversion Repositories eduke32

Rev

Rev 4541 | Rev 4773 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4541 Rev 4770
1
//-------------------------------------------------------------------------
1
//-------------------------------------------------------------------------
2
/*
2
/*
3
Copyright (C) 2010 EDuke32 developers and contributors
3
Copyright (C) 2010 EDuke32 developers and contributors
4

4

5
This file is part of EDuke32.
5
This file is part of EDuke32.
6

6

7
EDuke32 is free software; you can redistribute it and/or
7
EDuke32 is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License version 2
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
9
as published by the Free Software Foundation.
10

10

11
This program is distributed in the hope that it will be useful,
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14

14

15
See the GNU General Public License for more details.
15
See the GNU General Public License for more details.
16

16

17
You should have received a copy of the GNU General Public License
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
*/
20
*/
21
//-------------------------------------------------------------------------
21
//-------------------------------------------------------------------------
22
22
-
 
23
#include "gtkpixdata.h"
-
 
24
23
#if defined(LINKED_GTK)
25
#if defined(LINKED_GTK)
24
#include <gtk/gtk.h>
26
#include <gtk/gtk.h>
25
#include <gdk-pixbuf/gdk-pixdata.h>
27
#include <gdk-pixbuf/gdk-pixdata.h>
26
#else
28
#else
27
#include "dynamicgtk.h"
29
#include "dynamicgtk.h"
28
#endif
30
#endif
29
31
30
#include "duke3d.h"
32
#include "duke3d.h"
31
#include "grpscan.h"
33
#include "grpscan.h"
32
#include "build.h"
34
#include "build.h"
33
35
34
#include "game.h"
36
#include "game.h"
35
#include "common.h"
37
#include "common.h"
36
#include "common_game.h"
38
#include "common_game.h"
37
39
38
enum
40
enum
39
{
41
{
40
    NONE,
42
    NONE,
41
    ALL,
43
    ALL,
42
    POPULATE_VIDEO,
44
    POPULATE_VIDEO,
43
    POPULATE_CONFIG,
45
    POPULATE_CONFIG,
44
    POPULATE_GAME,
46
    POPULATE_GAME,
45
};
47
};
46
48
47
enum
49
enum
48
{
50
{
49
    TAB_CONFIG,
51
    TAB_CONFIG,
50
    TAB_GAME,
52
    TAB_GAME,
51
    TAB_MESSAGES,
53
    TAB_MESSAGES,
52
};
54
};
53
55
54
enum
56
enum
55
{
57
{
56
    INPUT_KB,
58
    INPUT_KB,
57
    INPUT_MOUSE,
59
    INPUT_MOUSE,
58
    INPUT_JOYSTICK,
60
    INPUT_JOYSTICK,
59
    INPUT_ALL,
61
    INPUT_ALL,
60
};
62
};
61
63
62
static struct
64
static struct
63
{
65
{
64
    GtkWidget *startwin;
66
    GtkWidget *startwin;
65
    GtkWidget *hlayout;
67
    GtkWidget *hlayout;
66
    GtkWidget *banner;
68
    GtkWidget *banner;
67
    GtkWidget *vlayout;
69
    GtkWidget *vlayout;
68
    GtkWidget *tabs;
70
    GtkWidget *tabs;
69
    GtkWidget *configtlayout;
71
    GtkWidget *configtlayout;
70
    GtkWidget *displayvlayout;
72
    GtkWidget *displayvlayout;
71
    GtkWidget *vmode3dlabel;
73
    GtkWidget *vmode3dlabel;
72
    GtkWidget *vmode3dcombo;
74
    GtkWidget *vmode3dcombo;
73
    GtkWidget *fullscreencheck;
75
    GtkWidget *fullscreencheck;
74
#ifdef POLYMER
76
#ifdef POLYMER
75
    GtkWidget *polymercheck;
77
    GtkWidget *polymercheck;
76
#endif
78
#endif
77
    GtkWidget *inputdevlabel;
79
    GtkWidget *inputdevlabel;
78
    GtkWidget *inputdevcombo;
80
    GtkWidget *inputdevcombo;
79
    GtkWidget *custommodlabel;
81
    GtkWidget *custommodlabel;
80
    GtkWidget *custommodcombo;
82
    GtkWidget *custommodcombo;
81
    GtkWidget *emptyhlayout;
83
    GtkWidget *emptyhlayout;
82
    GtkWidget *autoloadcheck;
84
    GtkWidget *autoloadcheck;
83
    GtkWidget *alwaysshowcheck;
85
    GtkWidget *alwaysshowcheck;
84
    GtkWidget *configtab;
86
    GtkWidget *configtab;
85
    GtkWidget *gamevlayout;
87
    GtkWidget *gamevlayout;
86
    GtkWidget *gamelabel;
88
    GtkWidget *gamelabel;
87
    GtkWidget *gamescroll;
89
    GtkWidget *gamescroll;
88
    GtkWidget *gamelist;
90
    GtkWidget *gamelist;
89
    GtkWidget *gametab;
91
    GtkWidget *gametab;
90
    GtkWidget *messagesscroll;
92
    GtkWidget *messagesscroll;
91
    GtkWidget *messagestext;
93
    GtkWidget *messagestext;
92
    GtkWidget *messagestab;
94
    GtkWidget *messagestab;
93
    GtkWidget *buttons;
95
    GtkWidget *buttons;
94
    GtkWidget *cancelbutton;
96
    GtkWidget *cancelbutton;
95
    GtkWidget *cancelbuttonalign;
97
    GtkWidget *cancelbuttonalign;
96
    GtkWidget *cancelbuttonlayout;
98
    GtkWidget *cancelbuttonlayout;
97
    GtkWidget *cancelbuttonicon;
99
    GtkWidget *cancelbuttonicon;
98
    GtkWidget *cancelbuttonlabel;
100
    GtkWidget *cancelbuttonlabel;
99
    GtkWidget *startbutton;
101
    GtkWidget *startbutton;
100
    GtkWidget *startbuttonalign;
102
    GtkWidget *startbuttonalign;
101
    GtkWidget *startbuttonlayout;
103
    GtkWidget *startbuttonlayout;
102
    GtkWidget *startbuttonicon;
104
    GtkWidget *startbuttonicon;
103
    GtkWidget *startbuttonlabel;
105
    GtkWidget *startbuttonlabel;
104
} stwidgets;
106
} stwidgets;
105
107
106
static struct
108
static struct
107
{
109
{
108
    int32_t fullscreen;
110
    int32_t fullscreen;
109
#ifdef POLYMER
111
#ifdef POLYMER
110
    int32_t polymer;
112
    int32_t polymer;
111
#endif
113
#endif
112
    int32_t xdim3d, ydim3d, bpp3d;
114
    int32_t xdim3d, ydim3d, bpp3d;
113
    int32_t forcesetup;
115
    int32_t forcesetup;
114
    int32_t autoload;
116
    int32_t autoload;
115
    int32_t usemouse, usejoy;
117
    int32_t usemouse, usejoy;
116
    int32_t game;
118
    int32_t game;
117
    int32_t crcval;
119
    int32_t crcval;
118
    char *custommoddir;
120
    char *custommoddir;
119
    char selectedgrp[BMAX_PATH];
121
    char selectedgrp[BMAX_PATH];
120
} settings;
122
} settings;
121
123
122
static int32_t retval = -1, mode = TAB_MESSAGES;
124
static int32_t retval = -1, mode = TAB_MESSAGES;
123
extern int32_t gtkenabled;
125
extern int32_t gtkenabled;
124
static void PopulateForm(unsigned char pgs);
126
static void PopulateForm(unsigned char pgs);
125
127
126
128
127
// -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
129
// -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
128
130
129
static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
131
static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
130
{
132
{
131
    GtkTreeModel *data;
133
    GtkTreeModel *data;
132
    GtkTreeIter iter;
134
    GtkTreeIter iter;
133
    int32_t val;
135
    int32_t val;
134
    UNREFERENCED_PARAMETER(user_data);
136
    UNREFERENCED_PARAMETER(user_data);
135
137
136
    if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
138
    if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
137
    if (!(data = gtk_combo_box_get_model(combobox))) return;
139
    if (!(data = gtk_combo_box_get_model(combobox))) return;
138
    gtk_tree_model_get(data, &iter, 1, &val, -1);
140
    gtk_tree_model_get(data, &iter, 1, &val, -1);
139
    settings.xdim3d = validmode[val].xdim;
141
    settings.xdim3d = validmode[val].xdim;
140
    settings.ydim3d = validmode[val].ydim;
142
    settings.ydim3d = validmode[val].ydim;
141
}
143
}
142
144
143
static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
145
static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
144
{
146
{
145
    UNREFERENCED_PARAMETER(user_data);
147
    UNREFERENCED_PARAMETER(user_data);
146
    settings.fullscreen = gtk_toggle_button_get_active(togglebutton);
148
    settings.fullscreen = gtk_toggle_button_get_active(togglebutton);
147
    PopulateForm(POPULATE_VIDEO);
149
    PopulateForm(POPULATE_VIDEO);
148
}
150
}
149
151
150
#ifdef POLYMER
152
#ifdef POLYMER
151
static void on_polymercheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
153
static void on_polymercheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
152
{
154
{
153
    UNREFERENCED_PARAMETER(user_data);
155
    UNREFERENCED_PARAMETER(user_data);
154
    if (gtk_toggle_button_get_active(togglebutton))
156
    if (gtk_toggle_button_get_active(togglebutton))
155
    {
157
    {
156
        glrendmode = REND_POLYMER;
158
        glrendmode = REND_POLYMER;
157
        settings.polymer = TRUE;
159
        settings.polymer = TRUE;
158
        if (settings.bpp3d == 8)
160
        if (settings.bpp3d == 8)
159
        {
161
        {
160
            settings.bpp3d = 32;
162
            settings.bpp3d = 32;
161
            PopulateForm(POPULATE_VIDEO);
163
            PopulateForm(POPULATE_VIDEO);
162
        }
164
        }
163
    }
165
    }
164
    else
166
    else
165
    {
167
    {
166
        glrendmode = REND_POLYMOST;
168
        glrendmode = REND_POLYMOST;
167
        settings.polymer = FALSE;
169
        settings.polymer = FALSE;
168
    }
170
    }
169
}
171
}
170
#endif
172
#endif
171
173
172
static void on_inputdevcombo_changed(GtkComboBox *combobox, gpointer user_data)
174
static void on_inputdevcombo_changed(GtkComboBox *combobox, gpointer user_data)
173
{
175
{
174
    UNREFERENCED_PARAMETER(user_data);
176
    UNREFERENCED_PARAMETER(user_data);
175
    switch (gtk_combo_box_get_active(combobox))
177
    switch (gtk_combo_box_get_active(combobox))
176
    {
178
    {
177
    case 0: settings.usemouse = 0; settings.usejoy = 0; break;
179
    case 0: settings.usemouse = 0; settings.usejoy = 0; break;
178
    case 1:     settings.usemouse = 1; settings.usejoy = 0; break;
180
    case 1:     settings.usemouse = 1; settings.usejoy = 0; break;
179
    case 2:     settings.usemouse = 0; settings.usejoy = 1; break;
181
    case 2:     settings.usemouse = 0; settings.usejoy = 1; break;
180
    case 3:     settings.usemouse = 1; settings.usejoy = 1; break;
182
    case 3:     settings.usemouse = 1; settings.usejoy = 1; break;
181
    }
183
    }
182
}
184
}
183
185
184
static void on_custommodcombo_changed(GtkComboBox *combobox, gpointer user_data)
186
static void on_custommodcombo_changed(GtkComboBox *combobox, gpointer user_data)
185
{
187
{
186
    GtkTreeIter iter;
188
    GtkTreeIter iter;
187
    GtkTreeModel *model;
189
    GtkTreeModel *model;
188
    GtkTreePath *path;
190
    GtkTreePath *path;
189
    char *value;
191
    char *value;
190
    UNREFERENCED_PARAMETER(user_data);
192
    UNREFERENCED_PARAMETER(user_data);
191
193
192
    if (gtk_combo_box_get_active_iter(combobox, &iter))
194
    if (gtk_combo_box_get_active_iter(combobox, &iter))
193
    {
195
    {
194
        model = gtk_combo_box_get_model(combobox);
196
        model = gtk_combo_box_get_model(combobox);
195
        gtk_tree_model_get(model, &iter, 0,&value, -1);
197
        gtk_tree_model_get(model, &iter, 0,&value, -1);
196
        path = gtk_tree_model_get_path(model, &iter);
198
        path = gtk_tree_model_get_path(model, &iter);
197
199
198
        if (*gtk_tree_path_get_indices(path) == NONE)
200
        if (*gtk_tree_path_get_indices(path) == NONE)
199
            settings.custommoddir = NULL;
201
            settings.custommoddir = NULL;
200
        else settings.custommoddir = value;
202
        else settings.custommoddir = value;
201
    }
203
    }
202
}
204
}
203
205
204
static void on_autoloadcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
206
static void on_autoloadcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
205
{
207
{
206
    UNREFERENCED_PARAMETER(user_data);
208
    UNREFERENCED_PARAMETER(user_data);
207
    settings.autoload = gtk_toggle_button_get_active(togglebutton);
209
    settings.autoload = gtk_toggle_button_get_active(togglebutton);
208
}
210
}
209
211
210
static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
212
static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
211
{
213
{
212
    UNREFERENCED_PARAMETER(user_data);
214
    UNREFERENCED_PARAMETER(user_data);
213
    settings.forcesetup = gtk_toggle_button_get_active(togglebutton);
215
    settings.forcesetup = gtk_toggle_button_get_active(togglebutton);
214
}
216
}
215
217
216
static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
218
static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
217
{
219
{
218
    UNREFERENCED_PARAMETER(button);
220
    UNREFERENCED_PARAMETER(button);
219
    UNREFERENCED_PARAMETER(user_data);
221
    UNREFERENCED_PARAMETER(user_data);
220
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
222
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
221
    else quitevent++;
223
    else quitevent++;
222
}
224
}
223
225
224
static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
226
static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
225
{
227
{
226
    UNREFERENCED_PARAMETER(button);
228
    UNREFERENCED_PARAMETER(button);
227
    UNREFERENCED_PARAMETER(user_data);
229
    UNREFERENCED_PARAMETER(user_data);
228
    retval = 1;
230
    retval = 1;
229
    gtk_main_quit();
231
    gtk_main_quit();
230
}
232
}
231
233
232
static void on_gamelist_selection_changed(GtkTreeSelection *selection, gpointer user_data)
234
static void on_gamelist_selection_changed(GtkTreeSelection *selection, gpointer user_data)
233
{
235
{
234
    GtkTreeIter iter;
236
    GtkTreeIter iter;
235
    GtkTreeModel *model;
237
    GtkTreeModel *model;
236
    struct grpfile *fg;
238
    struct grpfile *fg;
237
    UNREFERENCED_PARAMETER(user_data);
239
    UNREFERENCED_PARAMETER(user_data);
238
240
239
    if (gtk_tree_selection_get_selected(selection, &model, &iter))
241
    if (gtk_tree_selection_get_selected(selection, &model, &iter))
240
    {
242
    {
241
        gtk_tree_model_get(model, &iter, 2, (gpointer)&fg, -1);
243
        gtk_tree_model_get(model, &iter, 2, (gpointer)&fg, -1);
242
        strcpy(settings.selectedgrp, fg->name);
244
        strcpy(settings.selectedgrp, fg->name);
243
        settings.game = fg->game;
245
        settings.game = fg->game;
244
        settings.crcval = fg->crcval;
246
        settings.crcval = fg->crcval;
245
    }
247
    }
246
}
248
}
247
249
248
static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
250
static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
249
{
251
{
250
    UNREFERENCED_PARAMETER(widget);
252
    UNREFERENCED_PARAMETER(widget);
251
    UNREFERENCED_PARAMETER(event);
253
    UNREFERENCED_PARAMETER(event);
252
    UNREFERENCED_PARAMETER(user_data);
254
    UNREFERENCED_PARAMETER(user_data);
253
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
255
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
254
    else quitevent++;
256
    else quitevent++;
255
    return TRUE;        // FALSE would let the event go through. we want the game to decide when to close
257
    return TRUE;        // FALSE would let the event go through. we want the game to decide when to close
256
}
258
}
257
259
258
260
259
// -- SUPPORT FUNCTIONS -------------------------------------------------------
261
// -- SUPPORT FUNCTIONS -------------------------------------------------------
260
extern const GdkPixdata startbanner_pixdata;
-
 
261
262
262
static GdkPixbuf *load_banner(void)
263
static GdkPixbuf *load_banner(void)
263
{
264
{
264
    extern const GdkPixdata startbanner_pixdata;
-
 
265
    return gdk_pixbuf_from_pixdata(&startbanner_pixdata, FALSE, NULL);
265
    return gdk_pixbuf_from_pixdata((GdkPixdata*)&startbanner_pixdata, FALSE, NULL);
266
}
266
}
267
267
268
static void SetPage(int32_t n)
268
static void SetPage(int32_t n)
269
{
269
{
270
    if (!gtkenabled || !stwidgets.startwin) return;
270
    if (!gtkenabled || !stwidgets.startwin) return;
271
    mode = n;
271
    mode = n;
272
    gtk_notebook_set_current_page(GTK_NOTEBOOK(stwidgets.tabs), n);
272
    gtk_notebook_set_current_page(GTK_NOTEBOOK(stwidgets.tabs), n);
273
273
274
    // each control in the config page vertical layout plus the start button should be made (in)sensitive
274
    // each control in the config page vertical layout plus the start button should be made (in)sensitive
275
    if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
275
    if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
276
    gtk_widget_set_sensitive(stwidgets.startbutton, n);
276
    gtk_widget_set_sensitive(stwidgets.startbutton, n);
277
    gtk_container_foreach(GTK_CONTAINER(stwidgets.configtlayout),
277
    gtk_container_foreach(GTK_CONTAINER(stwidgets.configtlayout),
278
                          (GtkCallback)gtk_widget_set_sensitive,
278
                          (GtkCallback)gtk_widget_set_sensitive,
279
                          (gpointer)&n);
279
                          (gpointer)&n);
280
}
280
}
281
281
282
static unsigned char GetModsDirNames(GtkListStore *list)
282
static unsigned char GetModsDirNames(GtkListStore *list)
283
{
283
{
284
    char *homedir;
284
    char *homedir;
285
    char pdir[BMAX_PATH];
285
    char pdir[BMAX_PATH];
286
    unsigned char iternumb = 0;
286
    unsigned char iternumb = 0;
287
    CACHE1D_FIND_REC *dirs = NULL;
287
    CACHE1D_FIND_REC *dirs = NULL;
288
    GtkTreeIter iter;
288
    GtkTreeIter iter;
289
289
290
    pathsearchmode = 1;
290
    pathsearchmode = 1;
291
291
292
    if ((homedir = Bgethomedir()))
292
    if ((homedir = Bgethomedir()))
293
    {
293
    {
294
        Bsnprintf(pdir, sizeof(pdir), "%s/" ".eduke32", homedir);
294
        Bsnprintf(pdir, sizeof(pdir), "%s/" ".eduke32", homedir);
295
        dirs = klistpath(pdir, "*", CACHE1D_FIND_DIR);
295
        dirs = klistpath(pdir, "*", CACHE1D_FIND_DIR);
296
        for (dirs=dirs; dirs != NULL; dirs=dirs->next)
296
        for (dirs=dirs; dirs != NULL; dirs=dirs->next)
297
        {
297
        {
298
            if ((Bstrcmp(dirs->name, "autoload") == 0) ||
298
            if ((Bstrcmp(dirs->name, "autoload") == 0) ||
299
                    (Bstrcmp(dirs->name, "..") == 0) ||
299
                    (Bstrcmp(dirs->name, "..") == 0) ||
300
                    (Bstrcmp(dirs->name, ".") == 0))
300
                    (Bstrcmp(dirs->name, ".") == 0))
301
                continue;
301
                continue;
302
            else
302
            else
303
            {
303
            {
304
                gtk_list_store_append(list, &iter);
304
                gtk_list_store_append(list, &iter);
305
                gtk_list_store_set(list, &iter, 0,dirs->name, -1);
305
                gtk_list_store_set(list, &iter, 0,dirs->name, -1);
306
                iternumb++;
306
                iternumb++;
307
            }
307
            }
308
        }
308
        }
309
    }
309
    }
310
310
311
    klistfree(dirs);
311
    klistfree(dirs);
312
    dirs = NULL;
312
    dirs = NULL;
313
313
314
    return iternumb;
314
    return iternumb;
315
}
315
}
316
316
317
static void PopulateForm(unsigned char pgs)
317
static void PopulateForm(unsigned char pgs)
318
{
318
{
319
    if ((pgs == ALL) || (pgs == POPULATE_VIDEO))
319
    if ((pgs == ALL) || (pgs == POPULATE_VIDEO))
320
    {
320
    {
321
        int32_t mode3d, i;
321
        int32_t mode3d, i;
322
        GtkListStore *modes3d;
322
        GtkListStore *modes3d;
323
        GtkTreeIter iter;
323
        GtkTreeIter iter;
324
        char buf[64];
324
        char buf[64];
325
325
326
        mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
326
        mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
327
        if (mode3d < 0)
327
        if (mode3d < 0)
328
        {
328
        {
329
            int32_t i, cd[] = { 32, 24, 16, 15, 8, 0 };
329
            int32_t i, cd[] = { 32, 24, 16, 15, 8, 0 };
330
330
331
            for (i=0; cd[i];) { if (cd[i] >= settings.bpp3d) i++; else break; }
331
            for (i=0; cd[i];) { if (cd[i] >= settings.bpp3d) i++; else break; }
332
            for (; cd[i]; i++)
332
            for (; cd[i]; i++)
333
            {
333
            {
334
                mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
334
                mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
335
                if (mode3d < 0) continue;
335
                if (mode3d < 0) continue;
336
                settings.bpp3d = cd[i];
336
                settings.bpp3d = cd[i];
337
                break;
337
                break;
338
            }
338
            }
339
        }
339
        }
340
340
341
        modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.vmode3dcombo)));
341
        modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.vmode3dcombo)));
342
        gtk_list_store_clear(modes3d);
342
        gtk_list_store_clear(modes3d);
343
343
344
        for (i=0; i<validmodecnt; i++)
344
        for (i=0; i<validmodecnt; i++)
345
        {
345
        {
346
            if (validmode[i].fs != settings.fullscreen) continue;
346
            if (validmode[i].fs != settings.fullscreen) continue;
347
347
348
            // all modes get added to the 3D mode list
348
            // all modes get added to the 3D mode list
349
            Bsprintf(buf, "%d x %d %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
349
            Bsprintf(buf, "%d x %d %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
350
            gtk_list_store_append(modes3d, &iter);
350
            gtk_list_store_append(modes3d, &iter);
351
            gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
351
            gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
352
            if (i == mode3d)
352
            if (i == mode3d)
353
            {
353
            {
354
                g_signal_handlers_block_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
354
                g_signal_handlers_block_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
355
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.vmode3dcombo), &iter);
355
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.vmode3dcombo), &iter);
356
                g_signal_handlers_unblock_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
356
                g_signal_handlers_unblock_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
357
            }
357
            }
358
        }
358
        }
359
    }
359
    }
360
360
361
    if ((pgs == ALL) || (pgs == POPULATE_CONFIG))
361
    if ((pgs == ALL) || (pgs == POPULATE_CONFIG))
362
    {
362
    {
363
        GtkListStore *devlist, *modsdir;
363
        GtkListStore *devlist, *modsdir;
364
        GtkTreeIter iter;
364
        GtkTreeIter iter;
365
        GtkTreePath *path;
365
        GtkTreePath *path;
366
        char *value;
366
        char *value;
367
        unsigned char i, r = 0;
367
        unsigned char i, r = 0;
368
        const char *availabledev[] =
368
        const char *availabledev[] =
369
        {
369
        {
370
            "Keyboard only",
370
            "Keyboard only",
371
            "Keyboard and mouse",
371
            "Keyboard and mouse",
372
            "Keyboard and joystick",
372
            "Keyboard and joystick",
373
            "All supported devices"
373
            "All supported devices"
374
        };
374
        };
375
375
376
        // populate input devices combo
376
        // populate input devices combo
377
        devlist = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.inputdevcombo)));
377
        devlist = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.inputdevcombo)));
378
        gtk_list_store_clear(devlist);
378
        gtk_list_store_clear(devlist);
379
379
380
        for (i=0; i<(int32_t)G_N_ELEMENTS(availabledev); i++)
380
        for (i=0; i<(int32_t)G_N_ELEMENTS(availabledev); i++)
381
        {
381
        {
382
            gtk_list_store_append(devlist, &iter);
382
            gtk_list_store_append(devlist, &iter);
383
            gtk_list_store_set(devlist, &iter, 0,availabledev[i], -1);
383
            gtk_list_store_set(devlist, &iter, 0,availabledev[i], -1);
384
        }
384
        }
385
        switch (settings.usemouse)
385
        switch (settings.usemouse)
386
        {
386
        {
387
        case 0: if (settings.usejoy)
387
        case 0: if (settings.usejoy)
388
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_JOYSTICK);
388
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_JOYSTICK);
389
            else
389
            else
390
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_KB);
390
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_KB);
391
            break;
391
            break;
392
        case 1: if (settings.usejoy)
392
        case 1: if (settings.usejoy)
393
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_ALL);
393
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_ALL);
394
            else
394
            else
395
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_MOUSE);
395
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_MOUSE);
396
            break;
396
            break;
397
        }
397
        }
398
398
399
        // populate custom mod combo
399
        // populate custom mod combo
400
        modsdir = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.custommodcombo)));
400
        modsdir = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.custommodcombo)));
401
        gtk_list_store_clear(modsdir);
401
        gtk_list_store_clear(modsdir);
402
402
403
        gtk_list_store_append(modsdir, &iter);
403
        gtk_list_store_append(modsdir, &iter);
404
        gtk_list_store_set(modsdir, &iter, 0,"None", -1);
404
        gtk_list_store_set(modsdir, &iter, 0,"None", -1);
405
        r = GetModsDirNames(modsdir);
405
        r = GetModsDirNames(modsdir);
406
406
407
        for (i=0; i<=r; i++)
407
        for (i=0; i<=r; i++)
408
        {
408
        {
409
            path = gtk_tree_path_new_from_indices(i, -1);
409
            path = gtk_tree_path_new_from_indices(i, -1);
410
            gtk_tree_model_get_iter(GTK_TREE_MODEL(modsdir), &iter, path);
410
            gtk_tree_model_get_iter(GTK_TREE_MODEL(modsdir), &iter, path);
411
            gtk_tree_model_get(GTK_TREE_MODEL(modsdir), &iter, 0,&value, -1);
411
            gtk_tree_model_get(GTK_TREE_MODEL(modsdir), &iter, 0,&value, -1);
412
412
413
            if (Bstrcmp(settings.custommoddir, "/") == 0)
413
            if (Bstrcmp(settings.custommoddir, "/") == 0)
414
            {
414
            {
415
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.custommodcombo), NONE);
415
                gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.custommodcombo), NONE);
416
                settings.custommoddir = NULL;
416
                settings.custommoddir = NULL;
417
417
418
                break;
418
                break;
419
            }
419
            }
420
            if (Bstrcmp(settings.custommoddir, value) == 0)
420
            if (Bstrcmp(settings.custommoddir, value) == 0)
421
            {
421
            {
422
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.custommodcombo),
422
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.custommodcombo),
423
                                              &iter);
423
                                              &iter);
424
424
425
                break;
425
                break;
426
            }
426
            }
427
        }
427
        }
428
428
429
        // populate check buttons
429
        // populate check buttons
430
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.fullscreencheck), settings.fullscreen);
430
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.fullscreencheck), settings.fullscreen);
431
#ifdef POLYMER
431
#ifdef POLYMER
432
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.polymercheck), settings.polymer);
432
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.polymercheck), settings.polymer);
433
#endif
433
#endif
434
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.autoloadcheck), settings.autoload);
434
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.autoloadcheck), settings.autoload);
435
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.alwaysshowcheck), settings.forcesetup);
435
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.alwaysshowcheck), settings.forcesetup);
436
    }
436
    }
437
437
438
    if ((pgs == ALL) || (pgs == POPULATE_GAME))
438
    if ((pgs == ALL) || (pgs == POPULATE_GAME))
439
    {
439
    {
440
        struct grpfile *fg;
440
        struct grpfile *fg;
441
        GtkListStore *list;
441
        GtkListStore *list;
442
        GtkTreeIter iter;
442
        GtkTreeIter iter;
443
        GtkTreeView *gamelist;
443
        GtkTreeView *gamelist;
444
444
445
        gamelist = GTK_TREE_VIEW(stwidgets.gamelist);
445
        gamelist = GTK_TREE_VIEW(stwidgets.gamelist);
446
        list = GTK_LIST_STORE(gtk_tree_view_get_model(gamelist));
446
        list = GTK_LIST_STORE(gtk_tree_view_get_model(gamelist));
447
        gtk_list_store_clear(list);
447
        gtk_list_store_clear(list);
448
448
449
        for (fg = foundgrps; fg; fg=fg->next)
449
        for (fg = foundgrps; fg; fg=fg->next)
450
        {
450
        {
451
            struct grpfile *grp;
451
            struct grpfile *grp;
452
            for (grp = listgrps; grp; grp=grp->next)
452
            for (grp = listgrps; grp; grp=grp->next)
453
                if (fg->crcval == grp->crcval) break;
453
                if (fg->crcval == grp->crcval) break;
454
454
455
            if (grp == NULL)
455
            if (grp == NULL)
456
                continue;
456
                continue;
457
457
458
            gtk_list_store_append(list, &iter);
458
            gtk_list_store_append(list, &iter);
459
            gtk_list_store_set(list, &iter, 0, grp->name, 1, fg->name, 2, (gpointer)fg, -1);
459
            gtk_list_store_set(list, &iter, 0, grp->name, 1, fg->name, 2, (gpointer)fg, -1);
460
            if (!Bstrcasecmp(fg->name, settings.selectedgrp))
460
            if (!Bstrcasecmp(fg->name, settings.selectedgrp))
461
            {
461
            {
462
                GtkTreeSelection *sel = gtk_tree_view_get_selection(gamelist);
462
                GtkTreeSelection *sel = gtk_tree_view_get_selection(gamelist);
463
                g_signal_handlers_block_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
463
                g_signal_handlers_block_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
464
                gtk_tree_selection_select_iter(sel, &iter);
464
                gtk_tree_selection_select_iter(sel, &iter);
465
                g_signal_handlers_unblock_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
465
                g_signal_handlers_unblock_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
466
            }
466
            }
467
        }
467
        }
468
    }
468
    }
469
}
469
}
470
470
471
static gint name_sorter(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
471
static gint name_sorter(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
472
{
472
{
473
    gchar *as, *bs;
473
    gchar *as, *bs;
474
    gint r;
474
    gint r;
475
    UNREFERENCED_PARAMETER(user_data);
475
    UNREFERENCED_PARAMETER(user_data);
476
    gtk_tree_model_get(model, a, 0, &as, -1);
476
    gtk_tree_model_get(model, a, 0, &as, -1);
477
    gtk_tree_model_get(model, b, 0, &bs, -1);
477
    gtk_tree_model_get(model, b, 0, &bs, -1);
478
478
479
    r = g_utf8_collate(as,bs);
479
    r = g_utf8_collate(as,bs);
480
480
481
    g_free(as);
481
    g_free(as);
482
    g_free(bs);
482
    g_free(bs);
483
483
484
    return r;
484
    return r;
485
}
485
}
486
486
487
static GtkWidget *create_window(void)
487
static GtkWidget *create_window(void)
488
{
488
{
489
    // Basic window
489
    // Basic window
490
    stwidgets.startwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
490
    stwidgets.startwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
491
    gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), apptitle);     // NOTE: use global app title
491
    gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), apptitle);     // NOTE: use global app title
492
    gtk_window_set_position(GTK_WINDOW(stwidgets.startwin), GTK_WIN_POS_CENTER);
492
    gtk_window_set_position(GTK_WINDOW(stwidgets.startwin), GTK_WIN_POS_CENTER);
493
    gtk_window_set_resizable(GTK_WINDOW(stwidgets.startwin), FALSE);
493
    gtk_window_set_resizable(GTK_WINDOW(stwidgets.startwin), FALSE);
494
    gtk_window_set_type_hint(GTK_WINDOW(stwidgets.startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
494
    gtk_window_set_type_hint(GTK_WINDOW(stwidgets.startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
495
495
496
    // Horizontal layout of banner and controls
496
    // Horizontal layout of banner and controls
497
    stwidgets.hlayout = gtk_hbox_new(FALSE, 0);
497
    stwidgets.hlayout = gtk_hbox_new(FALSE, 0);
498
    gtk_container_add(GTK_CONTAINER(stwidgets.startwin), stwidgets.hlayout);
498
    gtk_container_add(GTK_CONTAINER(stwidgets.startwin), stwidgets.hlayout);
499
499
500
    // banner
500
    // banner
501
    {
501
    {
502
        GdkPixbuf *pixbuf = load_banner();
502
        GdkPixbuf *pixbuf = load_banner();
503
        stwidgets.banner = gtk_image_new_from_pixbuf(pixbuf);
503
        stwidgets.banner = gtk_image_new_from_pixbuf(pixbuf);
504
        g_object_unref((gpointer)pixbuf);
504
        g_object_unref((gpointer)pixbuf);
505
    }
505
    }
506
    gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.banner, FALSE, FALSE, 0);
506
    gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.banner, FALSE, FALSE, 0);
507
    gtk_misc_set_alignment(GTK_MISC(stwidgets.banner), 0.5, 0);
507
    gtk_misc_set_alignment(GTK_MISC(stwidgets.banner), 0.5, 0);
508
508
509
    // Vertical layout of tab control and start+cancel buttons
509
    // Vertical layout of tab control and start+cancel buttons
510
    stwidgets.vlayout = gtk_vbox_new(FALSE, 0);
510
    stwidgets.vlayout = gtk_vbox_new(FALSE, 0);
511
    gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.vlayout, TRUE, TRUE, 0);
511
    gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.vlayout, TRUE, TRUE, 0);
512
512
513
    // Tab control
513
    // Tab control
514
    stwidgets.tabs = gtk_notebook_new();
514
    stwidgets.tabs = gtk_notebook_new();
515
    gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.tabs, TRUE, TRUE, 0);
515
    gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.tabs, TRUE, TRUE, 0);
516
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.tabs), 4);
516
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.tabs), 4);
517
517
518
    // layout table of config page
518
    // layout table of config page
519
    stwidgets.configtlayout = gtk_table_new(6, 3, FALSE);
519
    stwidgets.configtlayout = gtk_table_new(6, 3, FALSE);
520
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.configtlayout);
520
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.configtlayout);
521
521
522
    // 3D video mode LabelText
522
    // 3D video mode LabelText
523
    stwidgets.vmode3dlabel = gtk_label_new_with_mnemonic("_Video mode:");
523
    stwidgets.vmode3dlabel = gtk_label_new_with_mnemonic("_Video mode:");
524
    gtk_misc_set_alignment(GTK_MISC(stwidgets.vmode3dlabel), 0.3, 0);
524
    gtk_misc_set_alignment(GTK_MISC(stwidgets.vmode3dlabel), 0.3, 0);
525
#ifdef POLYMER
525
#ifdef POLYMER
526
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
526
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
527
#else
527
#else
528
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
528
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
529
#endif
529
#endif
530
530
531
    // 3D video mode combo
531
    // 3D video mode combo
532
    {
532
    {
533
        GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
533
        GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
534
        GtkCellRenderer *cell;
534
        GtkCellRenderer *cell;
535
535
536
        stwidgets.vmode3dcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
536
        stwidgets.vmode3dcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
537
        g_object_unref(G_OBJECT(list));
537
        g_object_unref(G_OBJECT(list));
538
538
539
        cell = gtk_cell_renderer_text_new();
539
        cell = gtk_cell_renderer_text_new();
540
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, FALSE);
540
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, FALSE);
541
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, "text", 0, NULL);
541
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, "text", 0, NULL);
542
    }
542
    }
543
   
543
   
544
#ifdef POLYMER
544
#ifdef POLYMER
545
   gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1,
545
   gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1,
546
       (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
546
       (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
547
#else
547
#else
548
   gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1, GTK_EXPAND | GTK_FILL, (GtkAttachOptions)0, 4, 7);
548
   gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1, GTK_EXPAND | GTK_FILL, (GtkAttachOptions)0, 4, 7);
549
#endif
549
#endif
550
550
551
    // Fullscreen checkbox
551
    // Fullscreen checkbox
552
    stwidgets.displayvlayout = gtk_vbox_new(TRUE, 0);
552
    stwidgets.displayvlayout = gtk_vbox_new(TRUE, 0);
553
#ifdef POLYMER
553
#ifdef POLYMER
554
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
554
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
555
#else
555
#else
556
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
556
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
557
#endif
557
#endif
558
558
559
    stwidgets.fullscreencheck = gtk_check_button_new_with_mnemonic("_Fullscreen");
559
    stwidgets.fullscreencheck = gtk_check_button_new_with_mnemonic("_Fullscreen");
560
    gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.fullscreencheck, FALSE, FALSE, 0);
560
    gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.fullscreencheck, FALSE, FALSE, 0);
561
561
562
#ifdef POLYMER
562
#ifdef POLYMER
563
    // Polymer checkbox
563
    // Polymer checkbox
564
    stwidgets.polymercheck = gtk_check_button_new_with_mnemonic("_Polymer");
564
    stwidgets.polymercheck = gtk_check_button_new_with_mnemonic("_Polymer");
565
    gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.polymercheck, FALSE, FALSE, 0);
565
    gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.polymercheck, FALSE, FALSE, 0);
566
#endif
566
#endif
567
567
568
    // Input devices LabelText
568
    // Input devices LabelText
569
    stwidgets.inputdevlabel = gtk_label_new_with_mnemonic("_Input devices:");
569
    stwidgets.inputdevlabel = gtk_label_new_with_mnemonic("_Input devices:");
570
    gtk_misc_set_alignment(GTK_MISC(stwidgets.inputdevlabel), 0.3, 0);
570
    gtk_misc_set_alignment(GTK_MISC(stwidgets.inputdevlabel), 0.3, 0);
571
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevlabel, 0,1, 1,2, GTK_FILL, (GtkAttachOptions)0, 4, 0);
571
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevlabel, 0,1, 1,2, GTK_FILL, (GtkAttachOptions)0, 4, 0);
572
572
573
    // Input devices combo
573
    // Input devices combo
574
    {
574
    {
575
        GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
575
        GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
576
        GtkCellRenderer *cell;
576
        GtkCellRenderer *cell;
577
577
578
        stwidgets.inputdevcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
578
        stwidgets.inputdevcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
579
        g_object_unref(G_OBJECT(list));
579
        g_object_unref(G_OBJECT(list));
580
580
581
        cell = gtk_cell_renderer_text_new();
581
        cell = gtk_cell_renderer_text_new();
582
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, FALSE);
582
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, FALSE);
583
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, "text", 0, NULL);
583
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, "text", 0, NULL);
584
    }
584
    }
585
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevcombo, 1,2, 1,2,
585
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevcombo, 1,2, 1,2,
586
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
586
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
587
587
588
    // Custom mod LabelText
588
    // Custom mod LabelText
589
    stwidgets.custommodlabel = gtk_label_new_with_mnemonic("Custom _game:");
589
    stwidgets.custommodlabel = gtk_label_new_with_mnemonic("Custom _game:");
590
    gtk_misc_set_alignment(GTK_MISC(stwidgets.custommodlabel), 0.3, 0);
590
    gtk_misc_set_alignment(GTK_MISC(stwidgets.custommodlabel), 0.3, 0);
591
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodlabel, 0,1, 2,3, GTK_FILL, (GtkAttachOptions)0, 4, 7);
591
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodlabel, 0,1, 2,3, GTK_FILL, (GtkAttachOptions)0, 4, 7);
592
592
593
    // Custom mod combo
593
    // Custom mod combo
594
    {
594
    {
595
        GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
595
        GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
596
        GtkCellRenderer *cell;
596
        GtkCellRenderer *cell;
597
597
598
        stwidgets.custommodcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
598
        stwidgets.custommodcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
599
        g_object_unref(G_OBJECT(list));
599
        g_object_unref(G_OBJECT(list));
600
600
601
        cell = gtk_cell_renderer_text_new();
601
        cell = gtk_cell_renderer_text_new();
602
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, FALSE);
602
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, FALSE);
603
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, "text", 0, NULL);
603
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, "text", 0, NULL);
604
    }
604
    }
605
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodcombo, 1,2, 2,3,
605
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodcombo, 1,2, 2,3,
606
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 7);
606
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 7);
607
607
608
    // Empty horizontal layout
608
    // Empty horizontal layout
609
    stwidgets.emptyhlayout = gtk_hbox_new(TRUE, 0);
609
    stwidgets.emptyhlayout = gtk_hbox_new(TRUE, 0);
610
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.emptyhlayout, 0,3, 3,4, (GtkAttachOptions)0,
610
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.emptyhlayout, 0,3, 3,4, (GtkAttachOptions)0,
611
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 4, 0);
611
        (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 4, 0);
612
612
613
    // Autoload checkbox
613
    // Autoload checkbox
614
    stwidgets.autoloadcheck = gtk_check_button_new_with_mnemonic("_Enable \"autoload\" folder");
614
    stwidgets.autoloadcheck = gtk_check_button_new_with_mnemonic("_Enable \"autoload\" folder");
615
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.autoloadcheck, 0,3, 4,5, GTK_FILL, (GtkAttachOptions)0, 2, 2);
615
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.autoloadcheck, 0,3, 4,5, GTK_FILL, (GtkAttachOptions)0, 2, 2);
616
616
617
    // Always show config checkbox
617
    // Always show config checkbox
618
    stwidgets.alwaysshowcheck = gtk_check_button_new_with_mnemonic("_Always show this window at startup");
618
    stwidgets.alwaysshowcheck = gtk_check_button_new_with_mnemonic("_Always show this window at startup");
619
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.alwaysshowcheck, 0,3, 5,6, GTK_FILL, (GtkAttachOptions)0, 2, 2);
619
    gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.alwaysshowcheck, 0,3, 5,6, GTK_FILL, (GtkAttachOptions)0, 2, 2);
620
620
621
    // Configuration tab
621
    // Configuration tab
622
    stwidgets.configtab = gtk_label_new("Configuration");
622
    stwidgets.configtab = gtk_label_new("Configuration");
623
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 0), stwidgets.configtab);
623
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 0), stwidgets.configtab);
624
624
625
    // Game data layout
625
    // Game data layout
626
    stwidgets.gamevlayout = gtk_vbox_new(FALSE, 0);
626
    stwidgets.gamevlayout = gtk_vbox_new(FALSE, 0);
627
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.gamevlayout);
627
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.gamevlayout);
628
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.gamevlayout), 4);
628
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.gamevlayout), 4);
629
629
630
    // Game data field LabelText
630
    // Game data field LabelText
631
    stwidgets.gamelabel = gtk_label_new_with_mnemonic("_Game:");
631
    stwidgets.gamelabel = gtk_label_new_with_mnemonic("_Game:");
632
    gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamelabel, FALSE, FALSE, 0);
632
    gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamelabel, FALSE, FALSE, 0);
633
    gtk_misc_set_alignment(GTK_MISC(stwidgets.gamelabel), 0, 0.5);
633
    gtk_misc_set_alignment(GTK_MISC(stwidgets.gamelabel), 0, 0.5);
634
634
635
    // Game data scrollable area
635
    // Game data scrollable area
636
    stwidgets.gamescroll = gtk_scrolled_window_new(NULL, NULL);
636
    stwidgets.gamescroll = gtk_scrolled_window_new(NULL, NULL);
637
    gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamescroll, TRUE, TRUE, 0);
637
    gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamescroll, TRUE, TRUE, 0);
638
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
638
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
639
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_SHADOW_IN);
639
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_SHADOW_IN);
640
640
641
    // Game data list
641
    // Game data list
642
    {
642
    {
643
        GtkListStore *list = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
643
        GtkListStore *list = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
644
        GtkCellRenderer *cell;
644
        GtkCellRenderer *cell;
645
        GtkTreeViewColumn *col;
645
        GtkTreeViewColumn *col;
646
646
647
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list), 0, name_sorter, NULL, NULL);
647
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list), 0, name_sorter, NULL, NULL);
648
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list), 0, GTK_SORT_ASCENDING);
648
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list), 0, GTK_SORT_ASCENDING);
649
649
650
        stwidgets.gamelist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
650
        stwidgets.gamelist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
651
        g_object_unref(G_OBJECT(list));
651
        g_object_unref(G_OBJECT(list));
652
652
653
        cell = gtk_cell_renderer_text_new();
653
        cell = gtk_cell_renderer_text_new();
654
        col = gtk_tree_view_column_new_with_attributes("Game", cell, "text", 0, NULL);
654
        col = gtk_tree_view_column_new_with_attributes("Game", cell, "text", 0, NULL);
655
        gtk_tree_view_column_set_expand(col, TRUE);
655
        gtk_tree_view_column_set_expand(col, TRUE);
656
        gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
656
        gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
657
        col = gtk_tree_view_column_new_with_attributes("GRP file", cell, "text", 1, NULL);
657
        col = gtk_tree_view_column_new_with_attributes("GRP file", cell, "text", 1, NULL);
658
        gtk_tree_view_column_set_min_width(col, 64);
658
        gtk_tree_view_column_set_min_width(col, 64);
659
        gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
659
        gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
660
    }
660
    }
661
    gtk_container_add(GTK_CONTAINER(stwidgets.gamescroll), stwidgets.gamelist);
661
    gtk_container_add(GTK_CONTAINER(stwidgets.gamescroll), stwidgets.gamelist);
662
662
663
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
663
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
664
    gtk_tree_view_set_enable_search(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
664
    gtk_tree_view_set_enable_search(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
665
665
666
    // Game tab
666
    // Game tab
667
    stwidgets.gametab = gtk_label_new("Game");
667
    stwidgets.gametab = gtk_label_new("Game");
668
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 1), stwidgets.gametab);
668
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 1), stwidgets.gametab);
669
669
670
    // Messages scrollable area
670
    // Messages scrollable area
671
    stwidgets.messagesscroll = gtk_scrolled_window_new(NULL, NULL);
671
    stwidgets.messagesscroll = gtk_scrolled_window_new(NULL, NULL);
672
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.messagesscroll);
672
    gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.messagesscroll);
673
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
673
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
674
674
675
    // Messages text area
675
    // Messages text area
676
    stwidgets.messagestext = gtk_text_view_new();
676
    stwidgets.messagestext = gtk_text_view_new();
677
    gtk_container_add(GTK_CONTAINER(stwidgets.messagesscroll), stwidgets.messagestext);
677
    gtk_container_add(GTK_CONTAINER(stwidgets.messagesscroll), stwidgets.messagestext);
678
    gtk_text_view_set_editable(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
678
    gtk_text_view_set_editable(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
679
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(stwidgets.messagestext), GTK_WRAP_WORD);
679
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(stwidgets.messagestext), GTK_WRAP_WORD);
680
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
680
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
681
    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
681
    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
682
    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
682
    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
683
683
684
    // Messages tab
684
    // Messages tab
685
    stwidgets.messagestab = gtk_label_new("Messages");
685
    stwidgets.messagestab = gtk_label_new("Messages");
686
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 2), stwidgets.messagestab);
686
    gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 2), stwidgets.messagestab);
687
687
688
    // Dialogue box buttons layout
688
    // Dialogue box buttons layout
689
    stwidgets.buttons = gtk_hbutton_box_new();
689
    stwidgets.buttons = gtk_hbutton_box_new();
690
    gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.buttons, FALSE, TRUE, 0);
690
    gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.buttons, FALSE, TRUE, 0);
691
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.buttons), 3);
691
    gtk_container_set_border_width(GTK_CONTAINER(stwidgets.buttons), 3);
692
    gtk_button_box_set_layout(GTK_BUTTON_BOX(stwidgets.buttons), GTK_BUTTONBOX_END);
692
    gtk_button_box_set_layout(GTK_BUTTON_BOX(stwidgets.buttons), GTK_BUTTONBOX_END);
693
693
694
    // Cancel button
694
    // Cancel button
695
    stwidgets.cancelbutton = gtk_button_new();
695
    stwidgets.cancelbutton = gtk_button_new();
696
    gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.cancelbutton);
696
    gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.cancelbutton);
697
    GTK_WIDGET_SET_FLAGS(stwidgets.cancelbutton, GTK_CAN_DEFAULT);
697
    GTK_WIDGET_SET_FLAGS(stwidgets.cancelbutton, GTK_CAN_DEFAULT);
698
698
699
    stwidgets.cancelbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
699
    stwidgets.cancelbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
700
    gtk_container_add(GTK_CONTAINER(stwidgets.cancelbutton), stwidgets.cancelbuttonalign);
700
    gtk_container_add(GTK_CONTAINER(stwidgets.cancelbutton), stwidgets.cancelbuttonalign);
701
701
702
    stwidgets.cancelbuttonlayout = gtk_hbox_new(FALSE, 2);
702
    stwidgets.cancelbuttonlayout = gtk_hbox_new(FALSE, 2);
703
    gtk_container_add(GTK_CONTAINER(stwidgets.cancelbuttonalign), stwidgets.cancelbuttonlayout);
703
    gtk_container_add(GTK_CONTAINER(stwidgets.cancelbuttonalign), stwidgets.cancelbuttonlayout);
704
704
705
    stwidgets.cancelbuttonicon = gtk_image_new_from_stock("gtk-cancel", GTK_ICON_SIZE_BUTTON);
705
    stwidgets.cancelbuttonicon = gtk_image_new_from_stock("gtk-cancel", GTK_ICON_SIZE_BUTTON);
706
    gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonicon, FALSE, FALSE, 0);
706
    gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonicon, FALSE, FALSE, 0);
707
707
708
    stwidgets.cancelbuttonlabel = gtk_label_new_with_mnemonic("_Cancel");
708
    stwidgets.cancelbuttonlabel = gtk_label_new_with_mnemonic("_Cancel");
709
    gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonlabel, FALSE, FALSE, 0);
709
    gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonlabel, FALSE, FALSE, 0);
710
710
711
    // Start button
711
    // Start button
712
    stwidgets.startbutton = gtk_button_new();
712
    stwidgets.startbutton = gtk_button_new();
713
    gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.startbutton);
713
    gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.startbutton);
714
    GTK_WIDGET_SET_FLAGS(stwidgets.startbutton, GTK_CAN_DEFAULT);
714
    GTK_WIDGET_SET_FLAGS(stwidgets.startbutton, GTK_CAN_DEFAULT);
715
715
716
    gtk_window_set_default(GTK_WINDOW(stwidgets.startwin), stwidgets.startbutton);
716
    gtk_window_set_default(GTK_WINDOW(stwidgets.startwin), stwidgets.startbutton);
717
717
718
    stwidgets.startbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
718
    stwidgets.startbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
719
    gtk_container_add(GTK_CONTAINER(stwidgets.startbutton), stwidgets.startbuttonalign);
719
    gtk_container_add(GTK_CONTAINER(stwidgets.startbutton), stwidgets.startbuttonalign);
720
720
721
    stwidgets.startbuttonlayout = gtk_hbox_new(FALSE, 2);
721
    stwidgets.startbuttonlayout = gtk_hbox_new(FALSE, 2);
722
    gtk_container_add(GTK_CONTAINER(stwidgets.startbuttonalign), stwidgets.startbuttonlayout);
722
    gtk_container_add(GTK_CONTAINER(stwidgets.startbuttonalign), stwidgets.startbuttonlayout);
723
723
724
    stwidgets.startbuttonicon = gtk_image_new_from_stock("gtk-execute", GTK_ICON_SIZE_BUTTON);
724
    stwidgets.startbuttonicon = gtk_image_new_from_stock("gtk-execute", GTK_ICON_SIZE_BUTTON);
725
    gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonicon, FALSE, FALSE, 0);
725
    gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonicon, FALSE, FALSE, 0);
726
726
727
    stwidgets.startbuttonlabel = gtk_label_new_with_mnemonic("_Start");
727
    stwidgets.startbuttonlabel = gtk_label_new_with_mnemonic("_Start");
728
    gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonlabel, FALSE, FALSE, 0);
728
    gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonlabel, FALSE, FALSE, 0);
729
729
730
    // Wire up the signals
730
    // Wire up the signals
731
    g_signal_connect((gpointer) stwidgets.startwin, "delete_event",
731
    g_signal_connect((gpointer) stwidgets.startwin, "delete_event",
732
                     G_CALLBACK(on_startwin_delete_event),
732
                     G_CALLBACK(on_startwin_delete_event),
733
                     NULL);
733
                     NULL);
734
    g_signal_connect((gpointer) stwidgets.vmode3dcombo, "changed",
734
    g_signal_connect((gpointer) stwidgets.vmode3dcombo, "changed",
735
                     G_CALLBACK(on_vmode3dcombo_changed),
735
                     G_CALLBACK(on_vmode3dcombo_changed),
736
                     NULL);
736
                     NULL);
737
    g_signal_connect((gpointer) stwidgets.fullscreencheck, "toggled",
737
    g_signal_connect((gpointer) stwidgets.fullscreencheck, "toggled",
738
                     G_CALLBACK(on_fullscreencheck_toggled),
738
                     G_CALLBACK(on_fullscreencheck_toggled),
739
                     NULL);
739
                     NULL);
740
#ifdef POLYMER
740
#ifdef POLYMER
741
    g_signal_connect((gpointer) stwidgets.polymercheck, "toggled",
741
    g_signal_connect((gpointer) stwidgets.polymercheck, "toggled",
742
                     G_CALLBACK(on_polymercheck_toggled),
742
                     G_CALLBACK(on_polymercheck_toggled),
743
                     NULL);
743
                     NULL);
744
#endif
744
#endif
745
    g_signal_connect((gpointer) stwidgets.inputdevcombo, "changed",
745
    g_signal_connect((gpointer) stwidgets.inputdevcombo, "changed",
746
                     G_CALLBACK(on_inputdevcombo_changed),
746
                     G_CALLBACK(on_inputdevcombo_changed),
747
                     NULL);
747
                     NULL);
748
    g_signal_connect((gpointer) stwidgets.custommodcombo, "changed",
748
    g_signal_connect((gpointer) stwidgets.custommodcombo, "changed",
749
                     G_CALLBACK(on_custommodcombo_changed),
749
                     G_CALLBACK(on_custommodcombo_changed),
750
                     NULL);
750
                     NULL);
751
    g_signal_connect((gpointer) stwidgets.autoloadcheck, "toggled",
751
    g_signal_connect((gpointer) stwidgets.autoloadcheck, "toggled",
752
                     G_CALLBACK(on_autoloadcheck_toggled),
752
                     G_CALLBACK(on_autoloadcheck_toggled),
753
                     NULL);
753
                     NULL);
754
    g_signal_connect((gpointer) stwidgets.alwaysshowcheck, "toggled",
754
    g_signal_connect((gpointer) stwidgets.alwaysshowcheck, "toggled",
755
                     G_CALLBACK(on_alwaysshowcheck_toggled),
755
                     G_CALLBACK(on_alwaysshowcheck_toggled),
756
                     NULL);
756
                     NULL);
757
    g_signal_connect((gpointer) stwidgets.cancelbutton, "clicked",
757
    g_signal_connect((gpointer) stwidgets.cancelbutton, "clicked",
758
                     G_CALLBACK(on_cancelbutton_clicked),
758
                     G_CALLBACK(on_cancelbutton_clicked),
759
                     NULL);
759
                     NULL);
760
    g_signal_connect((gpointer) stwidgets.startbutton, "clicked",
760
    g_signal_connect((gpointer) stwidgets.startbutton, "clicked",
761
                     G_CALLBACK(on_startbutton_clicked),
761
                     G_CALLBACK(on_startbutton_clicked),
762
                     NULL);
762
                     NULL);
763
    {
763
    {
764
        GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(stwidgets.gamelist));
764
        GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(stwidgets.gamelist));
765
        gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
765
        gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
766
        g_signal_connect((gpointer) sel, "changed",
766
        g_signal_connect((gpointer) sel, "changed",
767
                         G_CALLBACK(on_gamelist_selection_changed),
767
                         G_CALLBACK(on_gamelist_selection_changed),
768
                         NULL);
768
                         NULL);
769
    }
769
    }
770
770
771
    // Associate labels with their controls
771
    // Associate labels with their controls
772
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.vmode3dlabel), stwidgets.vmode3dcombo);
772
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.vmode3dlabel), stwidgets.vmode3dcombo);
773
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.inputdevlabel), stwidgets.inputdevcombo);
773
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.inputdevlabel), stwidgets.inputdevcombo);
774
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.custommodlabel), stwidgets.custommodcombo);
774
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.custommodlabel), stwidgets.custommodcombo);
775
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.gamelabel), stwidgets.gamelist);
775
    gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.gamelabel), stwidgets.gamelist);
776
776
777
    return stwidgets.startwin;
777
    return stwidgets.startwin;
778
}
778
}
779
779
780
780
781
// -- BUILD ENTRY POINTS ------------------------------------------------------
781
// -- BUILD ENTRY POINTS ------------------------------------------------------
782
782
783
int32_t startwin_open(void)
783
int32_t startwin_open(void)
784
{
784
{
785
    if (!gtkenabled) return 0;
785
    if (!gtkenabled) return 0;
786
    if (stwidgets.startwin) return 1;
786
    if (stwidgets.startwin) return 1;
787
787
788
    stwidgets.startwin = create_window();
788
    stwidgets.startwin = create_window();
789
    if (stwidgets.startwin)
789
    if (stwidgets.startwin)
790
    {
790
    {
791
        SetPage(TAB_MESSAGES);
791
        SetPage(TAB_MESSAGES);
792
        gtk_widget_show_all(stwidgets.startwin);
792
        gtk_widget_show_all(stwidgets.startwin);
793
        gtk_main_iteration_do(FALSE);
793
        gtk_main_iteration_do(FALSE);
794
        return 0;
794
        return 0;
795
    }
795
    }
796
    return -1;
796
    return -1;
797
}
797
}
798
798
799
int32_t startwin_close(void)
799
int32_t startwin_close(void)
800
{
800
{
801
    if (!gtkenabled) return 0;
801
    if (!gtkenabled) return 0;
802
    if (!stwidgets.startwin) return 1;
802
    if (!stwidgets.startwin) return 1;
803
    gtk_widget_destroy(stwidgets.startwin);
803
    gtk_widget_destroy(stwidgets.startwin);
804
    stwidgets.startwin = NULL;
804
    stwidgets.startwin = NULL;
805
    return 0;
805
    return 0;
806
}
806
}
807
807
808
int32_t startwin_puts(const char *str)
808
int32_t startwin_puts(const char *str)
809
{
809
{
810
    GtkWidget *textview;
810
    GtkWidget *textview;
811
    GtkTextBuffer *textbuffer;
811
    GtkTextBuffer *textbuffer;
812
    GtkTextIter enditer;
812
    GtkTextIter enditer;
813
    GtkTextMark *mark;
813
    GtkTextMark *mark;
814
    const char *aptr, *bptr;
814
    const char *aptr, *bptr;
815
815
816
    if (!gtkenabled || !str) return 0;
816
    if (!gtkenabled || !str) return 0;
817
    if (!stwidgets.startwin) return 1;
817
    if (!stwidgets.startwin) return 1;
818
    if (!(textview = stwidgets.messagestext)) return -1;
818
    if (!(textview = stwidgets.messagestext)) return -1;
819
    textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
819
    textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
820
820
821
    gtk_text_buffer_get_end_iter(textbuffer, &enditer);
821
    gtk_text_buffer_get_end_iter(textbuffer, &enditer);
822
    for (aptr = bptr = str; *aptr != 0;)
822
    for (aptr = bptr = str; *aptr != 0;)
823
    {
823
    {
824
        switch (*bptr)
824
        switch (*bptr)
825
        {
825
        {
826
        case '\b':
826
        case '\b':
827
            if (bptr > aptr)
827
            if (bptr > aptr)
828
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
828
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
829
#if GTK_CHECK_VERSION(2,6,0)
829
#if GTK_CHECK_VERSION(2,6,0)
830
            gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
830
            gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
831
#else
831
#else
832
            {
832
            {
833
                GtkTextIter iter2 = enditer;
833
                GtkTextIter iter2 = enditer;
834
                gtk_text_iter_backward_cursor_position(&iter2);
834
                gtk_text_iter_backward_cursor_position(&iter2);
835
                //FIXME: this seems be deleting one too many chars somewhere!
835
                //FIXME: this seems be deleting one too many chars somewhere!
836
                if (!gtk_text_iter_equal(&iter2, &enditer))
836
                if (!gtk_text_iter_equal(&iter2, &enditer))
837
                    gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
837
                    gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
838
            }
838
            }
839
#endif
839
#endif
840
            aptr = ++bptr;
840
            aptr = ++bptr;
841
            break;
841
            break;
842
        case 0:
842
        case 0:
843
            if (bptr > aptr)
843
            if (bptr > aptr)
844
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
844
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
845
            aptr = bptr;
845
            aptr = bptr;
846
            break;
846
            break;
847
        case '\r':      // FIXME
847
        case '\r':      // FIXME
848
        default:
848
        default:
849
            bptr++;
849
            bptr++;
850
            break;
850
            break;
851
        }
851
        }
852
    }
852
    }
853
853
854
    mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
854
    mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
855
    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
855
    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
856
    gtk_text_buffer_delete_mark(textbuffer, mark);
856
    gtk_text_buffer_delete_mark(textbuffer, mark);
857
857
858
    return 0;
858
    return 0;
859
}
859
}
860
860
861
int32_t startwin_settitle(const char *title)
861
int32_t startwin_settitle(const char *title)
862
{
862
{
863
    if (!gtkenabled) return 0;
863
    if (!gtkenabled) return 0;
864
    if (!stwidgets.startwin) return 1;
864
    if (!stwidgets.startwin) return 1;
865
    gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), title);
865
    gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), title);
866
    return 0;
866
    return 0;
867
}
867
}
868
868
869
int32_t startwin_idle(void *s)
869
int32_t startwin_idle(void *s)
870
{
870
{
871
    UNREFERENCED_PARAMETER(s);
871
    UNREFERENCED_PARAMETER(s);
872
    if (!gtkenabled) return 0;
872
    if (!gtkenabled) return 0;
873
    //if (!stwidgets.startwin) return 1;
873
    //if (!stwidgets.startwin) return 1;
874
    gtk_main_iteration_do(FALSE);
874
    gtk_main_iteration_do(FALSE);
875
    return 0;
875
    return 0;
876
}
876
}
877
877
878
int32_t startwin_run(void)
878
int32_t startwin_run(void)
879
{
879
{
880
    if (!gtkenabled) return 1;
880
    if (!gtkenabled) return 1;
881
    if (!stwidgets.startwin) return 1;
881
    if (!stwidgets.startwin) return 1;
882
882
883
    SetPage(TAB_CONFIG);
883
    SetPage(TAB_CONFIG);
884
884
885
    settings.xdim3d = ud.config.ScreenWidth;
885
    settings.xdim3d = ud.config.ScreenWidth;
886
    settings.ydim3d = ud.config.ScreenHeight;
886
    settings.ydim3d = ud.config.ScreenHeight;
887
    settings.bpp3d = ud.config.ScreenBPP;
887
    settings.bpp3d = ud.config.ScreenBPP;
888
    settings.fullscreen = ud.config.ScreenMode;
888
    settings.fullscreen = ud.config.ScreenMode;
889
    settings.usemouse = ud.config.UseMouse;
889
    settings.usemouse = ud.config.UseMouse;
890
    settings.usejoy = ud.config.UseJoystick;
890
    settings.usejoy = ud.config.UseJoystick;
891
    settings.custommoddir = g_modDir;
891
    settings.custommoddir = g_modDir;
892
    settings.forcesetup = ud.config.ForceSetup;
892
    settings.forcesetup = ud.config.ForceSetup;
893
    settings.game = g_gameType;
893
    settings.game = g_gameType;
894
    Bstrncpyz(settings.selectedgrp, G_GrpFile(), BMAX_PATH);
894
    Bstrncpyz(settings.selectedgrp, G_GrpFile(), BMAX_PATH);
895
    if (ud.config.NoAutoLoad) settings.autoload = FALSE;
895
    if (ud.config.NoAutoLoad) settings.autoload = FALSE;
896
    else settings.autoload = TRUE;
896
    else settings.autoload = TRUE;
897
#ifdef POLYMER
897
#ifdef POLYMER
898
    if (glrendmode == REND_POLYMER)
898
    if (glrendmode == REND_POLYMER)
899
    {
899
    {
900
        if (settings.bpp3d == 8) settings.bpp3d = 32;
900
        if (settings.bpp3d == 8) settings.bpp3d = 32;
901
        settings.polymer = TRUE;
901
        settings.polymer = TRUE;
902
    }
902
    }
903
#endif
903
#endif
904
    PopulateForm(ALL);
904
    PopulateForm(ALL);
905
905
906
    gtk_main();
906
    gtk_main();
907
907
908
    SetPage(TAB_MESSAGES);
908
    SetPage(TAB_MESSAGES);
909
    if (retval) // launch the game with these parameters
909
    if (retval) // launch the game with these parameters
910
    {
910
    {
911
        ud.config.ScreenWidth = settings.xdim3d;
911
        ud.config.ScreenWidth = settings.xdim3d;
912
        ud.config.ScreenHeight = settings.ydim3d;
912
        ud.config.ScreenHeight = settings.ydim3d;
913
        ud.config.ScreenBPP = settings.bpp3d;
913
        ud.config.ScreenBPP = settings.bpp3d;
914
        ud.config.ScreenMode = settings.fullscreen;
914
        ud.config.ScreenMode = settings.fullscreen;
915
        ud.config.UseMouse = settings.usemouse;
915
        ud.config.UseMouse = settings.usemouse;
916
        ud.config.UseJoystick = settings.usejoy;
916
        ud.config.UseJoystick = settings.usejoy;
917
        ud.config.ForceSetup = settings.forcesetup;
917
        ud.config.ForceSetup = settings.forcesetup;
918
918
919
        clearGrpNamePtr();
919
        clearGrpNamePtr();
920
        g_grpNamePtr = dup_filename(settings.selectedgrp);
920
        g_grpNamePtr = dup_filename(settings.selectedgrp);
921
921
922
        g_gameType = settings.game;
922
        g_gameType = settings.game;
923
        if (settings.custommoddir != NULL)
923
        if (settings.custommoddir != NULL)
924
            Bstrcpy(g_modDir, settings.custommoddir);
924
            Bstrcpy(g_modDir, settings.custommoddir);
925
        else Bsprintf(g_modDir, "/");
925
        else Bsprintf(g_modDir, "/");
926
926
927
        if (settings.autoload) ud.config.NoAutoLoad = FALSE;
927
        if (settings.autoload) ud.config.NoAutoLoad = FALSE;
928
        else ud.config.NoAutoLoad = TRUE;
928
        else ud.config.NoAutoLoad = TRUE;
929
929
930
        {
930
        {
931
            struct grpfile *grp;
931
            struct grpfile *grp;
932
            for (grp = listgrps; grp; grp=grp->next)
932
            for (grp = listgrps; grp; grp=grp->next)
933
                if (settings.crcval == grp->crcval) break;
933
                if (settings.crcval == grp->crcval) break;
934
934
935
            if (grp)
935
            if (grp)
936
            {
936
            {
937
                g_gameNamePtr = grp->name;
937
                g_gameNamePtr = grp->name;
938
                g_dependencyCRC = grp->dependency;
938
                g_dependencyCRC = grp->dependency;
939
939
940
                if (grp->scriptname && g_scriptNamePtr == NULL)
940
                if (grp->scriptname && g_scriptNamePtr == NULL)
941
                    g_scriptNamePtr = dup_filename(grp->scriptname);
941
                    g_scriptNamePtr = dup_filename(grp->scriptname);
942
942
943
                if (grp->defname && g_defNamePtr == NULL)
943
                if (grp->defname && g_defNamePtr == NULL)
944
                    g_defNamePtr = dup_filename(grp->defname);
944
                    g_defNamePtr = dup_filename(grp->defname);
945
            }
945
            }
946
        }
946
        }
947
    }
947
    }
948
948
949
    return retval;
949
    return retval;
950
}
950
}
951
 
951