- replaced EDuke's game selector with GZDoom's.

This commit is contained in:
Christoph Oelckers 2019-12-24 15:28:00 +01:00
parent bfb3a797ff
commit 58d0585eaa
16 changed files with 254 additions and 2570 deletions

View file

@ -470,7 +470,6 @@ endif()
# Start defining source files for Demolition
set( PLAT_WIN32_SOURCES
platform/win32/startwin.game.cpp
platform/win32/base_sysfb.cpp
platform/win32/gl_sysfb.cpp
platform/win32/hardware.cpp
@ -484,21 +483,14 @@ set( PLAT_WIN32_SOURCES
platform/win32/i_specialpaths.cpp
platform/win32/i_system.cpp
platform/win32/i_xinput.cpp
platform/win32/startwin.game.cpp
platform/win32/st_start.cpp
platform/win32/st_start_util.cpp
platform/win32/win32basevideo.cpp
platform/win32/win32glvideo.cpp
platform/win32/win32vulkanvideo.cpp
# This needs a rework anyway in order to consolidate the startup dialogs so don't bother to sort in properly.
#startosx.game.mm
#sw/src/startgtk.game.cpp
)
set( PLAT_POSIX_SOURCES
#platform/gtk/startgtk.game.cpp
)
set( PLAT_SDL_SOURCES
@ -517,9 +509,6 @@ set( PLAT_OSX_SOURCES
)
set( PLAT_COCOA_SOURCES
#platform/macos/startosx.game.mm
#platform/macos/GrpFile.game.mm
#platform/macos/GameListSource.game.mm
)

View file

@ -74,8 +74,11 @@ TMap<FName, int32_t> NameToTileIndex; // for assigning names to tiles. The menu
// Todo: Add additional definition file for the other games or textures not in that list so that the menu does not have to rely on indices.
CVAR(Int, cl_defaultconfiguration, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, queryiwad, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, disableautoload, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
//CVAR(Bool, autoloadbrightmaps, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG) // hopefully this is an option for later
//CVAR(Bool, autoloadlights, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
UserConfig userConfig;
@ -194,8 +197,8 @@ void UserConfig::ProcessOptions()
nomusic = Args->CheckParm("-nomusic");
nosound = Args->CheckParm("-nosfx");
if (Args->CheckParm("-nosound")) nomusic = nosound = true;
if (Args->CheckParm("-setup")) setupstate = 1;
else if (Args->CheckParm("-nosetup")) setupstate = 0;
if (Args->CheckParm("-setup")) queryiwad = 1;
else if (Args->CheckParm("-nosetup")) queryiwad = 0;
if (Args->CheckParm("-file"))
@ -386,8 +389,48 @@ static TArray<GrpEntry> SetupGame()
g++;
}
}
if (groupno == -1 || userConfig.setupstate == 1)
groupno = ShowStartupWindow(groups);
if (groupno == -1)
{
int pick = 0;
// We got more than one so present the IWAD selection box.
if (groups.Size() > 1)
{
// Locate the user's prefered IWAD, if it was found.
if (defaultiwad[0] != '\0')
{
for (unsigned i = 0; i < groups.Size(); ++i)
{
FString& basename = groups[i].FileName;
if (stricmp(basename, defaultiwad) == 0)
{
pick = i;
break;
}
}
}
if (groups.Size() > 1)
{
TArray<WadStuff> wads;
for (auto& found : groups)
{
WadStuff stuff;
stuff.Name = found.FileInfo.name;
stuff.Path = ExtractFileBase(found.FileName);
wads.Push(stuff);
}
pick = I_PickIWad(&wads[0], (int)wads.Size(), queryiwad, pick);
if (pick >= 0)
{
// The newly selected IWAD becomes the new default
defaultiwad = groups[pick].FileName;
}
groupno = pick;
}
}
}
if (groupno == -1) return TArray<GrpEntry>();
auto& group = groups[groupno];

View file

@ -126,6 +126,11 @@ struct GrpInfo
};
struct WadStuff
{
FString Path;
FString Name;
};
struct GrpEntry
{

View file

@ -1,892 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "build.h"
#include "cmdline.h"
#include "common.h"
#include "common_game.h"
#include "compat.h"
#include "duke3d.h"
#include "dynamicgtk.h"
#include "game.h"
#include "grpscan.h"
#include "gtkpixdata.h"
BEGIN_DUKE_NS
enum
{
NONE,
ALL,
POPULATE_VIDEO,
POPULATE_CONFIG,
POPULATE_GAME,
};
enum
{
TAB_CONFIG,
TAB_GAME,
TAB_MESSAGES,
};
enum
{
INPUT_KB,
INPUT_MOUSE,
INPUT_JOYSTICK,
INPUT_ALL,
};
static struct
{
GtkWidget *startwin;
GtkWidget *hlayout;
GtkWidget *banner;
GtkWidget *vlayout;
GtkWidget *tabs;
GtkWidget *configtlayout;
GtkWidget *displayvlayout;
GtkWidget *vmode3dlabel;
GtkWidget *vmode3dcombo;
GtkWidget *fullscreencheck;
#ifdef POLYMER
GtkWidget *polymercheck;
#endif
GtkWidget *inputdevlabel;
GtkWidget *inputdevcombo;
GtkWidget *custommodlabel;
GtkWidget *custommodcombo;
GtkWidget *emptyhlayout;
GtkWidget *autoloadcheck;
GtkWidget *alwaysshowcheck;
GtkWidget *configtab;
GtkWidget *gamevlayout;
GtkWidget *gamelabel;
GtkWidget *gamescroll;
GtkWidget *gamelist;
GtkWidget *gametab;
GtkWidget *messagesscroll;
GtkWidget *messagestext;
GtkWidget *messagestab;
GtkWidget *buttons;
GtkWidget *cancelbutton;
GtkWidget *cancelbuttonalign;
GtkWidget *cancelbuttonlayout;
GtkWidget *cancelbuttonicon;
GtkWidget *cancelbuttonlabel;
GtkWidget *startbutton;
GtkWidget *startbuttonalign;
GtkWidget *startbuttonlayout;
GtkWidget *startbuttonicon;
GtkWidget *startbuttonlabel;
} stwidgets;
static struct
{
grpfile_t const * grp;
char *gamedir;
ud_setup_t shared;
#ifdef POLYMER
int polymer;
#endif
} settings;
static int32_t retval = -1, mode = TAB_MESSAGES;
extern int32_t gtkenabled;
static void PopulateForm(unsigned char pgs);
// -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
GtkTreeModel *data;
GtkTreeIter iter;
int32_t val;
UNREFERENCED_PARAMETER(user_data);
if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
if (!(data = gtk_combo_box_get_model(combobox))) return;
gtk_tree_model_get(data, &iter, 1, &val, -1);
settings.shared.xdim = validmode[val].xdim;
settings.shared.ydim = validmode[val].ydim;
settings.shared.bpp = validmode[val].bpp;
}
static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
UNREFERENCED_PARAMETER(user_data);
settings.shared.fullscreen = gtk_toggle_button_get_active(togglebutton);
PopulateForm(POPULATE_VIDEO);
}
#ifdef POLYMER
static void on_polymercheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
UNREFERENCED_PARAMETER(user_data);
if (gtk_toggle_button_get_active(togglebutton))
{
glrendmode = REND_POLYMER;
settings.polymer = TRUE;
if (settings.shared.bpp == 8)
{
settings.shared.bpp = 32;
PopulateForm(POPULATE_VIDEO);
}
}
else
{
glrendmode = REND_POLYMOST;
settings.polymer = FALSE;
}
}
#endif
static void on_inputdevcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
UNREFERENCED_PARAMETER(user_data);
switch (gtk_combo_box_get_active(combobox))
{
case 0: settings.shared.usemouse = 0; settings.shared.usejoystick = 0; break;
case 1: settings.shared.usemouse = 1; settings.shared.usejoystick = 0; break;
case 2: settings.shared.usemouse = 0; settings.shared.usejoystick = 1; break;
case 3: settings.shared.usemouse = 1; settings.shared.usejoystick = 1; break;
}
}
static void on_custommodcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreePath *path;
char *value;
UNREFERENCED_PARAMETER(user_data);
if (gtk_combo_box_get_active_iter(combobox, &iter))
{
model = gtk_combo_box_get_model(combobox);
gtk_tree_model_get(model, &iter, 0,&value, -1);
path = gtk_tree_model_get_path(model, &iter);
if (*gtk_tree_path_get_indices(path) == NONE)
settings.gamedir = NULL;
else settings.gamedir = value;
}
}
static void on_autoloadcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
UNREFERENCED_PARAMETER(user_data);
settings.shared.noautoload = !gtk_toggle_button_get_active(togglebutton);
}
static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
UNREFERENCED_PARAMETER(user_data);
settings.shared.forcesetup = gtk_toggle_button_get_active(togglebutton);
}
static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
{
UNREFERENCED_PARAMETER(button);
UNREFERENCED_PARAMETER(user_data);
if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
else quitevent++;
}
static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
{
UNREFERENCED_PARAMETER(button);
UNREFERENCED_PARAMETER(user_data);
retval = 1;
gtk_main_quit();
}
static void on_gamelist_selection_changed(GtkTreeSelection *selection, gpointer user_data)
{
GtkTreeIter iter;
GtkTreeModel *model;
UNREFERENCED_PARAMETER(user_data);
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
grpfile_t const *fg;
gtk_tree_model_get(model, &iter, 2, (gpointer)&fg, -1);
settings.grp = fg;
}
}
static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
UNREFERENCED_PARAMETER(widget);
UNREFERENCED_PARAMETER(event);
UNREFERENCED_PARAMETER(user_data);
if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
else quitevent++;
return TRUE; // FALSE would let the event go through. we want the game to decide when to close
}
// -- SUPPORT FUNCTIONS -------------------------------------------------------
static GdkPixbuf *load_banner(void)
{
return gdk_pixbuf_from_pixdata((GdkPixdata const *)&startbanner_pixdata, FALSE, NULL);
}
static void SetPage(int32_t n)
{
if (!gtkenabled || !stwidgets.startwin) return;
mode = n;
gtk_notebook_set_current_page(GTK_NOTEBOOK(stwidgets.tabs), n);
// each control in the config page vertical layout plus the start button should be made (in)sensitive
if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
gtk_widget_set_sensitive(stwidgets.startbutton, n);
gtk_container_foreach(GTK_CONTAINER(stwidgets.configtlayout),
(GtkCallback)gtk_widget_set_sensitive,
(gpointer)&n);
}
static unsigned char GetModsDirNames(GtkListStore *list)
{
char *homedir;
char pdir[BMAX_PATH];
unsigned char iternumb = 0;
BUILDVFS_FIND_REC *dirs = NULL;
GtkTreeIter iter;
pathsearchmode = 1;
if ((homedir = Bgethomedir()))
{
Bsnprintf(pdir, sizeof(pdir), "%s/" ".eduke32", homedir);
dirs = klistpath(pdir, "*", BUILDVFS_FIND_DIR);
for (; dirs != NULL; dirs=dirs->next)
{
if ((Bstrcmp(dirs->name, "autoload") == 0) ||
(Bstrcmp(dirs->name, "..") == 0) ||
(Bstrcmp(dirs->name, ".") == 0))
continue;
else
{
gtk_list_store_append(list, &iter);
gtk_list_store_set(list, &iter, 0,dirs->name, -1);
iternumb++;
}
}
}
klistfree(dirs);
dirs = NULL;
return iternumb;
}
static void PopulateForm(unsigned char pgs)
{
if ((pgs == ALL) || (pgs == POPULATE_VIDEO))
{
int32_t mode3d, i;
GtkListStore *modes3d;
GtkTreeIter iter;
char buf[64];
mode3d = videoCheckMode(&settings.shared.xdim, &settings.shared.ydim, settings.shared.bpp, settings.shared.fullscreen, 1);
if (mode3d < 0)
{
int32_t i, cd[] = { 32, 24, 16, 15, 8, 0 };
for (i=0; cd[i];) { if (cd[i] >= settings.shared.bpp) i++; else break; }
for (; cd[i]; i++)
{
mode3d = videoCheckMode(&settings.shared.xdim, &settings.shared.ydim, cd[i], settings.shared.fullscreen, 1);
if (mode3d < 0) continue;
settings.shared.bpp = cd[i];
break;
}
}
modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.vmode3dcombo)));
gtk_list_store_clear(modes3d);
for (i=0; i<validmodecnt; i++)
{
if (validmode[i].fs != settings.shared.fullscreen) continue;
// all modes get added to the 3D mode list
Bsprintf(buf, "%dx%d %s", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp == 8 ? "software" : "OpenGL");
gtk_list_store_append(modes3d, &iter);
gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
if (i == mode3d)
{
g_signal_handlers_block_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.vmode3dcombo), &iter);
g_signal_handlers_unblock_by_func(stwidgets.vmode3dcombo, (gpointer)on_vmode3dcombo_changed, NULL);
}
}
}
if ((pgs == ALL) || (pgs == POPULATE_CONFIG))
{
GtkListStore *devlist, *modsdir;
GtkTreeIter iter;
GtkTreePath *path;
char *value;
unsigned char i, r = 0;
const char *availabledev[] =
{
"Keyboard only",
"Keyboard and mouse",
"Keyboard and joystick",
"All supported devices"
};
// populate input devices combo
devlist = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.inputdevcombo)));
gtk_list_store_clear(devlist);
for (i=0; i<(int32_t)G_N_ELEMENTS(availabledev); i++)
{
gtk_list_store_append(devlist, &iter);
gtk_list_store_set(devlist, &iter, 0,availabledev[i], -1);
}
switch (settings.shared.usemouse)
{
case 0: if (settings.shared.usejoystick)
gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_JOYSTICK);
else
gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_KB);
break;
case 1: if (settings.shared.usejoystick)
gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_ALL);
else
gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.inputdevcombo), INPUT_MOUSE);
break;
}
// populate custom mod combo
modsdir = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(stwidgets.custommodcombo)));
gtk_list_store_clear(modsdir);
gtk_list_store_append(modsdir, &iter);
gtk_list_store_set(modsdir, &iter, 0,"None", -1);
r = GetModsDirNames(modsdir);
for (i=0; i<=r; i++)
{
path = gtk_tree_path_new_from_indices(i, -1);
gtk_tree_model_get_iter(GTK_TREE_MODEL(modsdir), &iter, path);
gtk_tree_model_get(GTK_TREE_MODEL(modsdir), &iter, 0,&value, -1);
if (Bstrcmp(settings.gamedir, "/") == 0)
{
gtk_combo_box_set_active(GTK_COMBO_BOX(stwidgets.custommodcombo), NONE);
settings.gamedir = NULL;
break;
}
if (Bstrcmp(settings.gamedir, value) == 0)
{
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stwidgets.custommodcombo),
&iter);
break;
}
}
// populate check buttons
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.fullscreencheck), settings.shared.fullscreen);
#ifdef POLYMER
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.polymercheck), settings.polymer);
#endif
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.autoloadcheck), !settings.shared.noautoload);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stwidgets.alwaysshowcheck), settings.shared.forcesetup);
}
if ((pgs == ALL) || (pgs == POPULATE_GAME))
{
GtkListStore *list;
GtkTreeIter iter;
GtkTreeView *gamelist;
gamelist = GTK_TREE_VIEW(stwidgets.gamelist);
list = GTK_LIST_STORE(gtk_tree_view_get_model(gamelist));
gtk_list_store_clear(list);
for (grpfile_t const * fg = foundgrps; fg; fg=fg->next)
{
gtk_list_store_append(list, &iter);
gtk_list_store_set(list, &iter, 0, fg->type->name, 1, fg->filename, 2, (void const *)fg, -1);
if (settings.grp == fg)
{
GtkTreeSelection *sel = gtk_tree_view_get_selection(gamelist);
g_signal_handlers_block_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
gtk_tree_selection_select_iter(sel, &iter);
g_signal_handlers_unblock_by_func(sel, (gpointer)on_gamelist_selection_changed, NULL);
}
}
}
}
static gint name_sorter(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
{
gchar *as, *bs;
gint r;
UNREFERENCED_PARAMETER(user_data);
gtk_tree_model_get(model, a, 0, &as, -1);
gtk_tree_model_get(model, b, 0, &bs, -1);
r = g_utf8_collate(as,bs);
g_free(as);
g_free(bs);
return r;
}
static GtkWidget *create_window(void)
{
// Basic window
stwidgets.startwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), apptitle); // NOTE: use global app title
gtk_window_set_position(GTK_WINDOW(stwidgets.startwin), GTK_WIN_POS_CENTER);
gtk_window_set_resizable(GTK_WINDOW(stwidgets.startwin), FALSE);
gtk_window_set_type_hint(GTK_WINDOW(stwidgets.startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
// Horizontal layout of banner and controls
stwidgets.hlayout = gtk_hbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(stwidgets.startwin), stwidgets.hlayout);
// banner
{
GdkPixbuf *pixbuf = load_banner();
stwidgets.banner = gtk_image_new_from_pixbuf(pixbuf);
g_object_unref((gpointer)pixbuf);
}
gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.banner, FALSE, FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(stwidgets.banner), 0.5, 0);
// Vertical layout of tab control and start+cancel buttons
stwidgets.vlayout = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(stwidgets.hlayout), stwidgets.vlayout, TRUE, TRUE, 0);
// Tab control
stwidgets.tabs = gtk_notebook_new();
gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.tabs, TRUE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(stwidgets.tabs), 4);
// layout table of config page
stwidgets.configtlayout = gtk_table_new(6, 3, FALSE);
gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.configtlayout);
// 3D video mode LabelText
stwidgets.vmode3dlabel = gtk_label_new_with_mnemonic("_Video mode:");
gtk_misc_set_alignment(GTK_MISC(stwidgets.vmode3dlabel), 0.3, 0);
#ifdef POLYMER
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
#else
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
#endif
// 3D video mode combo
{
GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
GtkCellRenderer *cell;
stwidgets.vmode3dcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
g_object_unref(G_OBJECT(list));
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, FALSE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.vmode3dcombo), cell, "text", 0, NULL);
}
#ifdef POLYMER
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1,
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
#else
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 7);
#endif
// Fullscreen checkbox
stwidgets.displayvlayout = gtk_vbox_new(TRUE, 0);
#ifdef POLYMER
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
#else
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
#endif
stwidgets.fullscreencheck = gtk_check_button_new_with_mnemonic("_Fullscreen");
gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.fullscreencheck, FALSE, FALSE, 0);
#ifdef POLYMER
// Polymer checkbox
stwidgets.polymercheck = gtk_check_button_new_with_mnemonic("_Polymer");
gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.polymercheck, FALSE, FALSE, 0);
#endif
// Input devices LabelText
stwidgets.inputdevlabel = gtk_label_new_with_mnemonic("_Input devices:");
gtk_misc_set_alignment(GTK_MISC(stwidgets.inputdevlabel), 0.3, 0);
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevlabel, 0,1, 1,2, GTK_FILL, (GtkAttachOptions)0, 4, 0);
// Input devices combo
{
GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
GtkCellRenderer *cell;
stwidgets.inputdevcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
g_object_unref(G_OBJECT(list));
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, FALSE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.inputdevcombo), cell, "text", 0, NULL);
}
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.inputdevcombo, 1,2, 1,2,
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
// Custom mod LabelText
stwidgets.custommodlabel = gtk_label_new_with_mnemonic("Custom _game:");
gtk_misc_set_alignment(GTK_MISC(stwidgets.custommodlabel), 0.3, 0);
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodlabel, 0,1, 2,3, GTK_FILL, (GtkAttachOptions)0, 4, 7);
// Custom mod combo
{
GtkListStore *list = gtk_list_store_new(1, G_TYPE_STRING);
GtkCellRenderer *cell;
stwidgets.custommodcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
g_object_unref(G_OBJECT(list));
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, FALSE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(stwidgets.custommodcombo), cell, "text", 0, NULL);
}
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.custommodcombo, 1,2, 2,3,
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 7);
// Empty horizontal layout
stwidgets.emptyhlayout = gtk_hbox_new(TRUE, 0);
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.emptyhlayout, 0,3, 3,4, (GtkAttachOptions)0,
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 4, 0);
// Autoload checkbox
stwidgets.autoloadcheck = gtk_check_button_new_with_mnemonic("_Enable \"autoload\" folder");
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.autoloadcheck, 0,3, 4,5, GTK_FILL, (GtkAttachOptions)0, 2, 2);
// Always show config checkbox
stwidgets.alwaysshowcheck = gtk_check_button_new_with_mnemonic("_Always show this window at startup");
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.alwaysshowcheck, 0,3, 5,6, GTK_FILL, (GtkAttachOptions)0, 2, 2);
// Configuration tab
stwidgets.configtab = gtk_label_new("Configuration");
gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 0), stwidgets.configtab);
// Game data layout
stwidgets.gamevlayout = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.gamevlayout);
gtk_container_set_border_width(GTK_CONTAINER(stwidgets.gamevlayout), 4);
// Game data field LabelText
stwidgets.gamelabel = gtk_label_new_with_mnemonic("_Game:");
gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamelabel, FALSE, FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(stwidgets.gamelabel), 0, 0.5);
// Game data scrollable area
stwidgets.gamescroll = gtk_scrolled_window_new(NULL, NULL);
gtk_box_pack_start(GTK_BOX(stwidgets.gamevlayout), stwidgets.gamescroll, TRUE, TRUE, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(stwidgets.gamescroll), GTK_SHADOW_IN);
// Game data list
{
GtkListStore *list = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
GtkCellRenderer *cell;
GtkTreeViewColumn *col;
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list), 0, name_sorter, NULL, NULL);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(list), 0, GTK_SORT_ASCENDING);
stwidgets.gamelist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
g_object_unref(G_OBJECT(list));
cell = gtk_cell_renderer_text_new();
col = gtk_tree_view_column_new_with_attributes("Game", cell, "text", 0, NULL);
gtk_tree_view_column_set_expand(col, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
col = gtk_tree_view_column_new_with_attributes("GRP file", cell, "text", 1, NULL);
gtk_tree_view_column_set_min_width(col, 64);
gtk_tree_view_append_column(GTK_TREE_VIEW(stwidgets.gamelist), col);
}
gtk_container_add(GTK_CONTAINER(stwidgets.gamescroll), stwidgets.gamelist);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(stwidgets.gamelist), FALSE);
// Game tab
stwidgets.gametab = gtk_label_new("Game");
gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 1), stwidgets.gametab);
// Messages scrollable area
stwidgets.messagesscroll = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(stwidgets.tabs), stwidgets.messagesscroll);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(stwidgets.messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
// Messages text area
stwidgets.messagestext = gtk_text_view_new();
gtk_container_add(GTK_CONTAINER(stwidgets.messagesscroll), stwidgets.messagestext);
gtk_text_view_set_editable(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(stwidgets.messagestext), GTK_WRAP_WORD);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(stwidgets.messagestext), FALSE);
gtk_text_view_set_left_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(stwidgets.messagestext), 2);
// Messages tab
stwidgets.messagestab = gtk_label_new("Messages");
gtk_notebook_set_tab_label(GTK_NOTEBOOK(stwidgets.tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(stwidgets.tabs), 2), stwidgets.messagestab);
// Dialogue box buttons layout
stwidgets.buttons = gtk_hbutton_box_new();
gtk_box_pack_start(GTK_BOX(stwidgets.vlayout), stwidgets.buttons, FALSE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(stwidgets.buttons), 3);
gtk_button_box_set_layout(GTK_BUTTON_BOX(stwidgets.buttons), GTK_BUTTONBOX_END);
// Cancel button
stwidgets.cancelbutton = gtk_button_new();
gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.cancelbutton);
GTK_WIDGET_SET_FLAGS(stwidgets.cancelbutton, GTK_CAN_DEFAULT);
stwidgets.cancelbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
gtk_container_add(GTK_CONTAINER(stwidgets.cancelbutton), stwidgets.cancelbuttonalign);
stwidgets.cancelbuttonlayout = gtk_hbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(stwidgets.cancelbuttonalign), stwidgets.cancelbuttonlayout);
stwidgets.cancelbuttonicon = gtk_image_new_from_stock("gtk-cancel", GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonicon, FALSE, FALSE, 0);
stwidgets.cancelbuttonlabel = gtk_label_new_with_mnemonic("_Cancel");
gtk_box_pack_start(GTK_BOX(stwidgets.cancelbuttonlayout), stwidgets.cancelbuttonlabel, FALSE, FALSE, 0);
// Start button
stwidgets.startbutton = gtk_button_new();
gtk_container_add(GTK_CONTAINER(stwidgets.buttons), stwidgets.startbutton);
GTK_WIDGET_SET_FLAGS(stwidgets.startbutton, GTK_CAN_DEFAULT);
gtk_window_set_default(GTK_WINDOW(stwidgets.startwin), stwidgets.startbutton);
stwidgets.startbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
gtk_container_add(GTK_CONTAINER(stwidgets.startbutton), stwidgets.startbuttonalign);
stwidgets.startbuttonlayout = gtk_hbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(stwidgets.startbuttonalign), stwidgets.startbuttonlayout);
stwidgets.startbuttonicon = gtk_image_new_from_stock("gtk-execute", GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonicon, FALSE, FALSE, 0);
stwidgets.startbuttonlabel = gtk_label_new_with_mnemonic("_Start");
gtk_box_pack_start(GTK_BOX(stwidgets.startbuttonlayout), stwidgets.startbuttonlabel, FALSE, FALSE, 0);
// Wire up the signals
g_signal_connect((gpointer) stwidgets.startwin, "delete_event",
G_CALLBACK(on_startwin_delete_event),
NULL);
g_signal_connect((gpointer) stwidgets.vmode3dcombo, "changed",
G_CALLBACK(on_vmode3dcombo_changed),
NULL);
g_signal_connect((gpointer) stwidgets.fullscreencheck, "toggled",
G_CALLBACK(on_fullscreencheck_toggled),
NULL);
#ifdef POLYMER
g_signal_connect((gpointer) stwidgets.polymercheck, "toggled",
G_CALLBACK(on_polymercheck_toggled),
NULL);
#endif
g_signal_connect((gpointer) stwidgets.inputdevcombo, "changed",
G_CALLBACK(on_inputdevcombo_changed),
NULL);
g_signal_connect((gpointer) stwidgets.custommodcombo, "changed",
G_CALLBACK(on_custommodcombo_changed),
NULL);
g_signal_connect((gpointer) stwidgets.autoloadcheck, "toggled",
G_CALLBACK(on_autoloadcheck_toggled),
NULL);
g_signal_connect((gpointer) stwidgets.alwaysshowcheck, "toggled",
G_CALLBACK(on_alwaysshowcheck_toggled),
NULL);
g_signal_connect((gpointer) stwidgets.cancelbutton, "clicked",
G_CALLBACK(on_cancelbutton_clicked),
NULL);
g_signal_connect((gpointer) stwidgets.startbutton, "clicked",
G_CALLBACK(on_startbutton_clicked),
NULL);
{
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(stwidgets.gamelist));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
g_signal_connect((gpointer) sel, "changed",
G_CALLBACK(on_gamelist_selection_changed),
NULL);
}
// Associate labels with their controls
gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.vmode3dlabel), stwidgets.vmode3dcombo);
gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.inputdevlabel), stwidgets.inputdevcombo);
gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.custommodlabel), stwidgets.custommodcombo);
gtk_label_set_mnemonic_widget(GTK_LABEL(stwidgets.gamelabel), stwidgets.gamelist);
return stwidgets.startwin;
}
// -- BUILD ENTRY POINTS ------------------------------------------------------
int32_t startwin_open(void)
{
if (!gtkenabled) return 0;
if (stwidgets.startwin) return 1;
stwidgets.startwin = create_window();
if (stwidgets.startwin)
{
SetPage(TAB_MESSAGES);
gtk_widget_show_all(stwidgets.startwin);
gtk_main_iteration_do(FALSE);
return 0;
}
return -1;
}
int32_t startwin_close(void)
{
if (!gtkenabled) return 0;
if (!stwidgets.startwin) return 1;
gtk_widget_destroy(stwidgets.startwin);
stwidgets.startwin = NULL;
return 0;
}
int32_t startwin_puts(const char *str)
{
GtkWidget *textview;
GtkTextBuffer *textbuffer;
GtkTextIter enditer;
GtkTextMark *mark;
const char *aptr, *bptr;
if (!gtkenabled || !str) return 0;
if (!stwidgets.startwin) return 1;
if (!(textview = stwidgets.messagestext)) return -1;
textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_get_end_iter(textbuffer, &enditer);
for (aptr = bptr = str; *aptr != 0;)
{
switch (*bptr)
{
case '\b':
if (bptr > aptr)
gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
#if GTK_CHECK_VERSION(2,6,0)
gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
#else
{
GtkTextIter iter2 = enditer;
gtk_text_iter_backward_cursor_position(&iter2);
//FIXME: this seems be deleting one too many chars somewhere!
if (!gtk_text_iter_equal(&iter2, &enditer))
gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
}
#endif
aptr = ++bptr;
break;
case 0:
if (bptr > aptr)
gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
aptr = bptr;
break;
case '\r': // FIXME
default:
bptr++;
break;
}
}
mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
gtk_text_buffer_delete_mark(textbuffer, mark);
return 0;
}
int32_t startwin_settitle(const char *title)
{
if (!gtkenabled) return 0;
if (!stwidgets.startwin) return 1;
gtk_window_set_title(GTK_WINDOW(stwidgets.startwin), title);
return 0;
}
int32_t startwin_idle(void *s)
{
UNREFERENCED_PARAMETER(s);
if (!gtkenabled) return 0;
//if (!stwidgets.startwin) return 1;
gtk_main_iteration_do(FALSE);
return 0;
}
int32_t startwin_run(void)
{
if (!gtkenabled) return 1;
if (!stwidgets.startwin) return 1;
SetPage(TAB_CONFIG);
settings.shared = ud.setup;
settings.gamedir = g_modDir;
settings.grp = g_selectedGrp;
#ifdef POLYMER
settings.polymer = (glrendmode == REND_POLYMER) & (settings.shared.bpp != 8);
#endif
PopulateForm(ALL);
gtk_main();
SetPage(TAB_MESSAGES);
if (retval) // launch the game with these parameters
{
ud.setup = settings.shared;
#ifdef POLYMER
glrendmode = (settings.polymer) ? REND_POLYMER : REND_POLYMOST;
#endif
g_selectedGrp = settings.grp;
Bstrcpy(g_modDir, (g_noSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return retval;
}
END_DUKE_NS

View file

@ -1,26 +0,0 @@
/*
* GameListSource.game.h
* duke3d
*
* Created by Jonathon Fowler on 24/07/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
@interface GameListSource : NSObject <NSComboBoxDataSource>
{
NSMutableArray *list;
}
- (id)init;
- (void)dealloc;
- (GrpFile*)grpAtIndex:(int)index;
- (int)findIndexForGrpname:(NSString*)grpname;
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex;
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
@end

View file

@ -1,77 +0,0 @@
/*
* GameListSource.game.m
* duke3d
*
* Created by Jonathon Fowler on 24/07/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#include "ns.h" // Must come before everything else!
#include "compat.h"
#import "GrpFile.game.h"
#import "GameListSource.game.h"
@implementation GameListSource
- (id)init
{
self = [super init];
if (self) {
list = [[NSMutableArray alloc] init];
for (grpfile_t const *p = foundgrps; p; p=p->next) {
[list addObject:[[GrpFile alloc] initWithGrpfile:p]];
}
}
return self;
}
- (void)dealloc
{
[list release];
[super dealloc];
}
- (GrpFile*)grpAtIndex:(int)index
{
return [list objectAtIndex:index];
}
- (int)findIndexForGrpname:(NSString*)grpname
{
NSUInteger i, listcount = [list count];
for (i=0; i<listcount; i++) {
if ([[[list objectAtIndex:i] grpname] isEqual:grpname]) return i;
}
return -1;
}
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex
{
UNREFERENCED_PARAMETER(aTableView);
NSParameterAssert((NSUInteger)rowIndex < [list count]);
switch ([[aTableColumn identifier] intValue]) {
case 0: // name column
return [[list objectAtIndex:rowIndex] name];
case 1: // grp column
return [[list objectAtIndex:rowIndex] grpname];
default: return nil;
}
}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
UNREFERENCED_PARAMETER(aTableView);
return [list count];
}
@end

View file

@ -1,26 +0,0 @@
/*
* GrpFile.game.h
* duke3d
*
* Created by Jonathon Fowler on 24/07/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
#include "grpscan.h"
@interface GrpFile : NSObject
{
NSString *namestring;
NSString *grpnamestring;
grpfile_t const *fg;
}
- (id)initWithGrpfile:(grpfile_t const *)grpfile;
- (void)dealloc;
- (NSString *)name;
- (NSString *)grpname;
- (grpfile_t const *)entryptr;
@end

View file

@ -1,44 +0,0 @@
/*
* GrpFile.game.m
* duke3d
*
* Created by Jonathon Fowler on 24/07/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include "ns.h" // Must come before everything else!
#include "GrpFile.game.h"
@implementation GrpFile
- (id)initWithGrpfile:(grpfile_t const *)grpfile
{
self = [super init];
if (self) {
fg = grpfile;
namestring = [NSString stringWithCString:fg->type->name encoding:NSUTF8StringEncoding];
[namestring retain];
grpnamestring = [NSString stringWithCString:fg->filename encoding:NSUTF8StringEncoding];
[grpnamestring retain];
}
return self;
}
- (void)dealloc
{
[namestring release];
[grpnamestring release];
[super dealloc];
}
- (NSString *)name
{
return namestring;
}
- (NSString *)grpname
{
return grpnamestring;
}
- (grpfile_t const *)entryptr
{
return fg;
}
@end

View file

@ -1,711 +0,0 @@
#import <Cocoa/Cocoa.h>
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "game.h"
#include "common.h"
#include "common_game.h"
#include "build.h"
#include "compat.h"
#include "baselayer.h"
#include "grpscan.h"
#include "osxbits.h"
#import "GrpFile.game.h"
#import "GameListSource.game.h"
#ifndef MAC_OS_X_VERSION_10_5
# define NSImageScaleNone NSScaleNone
#endif
#ifndef MAC_OS_X_VERSION_10_12
# define NSEventModifierFlagOption NSAlternateKeyMask
# define NSEventModifierFlagCommand NSCommandKeyMask
# define NSEventMaskAny NSAnyEventMask
# define NSWindowStyleMaskTitled NSTitledWindowMask
# define NSWindowStyleMaskClosable NSClosableWindowMask
# define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
# define NSWindowStyleMaskResizable NSResizableWindowMask
# define NSAlertStyleInformational NSInformationalAlertStyle
# define NSControlSizeSmall NSSmallControlSize
#endif
#ifndef MAC_OS_X_VERSION_10_14
# define NSButtonTypeSwitch NSSwitchButton
# define NSBezelStyleRounded NSRoundedBezelStyle
# define NSControlStateValueOn NSOnState
# define NSControlStateValueOff NSOffState
#endif
static NSRect NSRectChangeXY(NSRect const rect, CGFloat const x, CGFloat const y)
{
return NSMakeRect(x, y, rect.size.width, rect.size.height);
}
static NSRect NSSizeAddXY(NSSize const size, CGFloat const x, CGFloat const y)
{
return NSMakeRect(x, y, size.width, size.height);
}
#if 0
static CGFloat NSRightEdge(NSRect rect)
{
return rect.origin.x + rect.size.width;
}
#endif
static CGFloat NSTopEdge(NSRect rect)
{
return rect.origin.y + rect.size.height;
}
static void setFontToSmall(id control)
{
[control setFont:[NSFont fontWithDescriptor:[[control font] fontDescriptor] size:[NSFont smallSystemFontSize]]];
}
static void setControlToSmall(id control)
{
[control setControlSize:NSControlSizeSmall];
}
static NSTextField * makeLabel(NSString * labelText)
{
NSTextField *textField = [[NSTextField alloc] init];
setFontToSmall(textField);
setControlToSmall([textField cell]);
[textField setStringValue:labelText];
[textField setBezeled:NO];
[textField setDrawsBackground:NO];
[textField setEditable:NO];
[textField setSelectable:NO];
[textField sizeToFit];
return textField;
}
static NSButton * makeCheckbox(NSString * labelText)
{
NSButton *checkbox = [[NSButton alloc] init];
setFontToSmall(checkbox);
setControlToSmall([checkbox cell]);
[checkbox setTitle:labelText];
[checkbox setButtonType:NSButtonTypeSwitch];
[checkbox sizeToFit];
return checkbox;
}
static NSPopUpButton * makeComboBox(void)
{
NSPopUpButton *comboBox = [[NSPopUpButton alloc] init];
[comboBox setPullsDown:NO];
setFontToSmall(comboBox);
setControlToSmall([comboBox cell]);
[comboBox setBezelStyle:NSBezelStyleRounded];
[comboBox setPreferredEdge:NSMaxYEdge];
[[comboBox cell] setArrowPosition:NSPopUpArrowAtCenter];
[comboBox sizeToFit];
return comboBox;
}
/* setAppleMenu disappeared from the headers in 10.4 */
@interface NSApplication(NSAppleMenu)
- (void)setAppleMenu:(NSMenu *)menu;
@end
static NSString * GetApplicationName(void)
{
NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
if (!appName)
appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
static void CreateApplicationMenus(void)
{
NSString *appName;
NSString *title;
NSMenu *rootMenu;
NSMenu *serviceMenu;
NSMenuItem *menuItem;
NSMenu *mainMenu = [[NSMenu alloc] init];
/* Create the application menu */
appName = GetApplicationName();
rootMenu = [[NSMenu alloc] init];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:rootMenu];
[mainMenu addItem:menuItem];
[menuItem release];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[rootMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[rootMenu addItem:[NSMenuItem separatorItem]];
serviceMenu = [[NSMenu alloc] init];
menuItem = (NSMenuItem *)[rootMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""];
[menuItem setSubmenu:serviceMenu];
[nsapp setServicesMenu:serviceMenu];
[serviceMenu release];
[rootMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[rootMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[rootMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption|NSEventModifierFlagCommand)];
[rootMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[rootMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[rootMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Create the main menu bar */
[nsapp setMainMenu:mainMenu];
[mainMenu release]; /* we're done with it, let NSApp own it. */
/* Tell the application object that this is now the application menu */
[nsapp setAppleMenu:rootMenu];
[rootMenu release];
}
static int retval = -1;
static struct {
grpfile_t const * grp;
int fullscreen;
int xdim3d, ydim3d, bpp3d;
int forcesetup;
} settings;
@interface StartupWindow : NSWindow <NSWindowDelegate>
{
NSMutableArray *modeslist3d;
GameListSource *gamelistsrc;
NSButton *alwaysShowButton;
NSButton *fullscreenButton;
NSTextView *messagesView;
NSTabView *tabView;
NSTabViewItem *tabViewItemSetup;
NSTabViewItem *tabViewItemMessageLog;
NSPopUpButton *videoMode3DPUButton;
NSScrollView *gameList;
NSButton *cancelButton;
NSButton *startButton;
}
- (StartupWindow *)init;
- (void)dealloc;
- (void)populateVideoModes:(BOOL)firstTime;
- (void)fullscreenClicked:(id)sender;
- (void)cancel:(id)sender;
- (void)start:(id)sender;
- (void)setupRunMode;
- (void)setupMessagesMode;
- (void)putsMessage:(NSString *)str;
@end
@implementation StartupWindow : NSWindow
- (StartupWindow *)init
{
NSUInteger const style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;
NSRect const windowFrame = NSMakeRect(0, 0, 480, 280);
self = [super initWithContentRect:windowFrame styleMask:style backing:NSBackingStoreBuffered defer:NO];
if (self)
{
// window properties
[self setDelegate:self];
[self setReleasedWhenClosed:NO];
#if defined MAC_OS_X_VERSION_10_3 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3
[self setContentMinSize:[[self contentView] frame].size];
#else
[self setMinSize:[NSWindow frameRectForContentRect:[[self contentView] frame] styleMask:[self styleMask]].size];
#endif
// image on the left
NSRect const imageFrame = NSMakeRect(0, 0, 100, 280);
NSImageView * imageView = [[NSImageView alloc] initWithFrame:imageFrame];
[imageView setImageScaling:NSImageScaleNone];
[imageView setImage:[NSImage imageNamed:@"game"]];
[[self contentView] addSubview:imageView];
[imageView setAutoresizingMask:NSViewMaxXMargin | NSViewHeightSizable];
// buttons
CGFloat const buttonWidth = 80;
CGFloat const buttonHeight = 32;
NSRect const startButtonFrame = NSMakeRect(windowFrame.size.width - buttonWidth, 0, buttonWidth, buttonHeight);
startButton = [[NSButton alloc] initWithFrame:startButtonFrame];
[[self contentView] addSubview:startButton];
[startButton setTitle:@"Start"];
[startButton setTarget:self];
[startButton setAction:@selector(start:)];
[startButton setBezelStyle:NSBezelStyleRounded];
[startButton setKeyEquivalent:@"\r"];
[startButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin];
NSRect const cancelButtonFrame = NSMakeRect(startButtonFrame.origin.x - buttonWidth, 0, buttonWidth, buttonHeight);
cancelButton = [[NSButton alloc] initWithFrame:cancelButtonFrame];
[[self contentView] addSubview:cancelButton];
[cancelButton setTitle:@"Cancel"];
[cancelButton setTarget:self];
[cancelButton setAction:@selector(cancel:)];
[cancelButton setBezelStyle:NSBezelStyleRounded];
[cancelButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin];
// tab frame
NSRect const tabViewFrame = NSMakeRect(imageFrame.size.width, buttonHeight, windowFrame.size.width - imageFrame.size.width, windowFrame.size.height - buttonHeight - 5);
tabView = [[NSTabView alloc] initWithFrame:tabViewFrame];
[[self contentView] addSubview:tabView];
setFontToSmall(tabView);
setControlToSmall(tabView);
[tabView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// setup tab
tabViewItemSetup = [[NSTabViewItem alloc] init];
[tabView addTabViewItem:tabViewItemSetup];
[tabViewItemSetup setLabel:@"Setup"];
NSRect const tabViewItemSetupFrame = [[tabViewItemSetup view] frame];
// always show checkbox
alwaysShowButton = makeCheckbox(@"Always show this window at startup");
[[tabViewItemSetup view] addSubview:alwaysShowButton];
NSSize const alwaysShowButtonSize = [alwaysShowButton frame].size;
NSRect const alwaysShowButtonFrame = NSSizeAddXY(alwaysShowButtonSize, tabViewItemSetupFrame.size.width - alwaysShowButtonSize.width, 0);
[alwaysShowButton setFrame:alwaysShowButtonFrame];
[alwaysShowButton setAutoresizingMask:NSViewMinXMargin | NSViewMaxYMargin];
// video mode selectors and labels
NSTextField * labelVideoMode = makeLabel(@"Video mode:");
[[tabViewItemSetup view] addSubview:labelVideoMode];
NSSize const labelVideoModeSize = [labelVideoMode frame].size;
[labelVideoMode setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
fullscreenButton = makeCheckbox(@"Fullscreen");
[[tabViewItemSetup view] addSubview:fullscreenButton];
NSSize const fullscreenButtonSize = [fullscreenButton frame].size;
[fullscreenButton setAction:@selector(fullscreenClicked:)];
[fullscreenButton setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
videoMode3DPUButton = makeComboBox();
[[tabViewItemSetup view] addSubview:videoMode3DPUButton];
NSSize const videoMode3DPUButtonSize = [videoMode3DPUButton frame].size;
CGFloat const videoMode3DButtonX = labelVideoModeSize.width; // NSRightEdge(labelVideoModeFrame);
NSRect const videoMode3DPUButtonFrame = NSMakeRect(videoMode3DButtonX, tabViewItemSetupFrame.size.height - videoMode3DPUButtonSize.height, tabViewItemSetupFrame.size.width - videoMode3DButtonX - fullscreenButtonSize.width, videoMode3DPUButtonSize.height);
[videoMode3DPUButton setFrame:videoMode3DPUButtonFrame];
[videoMode3DPUButton setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
NSRect const labelVideoModeFrame = NSSizeAddXY(labelVideoModeSize, 0, videoMode3DPUButtonFrame.origin.y + rintf((videoMode3DPUButtonSize.height - labelVideoModeSize.height) * 0.5f) + 1);
[labelVideoMode setFrame:labelVideoModeFrame];
NSRect const fullscreenButtonFrame = NSSizeAddXY(fullscreenButtonSize, tabViewItemSetupFrame.size.width - fullscreenButtonSize.width, videoMode3DPUButtonFrame.origin.y + rintf((videoMode3DPUButtonSize.height - fullscreenButtonSize.height) * 0.5f) + 1);
[fullscreenButton setFrame:fullscreenButtonFrame];
// game selector and label
NSTextField * labelGame = makeLabel(@"Game:");
[[tabViewItemSetup view] addSubview:labelGame];
NSSize const labelGameSize = [labelGame frame].size;
NSRect const labelGameFrame = NSSizeAddXY(labelGameSize, 0, videoMode3DPUButtonFrame.origin.y - labelGameSize.height);
[labelGame setFrame:labelGameFrame];
[labelGame setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
CGFloat const gameListVerticalPadding = 3;
CGFloat const gameListY = NSTopEdge(alwaysShowButtonFrame) + gameListVerticalPadding;
NSRect const gameListFrame = NSMakeRect(0, gameListY, tabViewItemSetupFrame.size.width, labelGameFrame.origin.y - gameListY - gameListVerticalPadding);
gameList = [[NSScrollView alloc] initWithFrame:gameListFrame];
[[tabViewItemSetup view] addSubview:gameList];
[gameList setBorderType:NSBezelBorder];
[gameList setHasVerticalScroller:YES];
[gameList setHasHorizontalScroller:NO];
setControlToSmall([[gameList verticalScroller] cell]);
NSSize const gameListContentSize = [gameList contentSize];
[gameList setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
NSTableView * gameListTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0, 0, gameListContentSize.width, gameListContentSize.height)];
[gameList setDocumentView:gameListTable];
NSTableColumn * nameColumn = [[NSTableColumn alloc] initWithIdentifier:@"0"];
[gameListTable addTableColumn:nameColumn];
NSTableColumn * fileColumn = [[NSTableColumn alloc] initWithIdentifier:@"1"];
[gameListTable addTableColumn:fileColumn];
[nameColumn setEditable:NO];
[[nameColumn headerCell] setStringValue:@"Name"];
[nameColumn setWidth:gameListContentSize.width * (2.f/3.f)];
[fileColumn setEditable:NO];
[[fileColumn headerCell] setStringValue:@"File"];
[gameListTable sizeLastColumnToFit];
[gameListTable setAutoresizingMask:NSViewWidthSizable];
// message log tab
tabViewItemMessageLog = [[NSTabViewItem alloc] init];
[tabView addTabViewItem:tabViewItemMessageLog];
[tabViewItemMessageLog setLabel:@"Message Log"];
NSRect const tabViewItemMessageLogFrame = [[tabViewItemMessageLog view] frame];
// message log
NSScrollView * messagesScrollView = [[NSScrollView alloc] initWithFrame:NSRectChangeXY(tabViewItemMessageLogFrame, 0, 0)];
[[tabViewItemMessageLog view] addSubview:messagesScrollView];
[messagesScrollView setBorderType:NSBezelBorder];
[messagesScrollView setHasVerticalScroller:YES];
[messagesScrollView setHasHorizontalScroller:NO];
setControlToSmall([[messagesScrollView verticalScroller] cell]);
NSSize const messagesScrollViewContentSize = [messagesScrollView contentSize];
[messagesScrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
messagesView = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, messagesScrollViewContentSize.width, messagesScrollViewContentSize.height)];
[messagesScrollView setDocumentView:messagesView];
[messagesView setEditable:NO];
[messagesView setRichText:NO];
setFontToSmall(messagesView);
[messagesView setMinSize:NSMakeSize(0.0, messagesScrollViewContentSize.height)];
[messagesView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[messagesView setVerticallyResizable:YES];
[messagesView setHorizontallyResizable:NO];
[messagesView setAutoresizingMask:NSViewWidthSizable];
[[messagesView textContainer] setContainerSize:NSMakeSize(messagesScrollViewContentSize.width, FLT_MAX)];
[[messagesView textContainer] setWidthTracksTextView:YES];
}
return self;
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
- (BOOL)canBecomeMainWindow
{
return YES;
}
- (BOOL) windowShouldClose:(id)sender
{
UNREFERENCED_PARAMETER(sender);
retval = 0;
return YES;
}
- (void)dealloc
{
[gamelistsrc release];
[modeslist3d release];
[super dealloc];
}
- (void)populateVideoModes:(BOOL)firstTime
{
int i, mode3d, fullscreen = ([fullscreenButton state] == NSControlStateValueOn);
int idx3d = -1;
int xdim = 0, ydim = 0, bpp = 0;
if (firstTime) {
xdim = settings.xdim3d;
ydim = settings.ydim3d;
bpp = settings.bpp3d;
} else {
mode3d = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue];
if (mode3d >= 0) {
xdim = validmode[mode3d].xdim;
ydim = validmode[mode3d].ydim;
bpp = validmode[mode3d].bpp;
}
}
mode3d = videoCheckMode(&xdim, &ydim, bpp, fullscreen, 1);
if (mode3d < 0) {
int i, cd[] = { 32, 24, 16, 15, 8, 0 };
for (i=0; cd[i]; ) { if (cd[i] >= bpp) i++; else break; }
for ( ; cd[i]; i++) {
mode3d = videoCheckMode(&xdim, &ydim, cd[i], fullscreen, 1);
if (mode3d < 0) continue;
break;
}
}
[modeslist3d release];
[videoMode3DPUButton removeAllItems];
modeslist3d = [[NSMutableArray alloc] init];
for (i = 0; i < validmodecnt; i++) {
if (fullscreen == validmode[i].fs) {
if (i == mode3d) idx3d = [modeslist3d count];
[modeslist3d addObject:[NSNumber numberWithInt:i]];
[videoMode3DPUButton addItemWithTitle:[NSString stringWithFormat:@"%d %C %d %d-bpp",
validmode[i].xdim, 0xd7, validmode[i].ydim, validmode[i].bpp]];
}
}
if (idx3d >= 0) [videoMode3DPUButton selectItemAtIndex:idx3d];
}
- (void)fullscreenClicked:(id)sender
{
UNREFERENCED_PARAMETER(sender);
[self populateVideoModes:NO];
}
- (void)cancel:(id)sender
{
UNREFERENCED_PARAMETER(sender);
retval = 0;
}
- (void)start:(id)sender
{
UNREFERENCED_PARAMETER(sender);
int mode = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue];
if (mode >= 0) {
settings.xdim3d = validmode[mode].xdim;
settings.ydim3d = validmode[mode].ydim;
settings.bpp3d = validmode[mode].bpp;
settings.fullscreen = validmode[mode].fs;
}
int row = [[gameList documentView] selectedRow];
if (row >= 0) {
settings.grp = [[gamelistsrc grpAtIndex:row] entryptr];
}
settings.forcesetup = [alwaysShowButton state] == NSControlStateValueOn;
retval = 1;
}
- (void)setupRunMode
{
videoGetModes();
[fullscreenButton setState: (settings.fullscreen ? NSControlStateValueOn : NSControlStateValueOff)];
[alwaysShowButton setState: (settings.forcesetup ? NSControlStateValueOn : NSControlStateValueOff)];
[self populateVideoModes:YES];
// enable all the controls on the Configuration page
NSEnumerator *enumerator = [[[tabViewItemSetup view] subviews] objectEnumerator];
NSControl *control;
while ((control = [enumerator nextObject]))
{
if ([control respondsToSelector:@selector(setEnabled:)])
[control setEnabled:true];
}
gamelistsrc = [[GameListSource alloc] init];
[[gameList documentView] setDataSource:gamelistsrc];
[[gameList documentView] deselectAll:nil];
if (settings.grp)
{
int row = [gamelistsrc findIndexForGrpname:[NSString stringWithUTF8String:settings.grp->filename]];
if (row >= 0)
{
[[gameList documentView] scrollRowToVisible:row];
#if defined MAC_OS_X_VERSION_10_3 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3
[[gameList documentView] selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
#else
[[gameList documentView] selectRow:row byExtendingSelection:NO];
#endif
}
}
[cancelButton setEnabled:true];
[startButton setEnabled:true];
[tabView selectTabViewItem:tabViewItemSetup];
[NSCursor unhide]; // Why should I need to do this?
}
- (void)setupMessagesMode
{
[tabView selectTabViewItem:tabViewItemMessageLog];
// disable all the controls on the Configuration page except "always show", so the
// user can enable it if they want to while waiting for something else to happen
NSEnumerator *enumerator = [[[tabViewItemSetup view] subviews] objectEnumerator];
NSControl *control;
while ((control = [enumerator nextObject]))
{
if (control != alwaysShowButton && [control respondsToSelector:@selector(setEnabled:)])
[control setEnabled:false];
}
[cancelButton setEnabled:false];
[startButton setEnabled:false];
}
- (void)putsMessage:(NSString *)str
{
NSRange end;
NSTextStorage *text = [messagesView textStorage];
BOOL shouldAutoScroll;
shouldAutoScroll = ((int)NSMaxY([messagesView bounds]) == (int)NSMaxY([messagesView visibleRect]));
end.location = [text length];
end.length = 0;
[text beginEditing];
[messagesView replaceCharactersInRange:end withString:str];
[text endEditing];
if (shouldAutoScroll) {
end.location = [text length];
end.length = 0;
[messagesView scrollRangeToVisible:end];
}
}
@end
static StartupWindow *startwin = nil;
int startwin_open(void)
{
if (startwin != nil) return 1;
startwin = [[StartupWindow alloc] init];
if (startwin == nil) return -1;
[startwin setupMessagesMode];
[startwin center];
[startwin makeKeyAndOrderFront:nil];
CreateApplicationMenus();
return 0;
}
int startwin_close(void)
{
if (startwin == nil) return 1;
[startwin close];
[startwin release];
startwin = nil;
return 0;
}
int startwin_puts(const char *s)
{
NSString *ns;
if (!s) return -1;
if (startwin == nil) return 1;
ns = [NSString stringWithUTF8String:s];
[startwin putsMessage:ns];
[ns release];
return 0;
}
int startwin_settitle(const char *s)
{
NSString *ns;
if (!s) return -1;
if (startwin == nil) return 1;
ns = [NSString stringWithUTF8String:s];
[startwin setTitle:ns];
[ns release];
return 0;
}
int startwin_idle(void *v)
{
UNREFERENCED_PARAMETER(v);
if (startwin)
{
NSEvent *event;
do
{
event = [nsapp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate date] inMode:NSDefaultRunLoopMode dequeue:YES];
[nsapp sendEvent:event];
}
while (event != nil);
[startwin displayIfNeeded];
[nsapp updateWindows];
}
return 0;
}
int startwin_run(void)
{
if (startwin == nil) return 0;
settings.fullscreen = ud.setup.fullscreen;
settings.xdim3d = ud.setup.xdim;
settings.ydim3d = ud.setup.ydim;
settings.bpp3d = ud.setup.bpp;
settings.forcesetup = ud.setup.forcesetup;
settings.grp = g_selectedGrp;
[startwin setupRunMode];
do
{
NSEvent *event = [nsapp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
[nsapp sendEvent:event];
[nsapp updateWindows];
}
while (retval == -1);
[startwin setupMessagesMode];
[nsapp updateWindows];
if (retval) {
ud.setup.fullscreen = settings.fullscreen;
ud.setup.xdim = settings.xdim3d;
ud.setup.ydim = settings.ydim3d;
ud.setup.bpp = settings.bpp3d;
ud.setup.forcesetup = settings.forcesetup;
g_selectedGrp = settings.grp;
}
return retval;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 KiB

View file

@ -1,40 +1,34 @@
#define NEED_COMMCTRL_H
#include "../../build/include/windows_inc.h"
#include "startwin.game.h"
#include "afxres.h"
#include "resource.h"
#include "../../common/version.h"
#include "../../gitinfo.h"
RSRC_ICON ICON "game_icon.ico"
RSRC_BMP BITMAP "game.bmp"
IDI_ICON1 ICON "game_icon.ico"
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
CAPTION "Startup"
FONT 8, "MS Shell Dlg"
IDD_IWADDIALOG DIALOGEX 0, 0, 224, 249
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Welcome"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
END
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
CAPTION "Dialog"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "&Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 6, 50, 8
CONTROL "", IDCVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 4, 86, 56
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 6, 46, 10
//#if defined POLYMER && POLYMER != 0
// CONTROL "&Polymer", IDCPOLYMER, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 203, 6, 40, 10
//#endif
CONTROL "&Game:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 35, 100, 8
CONTROL "", IDCDATA, "LISTBOX", LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS | LBS_STANDARD | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 45, 226, 43
CONTROL "Custom game content &directory:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 90, 160, 8
CONTROL "", IDCGAMEDIR, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 10, 99, 226, 156
CONTROL "&Enable ""autoload"" folder", IDCAUTOLOAD, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 116, 100, 8
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
ICON IDI_ICON1,IDC_STATIC,7,7,20,20
LTEXT "Welcome to Demolition!",IDC_STATIC,42,8,180,8
LTEXT "<Version info>",IDC_WELCOME_VERSION,42,18,180,8
GROUPBOX "Game selection",IDC_STATIC,8,32,208,117
LTEXT "Select which game file (GRP) to run.",IDC_STATIC,12,44,190,8
LISTBOX IDC_IWADLIST,12,56,200,87,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Video settings",IDC_STATIC,8,155,109,52
CONTROL "Fullscreen",IDC_WELCOME_FULLSCREEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,167,48,10
GROUPBOX "Resource settings",IDC_STATIC,123,155,95,52
CONTROL "Disable autoload",IDC_WELCOME_NOAUTOLOAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,170,65,10
//CONTROL "Load lights",IDC_WELCOME_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,180,51,10
//CONTROL "Load brightmaps",IDC_WELCOME_BRIGHTMAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,190,65,10
CONTROL "Don't ask me this again",IDC_DONTASKIWAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,73,211,87,10
DEFPUSHBUTTON "Play Demolition",IDOK,8,228,90,14
PUSHBUTTON "Exit",IDCANCEL,166,228,50,14
CONTROL "OpenGL",IDC_WELCOME_VULKAN1,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,167,41,10
CONTROL "Vulkan",IDC_WELCOME_VULKAN2,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,13,177,37,10
CONTROL "SoftPoly",IDC_WELCOME_VULKAN3,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,13,188,43,10
END
IDD_CRASHDIALOG DIALOGEX 0, 0, 415, 308
@ -54,7 +48,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
EDITTEXT IDC_CRASHINFO,7,126,377,90,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
CONTROL "",IDC_PLEASETELLUS,"RichEdit20A",ES_MULTILINE | ES_READONLY,7,50,377,54,WS_EX_TRANSPARENT
LTEXT "(Optional) To help diagnose the cause of this error, please describe what you were doing when the error occured. If you were playing with custom wads, please also indicate where to obtain them:",IDC_STATIC,7,108,377,16,0,WS_EX_TRANSPARENT
LTEXT "(Optional) To help diagnose the cause of this error, please describe what you were doing when the error occured. If you were playing with custom data, please also indicate where to obtain them:",IDC_STATIC,7,108,377,16,0,WS_EX_TRANSPARENT
CONTROL 131,IDC_DEADGUYVIEWER,"Static",SS_BITMAP,345,7,23,26
CONTROL "",IDC_CRASHHEADER,"RichEdit20A",ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY,18,13,306,25,WS_EX_TRANSPARENT
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,42,407,1
@ -104,14 +98,14 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Demolition"
VALUE "FileVersion", STRFILEVER
VALUE "FileDescription", "Demolition " GIT_DESCRIPTION
VALUE "FileVersion", GIT_DESCRIPTION
VALUE "InternalName", "Demolition"
VALUE "LegalCopyright", "Copyright © 2019 Christoph Oelckers, Copyright © 2018 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
VALUE "LegalCopyright", "Copyright © 2019 Christoph Oelckers, Copyright © 2018 EDuke32 Developers, 1996, 2003, 2005 3D Realms Entertainment"
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC.; Shadow Warrior® is a Registered Trademark of GHI Media LLC."
VALUE "OriginalFilename", "demolition.exe"
VALUE "ProductName", "Demolition"
VALUE "ProductVersion", STRPRODUCTVER
VALUE "ProductVersion", GIT_DESCRIPTION
END
END
BLOCK "VarFileInfo"

View file

@ -76,7 +76,7 @@
#include "s_music.h"
#include "stats.h"
//#include "st_start.h"
#include "st_start.h"
// MACROS ------------------------------------------------------------------
@ -537,7 +537,7 @@ void RestoreConView()
ShowWindow (GameTitleWindow, SW_SHOW);
I_ShutdownInput (); // Make sure the mouse pointer is available.
// Make sure the progress bar isn't visible.
//DeleteStartupScreen();
DeleteStartupScreen();
}
//==========================================================================

View file

@ -69,6 +69,7 @@
#include "stats.h"
#include "v_text.h"
#include "utf8.h"
#include "gamecontrol.h"
#include "i_input.h"
#include "c_dispatch.h"
@ -494,6 +495,153 @@ static void SetQueryIWad(HWND dialog)
queryiwad = query;
}
//==========================================================================
//
// IWADBoxCallback
//
// Dialog proc for the IWAD selector.
//
//==========================================================================
BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND ctrl;
int i;
switch (message)
{
case WM_INITDIALOG:
// Add our program name to the window title
{
WCHAR label[256];
FString newlabel;
GetWindowTextW(hDlg, label, countof(label));
FString alabel(label);
newlabel.Format(GAMENAME " %s: %s", GetVersionString(), alabel.GetChars());
auto wlabel = newlabel.WideString();
SetWindowTextW(hDlg, wlabel.c_str());
}
// [SP] Upstreamed from Zandronum
char szString[256];
// Check the current video settings.
//SendDlgItemMessage( hDlg, vid_renderer ? IDC_WELCOME_OPENGL : IDC_WELCOME_SOFTWARE, BM_SETCHECK, BST_CHECKED, 0 );
SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_SETCHECK, vid_fullscreen ? BST_CHECKED : BST_UNCHECKED, 0 );
switch (vid_preferbackend)
{
case 1:
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN2, BM_SETCHECK, BST_CHECKED, 0 );
break;
case 2:
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN3, BM_SETCHECK, BST_CHECKED, 0 );
break;
default:
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN1, BM_SETCHECK, BST_CHECKED, 0 );
break;
}
// [SP] This is our's
SendDlgItemMessage( hDlg, IDC_WELCOME_NOAUTOLOAD, BM_SETCHECK, disableautoload ? BST_CHECKED : BST_UNCHECKED, 0 );
//SendDlgItemMessage( hDlg, IDC_WELCOME_LIGHTS, BM_SETCHECK, autoloadlights ? BST_CHECKED : BST_UNCHECKED, 0 );
//SendDlgItemMessage( hDlg, IDC_WELCOME_BRIGHTMAPS, BM_SETCHECK, autoloadbrightmaps ? BST_CHECKED : BST_UNCHECKED, 0 );
// Set up our version string.
sprintf(szString, "Version %s.", GetVersionString());
SetDlgItemTextA (hDlg, IDC_WELCOME_VERSION, szString);
// Populate the list with all the IWADs found
ctrl = GetDlgItem(hDlg, IDC_IWADLIST);
for (i = 0; i < NumWads; i++)
{
const char *filepart = strrchr(WadList[i].Path, '/');
if (filepart == NULL)
filepart = WadList[i].Path;
else
filepart++;
FStringf work("%s (%s)", WadList[i].Name.GetChars(), filepart);
std::wstring wide = work.WideString();
SendMessage(ctrl, LB_ADDSTRING, 0, (LPARAM)wide.c_str());
SendMessage(ctrl, LB_SETITEMDATA, i, (LPARAM)i);
}
SendMessage(ctrl, LB_SETCURSEL, DefaultWad, 0);
SetFocus(ctrl);
// Set the state of the "Don't ask me again" checkbox
ctrl = GetDlgItem(hDlg, IDC_DONTASKIWAD);
SendMessage(ctrl, BM_SETCHECK, queryiwad ? BST_UNCHECKED : BST_CHECKED, 0);
// Make sure the dialog is in front. If SHIFT was pressed to force it visible,
// then the other window will normally be on top.
SetForegroundWindow(hDlg);
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL)
{
EndDialog (hDlg, -1);
}
else if (LOWORD(wParam) == IDOK ||
(LOWORD(wParam) == IDC_IWADLIST && HIWORD(wParam) == LBN_DBLCLK))
{
SetQueryIWad(hDlg);
// [SP] Upstreamed from Zandronum
vid_fullscreen = SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN3, BM_GETCHECK, 0, 0) == BST_CHECKED)
vid_preferbackend = 2;
else if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN2, BM_GETCHECK, 0, 0) == BST_CHECKED)
vid_preferbackend = 1;
else if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN1, BM_GETCHECK, 0, 0) == BST_CHECKED)
vid_preferbackend = 0;
// [SP] This is our's.
disableautoload = SendDlgItemMessage( hDlg, IDC_WELCOME_NOAUTOLOAD, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
//autoloadlights = SendDlgItemMessage( hDlg, IDC_WELCOME_LIGHTS, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
//autoloadbrightmaps = SendDlgItemMessage( hDlg, IDC_WELCOME_BRIGHTMAPS, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
ctrl = GetDlgItem (hDlg, IDC_IWADLIST);
EndDialog(hDlg, SendMessage (ctrl, LB_GETCURSEL, 0, 0));
}
break;
}
return FALSE;
}
//==========================================================================
//
// I_PickIWad
//
// Open a dialog to pick the IWAD, if there is more than one found.
//
//==========================================================================
int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad)
{
int vkey;
if (stricmp(queryiwad_key, "shift") == 0)
{
vkey = VK_SHIFT;
}
else if (stricmp(queryiwad_key, "control") == 0 || stricmp (queryiwad_key, "ctrl") == 0)
{
vkey = VK_CONTROL;
}
else
{
vkey = 0;
}
if (showwin || (vkey != 0 && GetAsyncKeyState(vkey)))
{
WadList = wads;
NumWads = numwads;
DefaultWad = defaultiwad;
return (int)DialogBox(g_hInst, MAKEINTRESOURCE(IDD_IWADDIALOG),
(HWND)Window, (DLGPROC)IWADBoxCallback);
}
return defaultiwad;
}
//==========================================================================
//
// I_SetCursor

