- moved the startup dialog out of the game front ends, now that there is a global cross-game list of playable configurations.

This commit is contained in:
Christoph Oelckers 2019-10-31 23:25:21 +01:00
parent ba00fe4e66
commit 57f879fa8b
58 changed files with 907 additions and 8071 deletions

View file

@ -352,30 +352,6 @@ if( DEM_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
set( CMAKE_CXX_FLAGS "-DNO_SSE ${CMAKE_CXX_FLAGS}" )
endif()
# Use the highest C++ standard available since VS2015 compiles with C++14
# but we only require C++11. The recommended way to do this in CMake is to
# probably to use target_compile_features, but I don't feel like maintaining
# a list of features we use.
CHECK_CXX_COMPILER_FLAG( "-std=gnu++14" CAN_DO_CPP14 )
if ( CAN_DO_CPP14 )
set ( CMAKE_CXX_FLAGS "-std=gnu++14 ${CMAKE_CXX_FLAGS}" )
else ()
CHECK_CXX_COMPILER_FLAG( "-std=gnu++1y" CAN_DO_CPP1Y )
if ( CAN_DO_CPP1Y )
set ( CMAKE_CXX_FLAGS "-std=gnu++1y ${CMAKE_CXX_FLAGS}" )
else ()
CHECK_CXX_COMPILER_FLAG( "-std=gnu++11" CAN_DO_CPP11 )
if ( CAN_DO_CPP11 )
set ( CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}" )
else ()
CHECK_CXX_COMPILER_FLAG( "-std=gnu++0x" CAN_DO_CPP0X )
if ( CAN_DO_CPP0X )
set ( CMAKE_CXX_FLAGS "-std=gnu++0x ${CMAKE_CXX_FLAGS}" )
endif ()
endif ()
endif ()
endif ()
# Remove extra warnings when using the official DirectX headers.
# Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid,
# which is a royal pain. The previous version I had been using was fine with them.
@ -501,9 +477,9 @@ set( PLAT_WIN32_SOURCES
glad/src/glad_wgl.c
platform/win32/winbits.cpp
platform/win32/i_specialpaths.cpp
platform/win32/startwin.game.cpp
# This needs a rework anyway in order to consolidate the startup dialogs so don't bother to sort in properly.
#startgtk.game.cpp
#startosx.game.mm
#sw/src/startgtk.game.cpp
@ -512,6 +488,7 @@ set( PLAT_WIN32_SOURCES
set( PLAT_POSIX_SOURCES
#audiolib/src/driver_sdl.cpp
#audiolib/src/sdlmusic.cpp
#platform/gtk/startgtk.game.cpp
)
set( PLAT_SDL_SOURCES
@ -530,6 +507,9 @@ 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

@ -26,11 +26,6 @@ include_directories(
)
if (WIN32)
set( PLAT_SOURCES
src/startwin.game.cpp
)
endif()
set( PCH_SOURCES
src/actor.cpp
@ -123,7 +118,6 @@ file( GLOB HEADER_FILES
add_library( blood STATIC
${HEADER_FILES}
${PCH_SOURCES}
${PLAT_SOURCES}
)

View file

@ -1259,10 +1259,6 @@ int app_main(int argc, char const * const * argv)
gGameOptions.nMonsterSettings = userConfig.nomonsters;
bQuickStart = userConfig.nologo;
ParseOptions();
G_ExtInit();
//G_AddSearchPaths();
#ifdef STARTUP_SETUP_WINDOW
int const readSetup =
@ -1279,17 +1275,6 @@ int app_main(int argc, char const * const * argv)
ScanINIFiles();
#ifdef STARTUP_SETUP_WINDOW
if (readSetup < 0 || (!gNoSetup && (displaysetup)) || gCommandSetup)
{
if (quitevent || !gi->startwin_run())
{
engineUnInit();
Bexit(0);
}
}
#endif
G_LoadGroups();
initprintf("Initializing OSD...\n");
@ -2294,12 +2279,6 @@ void sndPlaySpecialMusicOrNothing(int nMusic)
extern void faketimerhandler();
extern int app_main(int argc, char const* const* argv);
extern void app_crashhandler(void);
extern int32_t startwin_open(void);
extern int32_t startwin_close(void);
extern int32_t startwin_puts(const char*);
extern int32_t startwin_settitle(const char*);
extern int32_t startwin_idle(void*);
extern int32_t startwin_run(void);
bool validate_hud(int layout);
void set_hud_layout(int layout);
void set_hud_scale(int scale);
@ -2313,12 +2292,6 @@ GameInterface Interface = {
set_hud_layout,
set_hud_scale,
app_crashhandler,
startwin_open,
startwin_close,
startwin_puts,
startwin_settitle,
startwin_idle,
startwin_run,
G_DefaultDefFile,
G_DefFile,
};

View file

@ -64,7 +64,7 @@ void clearGrpNamePtr(void)
const char *G_DefaultGrpFile(void)
{
return "nblood.pk3";
return "blood.rff";
}
const char *G_DefaultDefFile(void)
@ -104,41 +104,8 @@ void G_SetupGlobalPsky(void)
int32_t g_groupFileHandle;
struct strllist* CommandPaths, * CommandGrps;
struct strllist* CommandGrps;
void G_ExtInit(void)
{
char cwd[BMAX_PATH];
#ifdef EDUKE32_OSX
char *appdir = Bgetappdir();
addsearchpath(appdir);
Bfree(appdir);
#endif
if (getcwd(cwd,BMAX_PATH) && Bstrcmp(cwd,"/") != 0)
addsearchpath(cwd);
if (CommandPaths)
{
int32_t i;
struct strllist *s;
while (CommandPaths)
{
s = CommandPaths->next;
i = addsearchpath(CommandPaths->str);
if (i < 0)
{
initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
i==-1 ? "not a directory" : "no such directory");
}
Bfree(CommandPaths->str);
Bfree(CommandPaths);
CommandPaths = s;
}
}
}
static int32_t G_TryLoadingGrp(char const * const grpfile)
{
@ -232,52 +199,6 @@ void G_LoadGroups()
pathsearchmode = bakpathsearchmode;
}
void G_CleanupSearchPaths(void)
{
removesearchpaths_withuser(SEARCHPATH_REMOVE);
}
//////////
void G_AddGroup(const char *buffer)
{
char buf[BMAX_PATH];
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
Bstrcpy(buf, buffer);
if (Bstrchr(buf,'.') == 0)
Bstrcat(buf,".grp");
s->str = Xstrdup(buf);
if (CommandGrps)
{
struct strllist *t;
for (t = CommandGrps; t->next; t=t->next) ;
t->next = s;
return;
}
CommandGrps = s;
}
void G_AddPath(const char *buffer)
{
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
s->str = Xstrdup(buffer);
if (CommandPaths)
{
struct strllist *t;
for (t = CommandPaths; t->next; t=t->next) ;
t->next = s;
return;
}
CommandPaths = s;
}
//////////
// loads all group (grp, zip, pk3/4) files in the given directory

View file

@ -514,7 +514,6 @@ extern char *g_grpNamePtr;
extern int loaddefinitions_game(const char *fn, int32_t preload);
extern void G_AddSearchPaths(void);
extern void G_CleanupSearchPaths(void);
extern void G_ExtInit(void);
@ -961,7 +960,4 @@ public:
}
};
void G_AddGroup(const char* buffer);
void G_AddPath(const char* buffer);
END_BLD_NS

View file

@ -1,748 +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 "common.h"
#include "common_game.h"
#include "compat.h"
#include "dynamicgtk.h"
#include "blood.h"
#include "gtkpixdata.h"
#include "globals.h"
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;
GtkWidget *inputdevlabel;
GtkWidget *inputdevcombo;
GtkWidget *custommodlabel;
GtkWidget *custommodcombo;
GtkWidget *emptyhlayout;
GtkWidget *autoloadcheck;
GtkWidget *alwaysshowcheck;
GtkWidget *configtab;
GtkWidget *messagesscroll;
GtkWidget *messagestext;
GtkWidget *messagestab;
GtkWidget *buttons;
GtkWidget *cancelbutton;
GtkWidget *cancelbuttonalign;
GtkWidget *cancelbuttonlayout;
GtkWidget *cancelbuttonicon;
GtkWidget *cancelbuttonlabel;
GtkWidget *startbutton;
GtkWidget *startbuttonalign;
GtkWidget *startbuttonlayout;
GtkWidget *startbuttonicon;
GtkWidget *startbuttonlabel;
} stwidgets;
static struct
{
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);
}
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 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;
CACHE1D_FIND_REC *dirs = NULL;
GtkTreeIter iter;
pathsearchmode = 1;
if ((homedir = Bgethomedir()))
{
Bsnprintf(pdir, sizeof(pdir), "%s/" ".blood", homedir);
dirs = klistpath(pdir, "*", CACHE1D_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);
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 0
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);
}
}
}
#endif
}
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);
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dlabel, 0,1, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 7);
// 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);
}
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.vmode3dcombo, 1,2, 0,1,
(GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)0, 4, 0);
// Fullscreen checkbox
stwidgets.displayvlayout = gtk_vbox_new(TRUE, 0);
gtk_table_attach(GTK_TABLE(stwidgets.configtlayout), stwidgets.displayvlayout, 2,3, 0,1, GTK_FILL, (GtkAttachOptions)0, 4, 0);
stwidgets.fullscreencheck = gtk_check_button_new_with_mnemonic("_Fullscreen");
gtk_box_pack_start(GTK_BOX(stwidgets.displayvlayout), stwidgets.fullscreencheck, FALSE, FALSE, 0);
// 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);
// 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), 1), 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);
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);
// 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);
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 = gSetup;
settings.gamedir = g_modDir;
//settings.grp = g_selectedGrp;
#ifdef POLYMER
settings.polymer = 0;
#endif
PopulateForm(ALL);
gtk_main();
SetPage(TAB_MESSAGES);
if (retval) // launch the game with these parameters
{
gSetup = settings.shared;
#ifdef POLYMER
glrendmode = (settings.polymer) ? REND_POLYMER : REND_POLYMOST;
#endif
//g_selectedGrp = settings.grp;
Bstrcpy(g_modDir, (gNoSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return retval;
}

View file

@ -1,859 +0,0 @@
#define Rect CocoaRect
#import <Cocoa/Cocoa.h>
#undef Rect
#include "ns.h" // Must come before everything else!
#include "blood.h"
#include "common.h"
#include "common_game.h"
#include "build.h"
#include "compat.h"
#include "baselayer.h"
#include "globals.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
@interface GameEntry : NSObject
{
NSString *namestring;
NSString *inifilestring;
INICHAIN const *fg;
}
- (id)initWithINICHAIN:(INICHAIN const *)inichain;
- (void)dealloc;
- (NSString *)name;
- (NSString *)inifile;
- (INICHAIN const *)entryptr;
@end
@implementation GameEntry
- (id)initWithINICHAIN:(INICHAIN const *)inichain
{
self = [super init];
if (self)
{
fg = inichain;
char const *const name = nullptr == fg->pDescription ? fg->zName : fg->pDescription->pzName;
namestring = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
[namestring retain];
inifilestring = [NSString stringWithCString:fg->zName encoding:NSUTF8StringEncoding];
[inifilestring retain];
}
return self;
}
- (void)dealloc
{
[namestring release];
[inifilestring release];
[super dealloc];
}
- (NSString *)name
{
return namestring;
}
- (NSString *)inifile
{
return inifilestring;
}
- (INICHAIN const *)entryptr
{
return fg;
}
@end
@interface GameListSource : NSObject <NSComboBoxDataSource>
{
NSMutableArray *list;
}
- (id)init;
- (void)dealloc;
- (GameEntry *)entryAtIndex:(int)index;
- (int)findIndexForINI:(NSString*)inifile;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
@end
@implementation GameListSource
- (id)init
{
self = [super init];
if (self)
{
list = [[NSMutableArray alloc] init];
for (auto fg = pINIChain; nullptr != fg; fg = fg->pNext)
{
[list addObject:[[GameEntry alloc] initWithINICHAIN:fg]];
}
}
return self;
}
- (void)dealloc
{
[list release];
[super dealloc];
}
- (GameEntry *)entryAtIndex:(int)index
{
return [list objectAtIndex:index];
}
- (int)findIndexForINI:(NSString*)inifile
{
for (NSUInteger i = 0, count = [list count]; i < count; ++i)
{
if ([[[list objectAtIndex:i] inifile] isEqual:inifile])
{
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: // ini file column
return [[list objectAtIndex:rowIndex] inifile];
default:
return nil;
}
}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
UNREFERENCED_PARAMETER(aTableView);
return [list count];
}
@end
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)
{
#ifdef MAC_OS_X_VERSION_10_12
[control setControlSize:NSControlSizeSmall];
#else
[control setControlSize:NSControlSizeSmall];
#endif
}
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:NSSwitchButton];
[checkbox sizeToFit];
return checkbox;
}
static NSPopUpButton * makeComboBox(void)
{
NSPopUpButton *comboBox = [[NSPopUpButton alloc] init];
[comboBox setPullsDown:NO];
setFontToSmall(comboBox);
setControlToSmall([comboBox cell]);
[comboBox setBezelStyle:NSRoundedBezelStyle];
[comboBox setPreferredEdge:NSMaxYEdge];
[[comboBox cell] setArrowPosition:NSPopUpArrowAtCenter];
[comboBox sizeToFit];
return comboBox;
}
static id nsapp;
/* 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
{
INICHAIN const * ini;
char *gamedir;
ud_setup_t shared;
int polymer;
}
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:NSRoundedBezelStyle];
[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:NSRoundedBezelStyle];
[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] == NSOnState);
int idx3d = -1;
int xdim = 0, ydim = 0, bpp = 0;
if (firstTime) {
xdim = settings.shared.xdim;
ydim = settings.shared.ydim;
bpp = settings.shared.bpp;
} 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.shared.xdim = validmode[mode].xdim;
settings.shared.ydim = validmode[mode].ydim;
settings.shared.bpp = validmode[mode].bpp;
settings.shared.fullscreen = validmode[mode].fs;
}
int row = [[gameList documentView] selectedRow];
if (row >= 0)
{
settings.ini = [[gamelistsrc entryAtIndex:row] entryptr];
}
settings.shared.forcesetup = [alwaysShowButton state] == NSOnState;
retval = 1;
}
- (void)setupRunMode
{
videoGetModes();
[fullscreenButton setState: (settings.shared.fullscreen ? NSOnState : NSOffState)];
[alwaysShowButton setState: (settings.shared.forcesetup ? NSOnState : NSOffState)];
[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.ini)
{
int row = [gamelistsrc findIndexForINI:[NSString stringWithUTF8String:settings.ini->zName]];
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)
{
// fix for "ld: absolute address to symbol _NSApp in a different linkage unit not supported"
// (OS X 10.6) when building for PPC
nsapp = [NSApplication sharedApplication];
if (startwin != nil) return 1;
startwin = [[StartupWindow alloc] init];
if (startwin == nil) return -1;
[startwin setupMessagesMode];
[nsapp finishLaunching];
[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.shared = gSetup;
settings.ini = pINISelected;
settings.gamedir = g_modDir;
[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) {
gSetup = settings.shared;
glrendmode = settings.polymer ? REND_POLYMER : REND_POLYMOST;
pINISelected = settings.ini;
Bstrcpy(g_modDir, (gNoSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return retval;
}

View file

@ -1,48 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood 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 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

View file

@ -237,12 +237,6 @@ struct GameInterface
// These will later be removed.
void (*app_crashhandler)();
int32_t(*startwin_open)();
int32_t(*startwin_close)();
int32_t(*startwin_puts)(const char*);
int32_t(*startwin_settitle)(const char*);
int32_t (*startwin_idle)(void*);
int32_t (*startwin_run)(void);
const char* (*DefaultDefFile)();
const char* (*DefFile)();

View file

@ -1217,7 +1217,6 @@ int32_t Bclosedir(BDIR *dir);
////////// Paths //////////
char *Bgethomedir(void);
char *Bgetappdir(void);
int32_t Bcorrectfilename(char *filename, int32_t removefn);
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);

View file

@ -98,55 +98,6 @@ char *Bgethomedir(void)
#endif
}
char *Bgetappdir(void)
{
char *dir = NULL;
#ifdef _WIN32
char appdir[MAX_PATH];
if (GetModuleFileNameA(NULL, appdir, MAX_PATH) > 0) {
// trim off the filename
char *slash = Bstrrchr(appdir, '\\');
if (slash) slash[0] = 0;
dir = Xstrdup(appdir);
}
#elif defined EDUKE32_OSX
dir = osx_getappdir();
#elif defined __FreeBSD__
// the sysctl should also work when /proc/ is not mounted (which seems to
// be common on FreeBSD), so use it..
char buf[PATH_MAX] = {0};
int name[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
size_t len = sizeof(buf) - 1;
int ret = sysctl(name, ARRAY_SIZE(name), buf, &len, NULL, 0);
if (ret == 0 && buf[0] != '\0')
{
// again, remove executable name with dirname()
// on FreeBSD dirname() seems to use some internal buffer
dir = Xstrdup(dirname(buf));
}
#elif defined __linux || defined EDUKE32_BSD
char buf[PATH_MAX] = {0};
char buf2[PATH_MAX] = {0};
# ifdef __linux
Bsnprintf(buf, sizeof(buf), "/proc/%d/exe", getpid());
# else // the BSDs.. except for FreeBSD which has a sysctl
Bsnprintf(buf, sizeof(buf), "/proc/%d/file", getpid());
# endif
int len = readlink(buf, buf2, sizeof(buf2));
if (len != -1) {
// remove executable name with dirname(3)
// on Linux, dirname() will modify buf2 (cutting off executable name) and return it
// on FreeBSD it seems to use some internal buffer instead.. anyway, just strdup()
dir = Xstrdup(dirname(buf2));
}
#endif
return dir;
}
int32_t Bcorrectfilename(char *filename, int32_t removefn)
{

View file

@ -72,13 +72,6 @@ int32_t startwin_puts(const char *s) { UNREFERENCED_PARAMETER(s); return 0; }
int32_t startwin_idle(void *s) { UNREFERENCED_PARAMETER(s); return 0; }
int32_t startwin_settitle(const char *s) { UNREFERENCED_PARAMETER(s); return 0; }
int32_t startwin_run(void) { return 0; }
#else
int32_t startwin_open(void) { return gi->startwin_open(); }
int32_t startwin_close(void) { return gi->startwin_close(); }
int32_t startwin_puts(const char* s) { return gi->startwin_puts(s); }
int32_t startwin_idle(void* s) { return gi->startwin_idle(s); }
int32_t startwin_settitle(const char* s) { return gi->startwin_settitle(s); }
int32_t startwin_run(void) { return gi->startwin_run(); }
#endif
int myconnectindex, numplayers;
@ -338,7 +331,6 @@ void wm_setapptitle(const char *name)
}
#endif
startwin_settitle(apptitle);
#else
UNREFERENCED_PARAMETER(name);
#endif
@ -395,167 +387,6 @@ static void sighandler(int signum)
FString currentGame; // Currently there is no global state for the current game. This is a temporary workaround because the video init code needs to do a few things based on the active game.
namespace Duke
{
extern GameInterface Interface;
}
namespace Redneck
{
extern GameInterface Interface;
}
namespace Blood
{
extern GameInterface Interface;
}
namespace ShadowWarrior
{
extern GameInterface Interface;
}
GameInterface *CheckFrontend()
{
FILE* f = fopen("blood.rff", "rb");
if (f)
{
currentGame = "Blood";
fclose(f);
return &Blood::Interface;
}
else
{
f = fopen("redneck.grp", "rb");
if (f)
{
currentGame = "Redneck";
fseek(f, 0, SEEK_END);
auto pos = ftell(f);
// Quick hack to distinguish these two. This won't survive until production but for testing it's sufficient.
if (pos > 190'000'000) currentGame = "RedneckRides";
fclose(f);
return &Redneck::Interface;
}
else
{
f = fopen("sw.grp", "rb");
if (f)
{
currentGame = "ShadowWarrior";
fclose(f);
return &ShadowWarrior::Interface;
}
f = fopen("fury.grp", "rb");
if (f)
{
currentGame = "IonFury";
fclose(f);
return &Duke::Interface;
}
f = fopen("nam.grp", "rb");
if (f)
{
currentGame = "Nam";
fclose(f);
return &Duke::Interface;
}
f = fopen("ww2gi.grp", "rb");
if (f)
{
currentGame = "WW2GI";
fclose(f);
return &Duke::Interface;
}
else
{
currentGame = "Duke";
}
return &Duke::Interface;
}
}
}
void ChooseGame()
{
#if 0
gi = CheckFrontend();
return;
#else
auto dir = Args->CheckValue("-game");
if (dir && !chdir(dir))
{
gi = CheckFrontend();
return;
}
TArray<FString> paths;
std::vector<std::wstring> wgames;
TArray<TASKDIALOG_BUTTON> buttons;
char* token;
FileReader fr;
if (fr.OpenFile("./games.list"))
{
auto filedata = fr.ReadPadded(1);
auto script = scriptfile_fromstring((char*)filedata.Data());
int id = 1000;
while (!scriptfile_eof(script))
{
scriptfile_getstring(script, &token);
if (scriptfile_eof(script))
{
break;
}
FString game = token;
scriptfile_getstring(script, &token);
paths.Push(token);
FStringf display("%s\n%s", game.GetChars(), token);
wgames.push_back(display.WideString());
buttons.Push({ id++, wgames.back().c_str() });
}
}
if (paths.Size() == 0)
{
exit(1);
}
int nResult = 0;
TASKDIALOGCONFIG stTaskConfig;
ZeroMemory(&stTaskConfig, sizeof(stTaskConfig));
stTaskConfig.cbSize = sizeof(TASKDIALOGCONFIG);
stTaskConfig.hwndParent = NULL;
stTaskConfig.hInstance = NULL;
stTaskConfig.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION| TDF_USE_COMMAND_LINKS;
if (!gi)
{
// Open a popup to select the game.
// The entire startup code just doesn't work right if this isn't checked as the very first thing.
stTaskConfig.pszWindowTitle = L"Demolition";
stTaskConfig.pszMainInstruction = L"Choose your game";
stTaskConfig.pszContent = L"";
stTaskConfig.cButtons = buttons.Size();
stTaskConfig.pButtons = buttons.Data();
stTaskConfig.nDefaultButton = 1000;
if (SUCCEEDED(TaskDialogIndirect(&stTaskConfig, &nResult, NULL, NULL)))
{
if (nResult >= 1000 && nResult < 1000 +(int)buttons.Size())
{
nResult -= 1000;
chdir(paths[nResult]);
gi = CheckFrontend();
}
}
if (gi == nullptr) exit(1);
}
#endif
}
int WINAPI WinMain(HINSTANCE , HINSTANCE , LPSTR , int )
#else
@ -581,8 +412,6 @@ int main(int argc, char *argv[])
Args = new FArgs(buildargc, buildargv);
ChooseGame();
#if defined _WIN32 && defined SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING
// Thread naming interferes with debugging using MinGW-w64's GDB.
SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
@ -616,7 +445,6 @@ int main(int argc, char *argv[])
gtkbuild_init(&argc, &argv);
#endif
startwin_open();
try
{
@ -638,8 +466,6 @@ int main(int argc, char *argv[])
r = exit.Reason();
}
startwin_close();
#if defined(HAVE_GTK2)
gtkbuild_exit(r);
#endif
@ -884,6 +710,7 @@ void initputs(const char *buf)
OSD_Puts(buf);
// Bprintf("%s", buf);
#if 0
mutex_lock(&m_initprintf);
if (Bstrlen(dabuf) + Bstrlen(buf) > 1022)
{
@ -904,6 +731,7 @@ void initputs(const char *buf)
Bmemset(dabuf, 0, sizeof(dabuf));
}
mutex_unlock(&m_initprintf);
#endif
}
//
@ -1465,6 +1293,7 @@ static void destroy_window_resources()
#endif
}
extern int globalShadeDiv;
void sdlayer_setvideomode_opengl(void)
{
glsurface_destroy();
@ -1474,9 +1303,7 @@ void sdlayer_setvideomode_opengl(void)
GLInterface.Init();
GLInterface.InitGLState(4, glmultisample);
// I have no idea how to get this info from the lookup tables. Fortunately it is consistent per game.
if (!currentGame.Compare("Blood")) GLInterface.SetShadeDiv(62);
else if (!currentGame.Compare("IonFury")) GLInterface.SetShadeDiv(30);
else GLInterface.SetShadeDiv(26);
GLInterface.SetShadeDiv(globalShadeDiv);
GLInterface.mSamplers->SetTextureFilterMode(hw_texfilter, hw_anisotropy);
@ -1494,8 +1321,6 @@ int32_t setvideomode_sdlcommon(int32_t *x, int32_t *y, int32_t c, int32_t fs, in
if (videoCheckMode(x, y, c, fs, 0) < 0)
return -1;
startwin_close();
if (g_mouseGrabbed)
{
*regrab = 1;
@ -2341,11 +2166,6 @@ int32_t handleevents(void)
inputchecked = 0;
timerUpdateClock();
#ifndef _WIN32
startwin_idle(NULL);
#endif
return rv;
}

View file

@ -48,6 +48,7 @@
#include "filesystem.h"
#include "superfasthash.h"
#include "resourcefile.h"
#include "v_text.h"
//#include "md5.h"
//#include "doomstat.h"

View file

@ -17,6 +17,8 @@
InputState inputState;
void SetClipshapes();
int ShowStartupWindow(TArray<GrpEntry> &);
int globalShadeDiv;
struct GameFuncNameDesc
{
@ -287,6 +289,60 @@ void UserConfig::ProcessOptions()
}
//==========================================================================
//
//
//
//==========================================================================
namespace Duke
{
extern GameInterface Interface;
}
namespace Redneck
{
extern GameInterface Interface;
}
namespace Blood
{
extern GameInterface Interface;
}
namespace ShadowWarrior
{
extern GameInterface Interface;
}
void CheckFrontend(int flags)
{
if (flags & GAMEFLAG_BLOOD)
{
gi = &Blood::Interface;
globalShadeDiv = 62;
}
else if (flags & GAMEFLAG_RR)
{
gi = &Redneck::Interface;
globalShadeDiv = 30;
}
else if (flags & GAMEFLAG_FURY)
{
gi = &Duke::Interface;
globalShadeDiv = 26; // This is different from all other games which need a value two less than the amount of shades.
}
else if (flags & GAMEFLAG_SW)
{
gi = &ShadowWarrior::Interface;
globalShadeDiv = 30;
}
else
{
gi = &Duke::Interface;
globalShadeDiv = 30;
}
}
//==========================================================================
//
//
@ -305,14 +361,11 @@ void CONFIG_Init()
userConfig.ProcessOptions();
G_LoadConfig();
// Startup dialog must be presented here so that everything can be set up before reading the keybinds.
auto groups = GrpScan();
for (auto& grp : groups)
{
FStringf grpinfo("%s: %s, %s, %s, %s\r\n", grp.FileInfo.name.GetChars(), grp.FileName.GetChars(), grp.FileInfo.scriptname.GetChars(), grp.FileInfo.rtsname.GetChars(), grp.FileInfo.defname.GetChars());
OutputDebugStringA(grpinfo);
}
int groupno = ShowStartupWindow(groups);
LumpFilter = currentGame;
if (LumpFilter.Compare("Redneck") == 0) LumpFilter = "Redneck.Redneck";
else if (LumpFilter.Compare("RedneckRides") == 0) LumpFilter = "Redneck.RidesAgain";

View file

@ -127,10 +127,11 @@ enum
GAMEFLAG_DUKEBETA = 0x00000060, // includes 0x20 since it's a shareware beta
GAMEFLAG_FURY = 0x00000080,
GAMEFLAG_RR = 0x00000100,
GAMEFLAG_RRRA = 0x00000200,
GAMEFLAG_RRRA = 0x00000300,
GAMEFLAG_BLOOD = 0x00000400,
GAMEFLAG_STANDALONE = 0x00000800,
GAMEFLAGMASK = 0x000007FF, // flags allowed from grpinfo
GAMEFLAG_SW = 0x00000800,
GAMEFLAG_STANDALONE = 0x00001000,
GAMEFLAGMASK = 0x00000FFF, // flags allowed from grpinfo
};

View file

@ -42,6 +42,7 @@
#include "image.h"
#include "cache1d.h"
#include "imagehelpers.h"
#include "v_text.h"
extern "C"
{

View file

@ -43,6 +43,37 @@
class FArgs
{
public:
typedef TIterator<FString> iterator;
typedef TIterator<const FString> const_iterator;
typedef FString value_type;
iterator begin()
{
return &Argv[0];
}
const_iterator begin() const
{
return &Argv[0];
}
const_iterator cbegin() const
{
return &Argv[0];
}
iterator end()
{
return &Argv[Argv.Size()];
}
const_iterator end() const
{
return &Argv[Argv.Size()];
}
const_iterator cend() const
{
return &Argv[Argv.Size()];
}
FArgs();
FArgs(const FArgs &args);
FArgs(int argc, char **argv);

View file

@ -13,5 +13,3 @@ void OSD_Printf(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
void I_Error(const char *fmt, ...) ATTRIBUTE((format(printf,1,2)));
#include "v_text.h"

View file

@ -19,7 +19,7 @@
#include "templates.h"
#include "printf.h"
#include "name.h"
//#include "v_text.h"
#include "v_text.h"
#include "cache1d.h"
// MACROS ------------------------------------------------------------------

View file

@ -26,11 +26,6 @@ include_directories(
)
if (WIN32)
set( PLAT_SOURCES
src/startwin.game.cpp
)
endif()
set( NOT_COMPILED_SOURCE_FILES
src/gamestructures.cpp
@ -84,7 +79,6 @@ file( GLOB HEADER_FILES
add_library( duke3d STATIC
${HEADER_FILES}
${PCH_SOURCES}
${PLAT_SOURCES}
${NOT_COMPILED_SOURCE_FILES}
)

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

@ -12,15 +12,10 @@
#include "cmdlib.h"
#include "grpscan.h"
#include "rts.h"
#include "gamecontrol.h"
#include "vfs.h"
#ifdef _WIN32
# include "windows_inc.h"
# include "win32/winbits.h"
#elif defined __APPLE__
# include "osxbits.h"
#endif
#include "common.h"
#include "common_game.h"
@ -46,69 +41,19 @@ static const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "nam.def"
static const char *defaultgameconfilename[GAMECOUNT] = { "EDUKE.CON", "NAM.CON", "NAPALM.CON", "WW2GI.CON" };
#endif
// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
char *g_grpNamePtr = NULL;
// g_scriptNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
char *g_scriptNamePtr = NULL;
void clearGrpNamePtr(void)
{
Xfree(g_grpNamePtr);
// g_grpNamePtr assumed to be assigned to right after
}
void clearScriptNamePtr(void)
{
Xfree(g_scriptNamePtr);
// g_scriptNamePtr assumed to be assigned to right after
}
const char *G_DefaultGrpFile(void)
{
#ifndef EDUKE32_STANDALONE
if (DUKE)
return defaultgamegrp[GAME_DUKE];
else if (NAPALM)
return defaultgamegrp[GAME_NAPALM];
else if (WW2GI)
return defaultgamegrp[GAME_WW2GI];
else if (NAM)
return defaultgamegrp[GAME_NAM];
return defaultgamegrp[0];
#else
return "(none)";
#endif
return "(none)"; // must be define in GRPINFO.
}
const char *G_DefaultDefFile(void)
{
#ifndef EDUKE32_STANDALONE
if (DUKE)
return defaultdeffilename[GAME_DUKE];
else if (WW2GI)
return defaultdeffilename[GAME_WW2GI];
else if (NAPALM)
{
if (!testkopen(defaultdeffilename[GAME_NAPALM],0) && testkopen(defaultdeffilename[GAME_NAM],0))
return defaultdeffilename[GAME_NAM]; // NAM/NAPALM Sharing
else
return defaultdeffilename[GAME_NAPALM];
}
else if (NAM)
{
if (!testkopen(defaultdeffilename[GAME_NAM],0) && testkopen(defaultdeffilename[GAME_NAPALM],0))
return defaultdeffilename[GAME_NAPALM]; // NAM/NAPALM Sharing
else
return defaultdeffilename[GAME_NAM];
}
return defaultdeffilename[0];
#else
return "(none)";
#endif
// Todo: Get from the selected game record.
return "DUKE3D.DEF";
}
const char *G_DefaultConFile(void)
{
// Todo: Get from the selected game record.
#ifndef EDUKE32_STANDALONE
if (DUKE && testkopen(defaultgameconfilename[GAME_DUKE],0))
return defaultgameconfilename[GAME_DUKE];
@ -140,17 +85,17 @@ const char *G_DefaultConFile(void)
const char* G_GrpFile(void)
{
return (g_grpNamePtr == NULL) ? G_DefaultGrpFile() : g_grpNamePtr;
return userConfig.gamegrp.IsNotEmpty() ? userConfig.gamegrp.GetChars() : G_DefaultGrpFile();
}
const char* G_DefFile(void)
{
return (g_defNamePtr == NULL) ? G_DefaultDefFile() : g_defNamePtr;
return userConfig.DefaultDef.IsNotEmpty() ? userConfig.DefaultDef.GetChars() : G_DefaultDefFile();
}
const char* G_ConFile(void)
{
return (g_scriptNamePtr == NULL) ? G_DefaultConFile() : g_scriptNamePtr;
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile();
}
//////////
@ -241,66 +186,7 @@ void G_SetupGlobalPsky(void)
static void G_LoadAddon(void);
int32_t g_groupFileHandle;
struct strllist* CommandPaths, * CommandGrps;
void G_ExtInit(void)
{
#ifdef EDUKE32_OSX
char *appdir = Bgetappdir();
addsearchpath(appdir);
Xfree(appdir);
#endif
char cwd[BMAX_PATH];
#ifdef USE_PHYSFS
strncpy(cwd, PHYSFS_getBaseDir(), ARRAY_SIZE(cwd));
cwd[ARRAY_SIZE(cwd)-1] = '\0';
#else
if (buildvfs_getcwd(cwd, ARRAY_SIZE(cwd)) && Bstrcmp(cwd, "/") != 0)
#endif
addsearchpath(cwd);
if (CommandPaths)
{
int32_t i;
struct strllist *s;
while (CommandPaths)
{
s = CommandPaths->next;
i = addsearchpath(CommandPaths->str);
if (i < 0)
{
initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
i==-1 ? "not a directory" : "no such directory");
}
Xfree(CommandPaths->str);
Xfree(CommandPaths);
CommandPaths = s;
}
}
}
void G_ScanGroups(void)
{
ScanGroups();
g_selectedGrp = NULL;
char const * const currentGrp = G_GrpFile();
for (grpfile_t const *fg = foundgrps; fg; fg=fg->next)
{
if (!Bstrcasecmp(fg->filename, currentGrp))
{
g_selectedGrp = fg;
break;
}
}
if (g_selectedGrp == NULL)
g_selectedGrp = foundgrps;
}
struct strllist* CommandGrps;
static int32_t G_TryLoadingGrp(char const * const grpfile)
{
@ -363,16 +249,16 @@ void G_LoadGroups()
{
grpfile = g_selectedGrp->filename;
clearGrpNamePtr();
g_grpNamePtr = dup_filename(grpfile);
//clearGrpNamePtr();
//g_grpNamePtr = dup_filename(grpfile);
grpinfo_t const * const type = g_selectedGrp->type;
g_gameType = type->game;
g_gameNamePtr = type->name;
if (type->scriptname && g_scriptNamePtr == NULL)
g_scriptNamePtr = dup_filename(type->scriptname);
//if (type->scriptname && g_scriptNamePtr == NULL)
// g_scriptNamePtr = dup_filename(type->scriptname);
if (type->defname && g_defNamePtr == NULL)
g_defNamePtr = dup_filename(type->defname);
@ -397,18 +283,6 @@ void G_LoadGroups()
if (g_modDir[0] != '/')
G_LoadGroupsInDir(g_modDir);
#ifndef EDUKE32_STANDALONE
if (g_defNamePtr == NULL)
{
const char *tmpptr = getenv("DUKE3DDEF");
if (tmpptr)
{
clearDefNamePtr();
g_defNamePtr = dup_filename(tmpptr);
initprintf("Using \"%s\" as definitions file\n", g_defNamePtr);
}
}
#endif
loaddefinitions_game(G_DefFile(), TRUE);
@ -470,72 +344,6 @@ static void G_LoadAddon(void)
}
void G_CleanupSearchPaths(void)
{
removesearchpaths_withuser(SEARCHPATH_REMOVE);
if (!NAM)
removesearchpaths_withuser(SEARCHPATH_NAM);
if (!WW2GI)
removesearchpaths_withuser(SEARCHPATH_WW2GI);
}
//////////
GrowArray<char *> g_scriptModules;
void G_AddGroup(const char *buffer)
{
char buf[BMAX_PATH];
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
Bstrcpy(buf, buffer);
if (Bstrchr(buf,'.') == 0)
Bstrcat(buf,".grp");
s->str = Xstrdup(buf);
if (CommandGrps)
{
struct strllist *t;
for (t = CommandGrps; t->next; t=t->next) ;
t->next = s;
return;
}
CommandGrps = s;
}
void G_AddPath(const char *buffer)
{
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
s->str = Xstrdup(buffer);
if (CommandPaths)
{
struct strllist *t;
for (t = CommandPaths; t->next; t=t->next) ;
t->next = s;
return;
}
CommandPaths = s;
}
void G_AddCon(const char *buffer)
{
clearScriptNamePtr();
g_scriptNamePtr = dup_filename(buffer);
initprintf("Using CON file \"%s\".\n",g_scriptNamePtr);
}
void G_AddConModule(const char *buffer)
{
g_scriptModules.append(Xstrdup(buffer));
}
//////////
// loads all group (grp, zip, pk3/4) files in the given directory
@ -717,12 +525,6 @@ FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t const ismusic)
return origfp;
}
void Duke_CommonCleanup(void)
{
DO_FREE_AND_NULL(g_grpNamePtr);
DO_FREE_AND_NULL(g_scriptNamePtr);
}
#endif
END_DUKE_NS

View file

@ -67,23 +67,12 @@ typedef enum basepal_ {
extern const char *g_gameNamePtr;
extern char *g_grpNamePtr;
extern char *g_scriptNamePtr;
extern const char *G_DefaultGrpFile(void);
extern const char *G_GrpFile(void);
extern const char *G_DefaultConFile(void);
extern const char *G_ConFile(void);
extern GrowArray<char *> g_scriptModules;
extern void G_AddCon(const char *buffer);
extern void G_AddConModule(const char *buffer);
extern void clearGrpNamePtr(void);
extern void clearScriptNamePtr(void);
extern int loaddefinitions_game(const char *fn, int32_t preload);
extern int32_t g_groupFileHandle;
@ -95,10 +84,7 @@ extern void G_SetupGlobalPsky(void);
//////////
extern void G_AddSearchPaths(void);
extern void G_CleanupSearchPaths(void);
extern void G_ExtInit(void);
extern void G_ScanGroups(void);
extern void G_LoadGroups();
extern const char * G_GetInstallPath(int32_t insttype);
@ -117,8 +103,5 @@ extern void G_LoadLookups(void);
# define FORMAT_UPGRADE_ELIGIBLE
extern FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t ismusic);
void G_AddGroup(const char* buffer);
void G_AddPath(const char* buffer);
END_DUKE_NS
#endif

View file

@ -116,7 +116,6 @@ EDUKE32_STATIC_ASSERT(7 <= MAXTILES-MAXUSERTILES);
#include "gamecontrol.h"
#include "game.h"
#include "gamedef.h"
#include "gamedefs.h"
#include "gameexec.h"
#include "gamevars.h"
#include "global.h"

View file

@ -71,7 +71,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_DUKE_NS
void Duke_CommonCleanup(void);
extern const char* G_DefaultDefFile(void);
extern const char* G_DefFile(void);
@ -5776,8 +5775,6 @@ static void G_Cleanup(void)
hash_loop(&h_dukeanim, G_FreeHashAnim);
hash_free(&h_dukeanim);
Duke_CommonCleanup();
}
/*
@ -5821,9 +5818,6 @@ static void G_CompileScripts(void)
labeltype = (int32_t *)&wall[0]; // V8: 16384*32/4 = 131072 V7: 8192*32/4 = 65536
#endif
if (g_scriptNamePtr != NULL)
Bcorrectfilename(g_scriptNamePtr,0);
#if defined LUNATIC
Gv_Init();
C_InitProjectiles();
@ -6307,11 +6301,6 @@ int app_main(int argc, const char * const*argv)
// This needs to happen afterwards, as G_CheckCommandLine() is where we set
// up the command-line-provided search paths (duh).
G_ExtInit();
#if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
if (forcegl) initprintf("GL driver blacklist disabled.\n");
#endif
#ifdef STARTUP_SETUP_WINDOW
int const readSetup =
@ -6326,25 +6315,11 @@ int app_main(int argc, const char * const*argv)
Bexit(2);
}
G_ScanGroups();
#ifdef STARTUP_SETUP_WINDOW
if (readSetup < 0 || (!g_noSetup && (displaysetup)) || g_commandSetup)
{
if (quitevent || !gi->startwin_run())
{
engineUnInit();
Bexit(EXIT_SUCCESS);
}
}
#endif
g_logFlushWindow = 0;
G_LoadGroups();
// flushlogwindow = 1;
G_CleanupSearchPaths();
#ifndef EDUKE32_STANDALONE
G_SetupCheats();
@ -7112,12 +7087,6 @@ void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt)
extern void faketimerhandler();
extern int app_main(int argc, char const* const* argv);
extern void app_crashhandler(void);
extern int32_t startwin_open(void);
extern int32_t startwin_close(void);
extern int32_t startwin_puts(const char*);
extern int32_t startwin_settitle(const char*);
extern int32_t startwin_idle(void*);
extern int32_t startwin_run(void);
GameInterface Interface = {
TICRATE,
@ -7127,12 +7096,6 @@ GameInterface Interface = {
set_hud_layout,
set_hud_scale,
app_crashhandler,
startwin_open,
startwin_close,
startwin_puts,
startwin_settitle,
startwin_idle,
startwin_run,
G_DefaultDefFile,
G_DefFile,
};

View file

@ -30,7 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
#include "fix16.h"
#include "gamedefs.h"
#include "gamevars.h"
#include "mmulti.h"
#include "network.h"

View file

@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "namesdyn.h"
#include "osd.h"
#include "savegame.h"
#include "printf.h"
#include "m_argv.h"
#include "vfs.h"
@ -6104,9 +6106,7 @@ void C_Compile(const char *fileName)
if (g_loadFromGroupOnly == 1 || numgroupfiles == 0)
{
#ifndef EDUKE32_STANDALONE
char const *gf = G_GrpFile();
Bsprintf(tempbuf,"Required game data was not found. A valid copy of \"%s\" or other compatible data is needed to run EDuke32.\n\n"
"You must copy \"%s\" to your game directory before continuing!", gf, gf);
I_Error("Required game data was not found.");
G_GameExit(tempbuf);
#else
G_GameExit(" ");
@ -6157,12 +6157,10 @@ void C_Compile(const char *fileName)
C_AddDefaultDefinitions();
C_ParseCommand(true);
for (char * m : g_scriptModules)
for (FString& m : *userConfig.AddCons.get())
{
C_Include(m);
free(m);
}
g_scriptModules.clear();
g_logFlushWindow = 1;

View file

@ -1,47 +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.
*/
//-------------------------------------------------------------------------
// 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 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

