mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- 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:
parent
ba00fe4e66
commit
57f879fa8b
58 changed files with 907 additions and 8071 deletions
|
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -26,12 +26,7 @@ include_directories(
|
|||
)
|
||||
|
||||
|
||||
if (WIN32)
|
||||
set( PLAT_SOURCES
|
||||
src/startwin.game.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
set( PCH_SOURCES
|
||||
src/actor.cpp
|
||||
src/ai.cpp
|
||||
|
@ -123,7 +118,6 @@ file( GLOB HEADER_FILES
|
|||
add_library( blood STATIC
|
||||
${HEADER_FILES}
|
||||
${PCH_SOURCES}
|
||||
${PLAT_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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)();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "filesystem.h"
|
||||
#include "superfasthash.h"
|
||||
#include "resourcefile.h"
|
||||
#include "v_text.h"
|
||||
//#include "md5.h"
|
||||
//#include "doomstat.h"
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "image.h"
|
||||
#include "cache1d.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "v_text.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 ------------------------------------------------------------------
|
||||
|
|
|
@ -26,12 +26,7 @@ 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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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];
|
||||
|
@ -138,19 +83,19 @@ const char *G_DefaultConFile(void)
|
|||
return defaultconfilename;
|
||||
}
|
||||
|
||||
const char *G_GrpFile(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)
|
||||
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)
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,13 +6157,11 @@ void C_Compile(const char *fileName)
|
|||
C_AddDefaultDefinitions();
|
||||
C_ParseCommand(true);
|
||||
|
||||
for (char * m : g_scriptModules)
|
||||
{
|
||||
C_Include(m);
|
||||
free(m);
|
||||
}
|
||||
g_scriptModules.clear();
|
||||
|
||||
for (FString& m : *userConfig.AddCons.get())
|
||||
{
|
||||
C_Include(m);
|
||||
}
|
||||
|
||||
g_logFlushWindow = 1;
|
||||
|
||||
if (g_errorCnt > 63)
|
||||
|
|
|
@ -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
|
|
@ -6,7 +6,6 @@
|
|||
* Copyright 2009 __MyCompanyName__. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ns.h" // Must come before everything else!
|
||||
|
||||
#include "GrpFile.game.h"
|
File diff suppressed because it is too large
Load diff
|
@ -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)
|
||||
{
|
||||
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);
|
||||
int i=0;
|
||||
for (auto& grp : *gamedata)
|
||||
{
|
||||
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
|
||||
|
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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,24 +35,7 @@ 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)
|
||||
const char* G_DefaultGrpFile(void)
|
||||
{
|
||||
if (DUKE)
|
||||
return defaultgamegrp[GAME_DUKE];
|
||||
|
@ -73,7 +44,8 @@ const char *G_DefaultGrpFile(void)
|
|||
|
||||
return defaultgamegrp[0];
|
||||
}
|
||||
const char *G_DefaultDefFile(void)
|
||||
|
||||
const char* G_DefaultDefFile(void)
|
||||
{
|
||||
if (DUKE)
|
||||
return defaultdeffilename[GAME_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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *)§or[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,12 +7676,7 @@ 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 =
|
||||
#endif
|
||||
|
@ -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,
|
||||
|
||||
|
|
|
@ -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,13 +2431,12 @@ 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);
|
||||
C_Include(m);
|
||||
}
|
||||
g_scriptModules.clear();
|
||||
|
||||
userConfig.AddCons.reset();
|
||||
|
||||
g_logFlushWindow = 1;
|
||||
|
||||
if (g_errorCnt > 63)
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -26,12 +26,7 @@ include_directories(
|
|||
)
|
||||
|
||||
|
||||
if (WIN32)
|
||||
set( PLAT_SOURCES
|
||||
src/startwin.game.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
set( PCH_SOURCES
|
||||
src/actor.cpp
|
||||
src/ai.cpp
|
||||
|
@ -125,7 +120,6 @@ file( GLOB HEADER_FILES
|
|||
add_library( sw STATIC
|
||||
${HEADER_FILES}
|
||||
${PCH_SOURCES}
|
||||
${PLAT_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
Loading…
Reference in a new issue