View file

@ -89,10 +89,13 @@
#define IDC_NETSTARTPROGRESS 1079
#define IDC_NETSTARTMESSAGE 1080
#define IDC_NETSTARTCOUNT 1081
#define IDC_STATIC_TITLE 1082
#define IDC_STATIC_STARTUP 1083
#define IDC_STATIC_TITLE 1082
#define IDC_STATIC_STARTUP 1083
#define IDCE_ENVIRONMENTDIFFUSION 1085
#define IDC_WELCOME_VULKAN2 1085
#define IDCS_ENVIRONMENTDIFFUSION 1086
#define IDC_RADIO3 1086
#define IDC_WELCOME_VULKAN3 1086
#define IDCE_ROOM 1087
#define IDCS_ROOM 1088
#define IDCE_ROOMHF 1089
@ -143,26 +146,23 @@
#define IDCS_ROOMROLLOFFFACTOR 1134
#define IDCS_REFLECTIONSDELAY2 1135
#define IDCE_MODULATIONTIME2 1135
#define IDC_WELCOME_VERSION 4019
#define IDC_WELCOME_OPENGL 4020
#define IDC_WELCOME_SOFTWARE 4021
#define IDC_WELCOME_FULLSCREEN 4022
#define IDC_WELCOME_NOAUTOLOAD 4023
#define IDC_WELCOME_LIGHTS 4024
#define IDC_WELCOME_BRIGHTMAPS 4025
#define IDC_WELCOME_VULKAN 4026
#define IDC_WELCOME_VULKAN1 4026
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 151
#define _APS_NEXT_RESOURCE_VALUE 152
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1084
#define _APS_NEXT_CONTROL_VALUE 1087
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
// [SP] Upstreamed from Zandronum
#define IDC_WELCOME_VERSION 4019 // [RC] "Welcome" screen.
#define IDC_WELCOME_OPENGL 4020
#define IDC_WELCOME_SOFTWARE 4021
#define IDC_WELCOME_FULLSCREEN 4022
// [SP] This is our's.
#define IDC_WELCOME_NOAUTOLOAD 4023
#define IDC_WELCOME_LIGHTS 4024
#define IDC_WELCOME_BRIGHTMAPS 4025
#define IDC_WELCOME_VULKAN 4026