View file

@ -6,7 +6,6 @@
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include "ns.h" // Must come before everything else!
#include "GrpFile.game.h"

View file

@ -37,22 +37,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "_control.h"
#include "build.h"
#include "cache1d.h"
#include "cmdline.h"
#include "common_game.h"
#include "compat.h"
#include "control.h"
#include "gamecontrol.h"
#include "game.h"
#include "grpscan.h"
#include "inv.h"
#include "keyboard.h"
#include "startwin.game.h"
#include "windows_inc.h"
#include "gamecvars.h"
#include "gamecontrol.h"
#pragma warning(disable:4244) // There's just a bit too much of these in here...
BEGIN_DUKE_NS
#define TAB_CONFIG 0
@ -67,8 +60,7 @@ typedef struct {
static struct
{
struct grpfile_t const * grp;
char *gamedir;
int grp;
ud_setup_t shared;
int polymer;
}
@ -79,6 +71,8 @@ static HWND pages[3];
static int done = -1;
static int mode = TAB_CONFIG;
static TArray<GrpEntry> *gamedata;
static CACHE1D_FIND_REC *finddirs;
static inline void clearfilenames(void)
@ -121,6 +115,7 @@ static void PopulateForm(int32_t pgs)
{
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");
@ -137,12 +132,11 @@ static void PopulateForm(int32_t pgs)
(void)ComboBox_AddString(hwnd, dirs->name);
(void)ComboBox_SetItemData(hwnd, i, j);
if (Bstrcasecmp(dirs->name, settings.gamedir) == 0)
(void)ComboBox_SetCurSel(hwnd, i);
i++;
j++;
}
#endif
}
if (pgs & POPULATE_VIDEO)
@ -150,7 +144,7 @@ static void PopulateForm(int32_t pgs)
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
int mode = videoCheckMode(&settings.shared.xdim, &settings.shared.ydim, settings.shared.bpp, settings.shared.fullscreen, 1);
if (mode < 0 || (settings.shared.bpp < 15 && (settings.polymer)))
if (mode < 0 || (settings.shared.bpp < 15))
{
int CONSTEXPR cd[] = { 32, 24, 16, 15, 8, 0 };
int i;
@ -177,7 +171,7 @@ static void PopulateForm(int32_t pgs)
for (int i=0; i<validmodecnt; i++)
{
if (validmode[i].fs != (settings.shared.fullscreen)) continue;
if ((validmode[i].bpp < 15) && (settings.polymer)) continue;
if ((validmode[i].bpp < 15)) 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");
@ -192,13 +186,13 @@ static void PopulateForm(int32_t pgs)
{
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCDATA);
for (auto fg = foundgrps; fg; fg=fg->next)
int i=0;
for (auto& grp : *gamedata)
{
Bsprintf(buf, "%s\t%s", fg->type->name, fg->filename);
int const j = ListBox_AddString(hwnd, buf);
(void)ListBox_SetItemData(hwnd, j, (LPARAM)fg);
if (settings.grp == fg)
(void)ListBox_SetCurSel(hwnd, j);
FStringf grpinfo("%s %s", grp.FileInfo.name.GetChars(), grp.FileName.GetChars());
int const j = ListBox_AddString(hwnd, grpinfo.GetChars());
(void)ListBox_SetItemData(hwnd, j, i);
i++;
}
}
}
@ -239,28 +233,6 @@ static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
noautoload = (IsDlgButtonChecked(hwndDlg, IDCAUTOLOAD) != BST_CHECKED);
return TRUE;
case IDCGAMEDIR:
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)
{
if (i==0)
settings.gamedir = NULL;
else
{
CACHE1D_FIND_REC *dir = finddirs;
for (int j = 1; dir != NULL; dir = dir->next, j++)
{
if (j == i)
{
settings.gamedir = dir->name;
break;
}
}
}
}
}
return TRUE;
case IDCDATA:
{
@ -269,7 +241,7 @@ static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
if (i != CB_ERR) i = ListBox_GetItemData((HWND)lParam, i);
if (i != CB_ERR)
{
settings.grp = (grpfile_t const *)i;
settings.grp = i;
}
return TRUE;
}
@ -619,15 +591,8 @@ int32_t startwin_run(void)
SetPage(TAB_CONFIG);
EnableConfig(1);
#ifdef POLYMER
settings.polymer = (glrendmode == REND_POLYMER);
#else
settings.polymer = 0;
#endif
settings.shared = { ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP };
settings.grp = g_selectedGrp;
settings.gamedir = g_modDir;
settings.grp = 0;
PopulateForm(-1);
@ -661,14 +626,28 @@ int32_t startwin_run(void)
ScreenHeight = settings.shared.ydim;
ScreenMode = settings.shared.fullscreen;
ScreenBPP = settings.shared.bpp;
g_selectedGrp = settings.grp;
Bstrcpy(g_modDir, (g_noSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return done;
}
END_DUKE_NS
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)
{
Bexit(EXIT_SUCCESS);
}
}
startwin_close();
return settings.grp;
}
#endif // STARTUP_SETUP_WINDOW