View file

@ -1,598 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#ifndef _WIN32
#error Only for Windows
#endif
#include "renderlayer.h"
#ifdef STARTUP_SETUP_WINDOW
#define NEED_WINDOWSX_H
#define NEED_COMMCTRL_H
#define ONLY_USERDEFS
#include "build.h"
#include "compat.h"
#include "startwin.game.h"
#include "windows_inc.h"
#include "gamecontrol.h"
#pragma warning(disable:4244) // There's just a bit too much of these in here...
#define TAB_CONFIG 0
#define TAB_MESSAGES 1
typedef struct {
int32_t fullscreen;
int32_t xdim;
int32_t ydim;
int32_t bpp;
} ud_setup_t;
static struct
{
int grp;
ud_setup_t shared;
int polymer;
}
settings;
static HWND startupdlg;
static HWND pages[3];
static int done = -1;
static int mode = TAB_CONFIG;
static TArray<GrpEntry> *gamedata;
static inline void clearfilenames(void)
{
}
static inline void getfilenames(char const *path)
{
}
#define POPULATE_VIDEO 1
#define POPULATE_CONFIG 2
#define POPULATE_GAME 4
#define POPULATE_GAMEDIRS 8
#ifdef INPUT_MOUSE
#undef INPUT_MOUSE
#endif
#define INPUT_KB 0
#define INPUT_MOUSE 1
#define INPUT_JOYSTICK 2
#define INPUT_ALL 3
// Thanks, Microsoft for not providing alternatives for the dialog control macros. :(
#undef SNDMSG
#define SNDMSG ::SendMessageA
const char *controlstrings[] = { "Keyboard only", "Keyboard and mouse", "Keyboard and joystick", "All supported devices" };
static void PopulateForm(int32_t pgs)
{
//char buf[512];
if (pgs & POPULATE_GAMEDIRS)
{
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCGAMEDIR);
#if 0 // This doesn't currently work and in its current form is useless anyway. It should offer a real directory picker.
getfilenames("/");
(void)ComboBox_ResetContent(hwnd);
int const r = ComboBox_AddString(hwnd, "None");
(void)ComboBox_SetItemData(hwnd, r, 0);
(void)ComboBox_SetCurSel(hwnd, r);
auto dirs = finddirs;
for (int i=1, j=1; dirs != NULL; dirs=dirs->next)
{
if (Bstrcasecmp(dirs->name, "autoload") == 0)
{
j++;
continue;
}
(void)ComboBox_AddString(hwnd, dirs->name);
(void)ComboBox_SetItemData(hwnd, i, j);
i++;
j++;
}
#endif
}
if (pgs & POPULATE_GAME)
{
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCDATA);
int i=0;
for (auto& grp : *gamedata)
{
auto p = grp.FileName.LastIndexOfAny("/\\");
auto c = grp.FileName.GetChars();
if (p > 0) c += p+1;
FStringf grpinfo("%s\t%s", grp.FileInfo.name.GetChars(), c);
int const j = ListBox_AddString(hwnd, grpinfo.GetChars());
(void)ListBox_SetItemData(hwnd, j, i);
i++;
}
}
}
static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCFULLSCREEN:
settings.shared.fullscreen = !settings.shared.fullscreen;
PopulateForm(POPULATE_VIDEO);
return TRUE;
//case IDCPOLYMER:
// settings.polymer = !settings.polymer;
// if (settings.shared.bpp == 8) settings.shared.bpp = 32;
// PopulateForm(POPULATE_VIDEO);
// return TRUE;
case IDCVMODE:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
int i = ComboBox_GetCurSel((HWND)lParam);
if (i != CB_ERR) i = ComboBox_GetItemData((HWND)lParam, i);
if (i != CB_ERR)
{
settings.shared.xdim = validmode[i].xdim;
settings.shared.ydim = validmode[i].ydim;
settings.shared.bpp = validmode[i].bpp;
}
}
return TRUE;
case IDCALWAYSSHOW:
displaysetup = IsDlgButtonChecked(hwndDlg, IDCALWAYSSHOW) == BST_CHECKED;
return TRUE;
case IDCAUTOLOAD:
noautoload = (IsDlgButtonChecked(hwndDlg, IDCAUTOLOAD) != BST_CHECKED);
return TRUE;
case IDCGAMEDIR:
return TRUE;
case IDCDATA:
{
if (HIWORD(wParam) != LBN_SELCHANGE) break;
intptr_t i = ListBox_GetCurSel((HWND)lParam);
if (i != CB_ERR) i = ListBox_GetItemData((HWND)lParam, i);
if (i != CB_ERR)
{
settings.grp = i;
}
return TRUE;
}
default:
break;
}
break;
default:
break;
}
return FALSE;
}
static void SetPage(int pageNum)
{
HWND tab = GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL);
auto const cur = SendMessageA(tab, TCM_GETCURSEL, 0, 0);
ShowWindow(pages[cur], SW_HIDE);
SendMessageA(tab, TCM_SETCURSEL, pageNum, 0);
ShowWindow(pages[pageNum], SW_SHOW);
mode = pageNum;
SetFocus(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL));
}
static void EnableConfig(bool n)
{
//EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_CANCEL), n);
EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_START), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCDATA), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCGAMEDIR), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUT), n);
//EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCPOLYMER), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCVMODE), n);
}
static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hbmp = NULL;
switch (uMsg)
{
case WM_INITDIALOG:
{
// Fetch the positions (in screen coordinates) of all the windows we need to tweak
RECT chrome = {};
AdjustWindowRect(&chrome, GetWindowLong(hwndDlg, GWL_STYLE), FALSE);
RECT rdlg;
GetWindowRect(hwndDlg, &rdlg);
// Knock off the non-client area of the main dialogue to give just the client area
rdlg.left -= chrome.left;
rdlg.top -= chrome.top;
rdlg.right -= chrome.right;
rdlg.bottom -= chrome.bottom;
RECT rtab;
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), &rtab);
// Translate them to client-relative coordinates wrt the main dialogue window
rtab.right -= rtab.left - 1;
rtab.bottom -= rtab.top - 1;
rtab.left -= rdlg.left;
rtab.top -= rdlg.top;
RECT rcancel;
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), &rcancel);
rcancel.right -= rcancel.left - 1;
rcancel.bottom -= rcancel.top - 1;
rcancel.left -= rdlg.left;
rcancel.top -= rdlg.top;
RECT rstart;
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_START), &rstart);
rstart.right -= rstart.left - 1;
rstart.bottom -= rstart.top - 1;
rstart.left -= rdlg.left;
rstart.top -= rdlg.top;
// And then convert the main dialogue coordinates to just width/length
rdlg.right -= rdlg.left - 1;
rdlg.bottom -= rdlg.top - 1;
rdlg.left = 0;
rdlg.top = 0;
// Load the bitmap into the bitmap control and fetch its dimensions
hbmp = LoadBitmap((HINSTANCE)GetModuleHandleA(nullptr), MAKEINTRESOURCE(RSRC_BMP));
HWND hwnd = GetDlgItem(hwndDlg, WIN_STARTWIN_BITMAP);
SendMessageA(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
RECT r;
GetClientRect(hwnd, &r);
int const xoffset = r.right;
int const yoffset = r.bottom - rdlg.bottom;
// Shift and resize the controls that require it
rtab.left += xoffset;
rtab.bottom += yoffset;
rcancel.left += xoffset;
rcancel.top += yoffset;
rstart.left += xoffset;
rstart.top += yoffset;
rdlg.right += xoffset;
rdlg.bottom += yoffset;
// Move the controls to their new positions
MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), rtab.left, rtab.top, rtab.right, rtab.bottom, FALSE);
MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), rcancel.left, rcancel.top, rcancel.right, rcancel.bottom, FALSE);
MoveWindow(GetDlgItem(hwndDlg, WIN_STARTWIN_START), rstart.left, rstart.top, rstart.right, rstart.bottom, FALSE);
// Move the main dialogue to the centre of the screen
HDC hdc = GetDC(NULL);
rdlg.left = (GetDeviceCaps(hdc, HORZRES) - rdlg.right) / 2;
rdlg.top = (GetDeviceCaps(hdc, VERTRES) - rdlg.bottom) / 2;
ReleaseDC(NULL, hdc);
MoveWindow(hwndDlg, rdlg.left + chrome.left, rdlg.top + chrome.left,
rdlg.right + (-chrome.left+chrome.right), rdlg.bottom + (-chrome.top+chrome.bottom), TRUE);
// Add tabs to the tab control
{
static char textSetup[] = "Setup";
static char textMessageLog[] = "Message Log";
hwnd = GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL);
TCITEMA tab = {};
tab.mask = TCIF_TEXT;
tab.pszText = textSetup;
SendMessageA(hwnd, TCM_INSERTITEMA, (WPARAM)TAB_CONFIG, (LPARAM)&tab);
tab.mask = TCIF_TEXT;
tab.pszText = textMessageLog;
SendMessageA(hwnd, TCM_INSERTITEMA, (WPARAM)TAB_MESSAGES, (LPARAM)&tab);
// Work out the position and size of the area inside the tab control for the pages
ZeroMemory(&r, sizeof(r));
GetClientRect(hwnd, &r);
SendMessageA(hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM)&r);
r.right -= r.left-1;
r.bottom -= r.top-1;
r.top += rtab.top;
r.left += rtab.left;
// Create the pages and position them in the tab control, but hide them
pages[TAB_CONFIG] = CreateDialog((HINSTANCE)GetModuleHandleA(nullptr), MAKEINTRESOURCE(WIN_STARTWINPAGE_CONFIG), hwndDlg, ConfigPageProc);
SetWindowPos(pages[TAB_CONFIG], hwnd, r.left, r.top, r.right, r.bottom, SWP_HIDEWINDOW);
pages[TAB_MESSAGES] = GetDlgItem(hwndDlg, WIN_STARTWIN_MESSAGES);
SetWindowPos(pages[TAB_MESSAGES], hwnd, r.left, r.top, r.right, r.bottom, SWP_HIDEWINDOW);
// Tell the editfield acting as the console to exclude the width of the scrollbar
GetClientRect(pages[TAB_MESSAGES], &r);
r.right -= GetSystemMetrics(SM_CXVSCROLL)+4;
r.left = r.top = 0;
SendMessageA(pages[TAB_MESSAGES], EM_SETRECTNP,0,(LPARAM)&r);
// Set a tab stop in the game data listbox
{
DWORD tabs[1] = { 150 };
(void)ListBox_SetTabStops(GetDlgItem(pages[TAB_CONFIG], IDCDATA), 1, tabs);
}
SetFocus(GetDlgItem(hwndDlg, WIN_STARTWIN_START));
SetWindowTextA(hwndDlg, apptitle);
}
return FALSE;
}
case WM_NOTIFY:
{
auto nmhdr = (LPNMHDR)lParam;
if (nmhdr->idFrom != WIN_STARTWIN_TABCTL) break;
int const cur = SendMessageA(nmhdr->hwndFrom, TCM_GETCURSEL,0,0);
switch (nmhdr->code)
{
case TCN_SELCHANGING:
case TCN_SELCHANGE:
if (cur < 0 || !pages[cur])
break;
ShowWindow(pages[cur], nmhdr->code == TCN_SELCHANGING ? SW_HIDE : SW_SHOW);
return TRUE;
}
break;
}
case WM_CLOSE:
if (mode == TAB_CONFIG) done = 0;
return TRUE;
case WM_DESTROY:
if (hbmp)
{
DeleteObject(hbmp);
hbmp = NULL;
}
if (pages[TAB_CONFIG])
{
DestroyWindow(pages[TAB_CONFIG]);
pages[TAB_CONFIG] = NULL;
}
startupdlg = NULL;
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case WIN_STARTWIN_CANCEL:
if (mode == TAB_CONFIG) done = 0;
return TRUE;
case WIN_STARTWIN_START:
done = 1;
return TRUE;
}
return FALSE;
case WM_CTLCOLORSTATIC:
if ((HWND)lParam == pages[TAB_MESSAGES])
return (BOOL)(intptr_t)GetSysColorBrush(COLOR_WINDOW);
break;
default:
break;
}
return FALSE;
}
int32_t startwin_open(void)
{
if (startupdlg) return 1;
INITCOMMONCONTROLSEX icc = { sizeof(icc), ICC_TAB_CLASSES };
InitCommonControlsEx(&icc);
startupdlg = CreateDialog((HINSTANCE)GetModuleHandleA(nullptr), MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc);
if (startupdlg)
{
SetPage(TAB_MESSAGES);
EnableConfig(0);
return 0;
}
return -1;
}
int32_t startwin_close(void)
{
if (!startupdlg) return 1;
DestroyWindow(startupdlg);
startupdlg = NULL;
return 0;
}
int32_t startwin_puts(const char *buf)
{
if (!startupdlg) return 1;
const HWND edctl = pages[TAB_MESSAGES];
if (!edctl) return -1;
static HWND dactrl = NULL;
if (!dactrl) dactrl = GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL);
int const vis = ((int)SendMessageA(dactrl, TCM_GETCURSEL,0,0) == TAB_MESSAGES);
if (vis)
SendMessageA(edctl, WM_SETREDRAW, FALSE, 0);
int const curlen = SendMessageA(edctl, WM_GETTEXTLENGTH, 0,0);
SendMessageA(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen);
int const numlines = SendMessageA(edctl, EM_GETLINECOUNT, 0, 0);
static bool newline = false;
const char *p = buf;
while (*p)
{
if (newline)
{
SendMessageA(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n");
newline = false;
}
const char *q = p;
while (*q && *q != '\n') q++;
static char workbuf[1024];
Bmemcpy(workbuf, p, q-p);
if (*q == '\n')
{
if (!q[1])
{
newline = true;
workbuf[q-p] = 0;
}
else
{
workbuf[q-p] = '\r';
workbuf[q-p+1] = '\n';
workbuf[q-p+2] = 0;
}
p = q+1;
}
else
{
workbuf[q-p] = 0;
p = q;
}
SendMessageA(edctl, EM_REPLACESEL, 0, (LPARAM)workbuf);
}
int const newnumlines = SendMessageA(edctl, EM_GETLINECOUNT, 0, 0);
SendMessageA(edctl, EM_LINESCROLL, 0, newnumlines - numlines);
if (vis)
SendMessageA(edctl, WM_SETREDRAW, TRUE, 0);
return 0;
}
int32_t startwin_settitle(const char *str)
{
if (!startupdlg) return 1;
SetWindowTextA(startupdlg, str);
return 0;
}
int32_t startwin_idle(void *v)
{
if (!startupdlg || !IsWindow(startupdlg)) return 0;
if (IsDialogMessage(startupdlg, (MSG *)v)) return 1;
return 0;
}
int32_t startwin_run(void)
{
if (!startupdlg) return 1;
done = -1;
SetPage(TAB_CONFIG);
EnableConfig(1);
settings.shared = { 0, 0, 0, 0 };
settings.grp = 0;
PopulateForm(-1);
do
{
MSG msg;
switch (GetMessage(&msg, NULL, 0,0))
{
case 0:
done = 1;
break;
case -1:
return -1;
default:
if (IsWindow(startupdlg) && IsDialogMessage(startupdlg, &msg))
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
while (done < 0);
SetPage(TAB_MESSAGES);
EnableConfig(0);
return done;
}
int ShowStartupWindow(TArray<GrpEntry> &groups)
{
gamedata = &groups;
startwin_open();
startwin_settitle("Demolition");
if (1)//readSetup < 0 || (!g_noSetup && (displaysetup)) || g_commandSetup)
{
auto choice = startwin_run();
if (choice == 0)
{
startwin_close();
return - 1;
}
}
startwin_close();
return settings.grp;
}
#endif // STARTUP_SETUP_WINDOW

View file

@ -1,121 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
Copyright (C) 2019 Christoph Oelckers
Demolition is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
// resource ids
#define WIN_STARTWIN 1000
#define WIN_STARTWINPAGE_CONFIG 2000
#define WIN_STARTWIN_BITMAP 100 // banner bitmap
#define WIN_STARTWIN_TABCTL 101
#define WIN_STARTWIN_CANCEL IDCANCEL
#define WIN_STARTWIN_START IDOK
#define WIN_STARTWIN_MESSAGES 104 // output list box
#define IDD_CRASHDIALOG 105
#define IDD_CRASHDETAILS 106
#define IDD_CRASHOVERVIEW 107
#define IDD_ERRORPANE 108
#define RSRC_ICON 100
#define RSRC_BMP 200
// config page
#define IDCFULLSCREEN 100
#define IDCVMODE 101
#define IDCSOUNDDRV 102
#define IDCMIDIDEV 103
#define IDCCDADEV 104
#define IDCALWAYSSHOW 105
#define IDCDATA 106
#define IDCGAMEDIR 107
#define IDCPOLYMER 108
#define IDCAUTOLOAD 109
#define IDCINPUT 110
#define IDC_STATIC (-1)
#define IDC_ERRORMESSAGE 1004
#define IDQUIT 1005
#define IDC_IWADLIST 1006
#define IDC_DONTASKIWAD 1007
#define IDC_SPIN1 1010
#define IDC_SPINID1 1010
#define IDC_CRASHINFO 1011
#define IDC_SPINID2 1011
#define IDC_TOOLTIP1 1012
#define IDCE_ENVIRONMENTSIZE 1025
#define IDCS_ENVIRONMENTSIZE 1026
#define IDC_DECAYTIMESCALE 1027
#define IDC_REFLECTIONSSCALE 1028
#define IDC_REFLECTIONSDELAYSCALE 1029
#define IDC_REVERBSCALE 1030
#define IDC_REVERBDELAYSCALE 1031
#define IDC_DECAYHFLIMIT 1032
#define IDC_ECHOTIMESCALE 1033
#define IDC_MODULATIONTIMESCALE 1034
#define IDC_DUMMY 1035
#define IDC_NEW 1036
#define IDC_SAVE 1037
#define IDC_REVERT 1038
#define IDC_CURRENTENVIRONMENT 1039
#define IDC_ID2 1040
#define IDC_ID1 1041
#define IDC_SHOWIDS 1043
#define IDC_LIST3 1047
#define IDC_ENVIRONMENTLIST 1047
#define IDC_SIZEBOX 1048
#define IDC_EDIT1 1049
#define IDC_NEWENVNAME 1049
#define IDC_CRASHFILECONTENTS 1049
#define IDC_BOINGEDIT 1049
#define IDC_EDITID1 1050
#define IDC_EDITID2 1051
#define IDC_HOTKEY1 1053
#define IDC_LIST1 1054
#define IDC_ENVLIST 1054
#define IDC_CRASHFILES 1054
#define IDC_SELECTALL 1055
#define IDC_SELECTNONE 1056
#define IDC_SAVEGROUP 1057
#define IDC_TESTEAX 1058
#define IDC_RICHEDIT21 1059
#define IDC_CRASHHEADER 1059
#define IDC_RICHEDIT22 1061
#define IDC_PLEASETELLUS 1061
#define IDC_BUTTON2 1062
#define IDC_CRASHDETAILS 1062
#define IDC_DEADGUYVIEWER 1063
#define IDC_CRASHFILESIZE 1066
#define IDC_BUTTON1 1071
#define IDC_BOINGSTATUS 1072
#define IDC_BOINGPROGRESS 1073
#define IDC_TAB1 1074
#define IDC_CRASHTAB 1074
#define IDC_RICHEDIT23 1075
#define IDC_CRASHSUMMARY 1075
#define IDC_ERRORTEXT 1076
#define IDC_ICONPIC 1077
#define IDC_DIVIDERBAR 1078
#define IDC_PROGRESS1 1079
#define IDC_NETSTARTPROGRESS 1079
#define IDC_NETSTARTMESSAGE 1080
#define IDC_NETSTARTCOUNT 1081
#define IDC_STATIC_TITLE 1082
#define IDC_STATIC_STARTUP 1083
#define IDC_SAVEREPORT 1084