View file

@ -26,12 +26,6 @@ include_directories(
)
if (WIN32)
set( PLAT_SOURCES
src/startwin.game.cpp
)
endif()
set( NOT_COMPILED_SOURCE_FILES
)
@ -82,7 +76,6 @@ file( GLOB HEADER_FILES
add_library( rr STATIC
${HEADER_FILES}
${PCH_SOURCES}
${PLAT_SOURCES}
${NOT_COMPILED_SOURCE_FILES}
)

View file

@ -11,20 +11,8 @@
#include "grpscan.h"
#include "gamecvars.h"
#include "rts.h"
#include "gamecontrol.h"
#ifdef _WIN32
# define NEED_SHLWAPI_H
# include "windows_inc.h"
# include "win32/winbits.h"
# ifndef KEY_WOW64_64KEY
# define KEY_WOW64_64KEY 0x0100
# endif
# ifndef KEY_WOW64_32KEY
# define KEY_WOW64_32KEY 0x0200
# endif
#elif defined __APPLE__
# include "osxbits.h"
#endif
#include "common.h"
#include "common_game.h"
@ -47,23 +35,6 @@ static const char *defaultgamegrp[GAMECOUNT] = { "DUKE3D.GRP", "REDNECK.
static const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "rr.def", "rrra.def", "nam.def", "napalm.grp" };
static const char *defaultgameconfilename[GAMECOUNT] = { "GAME.CON", "GAME.CON", "GAME.CON", "NAM.CON", "NAPALM.CON" };
// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
char *g_grpNamePtr = NULL;
// g_scriptNamePtr can ONLY point to a malloc'd block (length BMAX_PATH)
char *g_scriptNamePtr = NULL;
void clearGrpNamePtr(void)
{
Bfree(g_grpNamePtr);
// g_grpNamePtr assumed to be assigned to right after
}
void clearScriptNamePtr(void)
{
Bfree(g_scriptNamePtr);
// g_scriptNamePtr assumed to be assigned to right after
}
const char* G_DefaultGrpFile(void)
{
if (DUKE)
@ -73,6 +44,7 @@ const char *G_DefaultGrpFile(void)
return defaultgamegrp[0];
}
const char* G_DefaultDefFile(void)
{
if (DUKE)
@ -115,17 +87,17 @@ const char *G_DefaultConFile(void)
const char *G_GrpFile(void)
{
return (g_grpNamePtr == NULL) ? G_DefaultGrpFile() : g_grpNamePtr;
return userConfig.gamegrp.IsNotEmpty()? userConfig.gamegrp.GetChars() : G_DefaultGrpFile();
}
const char *G_DefFile(void)
{
return (g_defNamePtr == NULL) ? G_DefaultDefFile() : g_defNamePtr;
return userConfig.DefaultDef.IsNotEmpty() ? userConfig.DefaultDef.GetChars() : G_DefaultDefFile();
}
const char *G_ConFile(void)
{
return (g_scriptNamePtr == NULL) ? G_DefaultConFile() : g_scriptNamePtr;
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile();
}
//////////
@ -213,62 +185,7 @@ void G_SetupGlobalPsky(void)
static void G_LoadAddon(void);
int32_t g_groupFileHandle;
struct strllist* CommandPaths, * CommandGrps;
void G_ExtInit(void)
{
char cwd[BMAX_PATH];
#ifdef EDUKE32_OSX
char *appdir = Bgetappdir();
addsearchpath(appdir);
Bfree(appdir);
#endif
if (getcwd(cwd,BMAX_PATH) && Bstrcmp(cwd,"/") != 0)
addsearchpath(cwd);
if (CommandPaths)
{
int32_t i;
struct strllist *s;
while (CommandPaths)
{
s = CommandPaths->next;
i = addsearchpath(CommandPaths->str);
if (i < 0)
{
initprintf("Failed adding %s for game data: %s\n", CommandPaths->str,
i==-1 ? "not a directory" : "no such directory");
}
Bfree(CommandPaths->str);
Bfree(CommandPaths);
CommandPaths = s;
}
}
}
void G_ScanGroups(void)
{
ScanGroups();
g_selectedGrp = NULL;
char const * const currentGrp = G_GrpFile();
for (grpfile_t const *fg = foundgrps; fg; fg=fg->next)
{
if (!Bstrcasecmp(fg->filename, currentGrp))
{
g_selectedGrp = fg;
break;
}
}
if (g_selectedGrp == NULL)
g_selectedGrp = foundgrps;
}
struct strllist* CommandGrps;
static int32_t G_TryLoadingGrp(char const * const grpfile)
{
@ -333,16 +250,16 @@ void G_LoadGroups()
{
grpfile = g_selectedGrp->filename;
clearGrpNamePtr();
g_grpNamePtr = dup_filename(grpfile);
//clearGrpNamePtr();
//g_grpNamePtr = dup_filename(grpfile);
grpinfo_t const * const type = g_selectedGrp->type;
g_gameType = type->game;
g_gameNamePtr = type->name;
if (type->scriptname && g_scriptNamePtr == NULL)
g_scriptNamePtr = dup_filename(type->scriptname);
//if (type->scriptname && g_scriptNamePtr == NULL)
// g_scriptNamePtr = dup_filename(type->scriptname);
if (type->defname && g_defNamePtr == NULL)
g_defNamePtr = dup_filename(type->defname);
@ -437,77 +354,9 @@ static void G_LoadAddon(void)
void G_CleanupSearchPaths(void)
{
removesearchpaths_withuser(SEARCHPATH_REMOVE);
if (!NAM)
removesearchpaths_withuser(SEARCHPATH_NAM);
if (!RRRA)
removesearchpaths_withuser(SEARCHPATH_RRRA);
if (!RR || RRRA)
removesearchpaths_withuser(SEARCHPATH_RR);
}
//////////
GrowArray<char *> g_scriptModules;
void G_AddGroup(const char *buffer)
{
char buf[BMAX_PATH];
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
Bstrcpy(buf, buffer);
if (Bstrchr(buf,'.') == 0)
Bstrcat(buf,".grp");
s->str = Xstrdup(buf);
if (CommandGrps)
{
struct strllist *t;
for (t = CommandGrps; t->next; t=t->next) ;
t->next = s;
return;
}
CommandGrps = s;
}
void G_AddPath(const char *buffer)
{
struct strllist *s = (struct strllist *)Xcalloc(1,sizeof(struct strllist));
s->str = Xstrdup(buffer);
if (CommandPaths)
{
struct strllist *t;
for (t = CommandPaths; t->next; t=t->next) ;
t->next = s;
return;
}
CommandPaths = s;
}
void G_AddCon(const char *buffer)
{
clearScriptNamePtr();
g_scriptNamePtr = dup_filename(buffer);
initprintf("Using CON file \"%s\".\n",g_scriptNamePtr);
}
void G_AddConModule(const char *buffer)
{
g_scriptModules.append(Xstrdup(buffer));
}
//////////
// loads all group (grp, zip, pk3/4) files in the given directory
void G_LoadGroupsInDir(const char *dirname)
{
@ -733,12 +582,6 @@ FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t const ismusic)
return origfp;
}
void Duke_CommonCleanup(void)
{
DO_FREE_AND_NULL(g_grpNamePtr);
DO_FREE_AND_NULL(g_scriptNamePtr);
}
#endif
END_RR_NS

View file

@ -84,23 +84,12 @@ typedef enum basepal_ {
extern const char *g_gameNamePtr;
extern char *g_grpNamePtr;
extern char *g_scriptNamePtr;
extern const char *G_DefaultGrpFile(void);
extern const char *G_GrpFile(void);
extern const char *G_DefaultConFile(void);
extern const char *G_ConFile(void);
extern GrowArray<char *> g_scriptModules;
extern void G_AddCon(const char *buffer);
extern void G_AddConModule(const char *buffer);
extern void clearGrpNamePtr(void);
extern void clearScriptNamePtr(void);
extern int loaddefinitions_game(const char *fn, int32_t preload);
extern int32_t g_groupFileHandle;
@ -112,10 +101,7 @@ extern void G_SetupGlobalPsky(void);
//////////
extern void G_AddSearchPaths(void);
extern void G_CleanupSearchPaths(void);
extern void G_ExtInit(void);
extern void G_ScanGroups(void);
extern void G_LoadGroups();
extern const char * G_GetInstallPath(int32_t insttype);
@ -134,9 +120,6 @@ extern void G_LoadLookups(void);
# define FORMAT_UPGRADE_ELIGIBLE
extern FileReader S_OpenAudio(const char *fn, char searchfirst, uint8_t ismusic);
void G_AddGroup(const char* buffer);
void G_AddPath(const char* buffer);
END_RR_NS
#endif

View file

@ -71,7 +71,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_RR_NS
void Duke_CommonCleanup(void);
extern const char* G_DefaultDefFile(void);
extern const char* G_DefFile(void);
@ -7134,8 +7133,6 @@ static void G_Cleanup(void)
hash_loop(&h_dukeanim, G_FreeHashAnim);
hash_free(&h_dukeanim);
Duke_CommonCleanup();
}
/*
@ -7178,9 +7175,6 @@ static void G_CompileScripts(void)
labelcode = (int32_t *)&sector[0]; // V8: 4096*40/4 = 40960 V7: 1024*40/4 = 10240
labeltype = (int32_t *)&wall[0]; // V8: 16384*32/4 = 131072 V7: 8192*32/4 = 65536
if (g_scriptNamePtr != NULL)
Bcorrectfilename(g_scriptNamePtr,0);
// if we compile for a V7 engine wall[] should be used for label names since it's bigger
pathsearchmode = 1;
@ -7682,11 +7676,6 @@ int app_main(int argc, char const * const * argv)
// This needs to happen afterwards, as G_CheckCommandLine() is where we set
// up the command-line-provided search paths (duh).
G_ExtInit();
#if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
if (forcegl) initprintf("GL driver blacklist disabled.\n");
#endif
#ifdef STARTUP_SETUP_WINDOW
int const readSetup =
@ -7702,25 +7691,11 @@ int app_main(int argc, char const * const * argv)
Bexit(2);
}
G_ScanGroups();
#ifdef STARTUP_SETUP_WINDOW
if (readSetup < 0 || (!g_noSetup && (displaysetup)) || g_commandSetup)
{
if (quitevent || !gi->startwin_run())
{
engineUnInit();
Bexit(0);
}
}
#endif
g_logFlushWindow = 0;
G_LoadGroups();
// flushlogwindow = 1;
G_CleanupSearchPaths();
if (RR)
{
osdscale2 *= 0.5f;
@ -8561,12 +8536,6 @@ void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt)
extern void faketimerhandler();
extern int app_main(int argc, char const* const* argv);
extern void app_crashhandler(void);
extern int32_t startwin_open(void);
extern int32_t startwin_close(void);
extern int32_t startwin_puts(const char*);
extern int32_t startwin_settitle(const char*);
extern int32_t startwin_idle(void*);
extern int32_t startwin_run(void);
GameInterface Interface = {
TICRATE,
@ -8576,12 +8545,6 @@ GameInterface Interface = {
set_hud_layout,
set_hud_scale,
app_crashhandler,
startwin_open,
startwin_close,
startwin_puts,
startwin_settitle,
startwin_idle,
startwin_run,
G_DefaultDefFile,
G_DefFile,

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "common.h"
#include "common_game.h"
#include "cheats.h"
#include "m_argv.h"
#include "osd.h"
#include "crc32_.h"
@ -2430,12 +2431,11 @@ void C_Compile(const char *fileName)
C_ParseCommand(1);
for (char * m : g_scriptModules)
for (FString & m : *userConfig.AddCons.get())
{
C_Include(m);
free(m);
}
g_scriptModules.clear();
userConfig.AddCons.reset();
g_logFlushWindow = 1;

View file

@ -1,888 +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_RR_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;
int polymer;
} 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;
}
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;
CACHE1D_FIND_REC *dirs = NULL;
GtkTreeIter iter;
pathsearchmode = 1;
if ((homedir = Bgethomedir()))
{
Bsnprintf(pdir, sizeof(pdir), "%s/" ".eduke32", homedir);
dirs = klistpath(pdir, "*", CACHE1D_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);
#else
settings.polymer = 0;
#endif
PopulateForm(ALL);
gtk_main();
SetPage(TAB_MESSAGES);
if (retval) // launch the game with these parameters
{
ud.setup = settings.shared;
glrendmode = (settings.polymer) ? REND_POLYMER : REND_POLYMOST;
g_selectedGrp = settings.grp;
Bstrcpy(g_modDir, (g_noSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return retval;
}
END_RR_NS

View file

@ -1,715 +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"
#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
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)
{
#ifdef MAC_OS_X_VERSION_10_12
[control setControlSize:NSControlSizeSmall];
#else
[control setControlSize:NSControlSizeSmall];
#endif
}
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:NSSwitchButton];
[checkbox sizeToFit];
return checkbox;
}
static NSPopUpButton * makeComboBox(void)
{
NSPopUpButton *comboBox = [[NSPopUpButton alloc] init];
[comboBox setPullsDown:NO];
setFontToSmall(comboBox);
setControlToSmall([comboBox cell]);
[comboBox setBezelStyle:NSRoundedBezelStyle];
[comboBox setPreferredEdge:NSMaxYEdge];
[[comboBox cell] setArrowPosition:NSPopUpArrowAtCenter];
[comboBox sizeToFit];
return comboBox;
}
static id nsapp;
/* 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:NSRoundedBezelStyle];
[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:NSRoundedBezelStyle];
[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] == NSOnState);
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] == NSOnState;
retval = 1;
}
- (void)setupRunMode
{
videoGetModes();
[fullscreenButton setState: (settings.fullscreen ? NSOnState : NSOffState)];
[alwaysShowButton setState: (settings.forcesetup ? NSOnState : NSOffState)];
[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)
{
// fix for "ld: absolute address to symbol _NSApp in a different linkage unit not supported"
// (OS X 10.6) when building for PPC
nsapp = [NSApplication sharedApplication];
if (startwin != nil) return 1;
startwin = [[StartupWindow alloc] init];
if (startwin == nil) return -1;
[startwin setupMessagesMode];
[nsapp finishLaunching];
[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.config.ScreenMode;
settings.xdim3d = ud.config.ScreenWidth;
settings.ydim3d = ud.config.ScreenHeight;
settings.bpp3d = ud.config.ScreenBPP;
settings.forcesetup = ud.config.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.config.ScreenMode = settings.fullscreen;
ud.config.ScreenWidth = settings.xdim3d;
ud.config.ScreenHeight = settings.ydim3d;
ud.config.ScreenBPP = settings.bpp3d;
ud.config.ForceSetup = settings.forcesetup;
g_selectedGrp = settings.grp;
}
return retval;
}

View file

@ -1,676 +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 "_control.h"
#include "build.h"
#include "cache1d.h"
#include "cmdline.h"
#include "common_game.h"
#include "compat.h"
#include "control.h"
#include "gamecontrol.h"
#include "game.h"
#include "grpscan.h"
#include "inv.h"
#include "keyboard.h"
#include "gamecvars.h"
#include "startwin.game.h"
#include "windows_inc.h"
#pragma warning(disable:4244) // There's just a bit too much of these in here...
BEGIN_RR_NS
#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
{
struct grpfile_t const * grp;
char *gamedir;
ud_setup_t shared;
int polymer;
}
settings;
static HWND startupdlg;
static HWND pages[3];
static int done = -1;
static int mode = TAB_CONFIG;
static CACHE1D_FIND_REC *finddirs;
static inline void clearfilenames(void)
{
klistfree(finddirs);
finddirs = NULL;
}
static inline void getfilenames(char const *path)
{
clearfilenames();
finddirs = klistpath(path,"*",CACHE1D_FIND_DIR);
}
#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);
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);
if (Bstrcasecmp(dirs->name, settings.gamedir) == 0)
(void)ComboBox_SetCurSel(hwnd, i);
i++;
j++;
}
}
if (pgs & POPULATE_VIDEO)
{
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
int mode = videoCheckMode(&settings.shared.xdim, &settings.shared.ydim, settings.shared.bpp, settings.shared.fullscreen, 1);
if (mode < 0 || (settings.shared.bpp < 15 && (settings.polymer)))
{
int CONSTEXPR cd[] = { 32, 24, 16, 15, 8, 0 };
int i;
for (i=0; cd[i];)
{
if (cd[i] >= settings.shared.bpp) i++;
else break;
}
for (; cd[i]; i++)
{
mode = videoCheckMode(&settings.shared.xdim, &settings.shared.ydim, cd[i], settings.shared.fullscreen, 1);
if (mode < 0) continue;
settings.shared.bpp = cd[i];
break;
}
}
Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), ((settings.shared.fullscreen) ? BST_CHECKED : BST_UNCHECKED));
//Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCPOLYMER), ((settings.polymer) ? BST_CHECKED : BST_UNCHECKED));
(void)ComboBox_ResetContent(hwnd);
for (int i=0; i<validmodecnt; i++)
{
if (validmode[i].fs != (settings.shared.fullscreen)) continue;
if ((validmode[i].bpp < 15) && (settings.polymer)) 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");
int const j = ComboBox_AddString(hwnd, buf);
(void)ComboBox_SetItemData(hwnd, j, i);
if (i == mode)(void)ComboBox_SetCurSel(hwnd, j);
}
}
if (pgs & POPULATE_GAME)
{
HWND hwnd = GetDlgItem(pages[TAB_CONFIG], IDCDATA);
for (auto fg = foundgrps; fg; fg=fg->next)
{
Bsprintf(buf, "%s\t%s", fg->type->name, fg->filename);
int const j = ListBox_AddString(hwnd, buf);
(void)ListBox_SetItemData(hwnd, j, (LPARAM)fg);
if (settings.grp == fg)
(void)ListBox_SetCurSel(hwnd, j);
}
}
}
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 IDCINPUT:
return TRUE;
case IDCGAMEDIR:
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)
{
if (i==0)
settings.gamedir = NULL;
else
{
CACHE1D_FIND_REC *dir = finddirs;
for (int j = 1; dir != NULL; dir = dir->next, j++)
{
if (j == i)
{
settings.gamedir = dir->name;
break;
}
}
}
}
}
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 = (grpfile_t const *)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)win_gethinstance(), 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)win_gethinstance(), 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;
else quitevent++;
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;
else quitevent++;
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)win_gethinstance(), 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);
#ifdef POLYMER
settings.polymer = (glrendmode == REND_POLYMER);
#else
settings.polymer = 0;
#endif
settings.shared = { ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP };
settings.grp = g_selectedGrp;
settings.gamedir = g_modDir;
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);
if (done)
{
ScreenWidth = settings.shared.xdim;
ScreenHeight = settings.shared.ydim;
ScreenMode = settings.shared.fullscreen;
ScreenBPP = settings.shared.bpp;
glrendmode = REND_POLYMOST;
g_selectedGrp = settings.grp;
Bstrcpy(g_modDir, (g_noSetup == 0 && settings.gamedir != NULL) ? settings.gamedir : "/");
}
return done;
}
END_RR_NS
#endif // STARTUP_SETUP_WINDOW

View file

@ -1,47 +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.
*/
//-------------------------------------------------------------------------
// 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 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

View file

@ -26,11 +26,6 @@ include_directories(
)
if (WIN32)
set( PLAT_SOURCES
src/startwin.game.cpp
)
endif()
set( PCH_SOURCES
src/actor.cpp
@ -125,7 +120,6 @@ file( GLOB HEADER_FILES
add_library( sw STATIC
${HEADER_FILES}
${PCH_SOURCES}
${PLAT_SOURCES}
)

View file

@ -1,37 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 Jonathon Fowler <jf@jonof.id.au>
This file is part of JFShadowWarrior
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
*/
//-------------------------------------------------------------------------
@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,89 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 Jonathon Fowler <jf@jonof.id.au>
This file is part of JFShadowWarrior
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
*/
//-------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import "GrpFile.game.h"
#import "GameListSource.game.h"
@implementation GameListSource
- (id)init
{
self = [super init];
if (self) {
struct grpfile *p;
int i;
list = [[NSMutableArray alloc] init];
for (p = foundgrps; p; p=p->next) {
for (i=0; i<numgrpfiles; i++) if (p->crcval == grpfiles[i].crcval) break;
if (i == numgrpfiles) continue;
[list addObject:[[GrpFile alloc] initWithGrpfile:p andName:[NSString stringWithUTF8String:grpfiles[i].name]]];
}
}
return self;
}
- (void)dealloc
{
[list release];
[super dealloc];
}
- (GrpFile*)grpAtIndex:(int)index
{
return [list objectAtIndex:index];
}
- (int)findIndexForGrpname:(NSString*)grpname
{
unsigned i;
for (i=0; i<[list count]; i++) {
if ([[[list objectAtIndex:i] grpname] isEqual:grpname]) return i;
}
return -1;
}
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex
{
NSParameterAssert(rowIndex >= 0 && 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
{
return [list count];
}
@end

View file

@ -1,40 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 Jonathon Fowler <jf@jonof.id.au>
This file is part of JFShadowWarrior
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
*/
//-------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#include "grpscan.h"
@interface GrpFile : NSObject
{
NSString *name;
struct grpfile *fg;
}
- (id)initWithGrpfile:(struct grpfile *)grpfile andName:(NSString *)aName;
- (void)dealloc;
- (NSString *)name;
- (NSString *)grpname;
- (struct grpfile *)entryptr;
@end

View file

@ -1,54 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 Jonathon Fowler <jf@jonof.id.au>
This file is part of JFShadowWarrior
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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 "GrpFile.game.h"
@implementation GrpFile
- (id)initWithGrpfile:(struct grpfile *)grpfile andName:(NSString*)aName
{
self = [super init];
if (self) {
fg = grpfile;
name = aName;
[aName retain];
}
return self;
}
- (void)dealloc
{
[name release];
[super dealloc];
}
- (NSString *)name
{
return name;
}
- (NSString *)grpname
{
return [NSString stringWithUTF8String:(fg->name)];
}
- (struct grpfile *)entryptr
{
return fg;
}
@end

View file

@ -1,468 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2007 Jonathon Fowler <jf@jonof.id.au>
This file is part of JFShadowWarrior
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
*/
//-------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#include "compat.h"
#include "types.h"
#include "build.h"
#include "baselayer.h"
#include "grpscan.h"
#include "gamedefs.h"
#include "config.h"
#import "GrpFile.game.h"
#import "GameListSource.game.h"
static struct {
int fullscreen;
int xdim3d, ydim3d, bpp3d;
int forcesetup;
char selectedgrp[BMAX_PATH+1];
int samplerate, bitspersample, channels;
int usemouse, usejoystick;
} settings;
static struct soundQuality_t {
int frequency;
int samplesize;
int channels;
} * soundQualities = 0;
@interface StartupWinController : NSWindowController
{
NSMutableArray *modeslist3d;
GameListSource *gamelistsrc;
IBOutlet NSButton *alwaysShowButton;
IBOutlet NSButton *fullscreenButton;
IBOutlet NSButton *useMouseButton;
IBOutlet NSButton *useJoystickButton;
IBOutlet NSTextView *messagesView;
IBOutlet NSTabView *tabView;
IBOutlet NSPopUpButton *videoMode3DPUButton;
IBOutlet NSPopUpButton *soundQualityPUButton;
IBOutlet NSScrollView *gameList;
IBOutlet NSButton *cancelButton;
IBOutlet NSButton *startButton;
}
- (void)dealloc;
- (void)populateVideoModes:(BOOL)firstTime;
- (void)populateSoundQuality:(BOOL)firstTime;
- (IBAction)alwaysShowClicked:(id)sender;
- (IBAction)fullscreenClicked:(id)sender;
- (IBAction)cancel:(id)sender;
- (IBAction)start:(id)sender;
- (void)setupRunMode;
- (void)setupMessagesMode;
- (void)putsMessage:(NSString *)str;
- (void)setTitle:(NSString *)str;
@end
@implementation StartupWinController
- (void)dealloc
{
[gamelistsrc release];
[modeslist3d release];
[super dealloc];
}
- (void)populateVideoModes:(BOOL)firstTime
{
int i, mode3d, fullscreen = ([fullscreenButton state] == NSOnState);
int idx3d = -1;
int xdim, ydim, bpp;
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 = checkvideomode(&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 = checkvideomode(&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)populateSoundQuality:(BOOL)firstTime
{
int i, curidx = -1;
[soundQualityPUButton removeAllItems];
for (i = 0; soundQualities[i].frequency > 0; i++) {
const char *ch;
switch (soundQualities[i].channels) {
case 1: ch = "Mono"; break;
case 2: ch = "Stereo"; break;
default: ch = "?"; break;
}
NSString *s = [NSString stringWithFormat:@"%dkHz, %d-bit, %s",
soundQualities[i].frequency / 1000,
soundQualities[i].samplesize,
ch
];
[soundQualityPUButton addItemWithTitle:s];
if (firstTime &&
soundQualities[i].frequency == settings.samplerate &&
soundQualities[i].samplesize == settings.bitspersample &&
soundQualities[i].channels == settings.channels) {
curidx = i;
}
}
if (firstTime && curidx < 0) {
soundQualities[i].frequency = settings.samplerate;
soundQualities[i].samplesize = settings.bitspersample;
soundQualities[i].channels = settings.channels;
const char *ch;
switch (soundQualities[i].channels) {
case 1: ch = "Mono"; break;
case 2: ch = "Stereo"; break;
default: ch = "?"; break;
}
NSString *s = [NSString stringWithFormat:@"%dkHz, %d-bit, %s",
soundQualities[i].frequency / 1000,
soundQualities[i].samplesize,
ch
];
[soundQualityPUButton addItemWithTitle:s];
curidx = i++;
soundQualities[i].frequency = -1;
}
if (curidx >= 0) {
[soundQualityPUButton selectItemAtIndex:curidx];
}
}
- (IBAction)alwaysShowClicked:(id)sender
{
}
- (IBAction)fullscreenClicked:(id)sender
{
[self populateVideoModes:NO];
}
- (IBAction)cancel:(id)sender
{
[NSApp abortModal];
}
- (IBAction)start:(id)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 quality = [soundQualityPUButton indexOfSelectedItem];
if (quality >= 0) {
settings.samplerate = soundQualities[quality].frequency;
settings.bitspersample = soundQualities[quality].samplesize;
settings.channels = soundQualities[quality].channels;
}
int row = [[gameList documentView] selectedRow];
if (row >= 0) {
struct grpfile *p = [[gamelistsrc grpAtIndex:row] entryptr];
if (p) {
strcpy(settings.selectedgrp, p->name);
}
}
settings.usemouse = [useMouseButton state] == NSOnState;
settings.usejoystick = [useJoystickButton state] == NSOnState;
settings.forcesetup = [alwaysShowButton state] == NSOnState;
[NSApp stopModal];
}
- (void)setupRunMode
{
getvalidmodes();
[fullscreenButton setState: (settings.fullscreen ? NSOnState : NSOffState)];
[alwaysShowButton setState: (settings.forcesetup ? NSOnState : NSOffState)];
[useMouseButton setState: (settings.usemouse ? NSOnState : NSOffState)];
[useJoystickButton setState: (settings.usejoystick ? NSOnState : NSOffState)];
[self populateVideoModes:YES];
[self populateSoundQuality:YES];
// enable all the controls on the Configuration page
NSEnumerator *enumerator = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator];
NSControl *control;
while ((control = [enumerator nextObject])) {
[control setEnabled:true];
}
gamelistsrc = [[GameListSource alloc] init];
[[gameList documentView] setDataSource:gamelistsrc];
[[gameList documentView] deselectAll:nil];
int row = [gamelistsrc findIndexForGrpname:[NSString stringWithUTF8String:settings.selectedgrp]];
if (row >= 0) {
[[gameList documentView] scrollRowToVisible:row];
[[gameList documentView] selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
}
[cancelButton setEnabled:true];
[startButton setEnabled:true];
[tabView selectTabViewItemAtIndex:0];
[NSCursor unhide]; // Why should I need to do this?
}
- (void)setupMessagesMode
{
[tabView selectTabViewItemAtIndex:2];
// 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 = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator];
NSControl *control;
while ((control = [enumerator nextObject])) {
if (control == alwaysShowButton) continue;
[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];
}
}
- (void)setTitle:(NSString *)str
{
[[self window] setTitle:str];
}
@end
static StartupWinController *startwin = nil;
int startwin_open(void)
{
if (startwin != nil) return 1;
startwin = [[StartupWinController alloc] initWithWindowNibName:@"startwin.game"];
if (startwin == nil) return -1;
{
static unsigned soundQualityFrequencies[] = { 44100, 22050, 11025 };
static unsigned soundQualitySampleSizes[] = { 16, 8 };
static unsigned soundQualityChannels[] = { 2, 1 };
unsigned f, b, c, i;
i = sizeof(soundQualityFrequencies) *
sizeof(soundQualitySampleSizes) *
sizeof(soundQualityChannels) /
sizeof(int) + 2; // one for the terminator, one for a custom setting
soundQualities = (struct soundQuality_t *) malloc(i * sizeof(struct soundQuality_t));
i = 0;
for (c = 0; c < sizeof(soundQualityChannels) / sizeof(int); c++) {
for (b = 0; b < sizeof(soundQualitySampleSizes) / sizeof(int); b++) {
for (f = 0; f < sizeof(soundQualityFrequencies) / sizeof(int); f++) {
soundQualities[i].frequency = soundQualityFrequencies[f];
soundQualities[i].samplesize = soundQualitySampleSizes[b];
soundQualities[i].channels = soundQualityChannels[c];
i++;
}
}
}
soundQualities[i].frequency = -1;
}
[startwin setupMessagesMode];
[startwin showWindow:nil];
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 alloc] initWithCString: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 alloc] initWithCString:s];
[startwin setTitle:ns];
[ns release];
return 0;
}
int startwin_idle(void *v)
{
if (startwin) [[startwin window] displayIfNeeded];
return 0;
}
extern char* grpfile;
extern int32 ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP, ForceSetup, UseMouse, UseJoystick;
int startwin_run(void)
{
int retval;
if (startwin == nil) return 0;
ScanGroups();
settings.fullscreen = ScreenMode;
settings.xdim3d = ScreenWidth;
settings.ydim3d = ScreenHeight;
settings.bpp3d = ScreenBPP;
settings.samplerate = MixRate;
settings.bitspersample = NumBits;
settings.channels = NumChannels;
settings.usemouse = UseMouse;
settings.usejoystick = UseJoystick;
settings.forcesetup = ForceSetup;
strncpy(settings.selectedgrp, grpfile, BMAX_PATH);
[startwin setupRunMode];
switch ([NSApp runModalForWindow:[startwin window]]) {
#ifdef MAC_OS_X_VERSION_10_9
case NSModalResponseStop: retval = 1; break;
case NSModalResponseAbort: retval = 0; break;
#else
case NSRunStoppedResponse: retval = 1; break;
case NSRunAbortedResponse: retval = 0; break;
#endif
default: retval = -1;
}
[startwin setupMessagesMode];
if (retval) {
ScreenMode = settings.fullscreen;
ScreenWidth = settings.xdim3d;
ScreenHeight = settings.ydim3d;
ScreenBPP = settings.bpp3d;
MixRate = settings.samplerate;
NumBits = settings.bitspersample;
NumChannels = settings.channels;
UseMouse = settings.usemouse;
UseJoystick = settings.usejoystick;
ForceSetup = settings.forcesetup;
grpfile = settings.selectedgrp;
}
return retval;
}

View file

@ -842,7 +842,6 @@ void COVERsetbrightness(int bright, unsigned char *pal)
static int firstnet = 0; // JBF
int nextvoxid = 0; // JBF
extern int startwin_run(void);
static void SW_FatalEngineError(void)
{
@ -3357,17 +3356,6 @@ int32_t app_main(int32_t argc, char const * const * argv)
exit(1);
}
#ifdef STARTUP_SETUP_WINDOW
if (i < 0 || displaysetup || CommandSetup)
{
if (quitevent || !startwin_run())
{
engineUnInit();
exit(0);
}
}
#endif
initgroupfile(G_GrpFile());
if (!DetectShareware())
{
@ -5562,12 +5550,6 @@ saveable_module saveable_build =
extern void faketimerhandler();
extern int app_main(int argc, char const* const* argv);
extern void app_crashhandler(void);
extern int32_t startwin_open(void);
extern int32_t startwin_close(void);
extern int32_t startwin_puts(const char*);
extern int32_t startwin_settitle(const char*);
extern int32_t startwin_idle(void*);
extern int32_t startwin_run(void);
/*extern*/ bool validate_hud(int requested_size) { return requested_size; }
/*extern*/ void set_hud(int requested_size) { /* the relevant setting is gs.BorderNum */}
@ -5579,12 +5561,6 @@ GameInterface Interface = {
set_hud,
set_hud,
app_crashhandler,
startwin_open,
startwin_close,
startwin_puts,
startwin_settitle,
startwin_idle,
startwin_run,
G_DefFile,
G_DefFile,
};

View file

@ -1,756 +0,0 @@
/* NOTE: Glade will generate code for a dialogue box which you should
* then patch into this file whenever you make a change to the Glade
* template.
*/
#include "ns.h"
#include "compat.h"
#include <gdk-pixbuf/gdk-pixdata.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "dynamicgtk.h"
#include "types.h"
#include "build.h"
#include "baselayer.h"
#include "grpscan.h"
#include "common.h"
#include "common_game.h"
#define TAB_CONFIG 0
#define TAB_GAME 1
#define TAB_MESSAGES 2
BEGIN_SW_NS
static struct
{
int fullscreen;
int xdim3d, ydim3d, bpp3d;
int forcesetup;
int usemouse, usejoy;
char selectedgrp[BMAX_PATH+1];
} settings;
extern int gtkenabled;
static GtkWidget *startwin = NULL;
static int retval = -1, mode = TAB_MESSAGES;
// -- SUPPORT FUNCTIONS -------------------------------------------------------
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
g_object_set_data (G_OBJECT (component), name, widget)
#define lookup_widget(x,w) \
(GtkWidget*) g_object_get_data(G_OBJECT(x), w)
static GdkPixbuf *load_banner(void)
{
extern const GdkPixdata startbanner_pixdata;
return gdk_pixbuf_from_pixdata((GdkPixdata const *)&startbanner_pixdata, FALSE, NULL);
}
static void SetPage(int n)
{
gboolean gb;
if (!gtkenabled || !startwin) return;
mode = n;
gtk_notebook_set_current_page(GTK_NOTEBOOK(lookup_widget(startwin,"tabs")), n);
// each control in the config page vertical layout plus the start button should be made (in)sensitive
if (n == TAB_CONFIG)
{
gb = TRUE;
}
else
{
gb = FALSE;
}
gtk_widget_set_sensitive(lookup_widget(startwin,"startbutton"), gb);
gtk_container_foreach(GTK_CONTAINER(lookup_widget(startwin,"configvlayout")),
(GtkCallback)gtk_widget_set_sensitive, (gpointer)(gintptr)gb);
}
static void on_vmode3dcombo_changed(GtkComboBox *, gpointer);
static void on_gamelist_selection_changed(GtkTreeSelection *, gpointer);
static void PopulateForm(int pgs)
{
if (pgs & (1<<TAB_CONFIG))
{
int mode3d, i;
GtkListStore *modes3d;
GtkTreeIter iter;
GtkComboBox *box3d;
char buf[64];
mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
if (mode3d < 0)
{
int i, cd[] = { 32, 24, 16, 15, 8, 0 };
for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; }
for (; cd[i]; i++)
{
mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
if (mode3d < 0) continue;
settings.bpp3d = cd[i];
break;
}
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"fullscreencheck")), settings.fullscreen);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"alwaysshowcheck")), settings.forcesetup);
box3d = GTK_COMBO_BOX(lookup_widget(startwin,"vmode3dcombo"));
modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(box3d));
gtk_list_store_clear(modes3d);
for (i=0; i<validmodecnt; i++)
{
if (validmode[i].fs != settings.fullscreen) continue;
// all modes get added to the 3D mode list
Bsprintf(buf, "%d x %d %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
gtk_list_store_append(modes3d, &iter);
gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
if (i == mode3d)
{
g_signal_handlers_block_by_func(box3d, on_vmode3dcombo_changed, NULL);
gtk_combo_box_set_active_iter(box3d, &iter);
g_signal_handlers_unblock_by_func(box3d, on_vmode3dcombo_changed, NULL);
}
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputmousecheck")), settings.usemouse);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputjoycheck")), settings.usejoy);
}
if (pgs & (1<<TAB_GAME))
{
struct grpfile *fg;
int i;
GtkListStore *list;
GtkTreeIter iter;
GtkTreeView *gamelist;
gamelist = GTK_TREE_VIEW(lookup_widget(startwin,"gamelist"));
list = GTK_LIST_STORE(gtk_tree_view_get_model(gamelist));
gtk_list_store_clear(list);
for (fg = foundgrps; fg; fg=fg->next)
{
for (i = 0; i<numgrpfiles; i++)
if (fg->crcval == grpfiles[i].crcval) break;
if (i == numgrpfiles) continue; // unrecognised grp file
gtk_list_store_append(list, &iter);
gtk_list_store_set(list, &iter, 0, grpfiles[i].name, 1, fg->name, 2, (gpointer)fg, -1);
if (!Bstrcasecmp(fg->name, settings.selectedgrp))
{
GtkTreeSelection *sel = gtk_tree_view_get_selection(gamelist);
g_signal_handlers_block_by_func(sel, on_gamelist_selection_changed, NULL);
gtk_tree_selection_select_iter(sel, &iter);
g_signal_handlers_unblock_by_func(sel, on_gamelist_selection_changed, NULL);
}
}
}
}
// -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
{
GtkTreeModel *data;
GtkTreeIter iter;
int val;
if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
if (!(data = gtk_combo_box_get_model(combobox))) return;
gtk_tree_model_get(data, &iter, 1, &val, -1);
settings.xdim3d = validmode[val].xdim;
settings.ydim3d = validmode[val].ydim;
}
static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
settings.fullscreen = (gtk_toggle_button_get_active(togglebutton) == TRUE);
PopulateForm(1<<TAB_CONFIG);
}
static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
settings.forcesetup = (gtk_toggle_button_get_active(togglebutton) == TRUE);
}
static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
{
if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
else quitevent++;
}
static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
{
retval = 1;
gtk_main_quit();
}
static void on_inputmousecheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
settings.usemouse = (gtk_toggle_button_get_active(togglebutton) == TRUE);
}
static void on_inputjoycheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
{
settings.usejoy = (gtk_toggle_button_get_active(togglebutton) == TRUE);
}
static void on_gamelist_selection_changed(GtkTreeSelection *selection, gpointer user_data)
{
GtkTreeIter iter;
GtkTreeModel *model;
struct grpfile *fg;
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
gtk_tree_model_get(model, &iter, 2, (gpointer)&fg, -1);
strcpy(settings.selectedgrp, fg->name);
}
}
static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
else quitevent++;
return TRUE; // FALSE would let the event go through. we want the game to decide when to close
}
static gint name_sorter(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
{
gchar *as, *bs;
gint r;
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)
{
GtkWidget *startwin;
GtkWidget *hlayout;
GtkWidget *banner;
GtkWidget *vlayout;
GtkWidget *tabs;
GtkWidget *configvlayout;
GtkWidget *configlayout;
GtkWidget *fullscreencheck;
GtkWidget *vmode3dlabel;
GtkWidget *inputdevlabel;
GtkWidget *inputmousecheck;
GtkWidget *inputjoycheck;
GtkWidget *vmode3dcombo;
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;
GtkAccelGroup *accel_group;
accel_group = gtk_accel_group_new();
// Basic window
startwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(startwin), apptitle); // NOTE: use global app title
gtk_window_set_position(GTK_WINDOW(startwin), GTK_WIN_POS_CENTER);
gtk_window_set_resizable(GTK_WINDOW(startwin), FALSE);
gtk_window_set_type_hint(GTK_WINDOW(startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
// Horizontal layout of banner and controls
hlayout = gtk_hbox_new(FALSE, 0);
gtk_widget_show(hlayout);
gtk_container_add(GTK_CONTAINER(startwin), hlayout);
// Banner
{
GdkPixbuf *pixbuf = load_banner();
banner = gtk_image_new_from_pixbuf(pixbuf);
g_object_unref((gpointer)pixbuf);
}
gtk_widget_show(banner);
gtk_box_pack_start(GTK_BOX(hlayout), banner, FALSE, FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(banner), 0.5, 0);
// Vertical layout of tab control and start+cancel buttons
vlayout = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vlayout);
gtk_box_pack_start(GTK_BOX(hlayout), vlayout, TRUE, TRUE, 0);
// Tab control
tabs = gtk_notebook_new();
gtk_widget_show(tabs);
gtk_box_pack_start(GTK_BOX(vlayout), tabs, TRUE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(tabs), 4);
// Vertical layout of config page main body
configvlayout = gtk_vbox_new(FALSE, 0);
gtk_widget_show(configvlayout);
gtk_container_add(GTK_CONTAINER(tabs), configvlayout);
// Fixed-position layout of config page controls
configlayout = gtk_fixed_new();
gtk_widget_show(configlayout);
gtk_box_pack_start(GTK_BOX(configvlayout), configlayout, TRUE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(configlayout), 6);
// Fullscreen checkbox
fullscreencheck = gtk_check_button_new_with_mnemonic("_Fullscreen");
gtk_widget_show(fullscreencheck);
gtk_fixed_put(GTK_FIXED(configlayout), fullscreencheck, 248, 0);
gtk_widget_set_size_request(fullscreencheck, 85, 29);
gtk_widget_add_accelerator(fullscreencheck, "grab_focus", accel_group,
GDK_F, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
// 3D video mode label
vmode3dlabel = gtk_label_new_with_mnemonic("_Video mode:");
gtk_widget_show(vmode3dlabel);
gtk_fixed_put(GTK_FIXED(configlayout), vmode3dlabel, 0, 0);
gtk_widget_set_size_request(vmode3dlabel, 88, 29);
gtk_misc_set_alignment(GTK_MISC(vmode3dlabel), 0, 0.5);
inputdevlabel = gtk_label_new("Input devices:");
gtk_widget_show(inputdevlabel);
gtk_fixed_put(GTK_FIXED(configlayout), inputdevlabel, 0, 120);
gtk_widget_set_size_request(inputdevlabel, 88, 20);
gtk_misc_set_alignment(GTK_MISC(inputdevlabel), 0, 0.5);
inputmousecheck = gtk_check_button_new_with_mnemonic("Mo_use");
gtk_widget_show(inputmousecheck);
gtk_fixed_put(GTK_FIXED(configlayout), inputmousecheck, 88, 120);
gtk_widget_set_size_request(inputmousecheck, 80, 20);
gtk_widget_add_accelerator(inputmousecheck, "grab_focus", accel_group,
GDK_U, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
inputjoycheck = gtk_check_button_new_with_mnemonic("_Joystick");
gtk_widget_show(inputjoycheck);
gtk_fixed_put(GTK_FIXED(configlayout), inputjoycheck, 168, 120);
gtk_widget_set_size_request(inputjoycheck, 80, 20);
gtk_widget_add_accelerator(inputjoycheck, "grab_focus", accel_group,
GDK_J, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
// 3D video mode combo
{
GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
GtkCellRenderer *cell;
vmode3dcombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list));
g_object_unref(G_OBJECT(list));
cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(vmode3dcombo), cell, FALSE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(vmode3dcombo), cell, "text", 0, NULL);
}
gtk_widget_show(vmode3dcombo);
gtk_fixed_put(GTK_FIXED(configlayout), vmode3dcombo, 88, 0);
gtk_widget_set_size_request(vmode3dcombo, 150, 29);
gtk_widget_add_accelerator(vmode3dcombo, "grab_focus", accel_group,
GDK_V, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
// Always show config checkbox
alwaysshowcheck = gtk_check_button_new_with_mnemonic("_Always show configuration on start");
gtk_widget_show(alwaysshowcheck);
gtk_box_pack_start(GTK_BOX(configvlayout), alwaysshowcheck, FALSE, FALSE, 0);
gtk_widget_add_accelerator(alwaysshowcheck, "grab_focus", accel_group,
GDK_A, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
// Configuration tab
configtab = gtk_label_new("Configuration");
gtk_widget_show(configtab);
gtk_notebook_set_tab_label(GTK_NOTEBOOK(tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(tabs), 0), configtab);
// Game data layout
gamevlayout = gtk_vbox_new(FALSE, 0);
gtk_widget_show(gamevlayout);
gtk_container_add(GTK_CONTAINER(tabs), gamevlayout);
gtk_container_set_border_width(GTK_CONTAINER(gamevlayout), 4);
// Game data field label
gamelabel = gtk_label_new_with_mnemonic("_Game or addon:");
gtk_widget_show(gamelabel);
gtk_box_pack_start(GTK_BOX(gamevlayout), gamelabel, FALSE, FALSE, 0);
gtk_misc_set_alignment(GTK_MISC(gamelabel), 0, 0.5);
// Game data scrollable area
gamescroll = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_show(gamescroll);
gtk_box_pack_start(GTK_BOX(gamevlayout), gamescroll, TRUE, TRUE, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gamescroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(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);
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(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(gamelist), col);
}
gtk_widget_show(gamelist);
gtk_container_add(GTK_CONTAINER(gamescroll), gamelist);
gtk_widget_add_accelerator(gamelist, "grab_focus", accel_group,
GDK_G, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gamelist), FALSE);
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(gamelist), FALSE);
// Game tab
gametab = gtk_label_new("Game");
gtk_widget_show(gametab);
gtk_notebook_set_tab_label(GTK_NOTEBOOK(tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(tabs), 1), gametab);
// Messages scrollable area
messagesscroll = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_show(messagesscroll);
gtk_container_add(GTK_CONTAINER(tabs), messagesscroll);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
// Messages text area
messagestext = gtk_text_view_new();
gtk_widget_show(messagestext);
gtk_container_add(GTK_CONTAINER(messagesscroll), messagestext);
gtk_text_view_set_editable(GTK_TEXT_VIEW(messagestext), FALSE);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(messagestext), GTK_WRAP_WORD);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(messagestext), FALSE);
gtk_text_view_set_left_margin(GTK_TEXT_VIEW(messagestext), 2);
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(messagestext), 2);
// Messages tab
messagestab = gtk_label_new("Messages");
gtk_widget_show(messagestab);
gtk_notebook_set_tab_label(GTK_NOTEBOOK(tabs), gtk_notebook_get_nth_page(GTK_NOTEBOOK(tabs), 2), messagestab);
// Dialogue box buttons layout
buttons = gtk_hbutton_box_new();
gtk_widget_show(buttons);
gtk_box_pack_start(GTK_BOX(vlayout), buttons, FALSE, TRUE, 0);
gtk_container_set_border_width(GTK_CONTAINER(buttons), 3);
gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons), GTK_BUTTONBOX_END);
// Cancel button
cancelbutton = gtk_button_new();
gtk_widget_show(cancelbutton);
gtk_container_add(GTK_CONTAINER(buttons), cancelbutton);
GTK_WIDGET_SET_FLAGS(cancelbutton, GTK_CAN_DEFAULT);
gtk_widget_add_accelerator(cancelbutton, "grab_focus", accel_group,
GDK_C, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
gtk_widget_add_accelerator(cancelbutton, "clicked", accel_group,
GDK_Escape, 0,
GTK_ACCEL_VISIBLE);
cancelbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
gtk_widget_show(cancelbuttonalign);
gtk_container_add(GTK_CONTAINER(cancelbutton), cancelbuttonalign);
cancelbuttonlayout = gtk_hbox_new(FALSE, 2);
gtk_widget_show(cancelbuttonlayout);
gtk_container_add(GTK_CONTAINER(cancelbuttonalign), cancelbuttonlayout);
cancelbuttonicon = gtk_image_new_from_stock("gtk-cancel", GTK_ICON_SIZE_BUTTON);
gtk_widget_show(cancelbuttonicon);
gtk_box_pack_start(GTK_BOX(cancelbuttonlayout), cancelbuttonicon, FALSE, FALSE, 0);
cancelbuttonlabel = gtk_label_new_with_mnemonic("_Cancel");
gtk_widget_show(cancelbuttonlabel);
gtk_box_pack_start(GTK_BOX(cancelbuttonlayout), cancelbuttonlabel, FALSE, FALSE, 0);
// Start button
startbutton = gtk_button_new();
gtk_widget_show(startbutton);
gtk_container_add(GTK_CONTAINER(buttons), startbutton);
GTK_WIDGET_SET_FLAGS(startbutton, GTK_CAN_DEFAULT);
gtk_widget_add_accelerator(startbutton, "grab_focus", accel_group,
GDK_S, GDK_MOD1_MASK,
GTK_ACCEL_VISIBLE);
gtk_widget_add_accelerator(startbutton, "clicked", accel_group,
GDK_Return, 0,
GTK_ACCEL_VISIBLE);
startbuttonalign = gtk_alignment_new(0.5, 0.5, 0, 0);
gtk_widget_show(startbuttonalign);
gtk_container_add(GTK_CONTAINER(startbutton), startbuttonalign);
startbuttonlayout = gtk_hbox_new(FALSE, 2);
gtk_widget_show(startbuttonlayout);
gtk_container_add(GTK_CONTAINER(startbuttonalign), startbuttonlayout);
startbuttonicon = gtk_image_new_from_stock("gtk-execute", GTK_ICON_SIZE_BUTTON);
gtk_widget_show(startbuttonicon);
gtk_box_pack_start(GTK_BOX(startbuttonlayout), startbuttonicon, FALSE, FALSE, 0);
startbuttonlabel = gtk_label_new_with_mnemonic("_Start");
gtk_widget_show(startbuttonlabel);
gtk_box_pack_start(GTK_BOX(startbuttonlayout), startbuttonlabel, FALSE, FALSE, 0);
// Wire up the signals
g_signal_connect((gpointer) startwin, "delete_event",
G_CALLBACK(on_startwin_delete_event),
NULL);
g_signal_connect((gpointer) fullscreencheck, "toggled",
G_CALLBACK(on_fullscreencheck_toggled),
NULL);
g_signal_connect((gpointer) inputmousecheck, "toggled",
G_CALLBACK(on_inputmousecheck_toggled),
NULL);
g_signal_connect((gpointer) inputjoycheck, "toggled",
G_CALLBACK(on_inputjoycheck_toggled),
NULL);
g_signal_connect((gpointer) vmode3dcombo, "changed",
G_CALLBACK(on_vmode3dcombo_changed),
NULL);
g_signal_connect((gpointer) alwaysshowcheck, "toggled",
G_CALLBACK(on_alwaysshowcheck_toggled),
NULL);
g_signal_connect((gpointer) cancelbutton, "clicked",
G_CALLBACK(on_cancelbutton_clicked),
NULL);
g_signal_connect((gpointer) startbutton, "clicked",
G_CALLBACK(on_startbutton_clicked),
NULL);
{
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(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(vmode3dlabel), vmode3dcombo);
gtk_label_set_mnemonic_widget(GTK_LABEL(gamelabel), gamelist);
/* Store pointers to all widgets, for use by lookup_widget(). */
GLADE_HOOKUP_OBJECT_NO_REF(startwin, startwin, "startwin");
GLADE_HOOKUP_OBJECT(startwin, hlayout, "hlayout");
GLADE_HOOKUP_OBJECT(startwin, banner, "banner");
GLADE_HOOKUP_OBJECT(startwin, vlayout, "vlayout");
GLADE_HOOKUP_OBJECT(startwin, tabs, "tabs");
GLADE_HOOKUP_OBJECT(startwin, configvlayout, "configvlayout");
GLADE_HOOKUP_OBJECT(startwin, configlayout, "configlayout");
GLADE_HOOKUP_OBJECT(startwin, fullscreencheck, "fullscreencheck");
GLADE_HOOKUP_OBJECT(startwin, vmode3dlabel, "vmode3dlabel");
GLADE_HOOKUP_OBJECT(startwin, inputdevlabel, "inputdevlabel");
GLADE_HOOKUP_OBJECT(startwin, inputmousecheck, "inputmousecheck");
GLADE_HOOKUP_OBJECT(startwin, inputjoycheck, "inputjoycheck");
GLADE_HOOKUP_OBJECT(startwin, vmode3dcombo, "vmode3dcombo");
GLADE_HOOKUP_OBJECT(startwin, alwaysshowcheck, "alwaysshowcheck");
GLADE_HOOKUP_OBJECT(startwin, configtab, "configtab");
GLADE_HOOKUP_OBJECT(startwin, gamevlayout, "gamevlayout");
GLADE_HOOKUP_OBJECT(startwin, gamelabel, "gamelabel");
GLADE_HOOKUP_OBJECT(startwin, gamescroll, "gamescroll");
GLADE_HOOKUP_OBJECT(startwin, gamelist, "gamelist");
GLADE_HOOKUP_OBJECT(startwin, gametab, "gametab");
GLADE_HOOKUP_OBJECT(startwin, messagesscroll, "messagesscroll");
GLADE_HOOKUP_OBJECT(startwin, messagestext, "messagestext");
GLADE_HOOKUP_OBJECT(startwin, messagestab, "messagestab");
GLADE_HOOKUP_OBJECT(startwin, buttons, "buttons");
GLADE_HOOKUP_OBJECT(startwin, cancelbutton, "cancelbutton");
GLADE_HOOKUP_OBJECT(startwin, cancelbuttonalign, "cancelbuttonalign");
GLADE_HOOKUP_OBJECT(startwin, cancelbuttonlayout, "cancelbuttonlayout");
GLADE_HOOKUP_OBJECT(startwin, cancelbuttonicon, "cancelbuttonicon");
GLADE_HOOKUP_OBJECT(startwin, cancelbuttonlabel, "cancelbuttonlabel");
GLADE_HOOKUP_OBJECT(startwin, startbutton, "startbutton");
GLADE_HOOKUP_OBJECT(startwin, startbuttonalign, "startbuttonalign");
GLADE_HOOKUP_OBJECT(startwin, startbuttonlayout, "startbuttonlayout");
GLADE_HOOKUP_OBJECT(startwin, startbuttonicon, "startbuttonicon");
GLADE_HOOKUP_OBJECT(startwin, startbuttonlabel, "startbuttonlabel");
gtk_window_add_accel_group(GTK_WINDOW(startwin), accel_group);
return startwin;
}
// -- BUILD ENTRY POINTS ------------------------------------------------------
int startwin_open(void)
{
if (!gtkenabled) return 0;
if (startwin) return 1;
startwin = create_window();
if (startwin)
{
SetPage(TAB_MESSAGES);
gtk_widget_show(startwin);
gtk_main_iteration_do(FALSE);
return 0;
}
return -1;
}
int startwin_close(void)
{
if (!gtkenabled) return 0;
if (!startwin) return 1;
gtk_widget_destroy(startwin);
startwin = NULL;
return 0;
}
int startwin_puts(const char *str)
{
GtkWidget *textview;
GtkTextBuffer *textbuffer;
GtkTextIter enditer;
GtkTextMark *mark;
const char *aptr, *bptr;
if (!gtkenabled || !str) return 0;
if (!startwin) return 1;
if (!(textview = lookup_widget(startwin, "messagestext"))) return -1;
textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_get_end_iter(textbuffer, &enditer);
for (aptr = bptr = str; *aptr != 0; )
{
switch (*bptr)
{
case '\b':
if (bptr > aptr)
gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
#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;
}
int startwin_settitle(const char *title)
{
if (!gtkenabled) return 0;
if (!startwin) return 1;
gtk_window_set_title(GTK_WINDOW(startwin), title);
return 0;
}
int startwin_idle(void *s)
{
if (!gtkenabled) return 0;
//if (!startwin) return 1;
gtk_main_iteration_do(FALSE);
return 0;
}
extern int32_t ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP, ForceSetup, UseMouse, UseJoystick;
int startwin_run(void)
{
if (!gtkenabled) return 0;
if (!startwin) return 1;
ScanGroups();
SetPage(TAB_CONFIG);
settings.fullscreen = ScreenMode;
settings.xdim3d = ScreenWidth;
settings.ydim3d = ScreenHeight;
settings.bpp3d = ScreenBPP;
settings.forcesetup = ForceSetup;
settings.usemouse = UseMouse;
settings.usejoy = UseJoystick;
Bstrncpyz(settings.selectedgrp, G_GrpFile(), BMAX_PATH);
PopulateForm(-1);
gtk_main();
SetPage(TAB_MESSAGES);
if (retval)
{
ScreenMode = settings.fullscreen;
ScreenWidth = settings.xdim3d;
ScreenHeight = settings.ydim3d;
ScreenBPP = settings.bpp3d;
ForceSetup = settings.forcesetup;
UseMouse = settings.usemouse;
UseJoystick = settings.usejoy;
g_grpNamePtr = dup_filename(settings.selectedgrp);
}
return retval;
}
END_SW_NS

View file

@ -1,675 +0,0 @@
#ifndef _WIN32
#error Only for Windows
#endif
#include "ns.h"
#include "build.h"
#define NEED_WINDOWSX_H
#define NEED_COMMCTRL_H
#include "windows_inc.h"
#include "renderlayer.h"
#include "common.h"
#include "common_game.h"
#include "gamedefs.h"
#include "config.h"
#include "grpscan.h"
#include "gamecvars.h"
#include "startwin.game.h"
BEGIN_SW_NS
#define TAB_CONFIG 0
#define TAB_GAME 1
#define TAB_MESSAGES 2
static struct
{
int fullscreen;
int xdim, ydim, bpp;
int usemouse, usejoy;
char selectedgrp[BMAX_PATH+1];
int samplerate, bitspersample, channels;
} settings;
static struct soundQuality_t
{
int frequency;
int samplesize;
int channels;
} *soundQualities = 0;
static HWND startupdlg = NULL;
static HWND pages[3] = { NULL, NULL, NULL };
static int done = -1, mode = TAB_CONFIG;
#define POPULATE_VIDEO 1
#define POPULATE_CONFIG 2
#define POPULATE_GAME 4
// Thanks, Microsoft for not providing alternatives for the dialog control macros. :(
#undef SNDMSG
#define SNDMSG ::SendMessageA
static int addSoundQualityItem(struct soundQuality_t *q, HWND hwnd)
{
char buf[128];
const char *ch;
switch (q->channels)
{
case 1: ch = "Mono"; break;
case 2: ch = "Stereo"; break;
default: ch = "?"; break;
}
sprintf(buf, "%dkHz, %d-bit, %s",
q->frequency / 1000,
q->samplesize,
ch);
return ComboBox_AddString(hwnd, buf);
}
static void PopulateForm(int pgs)
{
HWND hwnd;
char buf[256];
int i,j;
if (pgs & POPULATE_VIDEO)
{
int mode;
hwnd = GetDlgItem(pages[TAB_CONFIG], IDCVMODE);
mode = videoCheckMode(&settings.xdim, &settings.ydim, settings.bpp, settings.fullscreen, 1);
if (mode < 0)
{
int cd[] = { 32, 24, 16, 15, 8, 0 };
for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp) i++; else break; }
for (; cd[i]; i++)
{
mode = videoCheckMode(&settings.xdim, &settings.ydim, cd[i], settings.fullscreen, 1);
if (mode < 0) continue;
settings.bpp = cd[i];
break;
}
}
Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), (settings.fullscreen ? BST_CHECKED : BST_UNCHECKED));
ComboBox_ResetContent(hwnd);
for (i=0; i<validmodecnt; i++)
{
if (validmode[i].fs != settings.fullscreen) continue;
// all modes get added to the 3D mode list
Bsprintf(buf, "%d x %d %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
j = ComboBox_AddString(hwnd, buf);
ComboBox_SetItemData(hwnd, j, i);
if (i == mode) ComboBox_SetCurSel(hwnd, j);
}
}
if (pgs & POPULATE_CONFIG)
{
int curidx = -1;
Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCALWAYSSHOW), (displaysetup ? BST_CHECKED : BST_UNCHECKED));
Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), (settings.usemouse ? BST_CHECKED : BST_UNCHECKED));
Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), (settings.usejoy ? BST_CHECKED : BST_UNCHECKED));
hwnd = GetDlgItem(pages[TAB_CONFIG], IDCSOUNDQUAL);
ComboBox_ResetContent(hwnd);
for (i = 0; soundQualities[i].frequency > 0; i++)
{
j = addSoundQualityItem(&soundQualities[i], hwnd);
ComboBox_SetItemData(hwnd, j, i);
if (soundQualities[i].frequency == settings.samplerate &&
soundQualities[i].samplesize == settings.bitspersample &&
soundQualities[i].channels == settings.channels)
{
ComboBox_SetCurSel(hwnd, j);
}
}
if (curidx < 0)
{
soundQualities[i].frequency = settings.samplerate;
soundQualities[i].samplesize = settings.bitspersample;
soundQualities[i].channels = settings.channels;
j = addSoundQualityItem(&soundQualities[i], hwnd);
ComboBox_SetItemData(hwnd, j, i);
i++;
soundQualities[i].frequency = -1;
}
}
if (pgs & POPULATE_GAME)
{
struct grpfile *fg;
int i, j;
char buf[128+BMAX_PATH];
hwnd = GetDlgItem(pages[TAB_GAME], IDGDATA);
for (fg = foundgrps; fg; fg=fg->next)
{
for (i = 0; i<numgrpfiles; i++)
if (fg->crcval == grpfiles[i].crcval) break;
if (i == numgrpfiles) continue; // unrecognised grp file
Bsprintf(buf, "%s\t%s", grpfiles[i].name, fg->name);
j = ListBox_AddString(hwnd, buf);
ListBox_SetItemData(hwnd, j, (LPARAM)fg);
if (!Bstrcasecmp(fg->name, settings.selectedgrp)) ListBox_SetCurSel(hwnd, j);
}
}
}
static INT_PTR CALLBACK ConfigPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCFULLSCREEN:
settings.fullscreen = !settings.fullscreen;
PopulateForm(1<<TAB_CONFIG);
return TRUE;
case IDCVMODE:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
int i;
i = ComboBox_GetCurSel((HWND)lParam);
if (i != CB_ERR) i = ComboBox_GetItemData((HWND)lParam, i);
if (i != CB_ERR)
{
settings.xdim = validmode[i].xdim;
settings.ydim = validmode[i].ydim;
settings.bpp = validmode[i].bpp;
}
}
return TRUE;
case IDCSOUNDQUAL:
if (HIWORD(wParam) == CBN_SELCHANGE)
{
int i;
i = ComboBox_GetCurSel((HWND)lParam);
if (i != CB_ERR) i = ComboBox_GetItemData((HWND)lParam, i);
if (i != CB_ERR)
{
settings.samplerate = soundQualities[i].frequency;
settings.bitspersample = soundQualities[i].samplesize;
settings.channels = soundQualities[i].channels;
}
}
return TRUE;
case IDCALWAYSSHOW:
displaysetup = IsDlgButtonChecked(hwndDlg, IDCALWAYSSHOW) == BST_CHECKED;
return TRUE;
case IDCINPUTMOUSE:
settings.usemouse = IsDlgButtonChecked(hwndDlg, IDCINPUTMOUSE) == BST_CHECKED;
return TRUE;
case IDCINPUTJOY:
settings.usejoy = IsDlgButtonChecked(hwndDlg, IDCINPUTJOY) == BST_CHECKED;
return TRUE;
default: break;
}
break;
default: break;
}
return FALSE;
}
static INT_PTR CALLBACK GamePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDGDATA:
{
int i;
i = ListBox_GetCurSel((HWND)lParam);
if (i != CB_ERR)
{
LRESULT j = ListBox_GetItemData((HWND)lParam, i);
if (j != CB_ERR)
strcpy(settings.selectedgrp, ((struct grpfile const *)j)->name);
}
return TRUE;
}
default: break;
}
break;
default: break;
}
return FALSE;
}
static void SetPage(int n)
{
HWND tab;
int cur;
tab = GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL);
cur = (int)SendMessageA(tab, TCM_GETCURSEL,0,0);
ShowWindow(pages[cur],SW_HIDE);
SendMessageA(tab, TCM_SETCURSEL, n, 0);
ShowWindow(pages[n],SW_SHOW);
mode = n;
SetFocus(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL));
}
static void EnableConfig(int n)
{
//EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_CANCEL), n);
EnableWindow(GetDlgItem(startupdlg, WIN_STARTWIN_START), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCVMODE), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCSOUNDQUAL), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTMOUSE), n);
EnableWindow(GetDlgItem(pages[TAB_CONFIG], IDCINPUTJOY), n);
EnableWindow(GetDlgItem(pages[TAB_GAME], IDGDATA), n);
}
static INT_PTR CALLBACK startup_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hbmp = NULL;
HDC hdc;
switch (uMsg)
{
case WM_INITDIALOG:
{
HWND hwnd;
RECT r, rdlg, chrome, rtab, rcancel, rstart;
int xoffset = 0, yoffset = 0;
// Fetch the positions (in screen coordinates) of all the windows we need to tweak
ZeroMemory(&chrome, sizeof(chrome));
AdjustWindowRect(&chrome, GetWindowLong(hwndDlg, GWL_STYLE), FALSE);
GetWindowRect(hwndDlg, &rdlg);
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL), &rtab);
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_CANCEL), &rcancel);
GetWindowRect(GetDlgItem(hwndDlg, WIN_STARTWIN_START), &rstart);
// 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;
// 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;
rcancel.right -= rcancel.left - 1; rcancel.bottom -= rcancel.top - 1;
rcancel.left -= rdlg.left; rcancel.top -= rdlg.top;
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)win_gethinstance(), MAKEINTRESOURCE(RSRC_BMP));
hwnd = GetDlgItem(hwndDlg,WIN_STARTWIN_BITMAP);
SendMessageA(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
GetClientRect(hwnd, &r);
xoffset = r.right;
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 = 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
{
TCITEMA tab;
hwnd = GetDlgItem(hwndDlg, WIN_STARTWIN_TABCTL);
ZeroMemory(&tab, sizeof(tab));
tab.mask = TCIF_TEXT;
static char textConfiguration[] = ("Configuration");
tab.pszText = textConfiguration;
SendMessageA(hwnd, TCM_INSERTITEM, (WPARAM)TAB_CONFIG, (LPARAM)&tab);
tab.mask = TCIF_TEXT;
static char textGame[] = ("Game");
tab.pszText = textGame;
SendMessageA(hwnd, TCM_INSERTITEM, (WPARAM)TAB_GAME, (LPARAM)&tab);
tab.mask = TCIF_TEXT;
static char textMessages[] = ("Messages");
tab.pszText = textMessages;
SendMessageA(hwnd, TCM_INSERTITEM, (WPARAM)TAB_MESSAGES, (LPARAM)&tab);
// Work out the position and size of the area inside the tab control for the pages
ZeroMemory(&r, sizeof(r));
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)win_gethinstance(),
MAKEINTRESOURCE(WIN_STARTWINPAGE_CONFIG), hwndDlg, ConfigPageProc);
pages[TAB_GAME] = CreateDialog((HINSTANCE)win_gethinstance(),
MAKEINTRESOURCE(WIN_STARTWINPAGE_GAME), hwndDlg, GamePageProc);
pages[TAB_MESSAGES] = GetDlgItem(hwndDlg, WIN_STARTWIN_MESSAGES);
SetWindowPos(pages[TAB_CONFIG], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
SetWindowPos(pages[TAB_GAME], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
SetWindowPos(pages[TAB_MESSAGES], hwnd,r.left,r.top,r.right,r.bottom,SWP_HIDEWINDOW);
// Tell the editfield acting as the console to exclude the width of the scrollbar
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 };
ListBox_SetTabStops(GetDlgItem(pages[TAB_GAME], IDGDATA), 1, tabs);
}
SetFocus(GetDlgItem(hwndDlg, WIN_STARTWIN_START));
SetWindowTextA(hwndDlg, apptitle);
}
return FALSE;
}
case WM_NOTIFY:
{
LPNMHDR nmhdr = (LPNMHDR)lParam;
int cur;
if (nmhdr->idFrom != WIN_STARTWIN_TABCTL) break;
cur = (int)SendMessageA(nmhdr->hwndFrom, TCM_GETCURSEL,0,0);
switch (nmhdr->code)
{
case TCN_SELCHANGING:
{
if (cur < 0 || !pages[cur]) break;
ShowWindow(pages[cur],SW_HIDE);
return TRUE;
}
case TCN_SELCHANGE:
{
if (cur < 0 || !pages[cur]) break;
ShowWindow(pages[cur],SW_SHOW);
return TRUE;
}
}
break;
}
case WM_CLOSE:
if (mode == TAB_CONFIG) done = 0;
else quitevent++;
return TRUE;
case WM_DESTROY:
if (hbmp)
{
DeleteObject(hbmp);
hbmp = NULL;
}
if (pages[TAB_GAME])
{
DestroyWindow(pages[TAB_GAME]);
pages[TAB_GAME] = NULL;
}
if (pages[TAB_CONFIG])
{
DestroyWindow(pages[TAB_CONFIG]);
pages[TAB_CONFIG] = NULL;
}
startupdlg = NULL;
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case WIN_STARTWIN_CANCEL:
if (mode == TAB_CONFIG) done = 0;
else quitevent++;
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;
}
int startwin_open(void)
{
INITCOMMONCONTROLSEX icc;
if (startupdlg) return 1;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icc);
startupdlg = CreateDialog((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc);
if (startupdlg)
{
{
static int soundQualityFrequencies[] = { 44100, 22050, 11025 };
static int soundQualitySampleSizes[] = { 16, 8 };
static int soundQualityChannels[] = { 2, 1 };
unsigned int f, b, c, i;
i = sizeof(soundQualityFrequencies) *
sizeof(soundQualitySampleSizes) *
sizeof(soundQualityChannels) /
sizeof(int) + 2; // one for the terminator, one for a custom setting
soundQualities = (struct soundQuality_t *) malloc(i * sizeof(struct soundQuality_t));
i = 0;
for (c = 0; c < sizeof(soundQualityChannels) / sizeof(int); c++)
{
for (b = 0; b < sizeof(soundQualitySampleSizes) / sizeof(int); b++)
{
for (f = 0; f < sizeof(soundQualityFrequencies) / sizeof(int); f++)
{
soundQualities[i].frequency = soundQualityFrequencies[f];
soundQualities[i].samplesize = soundQualitySampleSizes[b];
soundQualities[i].channels = soundQualityChannels[c];
i++;
}
}
}
soundQualities[i].frequency = -1;
}
SetPage(TAB_MESSAGES);
EnableConfig(0);
return 0;
}
return -1;
}
int startwin_close(void)
{
if (!startupdlg) return 1;
DestroyWindow(startupdlg);
startupdlg = NULL;
free(soundQualities);
return 0;
}
int startwin_puts(const char *buf)
{
const char *p = NULL, *q = NULL;
char workbuf[1024];
static int newline = 0;
int curlen, linesbefore, linesafter;
HWND edctl;
int vis;
if (!startupdlg) return 1;
edctl = pages[TAB_MESSAGES];
if (!edctl) return -1;
vis = ((int)SendMessageA(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL), TCM_GETCURSEL,0,0) == TAB_MESSAGES);
if (vis) SendMessageA(edctl, WM_SETREDRAW, FALSE,0);
curlen = SendMessageA(edctl, WM_GETTEXTLENGTH, 0,0);
SendMessageA(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen);
linesbefore = SendMessageA(edctl, EM_GETLINECOUNT, 0,0);
p = buf;
while (*p)
{
if (newline)
{
SendMessageA(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n");
newline = 0;
}
q = p;
while (*q && *q != '\n') q++;
memcpy(workbuf, p, q-p);
if (*q == '\n')
{
if (!q[1])
{
newline = 1;
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);
}
linesafter = SendMessageA(edctl, EM_GETLINECOUNT, 0,0);
SendMessageA(edctl, EM_LINESCROLL, 0, linesafter-linesbefore);
if (vis) SendMessageA(edctl, WM_SETREDRAW, TRUE,0);
return 0;
}
int startwin_settitle(const char *str)
{
if (!startupdlg) return 1;
SetWindowTextA(startupdlg, str);
return 0;
}
int startwin_idle(void *v)
{
if (!startupdlg || !IsWindow(startupdlg)) return 0;
if (IsDialogMessage(startupdlg, (MSG *)v)) return 1;
return 0;
}
int startwin_run(void)
{
MSG msg;
if (!startupdlg) return 1;
done = -1;
ScanGroups();
SetPage(TAB_CONFIG);
EnableConfig(1);
settings.fullscreen = ScreenMode;
settings.xdim = ScreenWidth;
settings.ydim = ScreenHeight;
settings.bpp = ScreenBPP;
settings.samplerate = snd_mixrate;
settings.bitspersample = 16;
settings.channels = snd_numchannels;
settings.usemouse = UseMouse;
settings.usejoy = UseJoystick;
Bstrncpyz(settings.selectedgrp, G_GrpFile(), BMAX_PATH);
PopulateForm(-1);
while (done < 0)
{
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;
}
}
SetPage(TAB_MESSAGES);
EnableConfig(0);
if (done)
{
ScreenMode = settings.fullscreen;
ScreenWidth = settings.xdim;
ScreenHeight = settings.ydim;
ScreenBPP = settings.bpp;
UseMouse = settings.usemouse;
UseJoystick = settings.usejoy;
clearGrpNamePtr();
g_grpNamePtr = dup_filename(settings.selectedgrp);
}
FreeGroups();
return done;
}
END_SW_NS

View file

@ -1,25 +0,0 @@
// resource ids
#define WIN_STARTWIN 1000
#define WIN_STARTWINPAGE_CONFIG 2000
#define WIN_STARTWINPAGE_GAME 3000
#define WIN_STARTWIN_BITMAP 100 // banner bitmap
#define WIN_STARTWIN_TABCTL 101
#define WIN_STARTWIN_CANCEL IDCANCEL
#define WIN_STARTWIN_START IDOK
#define WIN_STARTWIN_MESSAGES 104 // output list box
#define RSRC_ICON 100
#define RSRC_BMP 200
// config page
#define IDCFULLSCREEN 100
#define IDCVMODE 101
#define IDCSOUNDQUAL 102
#define IDCINPUTMOUSE 105
#define IDCINPUTJOY 106
#define IDCALWAYSSHOW 107
// game page
#define IDGDATA 100