void gamedetect(){
// if we're inside a Nexuiz install
// default to nexuiz.game (unless the user used an option to inhibit this)
- bool nogamedetect = false;
+ //bool nogamedetect = false;
+ bool nogamedetect = true;
int i;
for ( i = 1; i < g_argc - 1; ++i )
{
if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "nexuiz.exe", buf, p - buf ) )
#elif GDEF_OS_MACOS
if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "Nexuiz.app/Contents/Info.plist", buf, p - buf ) )
-#else
+#elif GDEF_OS_LINUX
if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", "nexuiz-linux-glx.sh", buf, p - buf ) )
+#else
+ if ( gamedetect_check_game( "nexuiz.game", "data/common-spog.pk3", NULL, buf, p - buf ) )
#endif
{ return; }
namespace
{
-CopiedString home_path;
-CopiedString app_path;
+ // executable file path
+ CopiedString app_filepath;
+ // directory paths
+ CopiedString home_path;
+ CopiedString app_path;
+ CopiedString lib_path;
+ CopiedString data_path;
+}
+
+const char* environment_get_app_filepath(){
+ return app_filepath.c_str();
}
const char* environment_get_home_path(){
return app_path.c_str();
}
+const char *environment_get_lib_path()
+{
+ return lib_path.c_str();
+}
+
+const char *environment_get_data_path()
+{
+ return data_path.c_str();
+}
+
bool portable_app_setup(){
StringOutputStream confdir( 256 );
confdir << app_path.c_str() << "settings/";
- if ( file_exists( confdir.c_str() ) ) {
+ if ( file_is_directory( confdir.c_str() ) ) {
home_path = confdir.c_str();
return true;
}
const char* LINK_NAME =
#if GDEF_OS_LINUX
"/proc/self/exe"
-#else // FreeBSD and OSX
+#else // FreeBSD and macOS
"/proc/curproc/file"
#endif
;
-/// brief Returns the filename of the executable belonging to the current process, or 0 if not found.
+/// brief Returns the filename of the executable belonging to the current process, or empty string if not found.
char const* getexename( char *buf ){
/* Now read the symbolic link */
- int ret = readlink( LINK_NAME, buf, PATH_MAX );
+ const int ret = readlink( LINK_NAME, buf, PATH_MAX );
if ( ret == -1 ) {
globalOutputStream() << "getexename: falling back to argv[0]: " << makeQuoted( g_argv[0] );
- const char* path = realpath( g_argv[0], buf );
- if ( path == 0 ) {
+ if( realpath( g_argv[0], buf ) == 0 ) {
/* In case of an error, leave the handling up to the caller */
- return "";
+ *buf = '\0';
}
}
+ else {
+ /* Ensure proper NUL termination */
+ buf[ret] = 0;
+ }
- /* Ensure proper NUL termination */
- buf[ret] = 0;
+ return buf;
+}
+char const* getexepath( char *buf ) {
/* delete the program name */
*( strrchr( buf, '/' ) ) = '\0';
{
char real[PATH_MAX];
- app_path = getexename( real );
- ASSERT_MESSAGE( !string_empty( app_path.c_str() ), "failed to deduce app path" );
+ app_filepath = getexename( real );
+ ASSERT_MESSAGE( !string_empty( app_filepath.c_str() ), "failed to deduce app path" );
+
+ strncpy( real, app_filepath.c_str(), strlen( app_filepath.c_str() ) );
+ app_path = getexepath( real );
+ }
+
+ {
+#if defined(RADIANT_FHS_INSTALL)
+ StringOutputStream buffer;
+ #if defined(RADIANT_ADDONS_DIR)
+ buffer << RADIANT_ADDONS_DIR << "/";
+ #else
+ buffer << app_path.c_str() << "../lib/";
+ buffer << RADIANT_LIB_ARCH << "/";
+ buffer << RADIANT_BASENAME << "/";
+ #endif
+ lib_path = buffer.c_str();
+#else
+ lib_path = app_path.c_str();
+#endif
+ }
+
+ {
+#if defined(RADIANT_FHS_INSTALL)
+ StringOutputStream buffer;
+ #if defined(RADIANT_DATA_DIR)
+ buffer << RADIANT_DATA_DIR << "/";
+ #else
+ buffer << app_path.c_str() << "../share/";
+ buffer << RADIANT_BASENAME << "/";
+ #endif
+ data_path = buffer.c_str();
+#else
+ data_path = app_path.c_str();
+#endif
}
if ( !portable_app_setup() ) {
StringOutputStream home( 256 );
- home << DirectoryCleaned( g_get_user_config_dir() ) << "netradiant/";
+#if GDEF_OS_MACOS
+ /* This is used on macOS, this will produce
+ ~/Library/Application Support/NetRadiant folder. */
+ home << DirectoryCleaned( g_get_home_dir() );
+ Q_mkdir( home.c_str() );
+ home << "Library/";
+ Q_mkdir( home.c_str() );
+ home << "Application Support/";
+ Q_mkdir( home.c_str() );
+ home << RADIANT_NAME << "/";
+#else // if GDEF_OS_XDG
+ /* This is used on both Linux and FreeBSD,
+ this will produce ~/.config/netradiant folder
+ when environment has default settings, the
+ XDG_CONFIG_HOME variable modifies it. */
+ home << DirectoryCleaned( g_get_user_config_dir() );
+ Q_mkdir( home.c_str() );
+ home << RADIANT_BASENAME << "/";
+#endif // ! GDEF_OS_MACOS
Q_mkdir( home.c_str() );
home_path = home.c_str();
}
+
gamedetect();
}
{
// get path to the editor
char filename[MAX_PATH + 1];
+ StringOutputStream app_filepath_stream( 256 );
+ StringOutputStream app_path_stream( 256 );
+
GetModuleFileName( 0, filename, MAX_PATH );
+
+ app_filepath_stream << PathCleaned( filename );
+ app_filepath = app_filepath_stream.c_str();
+
char* last_separator = strrchr( filename, '\\' );
if ( last_separator != 0 ) {
*( last_separator + 1 ) = '\0';
{
filename[0] = '\0';
}
- StringOutputStream app( 256 );
- app << PathCleaned( filename );
- app_path = app.c_str();
+
+ app_path_stream << PathCleaned( filename );
+ app_path = app_path_stream.c_str();
+
+ lib_path = app_path;
+ data_path = app_path;
}
if ( !portable_app_setup() ) {
char *appdata = getenv( "APPDATA" );
+
StringOutputStream home( 256 );
home << PathCleaned( appdata );
- home << "/NetRadiantSettings/";
+ home << "/";
+ home << RADIANT_NAME;
+ home << "/";
+
Q_mkdir( home.c_str() );
home_path = home.c_str();
}
#include "referencecache.h"
#include "texwindow.h"
+#if GDEF_OS_WINDOWS
+#include <process.h>
+#else
+#include <spawn.h>
+#endif
+
+#ifdef WORKAROUND_WINDOWS_GTK2_GLWIDGET
+/* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
+#define WORKAROUND_GOBJECT_SET_GLWIDGET(window, widget) g_object_set_data( G_OBJECT( window ), "glwidget", G_OBJECT( widget ) )
+#else
+#define WORKAROUND_GOBJECT_SET_GLWIDGET(window, widget)
+#endif
struct layout_globals_t
{
RefreshReferences();
// also refresh texture browser
TextureBrowser_RefreshShaders();
+ // also show textures (all or common)
+ TextureBrowser_ShowStartupShaders( GlobalTextureBrowser() );
}
void VFS_Restart(){
}
path.clear();
path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/";
-#endif
-
-#if GDEF_OS_WINDOWS
+#elif GDEF_OS_WINDOWS
TCHAR mydocsdir[MAX_PATH + 1];
wchar_t *mydocsdirw;
HMODULE shfolder = LoadLibrary( "shfolder.dll" );
break;
}
}
-#endif
-
-#if GDEF_OS_POSIX
+#elif GDEF_OS_XDG
+ path.clear();
+ path << DirectoryCleaned( g_get_user_data_dir() ) << ( prefix + 1 ) << "/";
+ if ( file_exists( path.c_str() ) && file_is_directory( path.c_str() ) ) {
+ g_qeglobals.m_userEnginePath = path.c_str();
+ break;
+ }
+ else {
path.clear();
path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/";
g_qeglobals.m_userEnginePath = path.c_str();
break;
+ }
#endif
}
}
-// App Path
+// executable file path (full path)
+CopiedString g_strAppFilePath;
-CopiedString g_strAppPath; ///< holds the full path of the executable
+// directory paths
+CopiedString g_strAppPath;
+CopiedString g_strLibPath;
+CopiedString g_strDataPath;
+
+const char* AppFilePath_get(){
+ return g_strAppFilePath.c_str();
+}
const char* AppPath_get(){
return g_strAppPath.c_str();
}
+const char *LibPath_get()
+{
+ return g_strLibPath.c_str();
+}
+
+const char *DataPath_get()
+{
+ return g_strDataPath.c_str();
+}
+
/// the path to the local rc-dir
const char* LocalRcPath_get( void ){
static CopiedString rc_path;
bool g_disableEnginePath = false;
bool g_disableHomePath = false;
-void Paths_constructPreferences( PreferencesPage& page ){
+void Paths_constructBasicPreferences( PreferencesPage& page ) {
page.appendPathEntry( "Engine Path", true, make_property<EnginePath>(g_strEnginePath) );
+}
- page.appendCheckBox(
- "", "Do not use Engine Path",
- g_disableEnginePath
- );
+void Paths_constructPreferences( PreferencesPage& page ){
+ Paths_constructBasicPreferences( page );
- page.appendCheckBox(
- "", "Do not use Home Path",
- g_disableHomePath
- );
+ page.appendSpacer( 4 );
+ page.appendLabel( "", "Advanced options" );
+ page.appendCheckBox( "", "Do not use Engine Path", g_disableEnginePath );
+ page.appendCheckBox( "", "Do not use Home Path", g_disableHomePath );
- for ( int i = 0; i < g_pakPathCount; i++ ) {
- std::string label = "Pak Path " + std::to_string(i);
- switch (i) {
- case 0:
- page.appendPathEntry( label.c_str(), true, make_property<PakPath0>( g_strPakPath[i] ) );
- break;
- case 1:
- page.appendPathEntry( label.c_str(), true, make_property<PakPath1>( g_strPakPath[i] ) );
- break;
- case 2:
- page.appendPathEntry( label.c_str(), true, make_property<PakPath2>( g_strPakPath[i] ) );
- break;
- case 3:
- page.appendPathEntry( label.c_str(), true, make_property<PakPath3>( g_strPakPath[i] ) );
- break;
- case 4:
- page.appendPathEntry( label.c_str(), true, make_property<PakPath4>( g_strPakPath[i] ) );
- break;
-}
- }
+ page.appendSpacer( 4 );
+ page.appendLabel( "", "Only a very few games support Pak Paths," );
+ page.appendLabel( "", "if you don't know what it is, leave this blank." );
+
+ const char *label = "Pak Path ";
+ page.appendPathEntry( label, true, make_property<PakPath0>( g_strPakPath[0] ) );
+ page.appendPathEntry( label, true, make_property<PakPath1>( g_strPakPath[1] ) );
+ page.appendPathEntry( label, true, make_property<PakPath2>( g_strPakPath[2] ) );
+ page.appendPathEntry( label, true, make_property<PakPath3>( g_strPakPath[3] ) );
+ page.appendPathEntry( label, true, make_property<PakPath4>( g_strPakPath[4] ) );
}
void Paths_constructPage( PreferenceGroup& group ){
{
public:
ui::Window BuildDialog(){
- auto frame = create_dialog_frame( "Path settings", ui::Shadow::ETCHED_IN );
+ auto frame = create_dialog_frame( "Path Settings", ui::Shadow::ETCHED_IN );
auto vbox2 = create_dialog_vbox( 0, 4 );
frame.add(vbox2);
{
- PreferencesPage preferencesPage( *this, vbox2 );
- Paths_constructPreferences( preferencesPage );
+ PreferencesPage page( *this, vbox2 );
+ Paths_constructBasicPreferences( page );
}
return ui::Window(create_simple_modal_dialog_window( "Engine Path Not Found", m_modal, frame ));
PathsDialog g_PathsDialog;
+ bool g_strEnginePath_was_empty_1st_start = false;
+
void EnginePath_verify(){
- if ( !file_exists( g_strEnginePath.c_str() ) ) {
+ if ( !file_exists( g_strEnginePath.c_str() ) || g_strEnginePath_was_empty_1st_start ) {
g_PathsDialog.Create();
g_PathsDialog.DoModal();
g_PathsDialog.Destroy();
void Radiant_Initialise(){
GlobalModuleServer_Initialise();
- Radiant_loadModulesFromRoot( AppPath_get() );
+ Radiant_loadModulesFromRoot( LibPath_get() );
Preferences_Load();
}
void Exit(){
- if ( ConfirmModified( "Exit Radiant" ) ) {
+ if ( ConfirmModified( "Exit " RADIANT_NAME ) ) {
gtk_main_quit();
}
}
XY_UpdateAllWindows();
}
+/* color scheme to fit the GTK Adwaita Dark theme */
+void ColorScheme_AdwaitaDark()
+{
+ // SI_Colors0
+ // GlobalTextureBrowser().color_textureback
+ TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f));
+
+ // SI_Colors4
+ g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f);
+ // SI_Colors12
+ g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f);
+ CamWnd_Update(*g_pParentWnd->GetCamWnd());
+
+ // SI_Colors1
+ g_xywindow_globals.color_gridback = Vector3(0.25f, 0.25f, 0.25f);
+ // SI_Colors2
+ g_xywindow_globals.color_gridminor = Vector3(0.21f, 0.23f, 0.23f);
+ // SI_Colors3
+ g_xywindow_globals.color_gridmajor = Vector3(0.14f, 0.15f, 0.15f);
+ // SI_Colors14
+ g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f);
+ // SI_Colors6
+ g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f);
+ // SI_Colors7
+ g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f);
+ // ??
+ g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f);
+ // ??
+ g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f);
+ // SI_Colors8
+ g_xywindow_globals.color_brushes = Vector3(0.73f, 0.73f, 0.73f);
+
+ // SI_AxisColors0
+ g_xywindow_globals.AxisColorX = Vector3(1.0f, 0.0f, 0.0f);
+ // SI_AxisColors1
+ g_xywindow_globals.AxisColorY = Vector3(0.0f, 1.0f, 0.0f);
+ // SI_AxisColors2
+ g_xywindow_globals.AxisColorZ = Vector3(0.0f, 0.0f, 1.0f);
+ SetWorldspawnColour(g_xywindow_globals.color_brushes);
+ // ??
+ g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f);
+ XY_UpdateAllWindows();
+
+ // SI_Colors5
+ // g_entity_globals.color_entity = Vector3(0.0f, 0.0f, 0.0f);
+}
+
typedef Callback<void(Vector3&)> GetColourCallback;
typedef Callback<void(const Vector3&)> SetColourCallback;
create_menu_item_with_mnemonic( menu_3, "Q3Radiant Original", "ColorSchemeQER" );
create_menu_item_with_mnemonic( menu_3, "Black and Green", "ColorSchemeBlackAndGreen" );
create_menu_item_with_mnemonic( menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar" );
+ create_menu_item_with_mnemonic(menu_3, "Adwaita Dark", "ColorSchemeAdwaitaDark");
menu_separator( menu_in_menu );
static gint qe_every_second( gpointer data ){
- GdkModifierType mask;
+ if (g_pParentWnd == nullptr)
+ return TRUE;
- gdk_window_get_pointer( 0, 0, 0, &mask );
+ GdkModifierType mask;
+ gdk_window_get_pointer( gtk_widget_get_window(g_pParentWnd->m_window), nullptr, nullptr, &mask );
if ( ( mask & ( GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK ) ) == 0 ) {
QE_CheckAutoSave();
bool isActiveApp = MainFrame_isActiveApp();
g_wait = create_wait_dialog( title, message );
- gtk_grab_add( g_wait.m_window );
if ( isActiveApp ) {
g_wait.m_window.show();
+ gtk_grab_add( g_wait.m_window );
ScreenUpdates_process();
}
}
else if ( g_wait.m_window.visible() ) {
g_wait.m_label.text(message);
+ if ( GTK_IS_WINDOW(g_wait.m_window) ) {
+ gtk_grab_add(g_wait.m_window);
+ }
ScreenUpdates_process();
}
g_wait_stack.push_back( message );
create_menu_item_with_mnemonic( camera_menu, "Far Clip Plane In", "CubicClipZoomIn" );
create_menu_item_with_mnemonic( camera_menu, "Far Clip Plane Out", "CubicClipZoomOut" );
menu_separator( camera_menu );
+ create_menu_item_with_mnemonic( camera_menu, "Decrease FOV", "FOVDec" );
+ create_menu_item_with_mnemonic( camera_menu, "Increase FOV", "FOVInc" );
+ menu_separator( camera_menu );
create_menu_item_with_mnemonic( camera_menu, "Next leak spot", "NextLeakSpot" );
create_menu_item_with_mnemonic( camera_menu, "Previous leak spot", "PrevLeakSpot" );
menu_separator( camera_menu );
create_menu_item_with_mnemonic( menu, "Bug report", makeCallbackF(OpenBugReportURL) );
create_menu_item_with_mnemonic( menu, "Shortcuts list", makeCallbackF(DoCommandListDlg) );
- create_menu_item_with_mnemonic( menu, "_About", makeCallbackF(DoAbout) );
+ create_menu_item_with_mnemonic( menu, "_About...", makeCallbackF(DoAbout) );
return help_menu_item;
}
for ( std::vector<ui::Widget>::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i )
{
+#ifndef WORKAROUND_MACOS_GTK2_DESTROY
i->destroy();
+#endif
}
+#ifndef WORKAROUND_MACOS_GTK2_DESTROY
m_window.destroy();
+#endif
}
void MainFrame::SetActiveXY( XYWnd* p ){
WindowPositionTracker g_posYZWnd;
static gint mainframe_delete( ui::Widget widget, GdkEvent *event, gpointer data ){
- if ( ConfirmModified( "Exit Radiant" ) ) {
+ if ( ConfirmModified( "Exit " RADIANT_NAME ) ) {
gtk_main_quit();
}
return TRUE;
}
+PanedState g_single_hpaned = { 0.75f, -1, };
+PanedState g_single_vpaned = { 0.75f, -1, };
+
void MainFrame::Create(){
ui::Window window = ui::Window( ui::window_type::TOP );
window.show();
- if ( CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft ) {
+ if ( CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft )
+ {
{
ui::Widget hsplit = ui::HPaned(ui::New);
m_vSplit = hsplit;
vbox.pack_start( hsplit, TRUE, TRUE, 0 );
hsplit.show();
{
- ui::Widget vsplit = ui::VPaned(ui::New);
+ ui::Widget vsplit = ui::VPaned(ui::New);
vsplit.show();
- m_vSplit = vsplit;
+ m_vSplit = vsplit;
ui::Widget vsplit2 = ui::VPaned(ui::New);
vsplit2.show();
m_vSplit = vsplit2;
gtk_paned_add1( GTK_PANED( hsplit ), vsplit2 );
}
- // console
- ui::Widget console_window = Console_constructWindow( window );
- gtk_paned_pack2( GTK_PANED( vsplit ), console_window, FALSE, TRUE );
-
+ // console
+ ui::Widget console_window = Console_constructWindow( window );
+ gtk_paned_pack2( GTK_PANED( vsplit ), console_window, FALSE, TRUE );
+
// xy
m_pXYWnd = new XYWnd();
m_pXYWnd->SetViewType( XY );
gtk_paned_set_position( GTK_PANED( m_vSplit2 ), g_layout_globals.nCamHeight );
}
- else if ( CurrentStyle() == eFloating ) {
+ else if ( CurrentStyle() == eFloating )
+ {
{
ui::Window window = ui::Window(create_persistent_floating_window( "Camera", m_window ));
global_accel_connect_window( window );
}
CamWnd_setParent( *m_pCamWnd, window );
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, CamWnd_getWidget( *m_pCamWnd ) );
+
g_floating_windows.push_back( window );
}
}
XY_Top_Shown_Construct( window );
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXYWnd->GetWidget() );
+
g_floating_windows.push_back( window );
}
XZ_Front_Shown_Construct( window );
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXZWnd->GetWidget() );
+
g_floating_windows.push_back( window );
}
YZ_Side_Shown_Construct( window );
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pYZWnd->GetWidget() );
+
g_floating_windows.push_back( window );
}
{
auto frame = create_framed_widget( TextureBrowser_constructWindow( GroupDialog_getWindow() ) );
g_page_textures = GroupDialog_addPage( "Textures", frame, TextureBrowserExportTitleCaller() );
+
+ WORKAROUND_GOBJECT_SET_GLWIDGET( GroupDialog_getWindow(), TextureBrowser_getGLWidget() );
}
GroupDialog_show();
}
- else // 4 way
+ else if ( CurrentStyle() == eSplit )
{
m_pCamWnd = NewCamWnd();
GlobalCamera_setCamWnd( *m_pCamWnd );
{
auto frame = create_framed_widget( TextureBrowser_constructWindow( window ) );
g_page_textures = GroupDialog_addPage( "Textures", frame, TextureBrowserExportTitleCaller() );
+
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, TextureBrowser_getGLWidget() );
}
}
+ else // single window
+ {
+ m_pCamWnd = NewCamWnd();
+ GlobalCamera_setCamWnd( *m_pCamWnd );
+ CamWnd_setParent( *m_pCamWnd, window );
+
+ ui::Widget camera = CamWnd_getWidget( *m_pCamWnd );
+
+ m_pYZWnd = new XYWnd();
+ m_pYZWnd->SetViewType( YZ );
+
+ ui::Widget yz = m_pYZWnd->GetWidget();
+
+ m_pXYWnd = new XYWnd();
+ m_pXYWnd->SetViewType( XY );
+
+ ui::Widget xy = m_pXYWnd->GetWidget();
+
+ m_pXZWnd = new XYWnd();
+ m_pXZWnd->SetViewType( XZ );
+
+ ui::Widget xz = m_pXZWnd->GetWidget();
+
+ ui::Widget hsplit = ui::HPaned(ui::New);
+ vbox.pack_start( hsplit, TRUE, TRUE, 0 );
+ hsplit.show();
+
+ ui::Widget split = create_split_views( camera, yz, xy, xz );
+
+ ui::Widget vsplit = ui::VPaned(ui::New);
+ vsplit.show();
+
+ // textures
+ ui::Widget texture_window = create_framed_widget( TextureBrowser_constructWindow( window ) );
+
+ // console
+ ui::Widget console_window = create_framed_widget( Console_constructWindow( window ) );
+
+ gtk_paned_add1( GTK_PANED( hsplit ), split );
+ gtk_paned_add2( GTK_PANED( hsplit ), vsplit );
+
+ gtk_paned_add1( GTK_PANED( vsplit ), texture_window );
+ gtk_paned_add2( GTK_PANED( vsplit ), console_window );
+
+ hsplit.connect( "size_allocate", G_CALLBACK( hpaned_allocate ), &g_single_hpaned );
+ hsplit.connect( "notify::position", G_CALLBACK( paned_position ), &g_single_hpaned );
+
+ vsplit.connect( "size_allocate", G_CALLBACK( vpaned_allocate ), &g_single_vpaned );
+ vsplit.connect( "notify::position", G_CALLBACK( paned_position ), &g_single_vpaned );
+ }
EntityList_constructWindow( window );
PreferencesDialog_constructWindow( window );
}
void Sys_Status( const char* status ){
- if ( g_pParentWnd != 0 ) {
+ if ( g_pParentWnd != nullptr ) {
g_pParentWnd->SetStatusText( g_pParentWnd->m_command_status, status );
}
}
}
void GridStatus_onTextureLockEnabledChanged(){
- if ( g_pParentWnd != 0 ) {
+ if ( g_pParentWnd != nullptr ) {
g_pParentWnd->SetGridStatus();
}
}
void Layout_constructPreferences( PreferencesPage& page ){
{
- const char* layouts[] = { "window1.png", "window2.png", "window3.png", "window4.png" };
+ const char* layouts[] = { "window1.png", "window2.png", "window3.png", "window4.png", "window5.png" };
page.appendRadioIcons(
"Window Layout",
STRING_ARRAY_RANGE( layouts ),
PreferencesDialog_addInterfacePage( makeCallbackF(Layout_constructPage) );
}
-
#include "preferencesystem.h"
#include "stringio.h"
+#include "transformpath/transformpath.h"
void MainFrame_Construct(){
GlobalCommands_insert( "OpenManual", makeCallbackF(OpenHelpURL), Accelerator( GDK_KEY_F1 ) );
GlobalCommands_insert( "ColorSchemeQER", makeCallbackF(ColorScheme_QER) );
GlobalCommands_insert( "ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black) );
GlobalCommands_insert( "ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar) );
+ GlobalCommands_insert("ColorSchemeAdwaitaDark", makeCallbackF(ColorScheme_AdwaitaDark));
GlobalCommands_insert( "ChooseTextureBackgroundColor", makeCallback( g_ColoursMenu.m_textureback ) );
GlobalCommands_insert( "ChooseGridBackgroundColor", makeCallback( g_ColoursMenu.m_xyback ) );
GlobalCommands_insert( "ChooseGridMajorColor", makeCallback( g_ColoursMenu.m_gridmajor ) );
GlobalPreferenceSystem().registerPreference( "YZWnd", make_property<WindowPositionTracker_String>(g_posYZWnd) );
GlobalPreferenceSystem().registerPreference( "XZWnd", make_property<WindowPositionTracker_String>(g_posXZWnd) );
+ GlobalPreferenceSystem().registerPreference( "EnginePath", make_property_string( g_strEnginePath ) );
+ if ( g_strEnginePath.empty() )
{
+ g_strEnginePath_was_empty_1st_start = true;
const char* ENGINEPATH_ATTRIBUTE =
#if GDEF_OS_WINDOWS
"enginepath_win32"
#error "unknown platform"
#endif
;
+
StringOutputStream path( 256 );
path << DirectoryCleaned( g_pGameDescription->getRequiredKeyValue( ENGINEPATH_ATTRIBUTE ) );
- g_strEnginePath = path.c_str();
+
+ g_strEnginePath = transformPath( path.c_str() ).c_str();
+ GlobalPreferenceSystem().registerPreference( "EnginePath", make_property_string( g_strEnginePath ) );
}
- GlobalPreferenceSystem().registerPreference( "EnginePath", make_property_string( g_strEnginePath ) );
-
GlobalPreferenceSystem().registerPreference( "DisableEnginePath", make_property_string( g_disableEnginePath ) );
GlobalPreferenceSystem().registerPreference( "DisableHomePath", make_property_string( g_disableHomePath ) );
g_entityCount.setCountChangedCallback( makeCallbackF(QE_entityCountChanged) );
GlobalEntityCreator().setCounter( &g_entityCount );
- GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated;
- GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed;
+ glwidget_set_shared_context_constructors( GlobalGL_sharedContextCreated, GlobalGL_sharedContextDestroyed);
GlobalEntityClassManager().attach( g_WorldspawnColourEntityClassObserver );
}
void GLWindow_Destroy(){
}
+
+/* HACK: If ui::main is not called yet,
+gtk_main_quit will not quit, so tell main
+to not call ui::main. This happens when a
+map is loaded from command line and require
+a restart because of wrong format.
+Delete this when the code to not have to
+restart to load another format is merged. */
+extern bool g_dontStart;
+
+void Radiant_Restart(){
+ // preferences are expected to be already saved in any way
+ // this is just to be sure and be future proof
+ Preferences_Save();
+
+ // this asks user for saving if map is modified
+ // user can chose to not save, it's ok
+ ConfirmModified( "Restart " RADIANT_NAME );
+
+ int status;
+
+ char *argv[ 3 ];
+ char exe_file[ 256 ];
+ char map_file[ 256 ];
+ bool with_map = false;
+
+ strncpy( exe_file, g_strAppFilePath.c_str(), 256 );
+
+ if ( !Map_Unnamed( g_map ) ) {
+ strncpy( map_file, Map_Name( g_map ), 256 );
+ with_map = true;
+ }
+
+ argv[ 0 ] = exe_file;
+ argv[ 1 ] = with_map ? map_file : NULL;
+ argv[ 2 ] = NULL;
+
+#if GDEF_OS_WINDOWS
+ status = !_spawnvpe( P_NOWAIT, exe_file, argv, environ );
+#else
+ pid_t pid;
+
+ status = posix_spawn( &pid, exe_file, NULL, NULL, argv, environ );
+#endif
+
+ // quit if radiant successfully started
+ if ( status == 0 ) {
+ gtk_main_quit();
+ /* HACK: If ui::main is not called yet,
+ gtk_main_quit will not quit, so tell main
+ to not call ui::main. This happens when a
+ map is loaded from command line and require
+ a restart because of wrong format.
+ Delete this when the code to not have to
+ restart to load another format is merged. */
+ g_dontStart = true;
+ }
+}
MRU_AddFile( filename );
g_strLastMapFolder = g_path_get_dirname( filename );
+ bool switch_format = false;
+
{
ScopeTimer timer( "map load" );
if ( !format->wrongFormat ) {
break;
}
+ switch_format = !switch_format;
}
}
Map_StartPosition();
g_currentMap = &g_map;
+
+ Brush_switchFormat( switch_format );
}
class Excluder
const char *type = GlobalRadiant().getGameDescriptionKeyValue( "q3map2_type" );
int n = string_length( path_get_extension( filename ) );
if ( n && ( extension_equal( path_get_extension( filename ), "bsp" ) || extension_equal( path_get_extension( filename ), "map" ) ) ) {
- StringBuffer output;
- output.push_string( AppPath_get() );
- output.push_string( "q3map2." );
- output.push_string( RADIANT_EXECUTABLE );
- output.push_string( " -v -game " );
- output.push_string( ( type && *type ) ? type : "quake3" );
- output.push_string( " -fs_basepath \"" );
- output.push_string( EnginePath_get() );
- output.push_string( "\" -fs_homepath \"" );
- output.push_string( g_qeglobals.m_userEnginePath.c_str() );
- output.push_string( "\"" );
+ std::string output;
+ output += AppPath_get();
+ output += "q3map2";
+ output += GDEF_OS_EXE_EXT;
+
+ output += " -v -game ";
+ output += ( type && *type ) ? type : "quake3";
+ output += " -fs_basepath \"";
+ output += EnginePath_get();
+ output += "\" -fs_homepath \"";
+ output += g_qeglobals.m_userEnginePath.c_str();
+ output += "\"";
// extra pakpaths
for ( int i = 0; i < g_pakPathCount; i++ ) {
if ( g_strcmp0( g_strPakPath[i].c_str(), "") ) {
- output.push_string( " -fs_pakpath \"" );
- output.push_string( g_strPakPath[i].c_str() );
- output.push_string( "\"" );
+ output += " -fs_pakpath \"";
+ output += g_strPakPath[i].c_str();
+ output += "\"";
}
}
// extra switches
if ( g_disableEnginePath ) {
- output.push_string( " -fs_nobasepath " );
+ output += " -fs_nobasepath ";
}
if ( g_disableHomePath ) {
- output.push_string( " -fs_nohomepath " );
+ output += " -fs_nohomepath ";
}
- output.push_string( " -fs_game " );
- output.push_string( gamename_get() );
- output.push_string( " -convert -format " );
- output.push_string( Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map" );
+ output += " -fs_game ";
+ output += gamename_get();
+ output += " -convert -format ";
+ output += Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map";
if ( extension_equal( path_get_extension( filename ), "map" ) ) {
- output.push_string( " -readmap " );
+ output += " -readmap ";
}
- output.push_string( " \"" );
- output.push_string( filename );
- output.push_string( "\"" );
+ output += " \"";
+ output += filename;
+ output += "\"";
// run
Q_Exec( NULL, output.c_str(), NULL, false, true );
// rebuild filename as "filenamewithoutext_converted.map"
- output.clear();
- output.push_range( filename, filename + string_length( filename ) - ( n + 1 ) );
- output.push_string( "_converted.map" );
+ output = "";
+ output.append( filename, string_length( filename ) - ( n + 1 ) );
+ output += "_converted.map";
filename = output.c_str();
// open
return MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Selected, filename );
}
-
class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker
{
- scene::Node& m_parent;
+ scene::Node& m_parent;
+ mutable bool m_emptyOldParent;
+
public:
- ParentSelectedBrushesToEntityWalker( scene::Node& parent ) : m_parent( parent ){
+ ParentSelectedBrushesToEntityWalker( scene::Node& parent ) : m_parent( parent ), m_emptyOldParent( false ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get_pointer() != &m_parent
- && Node_isPrimitive( path.top() ) ) {
+ if ( path.top().get_pointer() != &m_parent && ( Node_isPrimitive( path.top() ) || m_emptyOldParent ) ) {
Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected()
- && path.size() > 1 ) {
+ if ( selectable && selectable->isSelected() && path.size() > 1 ) {
return false;
}
}
}
void post( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get_pointer() != &m_parent
- && Node_isPrimitive( path.top() ) ) {
+ if ( path.top().get_pointer() == &m_parent )
+ return;
+
+ if ( Node_isPrimitive( path.top() ) ){
+ m_emptyOldParent = false;
Selectable* selectable = Instance_getSelectable( instance );
- if ( selectable != 0
- && selectable->isSelected()
- && path.size() > 1 ) {
+
+ if ( selectable && selectable->isSelected() && path.size() > 1 ){
scene::Node& parent = path.parent();
- if ( &parent != &m_parent ) {
+ if ( &parent != &m_parent ){
NodeSmartReference node( path.top().get() );
- Node_getTraversable( parent )->erase( node );
+ scene::Traversable* traversable_parent = Node_getTraversable( parent );
+ traversable_parent->erase( node );
Node_getTraversable( m_parent )->insert( node );
+ if ( traversable_parent->empty() )
+ m_emptyOldParent = true;
}
}
}
+ else if ( m_emptyOldParent ){
+ m_emptyOldParent = false;
+ // delete empty entities
+ Entity* entity = Node_getEntity( path.top() );
+ if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map ) && Node_getTraversable( path.top() )->empty() ) {
+ Path_deleteTop( path );
+ }
+ }
}
};
void TextureGroups_addWad( TextureGroups& groups, const char* archive ){
if ( extension_equal( path_get_extension( archive ), "wad" ) ) {
-#if 1
groups.insert( archive );
-#else
- CopiedString archiveBaseName( path_get_filename_start( archive ), path_get_filename_base_end( archive ) );
- groups.insert( archiveBaseName );
-#endif
}
}
CopiedString shader;
ui::Window m_parent{ui::null};
+#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET
+ui::VBox m_vframe{ui::null};
+ui::VBox m_vfiller{ui::null};
+ui::HBox m_hframe{ui::null};
+ui::HBox m_hfiller{ui::null};
+#else // !WORKAROUND_MACOS_GTK2_GLWIDGET
+ui::VBox m_frame{ui::null};
+#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET
ui::GLArea m_gl_widget{ui::null};
ui::Widget m_texture_scroll{ui::null};
ui::TreeView m_treeViewTree{ui::New};
else if ( tex->width <= m_uniformTextureMinSize ){
*width = m_uniformTextureMinSize;
*height = (int)( m_uniformTextureMinSize * ( (float)tex->height / tex->width ) );
- }
- else {
+ }
+ else {
*width = tex->width;
*height = tex->height;
- }
+ }
}
else {
// Texture taller than it is wide
}
*/
- void getTextureWH( qtexture_t* tex, int *width, int *height ){
+ void getTextureWH( qtexture_t* tex, int &W, int &H ){
// Don't use uniform size
- *width = (int)( tex->width * ( (float)m_textureScale / 100 ) );
- *height = (int)( tex->height * ( (float)m_textureScale / 100 ) );
+ W = (int)( tex->width * ( (float)m_textureScale / 100 ) );
+ H = (int)( tex->height * ( (float)m_textureScale / 100 ) );
if ( g_TextureBrowser_fixedSize ){
- int W = *width;
- int H = *height;
if ( W >= H ) {
// Texture is square, or wider than it is tall
if ( W >= m_uniformTextureSize ){
- *width = m_uniformTextureSize;
- *height = m_uniformTextureSize * H / W;
- }
+ H = m_uniformTextureSize * H / W;
+ W = m_uniformTextureSize;
+ }
else if ( W <= m_uniformTextureMinSize ){
- *width = m_uniformTextureMinSize;
- *height = m_uniformTextureMinSize * H / W;
+ H = m_uniformTextureMinSize * H / W;
+ W = m_uniformTextureMinSize;
}
- }
- else {
+ }
+ else {
// Texture taller than it is wide
if ( H >= m_uniformTextureSize ){
- *height = m_uniformTextureSize;
- *width = m_uniformTextureSize * W / H;
- }
+ W = m_uniformTextureSize * W / H;
+ H = m_uniformTextureSize;
+ }
else if ( H <= m_uniformTextureMinSize ){
- *height = m_uniformTextureMinSize;
- *width = m_uniformTextureMinSize * W / H;
+ W = m_uniformTextureMinSize * W / H;
+ H = m_uniformTextureMinSize;
}
}
}
void TextureBrowser_updateScroll( TextureBrowser& textureBrowser );
-const char* TextureBrowser_getComonShadersName(){
+const char* TextureBrowser_getCommonShadersName(){
const char* value = g_pGameDescription->getKeyValue( "common_shaders_name" );
if ( !string_empty( value ) ) {
return value;
return "Common";
}
-const char* TextureBrowser_getComonShadersDir(){
+const char* TextureBrowser_getCommonShadersDir(){
const char* value = g_pGameDescription->getKeyValue( "common_shaders_dir" );
if ( !string_empty( value ) ) {
return value;
qtexture_t* q = current_texture;
int nWidth, nHeight;
- textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+ textureBrowser.getTextureWH( q, nWidth, nHeight );
if ( layout.current_x + nWidth > textureBrowser.width - 8 && layout.current_row ) { // go to the next row unless the texture is the first on the row
layout.current_x = 8;
layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 4;
}
}
else {
- if ( !shader_equal_prefix( shader_get_textureName( shader->getName() ), g_TextureBrowser_currentDirectory.c_str() ) ) {
+ if ( TextureBrowser_showWads() )
+ {
+ if ( g_TextureBrowser_currentDirectory != ""
+ && !string_equal( shader->getWadName(), g_TextureBrowser_currentDirectory.c_str() ) )
+ {
+ return false;
+ }
+ }
+ else if ( !shader_equal_prefix( shader_get_textureName( shader->getName() ), g_TextureBrowser_currentDirectory.c_str() ) ) {
return false;
}
}
int x, y;
Texture_NextPos( textureBrowser, layout, shader->getTexture(), &x, &y );
int nWidth, nHeight;
- textureBrowser.getTextureWH( shader->getTexture(), &nWidth, &nHeight );
+ textureBrowser.getTextureWH( shader->getTexture(), nWidth, nHeight );
textureBrowser.m_nTotalHeight = std::max( textureBrowser.m_nTotalHeight, abs( layout.current_y ) + TextureBrowser_fontHeight( textureBrowser ) + nHeight + 4 );
}
}
void visit( const char* name ){
IShader* shader = QERApp_Shader_ForName( CopiedString( StringRange( name, path_get_filename_base_end( name ) ) ).c_str() );
shader->DecRef();
+ shader->setWadName( g_TextureBrowser_currentDirectory.c_str() );
}
};
};
void TextureDirectory_loadTexture( const char* directory, const char* texture ){
+ // Doom3-like dds/ prefix (used by DarkPlaces).
+ // When we list dds/textures/ folder,
+ // store the texture names without dds/ prefix.
+ if ( !strncmp( "dds/", directory, 4 ) )
+ {
+ directory = &directory[ 4 ];
+ }
+
StringOutputStream name( 256 );
name << directory << StringRange( texture, path_get_filename_base_end( texture ) );
void TextureBrowser_ShowDirectory( TextureBrowser& textureBrowser, const char* directory ){
if ( TextureBrowser_showWads() ) {
+ g_TextureBrowser_currentDirectory = directory;
+ TextureBrowser_heightChanged( textureBrowser );
+
Archive* archive = GlobalFileSystem().getArchive( directory );
- ASSERT_NOTNULL( archive );
+ if ( archive != nullptr )
+ {
LoadShaderVisitor visitor;
archive->forEachFile( Archive::VisitorFunc( visitor, Archive::eFiles, 0 ), "textures/" );
+
+ // Doom3-like dds/ prefix (used by DarkPlaces).
+ archive->forEachFile( Archive::VisitorFunc( visitor, Archive::eFiles, 0 ), "dds/textures/" );
+ }
+ else if ( extension_equal_i( path_get_extension( directory ), "wad" ) )
+ {
+ globalErrorStream() << "Failed to load " << directory << "\n";
+ }
}
else
{
StringOutputStream dirstring( 64 );
dirstring << "textures/" << directory;
- Radiant_getImageModules().foreachModule( LoadTexturesByTypeVisitor( dirstring.c_str() ) );
+ {
+ LoadTexturesByTypeVisitor visitor( dirstring.c_str() );
+ Radiant_getImageModules().foreachModule( visitor );
+ }
+
+ // Doom3-like dds/ prefix (used by DarkPlaces).
+ dirstring.clear();
+ dirstring << "dds/textures/" << directory;
+
+ {
+ LoadTexturesByTypeVisitor visitor( dirstring.c_str() );
+ Radiant_getImageModules().foreachModule( visitor );
+ }
}
}
LoadTexturesByTypeVisitor visitor( dirstring.c_str() );
Radiant_getImageModules().foreachModule( visitor );
}
+
+ // Doom3-like dds/ prefix (used by DarkPlaces).
+ dirstring.clear();
+ dirstring << "dds/textures/" << directory;
+
+ {
+ LoadTexturesByTypeVisitor visitor( dirstring.c_str() );
+ Radiant_getImageModules().foreachModule( visitor );
+ }
}
// we'll display the newly loaded textures + all the ones already in use
void TextureBrowser_ShowStartupShaders( TextureBrowser& textureBrowser ){
if ( textureBrowser.m_startupShaders == STARTUPSHADERS_COMMON ) {
- TextureBrowser_ShowDirectory( textureBrowser, TextureBrowser_getComonShadersDir() );
+ TextureBrowser_ShowDirectory( textureBrowser, TextureBrowser_getCommonShadersDir() );
}
}
}
int nWidth, nHeight;
- textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+ textureBrowser.getTextureWH( q, nWidth, nHeight );
if ( mx > x && mx - x < nWidth
&& my < y && y - my < nHeight + TextureBrowser_fontHeight( textureBrowser ) ) {
return shader;
}
void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){
- textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, TextureBrowser_trackingDelta, &textureBrowser );
+ textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser );
}
void TextureBrowser_Tracking_MouseUp( TextureBrowser& textureBrowser ){
- textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_parent );
+ textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_gl_widget );
}
void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
textureBrowser.color_textureback[1],
textureBrowser.color_textureback[2],
0 );
+
glViewport( 0, 0, textureBrowser.width, textureBrowser.height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
}
int nWidth, nHeight;
- textureBrowser.getTextureWH( q, &nWidth, &nHeight );
+ textureBrowser.getTextureWH( q, nWidth, nHeight );
if ( y != last_y ) {
last_y = y;
gboolean TextureBrowser_button_press( ui::Widget widget, GdkEventButton* event, TextureBrowser* textureBrowser ){
if ( event->type == GDK_BUTTON_PRESS ) {
if ( event->button == 3 ) {
- if ( GlobalTextureBrowser().m_tags ) {
+ if ( textureBrowser->m_tags ) {
textureBrowser->m_rmbSelected = true;
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
else if ( event->button == 1 ) {
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
- if ( GlobalTextureBrowser().m_tags ) {
+ if ( textureBrowser->m_tags ) {
textureBrowser->m_rmbSelected = false;
textureBrowser->m_tag_frame.hide();
}
gboolean TextureBrowser_button_release( ui::Widget widget, GdkEventButton* event, TextureBrowser* textureBrowser ){
if ( event->type == GDK_BUTTON_RELEASE ) {
if ( event->button == 3 ) {
- if ( !GlobalTextureBrowser().m_tags ) {
+ if ( !textureBrowser->m_tags ) {
TextureBrowser_Tracking_MouseUp( *textureBrowser );
}
}
return FALSE;
}
-gboolean TextureBrowser_expose( ui::Widget widget, GdkEventExpose* event, TextureBrowser* textureBrowser ){
+void TextureBrowser_redraw( TextureBrowser* textureBrowser ){
if ( glwidget_make_current( textureBrowser->m_gl_widget ) != FALSE ) {
GlobalOpenGL_debugAssertNoErrors();
TextureBrowser_evaluateHeight( *textureBrowser );
GlobalOpenGL_debugAssertNoErrors();
glwidget_swap_buffers( textureBrowser->m_gl_widget );
}
- return FALSE;
}
-
-TextureBrowser g_TextureBrowser;
+gboolean TextureBrowser_expose( ui::Widget widget, GdkEventExpose* event, TextureBrowser* textureBrowser ){
+ TextureBrowser_redraw( textureBrowser );
+ return FALSE;
+}
TextureBrowser& GlobalTextureBrowser(){
- return g_TextureBrowser;
+ static TextureBrowser textureBrowser;
+ return textureBrowser;
}
bool TextureBrowser_hideUnused(){
- return g_TextureBrowser.m_hideUnused;
+ return GlobalTextureBrowser().m_hideUnused;
}
void TextureBrowser_ToggleHideUnused(){
- if ( g_TextureBrowser.m_hideUnused ) {
- TextureBrowser_SetHideUnused( g_TextureBrowser, false );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ if ( textureBrowser.m_hideUnused ) {
+ TextureBrowser_SetHideUnused( textureBrowser, false );
}
else
{
- TextureBrowser_SetHideUnused( g_TextureBrowser, true );
+ TextureBrowser_SetHideUnused( textureBrowser, true );
+ }
+}
+
+const char* TextureGroups_transformDirName( const char* dirName, StringOutputStream *archiveName )
+{
+ if ( TextureBrowser_showWads() ) {
+ archiveName->clear();
+ *archiveName << StringRange( path_get_filename_start( dirName ), path_get_filename_base_end( dirName ) ) \
+ << "." << path_get_extension( dirName );
+ return archiveName->c_str();
}
+ return dirName;
}
void TextureGroups_constructTreeModel( TextureGroups groups, ui::TreeStore store ){
TextureGroups::const_iterator i = groups.begin();
while ( i != groups.end() )
{
- const char* dirName = ( *i ).c_str();
+ StringOutputStream archiveName;
+ StringOutputStream nextArchiveName;
+ const char* dirName = TextureGroups_transformDirName( ( *i ).c_str(), &archiveName );
+
const char* firstUnderscore = strchr( dirName, '_' );
StringRange dirRoot( dirName, ( firstUnderscore == 0 ) ? dirName : firstUnderscore + 1 );
TextureGroups::const_iterator next = i;
++next;
+
if ( firstUnderscore != 0
&& next != groups.end()
- && string_equal_start( ( *next ).c_str(), dirRoot ) ) {
+ && string_equal_start( TextureGroups_transformDirName( ( *next ).c_str(), &nextArchiveName ), dirRoot ) ) {
gtk_tree_store_append( store, &iter, NULL );
gtk_tree_store_set( store, &iter, 0, CopiedString( StringRange( dirName, firstUnderscore ) ).c_str(), -1 );
// keep going...
- while ( i != groups.end() && string_equal_start( ( *i ).c_str(), dirRoot ) )
+ while ( i != groups.end() && string_equal_start( TextureGroups_transformDirName( ( *i ).c_str(), &nextArchiveName ), dirRoot ) )
{
gtk_tree_store_append( store, &child, &iter );
- gtk_tree_store_set( store, &child, 0, ( *i ).c_str(), -1 );
+ gtk_tree_store_set( store, &child, 0, TextureGroups_transformDirName( ( *i ).c_str(), &nextArchiveName ), -1 );
++i;
}
}
auto store = ui::TreeStore::from(gtk_tree_store_new( 1, G_TYPE_STRING ));
TextureGroups_constructTreeModel( groups, store );
- gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTree, store);
+ gtk_tree_view_set_model(GlobalTextureBrowser().m_treeViewTree, store);
g_object_unref( G_OBJECT( store ) );
}
void TextureBrowser_constructTreeStoreTags(){
TextureGroups groups;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
auto store = ui::TreeStore::from(gtk_tree_store_new( 1, G_TYPE_STRING ));
- auto model = g_TextureBrowser.m_all_tags_list;
+ auto model = GlobalTextureBrowser().m_all_tags_list;
- gtk_tree_view_set_model(g_TextureBrowser.m_treeViewTags, model );
+ gtk_tree_view_set_model(GlobalTextureBrowser().m_treeViewTags, model );
g_object_unref( G_OBJECT( store ) );
}
strcpy( dirName, buffer );
g_free( buffer );
- g_TextureBrowser.m_searchedTags = false;
+ GlobalTextureBrowser().m_searchedTags = false;
if ( !TextureBrowser_showWads() ) {
strcat( dirName, "/" );
}
void TextureBrowser_createTreeViewTree(){
- gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTree, FALSE );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ gtk_tree_view_set_enable_search(textureBrowser.m_treeViewTree, FALSE );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTree, FALSE );
- g_TextureBrowser.m_treeViewTree.connect( "row-activated", (GCallback) TreeView_onRowActivated, NULL );
+ gtk_tree_view_set_headers_visible(textureBrowser.m_treeViewTree, FALSE );
+ textureBrowser.m_treeViewTree.connect( "row-activated", (GCallback) TreeView_onRowActivated, NULL );
auto renderer = ui::CellRendererText(ui::New);
- gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTree, -1, "", renderer, "text", 0, NULL );
+ gtk_tree_view_insert_column_with_attributes(textureBrowser.m_treeViewTree, -1, "", renderer, "text", 0, NULL );
TextureBrowser_constructTreeStore();
}
}
void TextureBrowser_createTreeViewTags(){
- g_TextureBrowser.m_treeViewTags = ui::TreeView(ui::New);
- gtk_tree_view_set_enable_search(g_TextureBrowser.m_treeViewTags, FALSE );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_treeViewTags = ui::TreeView(ui::New);
+ gtk_tree_view_set_enable_search(textureBrowser.m_treeViewTags, FALSE );
- g_TextureBrowser.m_treeViewTags.connect( "button-press-event", (GCallback)TreeViewTags_onButtonPressed, NULL );
+ textureBrowser.m_treeViewTags.connect( "button-press-event", (GCallback)TreeViewTags_onButtonPressed, NULL );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_treeViewTags, FALSE );
+ gtk_tree_view_set_headers_visible(textureBrowser.m_treeViewTags, FALSE );
auto renderer = ui::CellRendererText(ui::New);
- gtk_tree_view_insert_column_with_attributes(g_TextureBrowser.m_treeViewTags, -1, "", renderer, "text", 0, NULL );
+ gtk_tree_view_insert_column_with_attributes(textureBrowser.m_treeViewTags, -1, "", renderer, "text", 0, NULL );
TextureBrowser_constructTreeStoreTags();
}
ui::MenuItem TextureBrowser_constructViewMenu( ui::Menu menu ){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
ui::MenuItem textures_menu_item = ui::MenuItem(new_sub_menu_item_with_mnemonic( "_View" ));
if ( g_Layout_enableDetachableMenus.m_value ) {
create_menu_item_with_mnemonic( menu, "Show All", "ShowAllTextures" );
// we always want to show shaders but don't want a "Show Shaders" menu for doom3 and .wad file games
- if ( g_pGameDescription->mGameType == "doom3" || !string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
- g_TextureBrowser.m_showShaders = true;
+ if ( g_pGameDescription->mGameType == "doom3" || TextureBrowser_showWads() ) {
+ textureBrowser.m_showShaders = true;
}
else
{
if ( g_pGameDescription->mGameType != "doom3" && string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
create_check_menu_item_with_mnemonic( menu, "Shaders Only", "ToggleShowShaderlistOnly" );
}
- if ( g_TextureBrowser.m_tags ) {
+ if ( textureBrowser.m_tags ) {
create_menu_item_with_mnemonic( menu, "Show Untagged", "ShowUntagged" );
}
if ( string_empty( g_pGameDescription->getKeyValue( "show_wads" ) ) ) {
menu_separator( menu );
- g_TextureBrowser.m_shader_info_item = ui::Widget(create_menu_item_with_mnemonic( menu, "Shader Info", "ShaderInfo" ));
- gtk_widget_set_sensitive( g_TextureBrowser.m_shader_info_item, FALSE );
+ textureBrowser.m_shader_info_item = ui::Widget(create_menu_item_with_mnemonic( menu, "Shader Info", "ShaderInfo" ));
+ gtk_widget_set_sensitive( textureBrowser.m_shader_info_item, FALSE );
}
return textures_menu_item;
}
-gboolean TextureBrowser_tagMoveHelper( ui::TreeModel model, ui::TreePath path, GtkTreeIter iter, GSList** selected ){
+gboolean TextureBrowser_tagMoveHelper( ui::TreeModel model, ui::TreePath path, GtkTreeIter* iter, GSList** selected ){
g_assert( selected != NULL );
auto rowref = gtk_tree_row_reference_new( model, path );
GSList* selected = NULL;
GSList* node;
gchar* tag_assigned;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_available_tree );
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
if ( path ) {
GtkTreeIter iter;
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_available_store, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, &tag_assigned, -1 );
- if ( !TagBuilder.CheckShaderTag( g_TextureBrowser.shader.c_str() ) ) {
+ if ( gtk_tree_model_get_iter(textureBrowser.m_available_store, &iter, path ) ) {
+ gtk_tree_model_get(textureBrowser.m_available_store, &iter, TAG_COLUMN, &tag_assigned, -1 );
+ if ( !TagBuilder.CheckShaderTag( textureBrowser.shader.c_str() ) ) {
// create a custom shader/texture entry
- IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
+ IShader* ishader = QERApp_Shader_ForName( textureBrowser.shader.c_str() );
CopiedString filename = ishader->getShaderFileName();
if ( filename.empty() ) {
// it's a texture
- TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, TEXTURE );
+ TagBuilder.AddShaderNode( textureBrowser.shader.c_str(), CUSTOM, TEXTURE );
}
else {
// it's a shader
- TagBuilder.AddShaderNode( g_TextureBrowser.shader.c_str(), CUSTOM, SHADER );
+ TagBuilder.AddShaderNode( textureBrowser.shader.c_str(), CUSTOM, SHADER );
}
ishader->DecRef();
}
- TagBuilder.AddShaderTag( g_TextureBrowser.shader.c_str(), (char*)tag_assigned, TAG );
+ TagBuilder.AddShaderTag( textureBrowser.shader.c_str(), (char*)tag_assigned, TAG );
- gtk_list_store_remove( g_TextureBrowser.m_available_store, &iter );
- g_TextureBrowser.m_assigned_store.append(TAG_COLUMN, tag_assigned);
+ gtk_list_store_remove( textureBrowser.m_available_store, &iter );
+ textureBrowser.m_assigned_store.append(TAG_COLUMN, tag_assigned);
}
}
}
GSList* selected = NULL;
GSList* node;
gchar* tag;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_assigned_tree );
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
if ( path ) {
GtkTreeIter iter;
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_assigned_store, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_assigned_store, &iter, TAG_COLUMN, &tag, -1 );
- TagBuilder.DeleteShaderTag( g_TextureBrowser.shader.c_str(), tag );
- gtk_list_store_remove( g_TextureBrowser.m_assigned_store, &iter );
+ if ( gtk_tree_model_get_iter(textureBrowser.m_assigned_store, &iter, path ) ) {
+ gtk_tree_model_get(textureBrowser.m_assigned_store, &iter, TAG_COLUMN, &tag, -1 );
+ TagBuilder.DeleteShaderTag( textureBrowser.shader.c_str(), tag );
+ gtk_list_store_remove( textureBrowser.m_assigned_store, &iter );
}
}
}
g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
// Update the "available tags list"
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
+ BuildStoreAvailableTags( textureBrowser.m_available_store, textureBrowser.m_assigned_store, textureBrowser.m_all_tags, &textureBrowser );
// Save changes
TagBuilder.SaveXmlDoc();
}
void TextureBrowser_buildTagList(){
- g_TextureBrowser.m_all_tags_list.clear();
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_all_tags_list.clear();
std::set<CopiedString>::iterator iter;
- for ( iter = g_TextureBrowser.m_all_tags.begin(); iter != g_TextureBrowser.m_all_tags.end(); ++iter )
+ for ( iter = textureBrowser.m_all_tags.begin(); iter != textureBrowser.m_all_tags.end(); ++iter )
{
- g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, (*iter).c_str());
+ textureBrowser.m_all_tags_list.append(TAG_COLUMN, (*iter).c_str());
}
}
gchar* tag;
char buffer[256];
char tags_searched[256];
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_treeViewTags );
gtk_tree_selection_selected_foreach( selection, (GtkTreeSelectionForeachFunc)TextureBrowser_tagMoveHelper, &selected );
if ( path ) {
GtkTreeIter iter;
- if ( gtk_tree_model_get_iter(g_TextureBrowser.m_all_tags_list, &iter, path ) ) {
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iter, TAG_COLUMN, &tag, -1 );
+ if ( gtk_tree_model_get_iter(textureBrowser.m_all_tags_list, &iter, path ) ) {
+ gtk_tree_model_get(textureBrowser.m_all_tags_list, &iter, TAG_COLUMN, &tag, -1 );
strcat( buffer, tag );
strcat( tags_searched, tag );
g_slist_foreach( selected, (GFunc)gtk_tree_row_reference_free, NULL );
- g_TextureBrowser.m_found_shaders.clear(); // delete old list
- TagBuilder.TagSearch( buffer, g_TextureBrowser.m_found_shaders );
+ textureBrowser.m_found_shaders.clear(); // delete old list
+ TagBuilder.TagSearch( buffer, textureBrowser.m_found_shaders );
- if ( !g_TextureBrowser.m_found_shaders.empty() ) { // found something
- size_t shaders_found = g_TextureBrowser.m_found_shaders.size();
+ if ( !textureBrowser.m_found_shaders.empty() ) { // found something
+ size_t shaders_found = textureBrowser.m_found_shaders.size();
globalOutputStream() << "Found " << (unsigned int)shaders_found << " textures and shaders with " << tags_searched << "\n";
ScopeDisableScreenUpdates disableScreenUpdates( "Searching...", "Loading Textures" );
std::set<CopiedString>::iterator iter;
- for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ )
+ for ( iter = textureBrowser.m_found_shaders.begin(); iter != textureBrowser.m_found_shaders.end(); iter++ )
{
std::string path = ( *iter ).c_str();
size_t pos = path.find_last_of( "/", path.size() );
TextureDirectory_loadTexture( path.c_str(), name.c_str() );
}
}
- g_TextureBrowser.m_searchedTags = true;
+ textureBrowser.m_searchedTags = true;
g_TextureBrowser_currentDirectory = tags_searched;
- g_TextureBrowser.m_nTotalHeight = 0;
- TextureBrowser_setOriginY( g_TextureBrowser, 0 );
- TextureBrowser_heightChanged( g_TextureBrowser );
+ textureBrowser.m_nTotalHeight = 0;
+ TextureBrowser_setOriginY( textureBrowser, 0 );
+ TextureBrowser_heightChanged( textureBrowser );
TextureBrowser_updateTitle();
}
g_slist_free( selected );
}
void TextureBrowser_toggleSearchButton(){
- gint page = gtk_notebook_get_current_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ) );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ gint page = gtk_notebook_get_current_page( GTK_NOTEBOOK( textureBrowser.m_tag_notebook ) );
if ( page == 0 ) { // tag page
- gtk_widget_show_all( g_TextureBrowser.m_search_button );
+ gtk_widget_show_all( textureBrowser.m_search_button );
}
else {
- g_TextureBrowser.m_search_button.hide();
+ textureBrowser.m_search_button.hide();
}
}
void TextureBrowser_constructTagNotebook(){
- g_TextureBrowser.m_tag_notebook = ui::Widget::from(gtk_notebook_new());
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_tag_notebook = ui::Widget::from(gtk_notebook_new());
ui::Widget labelTags = ui::Label( "Tags" );
ui::Widget labelTextures = ui::Label( "Textures" );
- gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tree, labelTextures );
- gtk_notebook_append_page( GTK_NOTEBOOK( g_TextureBrowser.m_tag_notebook ), g_TextureBrowser.m_scr_win_tags, labelTags );
+ gtk_notebook_append_page( GTK_NOTEBOOK( textureBrowser.m_tag_notebook ), textureBrowser.m_scr_win_tree, labelTextures );
+ gtk_notebook_append_page( GTK_NOTEBOOK( textureBrowser.m_tag_notebook ), textureBrowser.m_scr_win_tags, labelTags );
- g_TextureBrowser.m_tag_notebook.connect( "switch-page", G_CALLBACK( TextureBrowser_toggleSearchButton ), NULL );
+ textureBrowser.m_tag_notebook.connect( "switch-page", G_CALLBACK( TextureBrowser_toggleSearchButton ), NULL );
- gtk_widget_show_all( g_TextureBrowser.m_tag_notebook );
+ gtk_widget_show_all( textureBrowser.m_tag_notebook );
}
void TextureBrowser_constructSearchButton(){
auto image = ui::Widget::from(gtk_image_new_from_stock( GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR ));
- g_TextureBrowser.m_search_button = ui::Button(ui::New);
- g_TextureBrowser.m_search_button.connect( "clicked", G_CALLBACK( TextureBrowser_searchTags ), NULL );
- gtk_widget_set_tooltip_text(g_TextureBrowser.m_search_button, "Search with selected tags");
- g_TextureBrowser.m_search_button.add(image);
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_search_button = ui::Button(ui::New);
+ textureBrowser.m_search_button.connect( "clicked", G_CALLBACK( TextureBrowser_searchTags ), NULL );
+ gtk_widget_set_tooltip_text(textureBrowser.m_search_button, "Search with selected tags");
+ textureBrowser.m_search_button.add(image);
}
void TextureBrowser_checkTagFile(){
const char SHADERTAG_FILE[] = "shadertags.xml";
CopiedString default_filename, rc_filename;
StringOutputStream stream( 256 );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
stream << LocalRcPath_get();
stream << SHADERTAG_FILE;
rc_filename = stream.c_str();
if ( file_exists( rc_filename.c_str() ) ) {
- g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( rc_filename.c_str() );
+ textureBrowser.m_tags = TagBuilder.OpenXmlDoc( rc_filename.c_str() );
- if ( g_TextureBrowser.m_tags ) {
+ if ( textureBrowser.m_tags ) {
globalOutputStream() << "Loading tag file " << rc_filename.c_str() << ".\n";
}
}
default_filename = stream.c_str();
if ( file_exists( default_filename.c_str() ) ) {
- g_TextureBrowser.m_tags = TagBuilder.OpenXmlDoc( default_filename.c_str(), rc_filename.c_str() );
+ textureBrowser.m_tags = TagBuilder.OpenXmlDoc( default_filename.c_str(), rc_filename.c_str() );
- if ( g_TextureBrowser.m_tags ) {
+ if ( textureBrowser.m_tags ) {
globalOutputStream() << "Loading default tag file " << default_filename.c_str() << ".\n";
}
}
IShader* shadernotex = QERApp_Shader_ForName( DEFAULT_SHADERNOTEX_NAME );
g_notex = notex->getTexture()->name;
+
g_shadernotex = shadernotex->getTexture()->name;
notex->DecRef();
shadernotex->DecRef();
}
+static bool isGLWidgetConstructed = false;
+static bool isWindowConstructed = false;
+
+void TextureBrowser_constructGLWidget(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_gl_widget = glwidget_new( FALSE );
+ g_object_ref( textureBrowser.m_gl_widget._handle );
+
+ gtk_widget_set_events( textureBrowser.m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK );
+ gtk_widget_set_can_focus( textureBrowser.m_gl_widget, true );
+
+ textureBrowser.m_sizeHandler = textureBrowser.m_gl_widget.connect( "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &textureBrowser );
+ textureBrowser.m_exposeHandler = textureBrowser.m_gl_widget.on_render( G_CALLBACK( TextureBrowser_expose ), &textureBrowser );
+
+ textureBrowser.m_gl_widget.connect( "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &textureBrowser );
+ textureBrowser.m_gl_widget.connect( "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &textureBrowser );
+ textureBrowser.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &textureBrowser );
+ textureBrowser.m_gl_widget.connect( "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &textureBrowser );
+
+#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_hframe.pack_start( textureBrowser.m_gl_widget, TRUE, TRUE, 0 );
+#else // !WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_frame.pack_start( textureBrowser.m_gl_widget, TRUE, TRUE, 0 );
+#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET
+
+ textureBrowser.m_gl_widget.show();
+
+ isGLWidgetConstructed = true;
+}
+
ui::Widget TextureBrowser_constructWindow( ui::Window toplevel ){
// The gl_widget and the tag assignment frame should be packed into a GtkVPaned with the slider
// position stored in local.pref. gtk_paned_get_position() and gtk_paned_set_position() don't
// seem to work in gtk 2.4 and the arrow buttons don't handle GTK_FILL, so here's another thing
// for the "once-the-gtk-libs-are-updated-TODO-list" :x
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
TextureBrowser_checkTagFile();
TextureBrowser_SetNotex();
- GlobalShaderSystem().setActiveShadersChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_activeShadersChanged>( g_TextureBrowser ) );
+ GlobalShaderSystem().setActiveShadersChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_activeShadersChanged>( textureBrowser ) );
- g_TextureBrowser.m_parent = toplevel;
+ textureBrowser.m_parent = toplevel;
auto table = ui::Table(3, 3, FALSE);
auto vbox = ui::VBox(FALSE, 0);
menu_bar.show();
}
{ // Texture TreeView
- g_TextureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tree ), 0 );
+ textureBrowser.m_scr_win_tree = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width( GTK_CONTAINER( textureBrowser.m_scr_win_tree ), 0 );
// vertical only scrolling for treeview
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( textureBrowser.m_scr_win_tree ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
- g_TextureBrowser.m_scr_win_tree.show();
+ textureBrowser.m_scr_win_tree.show();
TextureBrowser_createTreeViewTree();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tree ), g_TextureBrowser.m_treeViewTree );
- g_TextureBrowser.m_treeViewTree.show();
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( textureBrowser.m_scr_win_tree ), textureBrowser.m_treeViewTree );
+ textureBrowser.m_treeViewTree.show();
}
{ // gl_widget scrollbar
auto w = ui::Widget::from(gtk_vscrollbar_new( ui::Adjustment( 0,0,0,1,1,0 ) ));
table.attach(w, {2, 3, 1, 2}, {GTK_SHRINK, GTK_FILL});
w.show();
- g_TextureBrowser.m_texture_scroll = w;
+ textureBrowser.m_texture_scroll = w;
- auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment( GTK_RANGE( g_TextureBrowser.m_texture_scroll ) ));
- vadjustment.connect( "value_changed", G_CALLBACK( TextureBrowser_verticalScroll ), &g_TextureBrowser );
+ auto vadjustment = ui::Adjustment::from(gtk_range_get_adjustment( GTK_RANGE( textureBrowser.m_texture_scroll ) ));
+ vadjustment.connect( "value_changed", G_CALLBACK( TextureBrowser_verticalScroll ), &textureBrowser );
- g_TextureBrowser.m_texture_scroll.visible(g_TextureBrowser.m_showTextureScrollbar);
+ textureBrowser.m_texture_scroll.visible(textureBrowser.m_showTextureScrollbar);
}
{ // gl_widget
- g_TextureBrowser.m_gl_widget = glwidget_new( FALSE );
- g_object_ref( g_TextureBrowser.m_gl_widget._handle );
+#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_vframe = ui::VBox( FALSE, 0 );
+ table.attach(textureBrowser.m_vframe, {1, 2, 1, 2});
- gtk_widget_set_events( g_TextureBrowser.m_gl_widget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK );
- gtk_widget_set_can_focus( g_TextureBrowser.m_gl_widget, true );
+ textureBrowser.m_vfiller = ui::VBox( FALSE, 0 );
+ textureBrowser.m_vframe.pack_start( textureBrowser.m_vfiller, FALSE, FALSE, 0 );
- table.attach(g_TextureBrowser.m_gl_widget, {1, 2, 1, 2});
- g_TextureBrowser.m_gl_widget.show();
+ textureBrowser.m_hframe = ui::HBox( FALSE, 0 );
+ textureBrowser.m_vframe.pack_start( textureBrowser.m_hframe, TRUE, TRUE, 0 );
- g_TextureBrowser.m_sizeHandler = g_TextureBrowser.m_gl_widget.connect( "size_allocate", G_CALLBACK( TextureBrowser_size_allocate ), &g_TextureBrowser );
- g_TextureBrowser.m_exposeHandler = g_TextureBrowser.m_gl_widget.on_render( G_CALLBACK( TextureBrowser_expose ), &g_TextureBrowser );
+ textureBrowser.m_hfiller = ui::HBox( FALSE, 0 );
+ textureBrowser.m_hframe.pack_start( textureBrowser.m_hfiller, FALSE, FALSE, 0 );
- g_TextureBrowser.m_gl_widget.connect( "button_press_event", G_CALLBACK( TextureBrowser_button_press ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "button_release_event", G_CALLBACK( TextureBrowser_button_release ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "motion_notify_event", G_CALLBACK( TextureBrowser_motion ), &g_TextureBrowser );
- g_TextureBrowser.m_gl_widget.connect( "scroll_event", G_CALLBACK( TextureBrowser_scroll ), &g_TextureBrowser );
+ textureBrowser.m_vframe.show();
+ textureBrowser.m_vfiller.show();
+ textureBrowser.m_hframe.show(),
+ textureBrowser.m_hfiller.show();
+#else // !WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_frame = ui::VBox( FALSE, 0 );
+ table.attach(textureBrowser.m_frame, {1, 2, 1, 2});
+ textureBrowser.m_frame.show();
+#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET
+
+ TextureBrowser_constructGLWidget();
}
// tag stuff
- if ( g_TextureBrowser.m_tags ) {
+ if ( textureBrowser.m_tags ) {
{ // fill tag GtkListStore
- g_TextureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_all_tags_list );
+ textureBrowser.m_all_tags_list = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
+ auto sortable = GTK_TREE_SORTABLE( textureBrowser.m_all_tags_list );
gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
- TagBuilder.GetAllTags( g_TextureBrowser.m_all_tags );
+ TagBuilder.GetAllTags( textureBrowser.m_all_tags );
TextureBrowser_buildTagList();
}
{ // tag menu bar
gtk_menu_shell_append( GTK_MENU_SHELL( menu_bar ), tags_item );
}
{ // Tag TreeView
- g_TextureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New);
- gtk_container_set_border_width( GTK_CONTAINER( g_TextureBrowser.m_scr_win_tags ), 0 );
+ textureBrowser.m_scr_win_tags = ui::ScrolledWindow(ui::New);
+ gtk_container_set_border_width( GTK_CONTAINER( textureBrowser.m_scr_win_tags ), 0 );
// vertical only scrolling for treeview
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( textureBrowser.m_scr_win_tags ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
TextureBrowser_createTreeViewTags();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_treeViewTags );
gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( g_TextureBrowser.m_scr_win_tags ), g_TextureBrowser.m_treeViewTags );
- g_TextureBrowser.m_treeViewTags.show();
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( textureBrowser.m_scr_win_tags ), textureBrowser.m_treeViewTags );
+ textureBrowser.m_treeViewTags.show();
}
{ // Texture/Tag notebook
TextureBrowser_constructTagNotebook();
- vbox.pack_start( g_TextureBrowser.m_tag_notebook, TRUE, TRUE, 0 );
+ vbox.pack_start( textureBrowser.m_tag_notebook, TRUE, TRUE, 0 );
}
{ // Tag search button
TextureBrowser_constructSearchButton();
- vbox.pack_end(g_TextureBrowser.m_search_button, FALSE, FALSE, 0);
+ vbox.pack_end(textureBrowser.m_search_button, FALSE, FALSE, 0);
}
auto frame_table = ui::Table(3, 3, FALSE);
{ // Tag frame
- g_TextureBrowser.m_tag_frame = ui::Frame( "Tag assignment" );
- gtk_frame_set_label_align( GTK_FRAME( g_TextureBrowser.m_tag_frame ), 0.5, 0.5 );
- gtk_frame_set_shadow_type( GTK_FRAME( g_TextureBrowser.m_tag_frame ), GTK_SHADOW_NONE );
+ textureBrowser.m_tag_frame = ui::Frame( "Tag assignment" );
+ gtk_frame_set_label_align( GTK_FRAME( textureBrowser.m_tag_frame ), 0.5, 0.5 );
+ gtk_frame_set_shadow_type( GTK_FRAME( textureBrowser.m_tag_frame ), GTK_SHADOW_NONE );
- table.attach(g_TextureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK});
+ table.attach(textureBrowser.m_tag_frame, {1, 3, 2, 3}, {GTK_FILL, GTK_SHRINK});
frame_table.show();
- g_TextureBrowser.m_tag_frame.add(frame_table);
+ textureBrowser.m_tag_frame.add(frame_table);
}
{ // assigned tag list
ui::Widget scrolled_win = ui::ScrolledWindow(ui::New);
gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 );
gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
- g_TextureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
+ textureBrowser.m_assigned_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_assigned_store );
+ auto sortable = GTK_TREE_SORTABLE( textureBrowser.m_assigned_store );
gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
auto renderer = ui::CellRendererText(ui::New);
- g_TextureBrowser.m_assigned_tree = ui::TreeView(ui::TreeModel::from(g_TextureBrowser.m_assigned_store._handle));
- g_TextureBrowser.m_assigned_store.unref();
- g_TextureBrowser.m_assigned_tree.connect( "row-activated", (GCallback) TextureBrowser_removeTags, NULL );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_assigned_tree, FALSE );
+ textureBrowser.m_assigned_tree = ui::TreeView(ui::TreeModel::from(textureBrowser.m_assigned_store._handle));
+ textureBrowser.m_assigned_store.unref();
+ textureBrowser.m_assigned_tree.connect( "row-activated", (GCallback) TextureBrowser_removeTags, NULL );
+ gtk_tree_view_set_headers_visible(textureBrowser.m_assigned_tree, FALSE );
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_assigned_tree );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_assigned_tree );
gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
auto column = ui::TreeViewColumn( "", renderer, {{"text", TAG_COLUMN}} );
- gtk_tree_view_append_column(g_TextureBrowser.m_assigned_tree, column );
- g_TextureBrowser.m_assigned_tree.show();
+ gtk_tree_view_append_column(textureBrowser.m_assigned_tree, column );
+ textureBrowser.m_assigned_tree.show();
scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_assigned_tree );
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), textureBrowser.m_assigned_tree );
frame_table.attach(scrolled_win, {0, 1, 1, 3}, {GTK_FILL, GTK_FILL});
}
gtk_container_set_border_width( GTK_CONTAINER( scrolled_win ), 0 );
gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled_win ), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS );
- g_TextureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
- auto sortable = GTK_TREE_SORTABLE( g_TextureBrowser.m_available_store );
+ textureBrowser.m_available_store = ui::ListStore::from(gtk_list_store_new( N_COLUMNS, G_TYPE_STRING ));
+ auto sortable = GTK_TREE_SORTABLE( textureBrowser.m_available_store );
gtk_tree_sortable_set_sort_column_id( sortable, TAG_COLUMN, GTK_SORT_ASCENDING );
auto renderer = ui::CellRendererText(ui::New);
- g_TextureBrowser.m_available_tree = ui::TreeView(ui::TreeModel::from(g_TextureBrowser.m_available_store._handle));
- g_TextureBrowser.m_available_store.unref();
- g_TextureBrowser.m_available_tree.connect( "row-activated", (GCallback) TextureBrowser_assignTags, NULL );
- gtk_tree_view_set_headers_visible(g_TextureBrowser.m_available_tree, FALSE );
+ textureBrowser.m_available_tree = ui::TreeView(ui::TreeModel::from(textureBrowser.m_available_store._handle));
+ textureBrowser.m_available_store.unref();
+ textureBrowser.m_available_tree.connect( "row-activated", (GCallback) TextureBrowser_assignTags, NULL );
+ gtk_tree_view_set_headers_visible(textureBrowser.m_available_tree, FALSE );
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_available_tree );
gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
auto column = ui::TreeViewColumn( "", renderer, {{"text", TAG_COLUMN}} );
- gtk_tree_view_append_column(g_TextureBrowser.m_available_tree, column );
- g_TextureBrowser.m_available_tree.show();
+ gtk_tree_view_append_column(textureBrowser.m_available_tree, column );
+ textureBrowser.m_available_tree.show();
scrolled_win.show();
- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), g_TextureBrowser.m_available_tree );
+ gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( scrolled_win ), textureBrowser.m_available_tree );
frame_table.attach(scrolled_win, {2, 3, 1, 3}, {GTK_FILL, GTK_FILL});
}
}
}
else { // no tag support, show the texture tree only
- vbox.pack_start( g_TextureBrowser.m_scr_win_tree, TRUE, TRUE, 0 );
+ vbox.pack_start( textureBrowser.m_scr_win_tree, TRUE, TRUE, 0 );
}
// TODO do we need this?
//gtk_container_set_focus_chain(GTK_CONTAINER(hbox_table), NULL);
+ isWindowConstructed = true;
+
return table;
}
+void TextureBrowser_destroyGLWidget(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ if ( isGLWidgetConstructed )
+ {
+ g_signal_handler_disconnect( G_OBJECT( textureBrowser.m_gl_widget ), textureBrowser.m_sizeHandler );
+ g_signal_handler_disconnect( G_OBJECT( textureBrowser.m_gl_widget ), textureBrowser.m_exposeHandler );
+
+#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_hframe.remove( textureBrowser.m_gl_widget );
+#else // !WORKAROUND_MACOS_GTK2_GLWIDGET
+ textureBrowser.m_frame.remove( textureBrowser.m_gl_widget );
+#endif // !WORKAROUND_MACOS_GTK2_GLWIDGET
+
+ textureBrowser.m_gl_widget.unref();
+
+ isGLWidgetConstructed = false;
+ }
+}
+
void TextureBrowser_destroyWindow(){
GlobalShaderSystem().setActiveShadersChangedNotify( Callback<void()>() );
- g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_sizeHandler );
- g_signal_handler_disconnect( G_OBJECT( g_TextureBrowser.m_gl_widget ), g_TextureBrowser.m_exposeHandler );
+ TextureBrowser_destroyGLWidget();
+}
+
+#ifdef WORKAROUND_MACOS_GTK2_GLWIDGET
+/* workaround for gtkglext on gtk 2 issue: OpenGL texture viewport being drawn over the other pages */
+/* this is very ugly: force the resizing of the viewport to a single bottom line by forcing the
+ * resizing of the gl widget by expanding some empty boxes, so the widget area size is reduced
+ * while covered by another page, so the texture viewport is still rendered over the other page
+ * but does not annoy the user that much because it's just a line on the bottom that may even
+ * be printed over existing bottom frame or very close to it. */
+void TextureBrowser_showGLWidget(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ if ( isWindowConstructed && isGLWidgetConstructed )
+ {
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_vfiller, FALSE, FALSE, 0, ui::Packing::START );
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_hframe, TRUE, TRUE, 0, ui::Packing::START );
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_hfiller, FALSE, FALSE, 0, ui::Packing::START );
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_gl_widget, TRUE, TRUE, 0, ui::Packing::START );
- g_TextureBrowser.m_gl_widget.unref();
+ textureBrowser.m_gl_widget.show();
+}
}
+void TextureBrowser_hideGLWidget(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ if ( isWindowConstructed && isGLWidgetConstructed )
+ {
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_vfiller, TRUE, TRUE, 0, ui::Packing::START);
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_hframe, FALSE, FALSE, 0, ui::Packing::END );
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_hfiller, TRUE, TRUE, 0, ui::Packing::START);
+ textureBrowser.m_vframe.set_child_packing( textureBrowser.m_gl_widget, FALSE, FALSE, 0, ui::Packing::END );
+
+ // The hack needs the GL widget to not be hidden to work,
+ // so resizing it triggers the redraw of it with the new size.
+ // GlobalTextureBrowser().m_gl_widget.hide();
+
+ // Trigger the redraw.
+ TextureBrowser_redraw( &GlobalTextureBrowser() );
+ ui::process();
+ }
+}
+#endif // WORKAROUND_MACOS_GTK2_GLWIDGET
+
const Vector3& TextureBrowser_getBackgroundColour( TextureBrowser& textureBrowser ){
return textureBrowser.color_textureback;
}
}
void TextureBrowser_shaderInfo(){
- const char* name = TextureBrowser_GetSelectedShader( g_TextureBrowser );
+ const char* name = TextureBrowser_GetSelectedShader( GlobalTextureBrowser() );
IShader* shader = QERApp_Shader_ForName( name );
DoShaderInfoDlg( name, shader->getShaderFileName(), "Shader Info" );
void TextureBrowser_addTag(){
CopiedString tag;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
EMessageBoxReturn result = DoShaderTagDlg( &tag, "Add shader tag" );
if ( result == eIDOK && !tag.empty() ) {
GtkTreeIter iter;
- g_TextureBrowser.m_all_tags.insert( tag.c_str() );
- gtk_list_store_append( g_TextureBrowser.m_available_store, &iter );
- gtk_list_store_set( g_TextureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1 );
+ textureBrowser.m_all_tags.insert( tag.c_str() );
+ gtk_list_store_append( textureBrowser.m_available_store, &iter );
+ gtk_list_store_set( textureBrowser.m_available_store, &iter, TAG_COLUMN, tag.c_str(), -1 );
// Select the currently added tag in the available list
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_available_tree );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_available_tree );
gtk_tree_selection_select_iter( selection, &iter );
- g_TextureBrowser.m_all_tags_list.append(TAG_COLUMN, tag.c_str());
+ textureBrowser.m_all_tags_list.append(TAG_COLUMN, tag.c_str());
}
}
*/
GSList* selected = NULL;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_treeViewTags );
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
if ( g_slist_length( selected ) == 1 ) { // we only rename a single tag
gchar* rowTag;
gchar* oldTag = (char*)selected->data;
- bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterList ) != 0;
+ bool row = gtk_tree_model_get_iter_first(textureBrowser.m_all_tags_list, &iterList ) != 0;
while ( row )
{
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, &rowTag, -1 );
+ gtk_tree_model_get(textureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, &rowTag, -1 );
if ( strcmp( rowTag, oldTag ) == 0 ) {
- gtk_list_store_set( g_TextureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1 );
+ gtk_list_store_set( textureBrowser.m_all_tags_list, &iterList, TAG_COLUMN, newTag.c_str(), -1 );
}
- row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterList ) != 0;
+ row = gtk_tree_model_iter_next(textureBrowser.m_all_tags_list, &iterList ) != 0;
}
TagBuilder.RenameShaderTag( oldTag, newTag.c_str() );
- g_TextureBrowser.m_all_tags.erase( (CopiedString)oldTag );
- g_TextureBrowser.m_all_tags.insert( newTag );
+ textureBrowser.m_all_tags.erase( (CopiedString)oldTag );
+ textureBrowser.m_all_tags.insert( newTag );
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
+ BuildStoreAssignedTags( textureBrowser.m_assigned_store, textureBrowser.shader.c_str(), &textureBrowser );
+ BuildStoreAvailableTags( textureBrowser.m_available_store, textureBrowser.m_assigned_store, textureBrowser.m_all_tags, &textureBrowser );
}
}
else
{
- ui::alert( g_TextureBrowser.m_parent, "Select a single tag for renaming." );
+ ui::alert( textureBrowser.m_parent, "Select a single tag for renaming." );
}
}
void TextureBrowser_deleteTag(){
GSList* selected = NULL;
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
- auto selection = gtk_tree_view_get_selection(g_TextureBrowser.m_treeViewTags );
+ auto selection = gtk_tree_view_get_selection(textureBrowser.m_treeViewTags );
gtk_tree_selection_selected_foreach( selection, GtkTreeSelectionForeachFunc( TextureBrowser_selectionHelper ), &selected );
if ( g_slist_length( selected ) == 1 ) { // we only delete a single tag
- auto result = ui::alert( g_TextureBrowser.m_parent, "Are you sure you want to delete the selected tag?", "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question );
+ auto result = ui::alert( textureBrowser.m_parent, "Are you sure you want to delete the selected tag?", "Delete Tag", ui::alert_type::YESNO, ui::alert_icon::Question );
if ( result == ui::alert_response::YES ) {
GtkTreeIter iterSelected;
gchar* tagSelected = (char*)selected->data;
- bool row = gtk_tree_model_get_iter_first(g_TextureBrowser.m_all_tags_list, &iterSelected ) != 0;
+ bool row = gtk_tree_model_get_iter_first(textureBrowser.m_all_tags_list, &iterSelected ) != 0;
while ( row )
{
- gtk_tree_model_get(g_TextureBrowser.m_all_tags_list, &iterSelected, TAG_COLUMN, &rowTag, -1 );
+ gtk_tree_model_get(textureBrowser.m_all_tags_list, &iterSelected, TAG_COLUMN, &rowTag, -1 );
if ( strcmp( rowTag, tagSelected ) == 0 ) {
- gtk_list_store_remove( g_TextureBrowser.m_all_tags_list, &iterSelected );
+ gtk_list_store_remove( textureBrowser.m_all_tags_list, &iterSelected );
break;
}
- row = gtk_tree_model_iter_next(g_TextureBrowser.m_all_tags_list, &iterSelected ) != 0;
+ row = gtk_tree_model_iter_next(textureBrowser.m_all_tags_list, &iterSelected ) != 0;
}
TagBuilder.DeleteTag( tagSelected );
- g_TextureBrowser.m_all_tags.erase( (CopiedString)tagSelected );
+ textureBrowser.m_all_tags.erase( (CopiedString)tagSelected );
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, g_TextureBrowser.shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
+ BuildStoreAssignedTags( textureBrowser.m_assigned_store, textureBrowser.shader.c_str(), &textureBrowser );
+ BuildStoreAvailableTags( textureBrowser.m_available_store, textureBrowser.m_assigned_store, textureBrowser.m_all_tags, &textureBrowser );
}
}
else {
- ui::alert( g_TextureBrowser.m_parent, "Select a single tag for deletion." );
+ ui::alert( textureBrowser.m_parent, "Select a single tag for deletion." );
}
}
void TextureBrowser_copyTag(){
- g_TextureBrowser.m_copied_tags.clear();
- TagBuilder.GetShaderTags( g_TextureBrowser.shader.c_str(), g_TextureBrowser.m_copied_tags );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ textureBrowser.m_copied_tags.clear();
+ TagBuilder.GetShaderTags( textureBrowser.shader.c_str(), textureBrowser.m_copied_tags );
}
void TextureBrowser_pasteTag(){
- IShader* ishader = QERApp_Shader_ForName( g_TextureBrowser.shader.c_str() );
- CopiedString shader = g_TextureBrowser.shader.c_str();
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ IShader* ishader = QERApp_Shader_ForName( textureBrowser.shader.c_str() );
+ CopiedString shader = textureBrowser.shader.c_str();
if ( !TagBuilder.CheckShaderTag( shader.c_str() ) ) {
CopiedString shaderFile = ishader->getShaderFileName();
TagBuilder.AddShaderNode( shader.c_str(), CUSTOM, SHADER );
}
- for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i )
+ for ( size_t i = 0; i < textureBrowser.m_copied_tags.size(); ++i )
{
- TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG );
+ TagBuilder.AddShaderTag( shader.c_str(), textureBrowser.m_copied_tags[i].c_str(), TAG );
}
}
else
{
- for ( size_t i = 0; i < g_TextureBrowser.m_copied_tags.size(); ++i )
+ for ( size_t i = 0; i < textureBrowser.m_copied_tags.size(); ++i )
{
- if ( !TagBuilder.CheckShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str() ) ) {
+ if ( !TagBuilder.CheckShaderTag( shader.c_str(), textureBrowser.m_copied_tags[i].c_str() ) ) {
// the tag doesn't exist - let's add it
- TagBuilder.AddShaderTag( shader.c_str(), g_TextureBrowser.m_copied_tags[i].c_str(), TAG );
+ TagBuilder.AddShaderTag( shader.c_str(), textureBrowser.m_copied_tags[i].c_str(), TAG );
}
}
}
ishader->DecRef();
TagBuilder.SaveXmlDoc();
- BuildStoreAssignedTags( g_TextureBrowser.m_assigned_store, shader.c_str(), &g_TextureBrowser );
- BuildStoreAvailableTags( g_TextureBrowser.m_available_store, g_TextureBrowser.m_assigned_store, g_TextureBrowser.m_all_tags, &g_TextureBrowser );
+ BuildStoreAssignedTags( textureBrowser.m_assigned_store, shader.c_str(), &textureBrowser );
+ BuildStoreAvailableTags( textureBrowser.m_available_store, textureBrowser.m_assigned_store, textureBrowser.m_all_tags, &textureBrowser );
}
void TextureBrowser_RefreshShaders(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Shaders" );
GlobalShaderSystem().refresh();
UpdateAllWindows();
}
void TextureBrowser_ToggleShowShaders(){
- g_TextureBrowser.m_showShaders ^= 1;
- g_TextureBrowser.m_showshaders_item.update();
- TextureBrowser_queueDraw( g_TextureBrowser );
+ GlobalTextureBrowser().m_showShaders ^= 1;
+ GlobalTextureBrowser().m_showshaders_item.update();
+ TextureBrowser_queueDraw( GlobalTextureBrowser() );
}
void TextureBrowser_ToggleShowShaderListOnly(){
g_TextureBrowser_shaderlistOnly ^= 1;
- g_TextureBrowser.m_showshaderlistonly_item.update();
+ GlobalTextureBrowser().m_showshaderlistonly_item.update();
TextureBrowser_constructTreeStore();
}
void TextureBrowser_showAll(){
g_TextureBrowser_currentDirectory = "";
- g_TextureBrowser.m_searchedTags = false;
- TextureBrowser_heightChanged( g_TextureBrowser );
+ GlobalTextureBrowser().m_searchedTags = false;
+ TextureBrowser_heightChanged( GlobalTextureBrowser() );
TextureBrowser_updateTitle();
}
void TextureBrowser_showUntagged(){
- auto result = ui::alert( g_TextureBrowser.m_parent, "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning );
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+ auto result = ui::alert( textureBrowser.m_parent, "WARNING! This function might need a lot of memory and time. Are you sure you want to use it?", "Show Untagged", ui::alert_type::YESNO, ui::alert_icon::Warning );
if ( result == ui::alert_response::YES ) {
- g_TextureBrowser.m_found_shaders.clear();
- TagBuilder.GetUntagged( g_TextureBrowser.m_found_shaders );
+ textureBrowser.m_found_shaders.clear();
+ TagBuilder.GetUntagged( textureBrowser.m_found_shaders );
std::set<CopiedString>::iterator iter;
ScopeDisableScreenUpdates disableScreenUpdates( "Searching untagged textures...", "Loading Textures" );
- for ( iter = g_TextureBrowser.m_found_shaders.begin(); iter != g_TextureBrowser.m_found_shaders.end(); iter++ )
+ for ( iter = textureBrowser.m_found_shaders.begin(); iter != textureBrowser.m_found_shaders.end(); iter++ )
{
std::string path = ( *iter ).c_str();
size_t pos = path.find_last_of( "/", path.size() );
g_TextureBrowser_currentDirectory = "Untagged";
TextureBrowser_queueDraw( GlobalTextureBrowser() );
- TextureBrowser_heightChanged( g_TextureBrowser );
+ TextureBrowser_heightChanged( textureBrowser );
TextureBrowser_updateTitle();
}
}
struct UniformTextureSize {
static void Export(const TextureBrowser &self, const Callback<void(int)> &returnz) {
- returnz(g_TextureBrowser.m_uniformTextureSize);
+ returnz(GlobalTextureBrowser().m_uniformTextureSize);
}
static void Import(TextureBrowser &self, int value) {
struct UniformTextureMinSize {
static void Export(const TextureBrowser &self, const Callback<void(int)> &returnz) {
- returnz(g_TextureBrowser.m_uniformTextureMinSize);
+ returnz(GlobalTextureBrowser().m_uniformTextureMinSize);
}
static void Import(TextureBrowser &self, int value) {
page.appendSpinner( "Thumbnails Min Size", GlobalTextureBrowser().m_uniformTextureMinSize, GlobalTextureBrowser().m_uniformTextureMinSize, 16, 8192 );
page.appendEntry( "Mousewheel Increment", GlobalTextureBrowser().m_mouseWheelScrollIncrement );
{
- const char* startup_shaders[] = { "None", TextureBrowser_getComonShadersName() };
+ const char* startup_shaders[] = { "None", TextureBrowser_getCommonShadersName() };
page.appendCombo( "Load Shaders at Startup", reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ), STRING_ARRAY_RANGE( startup_shaders ) );
}
}
void TextureClipboard_textureSelected( const char* shader );
void TextureBrowser_Construct(){
+ TextureBrowser &textureBrowser = GlobalTextureBrowser();
+
GlobalCommands_insert( "ShaderInfo", makeCallbackF(TextureBrowser_shaderInfo) );
GlobalCommands_insert( "ShowUntagged", makeCallbackF(TextureBrowser_showUntagged) );
GlobalCommands_insert( "AddTag", makeCallbackF(TextureBrowser_addTag) );
GlobalCommands_insert( "CopyTag", makeCallbackF(TextureBrowser_copyTag) );
GlobalCommands_insert( "PasteTag", makeCallbackF(TextureBrowser_pasteTag) );
GlobalCommands_insert( "RefreshShaders", makeCallbackF(VFS_Refresh) );
- GlobalToggles_insert( "ShowInUse", makeCallbackF(TextureBrowser_ToggleHideUnused), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hideunused_item ), Accelerator( 'U' ) );
+ GlobalToggles_insert( "ShowInUse", makeCallbackF(TextureBrowser_ToggleHideUnused), ToggleItem::AddCallbackCaller( textureBrowser.m_hideunused_item ), Accelerator( 'U' ) );
GlobalCommands_insert( "ShowAllTextures", makeCallbackF(TextureBrowser_showAll), Accelerator( 'A', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "ToggleTextures", makeCallbackF(TextureBrowser_toggleShow), Accelerator( 'T' ) );
- GlobalToggles_insert( "ToggleShowShaders", makeCallbackF(TextureBrowser_ToggleShowShaders), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaders_item ) );
- GlobalToggles_insert( "ToggleShowShaderlistOnly", makeCallbackF(TextureBrowser_ToggleShowShaderListOnly), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_showshaderlistonly_item ) );
- GlobalToggles_insert( "FixedSize", makeCallbackF(TextureBrowser_FixedSize), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_fixedsize_item ) );
- GlobalToggles_insert( "FilterMissing", makeCallbackF(TextureBrowser_FilterMissing), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_filternotex_item ) );
- GlobalToggles_insert( "FilterFallback", makeCallbackF(TextureBrowser_FilterFallback), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_hidenotex_item ) );
- GlobalToggles_insert( "EnableAlpha", makeCallbackF(TextureBrowser_EnableAlpha), ToggleItem::AddCallbackCaller( g_TextureBrowser.m_enablealpha_item ) );
-
- GlobalPreferenceSystem().registerPreference( "TextureScale", make_property_string<TextureScale>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "UniformTextureSize", make_property_string<UniformTextureSize>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize", make_property_string<UniformTextureMinSize>(g_TextureBrowser) );
- GlobalPreferenceSystem().registerPreference( "TextureScrollbar", make_property_string<TextureBrowser_ShowScrollbar>(GlobalTextureBrowser()));
- GlobalPreferenceSystem().registerPreference( "ShowShaders", make_property_string( GlobalTextureBrowser().m_showShaders ) );
+ GlobalToggles_insert( "ToggleShowShaders", makeCallbackF(TextureBrowser_ToggleShowShaders), ToggleItem::AddCallbackCaller( textureBrowser.m_showshaders_item ) );
+ GlobalToggles_insert( "ToggleShowShaderlistOnly", makeCallbackF(TextureBrowser_ToggleShowShaderListOnly), ToggleItem::AddCallbackCaller( textureBrowser.m_showshaderlistonly_item ) );
+ GlobalToggles_insert( "FixedSize", makeCallbackF(TextureBrowser_FixedSize), ToggleItem::AddCallbackCaller( textureBrowser.m_fixedsize_item ) );
+ GlobalToggles_insert( "FilterMissing", makeCallbackF(TextureBrowser_FilterMissing), ToggleItem::AddCallbackCaller( textureBrowser.m_filternotex_item ) );
+ GlobalToggles_insert( "FilterFallback", makeCallbackF(TextureBrowser_FilterFallback), ToggleItem::AddCallbackCaller( textureBrowser.m_hidenotex_item ) );
+ GlobalToggles_insert( "EnableAlpha", makeCallbackF(TextureBrowser_EnableAlpha), ToggleItem::AddCallbackCaller( textureBrowser.m_enablealpha_item ) );
+
+ GlobalPreferenceSystem().registerPreference( "TextureScale", make_property_string<TextureScale>(textureBrowser) );
+ GlobalPreferenceSystem().registerPreference( "UniformTextureSize", make_property_string<UniformTextureSize>(textureBrowser) );
+ GlobalPreferenceSystem().registerPreference( "UniformTextureMinSize", make_property_string<UniformTextureMinSize>(textureBrowser) );
+ GlobalPreferenceSystem().registerPreference( "TextureScrollbar", make_property_string<TextureBrowser_ShowScrollbar>(textureBrowser));
+ GlobalPreferenceSystem().registerPreference( "ShowShaders", make_property_string( textureBrowser.m_showShaders ) );
GlobalPreferenceSystem().registerPreference( "ShowShaderlistOnly", make_property_string( g_TextureBrowser_shaderlistOnly ) );
GlobalPreferenceSystem().registerPreference( "FixedSize", make_property_string( g_TextureBrowser_fixedSize ) );
GlobalPreferenceSystem().registerPreference( "FilterMissing", make_property_string( g_TextureBrowser_filterMissing ) );
GlobalPreferenceSystem().registerPreference( "EnableAlpha", make_property_string( g_TextureBrowser_enableAlpha ) );
- GlobalPreferenceSystem().registerPreference( "LoadShaders", make_property_string( reinterpret_cast<int&>( GlobalTextureBrowser().m_startupShaders ) ) );
- GlobalPreferenceSystem().registerPreference( "WheelMouseInc", make_property_string( GlobalTextureBrowser().m_mouseWheelScrollIncrement ) );
- GlobalPreferenceSystem().registerPreference( "SI_Colors0", make_property_string( GlobalTextureBrowser().color_textureback ) );
+ GlobalPreferenceSystem().registerPreference( "LoadShaders", make_property_string( reinterpret_cast<int&>( textureBrowser.m_startupShaders ) ) );
+ GlobalPreferenceSystem().registerPreference( "WheelMouseInc", make_property_string( textureBrowser.m_mouseWheelScrollIncrement ) );
+ GlobalPreferenceSystem().registerPreference( "SI_Colors0", make_property_string( textureBrowser.color_textureback ) );
- g_TextureBrowser.shader = texdef_name_default();
+ textureBrowser.shader = texdef_name_default();
- Textures_setModeChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_queueDraw>( g_TextureBrowser ) );
+ Textures_setModeChangedNotify( ReferenceCaller<TextureBrowser, void(), TextureBrowser_queueDraw>( textureBrowser ) );
TextureBrowser_registerPreferencesPage();
Textures_setModeChangedNotify( Callback<void()>() );
}
+
+#if WORKAROUND_WINDOWS_GTK2_GLWIDGET
+ui::GLArea TextureBrowser_getGLWidget(){
+ return GlobalTextureBrowser().m_gl_widget;
+}
+#endif // WORKAROUND_WINDOWS_GTK2_GLWIDGET
}
else if ( numBSPDrawVerts > numBSPDrawVertsBuffer ) {
+ bspDrawVert_t *newBspDrawVerts;
+
numBSPDrawVertsBuffer *= 3; // multiply by 1.5
numBSPDrawVertsBuffer /= 2;
- bspDrawVerts = realloc( bspDrawVerts, sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer );
+ newBspDrawVerts = realloc( bspDrawVerts, sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer );
- if ( !bspDrawVerts ) {
+ if ( !newBspDrawVerts ) {
+ free (bspDrawVerts);
Error( "realloc() failed (IncDrawVerts)" );
}
+
+ bspDrawVerts = newBspDrawVerts;
}
memset( bspDrawVerts + ( numBSPDrawVerts - 1 ), 0, sizeof( bspDrawVert_t ) );
numBSPDrawVerts = n;
numBSPDrawVertsBuffer = numBSPDrawVerts;
- bspDrawVerts = safe_malloc_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
-
- memset( bspDrawVerts, 0, n * sizeof( bspDrawVert_t ) );
+ bspDrawVerts = safe_malloc0_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
}
int numBSPDrawSurfacesBuffer = 0;
numBSPDrawSurfacesBuffer = MAX_MAP_DRAW_SURFS;
- bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
-
- memset( bspDrawSurfaces, 0, MAX_MAP_DRAW_SURFS * sizeof( bspDrawSurface_t ) );
+ bspDrawSurfaces = safe_malloc0_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
}
void SetDrawSurfaces( int n ){
numBSPDrawSurfaces = n;
numBSPDrawSurfacesBuffer = numBSPDrawSurfaces;
- bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
-
- memset( bspDrawSurfaces, 0, n * sizeof( bspDrawSurface_t ) );
+ bspDrawSurfaces = safe_malloc0_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
}
void BSPFilesCleanup(){
void AddLump( FILE *file, bspHeader_t *header, int lumpNum, const void *data, int length ){
bspLump_t *lump;
-
/* add lump to bsp file header */
lump = &header->lumps[ lumpNum ];
lump->offset = LittleLong( ftell( file ) );
lump->length = LittleLong( length );
/* write lump to file */
- SafeWrite( file, data, ( length + 3 ) & ~3 );
+ SafeWrite( file, data, length );
+
+ /* write padding zeros */
+ SafeWrite( file, (const byte[3]){ 0, 0, 0 }, ( ( length + 3 ) & ~3 ) - length );
}
/* allocate and clear new epair */
- e = safe_malloc( sizeof( epair_t ) );
- memset( e, 0, sizeof( epair_t ) );
+ e = safe_malloc0( sizeof( epair_t ) );
/* handle key */
if ( strlen( token ) >= ( MAX_KEY - 1 ) ) {
for ( i = beginArgs; i < endArgs; ++i )
{
+ if ( argv[i] == NULL ) {
+ continue;
+ }
if ( outpos != sentinel && i != beginArgs ) {
*outpos++ = ' ';
}
}
/* error check */
- if ( front->numVerts > maxPoints || front->numVerts > maxPoints ) {
+ if ( front->numVerts > maxPoints ) {
Error( "RadClipWindingEpsilon: points exceeded estimate" );
}
- if ( front->numVerts > MAX_POINTS_ON_WINDING || front->numVerts > MAX_POINTS_ON_WINDING ) {
+ if ( front->numVerts > MAX_POINTS_ON_WINDING ) {
Error( "RadClipWindingEpsilon: MAX_POINTS_ON_WINDING" );
}
}
+/*
+ Modulo1IfNegative()
+ Previously the bias computation was doing:
+
+ while ( f < 0.0f ) {
+ f += 1.0f;
+ }
+
+ That may end in infinite loop in some case.
+ It may also be slower because of useless loops.
+ I don't know what that computation is for.
+ -- illwieckz
+*/
+float Modulo1IfNegative( float f ){
+ return f < 0.0f ? f - floor( f ) : f;
+}
+
/*
*/
qboolean RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float color[ 4 ] ){
- float sto[ 2 ];
int x, y;
-
/* clear color first */
color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 255;
return qfalse;
}
- /* bias st */
- sto[ 0 ] = st[ 0 ];
- while ( sto[ 0 ] < 0.0f )
- sto[ 0 ] += 1.0f;
- sto[ 1 ] = st[ 1 ];
- while ( sto[ 1 ] < 0.0f )
- sto[ 1 ] += 1.0f;
-
/* get offsets */
- x = ( (float) width * sto[ 0 ] ) + 0.5f;
+ x = ( (float) width * Modulo1IfNegative( st[ 0 ] ) ) + 0.5f;
x %= width;
- y = ( (float) height * sto[ 1 ] ) + 0.5f;
+ y = ( (float) height * Modulo1IfNegative( st[ 1 ] ) ) + 0.5f;
y %= height;
/* get pixel */
/* multiply by texture color */
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, rw->verts[ samples ].st, textureColor ) ) {
VectorCopy( si->averageColor, textureColor );
- textureColor[ 4 ] = 255.0f;
+ textureColor[ 3 ] = 255.0f;
}
avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
for ( i = 0; i < 3; i++ )
/* multiply by texture color */
if ( !RadSampleImage( si->lightImage->pixels, si->lightImage->width, si->lightImage->height, st, textureColor ) ) {
VectorCopy( si->averageColor, textureColor );
- textureColor[ 4 ] = 255;
+ textureColor[ 3 ] = 255;
}
avgcolor = ( textureColor[ 0 ] + textureColor[ 1 ] + textureColor[ 2 ] ) / 3;
for ( l = 0; l < 3; l++ ){
}
/* create a light */
- light = safe_malloc( sizeof( *light ) );
- memset( light, 0, sizeof( *light ) );
+ light = safe_malloc0( sizeof( *light ) );
/* attach it */
ThreadLock();
/* optionally create a point splashsplash light for first pass */
if ( original && si->backsplashFraction > 0 ) {
/* allocate a new point light */
- splash = safe_malloc( sizeof( *splash ) );
- memset( splash, 0, sizeof( *splash ) );
+ splash = safe_malloc0( sizeof( *splash ) );
splash->next = lights;
lights = splash;
/* allocate a buffer and set it up */
buffer = safe_malloc( width * height * 3 + 18 );
+ /* we may also use safe_malloc0 on the whole instead,
+ * this would just be a bit slower */
memset( buffer, 0, 18 );
buffer[ 2 ] = 2;
buffer[ 12 ] = width & 255;
int ExportLightmapsMain( int argc, char **argv ){
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -export [-v] <mapname>\n" );
return 0;
}
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -import [-v] <mapname>\n" );
return 0;
}
/* for planar surfaces, create lightmap vectors for st->xyz conversion */
if ( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */
/* allocate space for the vectors */
- lm->vecs = safe_malloc( 3 * sizeof( vec3_t ) );
- memset( lm->vecs, 0, 3 * sizeof( vec3_t ) );
+ lm->vecs = safe_malloc0( 3 * sizeof( vec3_t ) );
VectorCopy( ds->lightmapVecs[ 2 ], lm->vecs[ 2 ] );
/* project stepped lightmap blocks and subtract to get planevecs */
/* allocate a list of surface clusters */
numSurfaceClusters = 0;
maxSurfaceClusters = numBSPLeafSurfaces;
- surfaceClusters = safe_malloc( maxSurfaceClusters * sizeof( *surfaceClusters ) );
- memset( surfaceClusters, 0, maxSurfaceClusters * sizeof( *surfaceClusters ) );
+ surfaceClusters = safe_malloc0( maxSurfaceClusters * sizeof( *surfaceClusters ) );
/* allocate a list for per-surface info */
- surfaceInfos = safe_malloc( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
- memset( surfaceInfos, 0, numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
+ surfaceInfos = safe_malloc0( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
for ( i = 0; i < numBSPDrawSurfaces; i++ )
surfaceInfos[ i ].childSurfaceNum = -1;
/* allocate a list of surface indexes to be sorted */
- sortSurfaces = safe_malloc( numBSPDrawSurfaces * sizeof( int ) );
- memset( sortSurfaces, 0, numBSPDrawSurfaces * sizeof( int ) );
+ sortSurfaces = safe_malloc0( numBSPDrawSurfaces * sizeof( int ) );
/* walk each model in the bsp */
for ( i = 0; i < numBSPModels; i++ )
/* allocate a list of surfaces that would go into raw lightmaps */
numLightSurfaces = 0;
- lightSurfaces = safe_malloc( numSurfsLightmapped * sizeof( int ) );
- memset( lightSurfaces, 0, numSurfsLightmapped * sizeof( int ) );
+ lightSurfaces = safe_malloc0( numSurfsLightmapped * sizeof( int ) );
/* allocate a list of raw lightmaps */
numRawSuperLuxels = 0;
numRawLightmaps = 0;
- rawLightmaps = safe_malloc( numSurfsLightmapped * sizeof( *rawLightmaps ) );
- memset( rawLightmaps, 0, numSurfsLightmapped * sizeof( *rawLightmaps ) );
+ rawLightmaps = safe_malloc0( numSurfsLightmapped * sizeof( *rawLightmaps ) );
/* walk the list of sorted surfaces */
for ( i = 0; i < numBSPDrawSurfaces; i++ )
/* allocate vertex luxel storage */
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
{
- vertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( vertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- radVertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( radVertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ vertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ radVertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
}
/* emit some stats */
olm->numShaders = 0;
/* allocate buffers */
- olm->lightBits = safe_malloc( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- memset( olm->lightBits, 0, ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- olm->bspLightBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->lightBits = safe_malloc0( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
+ olm->bspLightBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
if ( deluxemap ) {
- olm->bspDirBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspDirBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->bspDirBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
}
}
qboolean ok;
int xIncrement, yIncrement;
-
/* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
lm->outLightmapNums[ lightmapNum ] = -3;
/* allocate LIGHTMAP_RESERVE_COUNT new output lightmaps */
numOutLightmaps += LIGHTMAP_RESERVE_COUNT;
olm = safe_malloc( numOutLightmaps * sizeof( outLightmap_t ) );
+ if ( !olm ){
+ Error( "FindOutLightmaps: Failed to allocate memory.\n" );
+ }
+
if ( outLightmaps != NULL && numOutLightmaps > LIGHTMAP_RESERVE_COUNT ) {
memcpy( olm, outLightmaps, ( numOutLightmaps - LIGHTMAP_RESERVE_COUNT ) * sizeof( outLightmap_t ) );
free( outLightmaps );
stores the surface lightmaps into the bsp as byte rgb triplets
*/
-void StoreSurfaceLightmaps( qboolean fastAllocate ){
+void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal ){
int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples;
int style, size, lightmapNum, lightmapNum2;
float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples;
/* allocate bsp luxel storage */
if ( lm->bspLuxels[ lightmapNum ] == NULL ) {
size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float );
- lm->bspLuxels[ lightmapNum ] = safe_malloc( size );
- memset( lm->bspLuxels[ lightmapNum ], 0, size );
+ lm->bspLuxels[ lightmapNum ] = safe_malloc0( size );
}
/* allocate radiosity lightmap storage */
collapse non-unique lightmaps
----------------------------------------------------------------- */
- if ( noCollapse == qfalse && deluxemap == qfalse ) {
+ if ( storeForReal && noCollapse == qfalse && deluxemap == qfalse ) {
/* note it */
Sys_FPrintf( SYS_VRB, "collapsing..." );
allocate output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "allocating..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "allocating..." );
- /* kill all existing output lightmaps */
- if ( outLightmaps != NULL ) {
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- free( outLightmaps[ i ].lightBits );
- free( outLightmaps[ i ].bspLightBytes );
+ /* kill all existing output lightmaps */
+ if ( outLightmaps != NULL ) {
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ free( outLightmaps[ i ].lightBits );
+ free( outLightmaps[ i ].bspLightBytes );
+ }
+ free( outLightmaps );
+ outLightmaps = NULL;
}
- free( outLightmaps );
- outLightmaps = NULL;
- }
-
- numLightmapShaders = 0;
- numOutLightmaps = 0;
- numBSPLightmaps = 0;
- numExtLightmaps = 0;
- /* find output lightmap */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
- FindOutLightmaps( lm, fastAllocate );
- }
+ numLightmapShaders = 0;
+ numOutLightmaps = 0;
+ numBSPLightmaps = 0;
+ numExtLightmaps = 0;
- /* set output numbers in twinned lightmaps */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- /* get lightmap */
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ /* find output lightmap */
+ for ( i = 0; i < numRawLightmaps; i++ )
+ {
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ FindOutLightmaps( lm, fastAllocate );
+ }
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* set output numbers in twinned lightmaps */
+ for ( i = 0; i < numRawLightmaps; i++ )
{
- /* get twin */
- lm2 = lm->twins[ lightmapNum ];
- if ( lm2 == NULL ) {
- continue;
- }
- lightmapNum2 = lm->twinNums[ lightmapNum ];
+ /* get lightmap */
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
- /* find output lightmap from twin */
- lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
- lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
- lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* get twin */
+ lm2 = lm->twins[ lightmapNum ];
+ if ( lm2 == NULL ) {
+ continue;
+ }
+ lightmapNum2 = lm->twinNums[ lightmapNum ];
+
+ /* find output lightmap from twin */
+ lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
+ lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
+ lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ }
}
}
store output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "storing..." );
-
- /* count the bsp lightmaps and allocate space */
- if ( bspLightBytes != NULL ) {
- free( bspLightBytes );
- }
- if ( numBSPLightmaps == 0 || externalLightmaps ) {
- numBSPLightBytes = 0;
- bspLightBytes = NULL;
- }
- else
- {
- numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
- bspLightBytes = safe_malloc( numBSPLightBytes );
- memset( bspLightBytes, 0, numBSPLightBytes );
- }
-
- /* walk the list of output lightmaps */
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- /* get output lightmap */
- olm = &outLightmaps[ i ];
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "storing..." );
- /* fill output lightmap */
- if ( lightmapFill ) {
- FillOutLightmap( olm );
+ /* count the bsp lightmaps and allocate space */
+ if ( bspLightBytes != NULL ) {
+ free( bspLightBytes );
+ }
+ if ( numBSPLightmaps == 0 || externalLightmaps ) {
+ numBSPLightBytes = 0;
+ bspLightBytes = NULL;
+ }
+ else
+ {
+ numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
+ bspLightBytes = safe_malloc0( numBSPLightBytes );
}
- /* is this a valid bsp lightmap? */
- if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
- /* copy lighting data */
- lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* walk the list of output lightmaps */
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ /* get output lightmap */
+ olm = &outLightmaps[ i ];
- /* copy direction data */
- if ( deluxemap ) {
- lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* fill output lightmap */
+ if ( lightmapFill ) {
+ FillOutLightmap( olm );
}
- }
- /* external lightmap? */
- if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
- /* make a directory for the lightmaps */
- Q_mkdir( dirname );
+ /* is this a valid bsp lightmap? */
+ if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
+ /* copy lighting data */
+ lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
- /* set external lightmap number */
- olm->extLightmapNum = numExtLightmaps;
+ /* copy direction data */
+ if ( deluxemap ) {
+ lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ }
+ }
+
+ /* external lightmap? */
+ if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
+ /* make a directory for the lightmaps */
+ Q_mkdir( dirname );
- /* write lightmap */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
- Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
- numExtLightmaps++;
+ /* set external lightmap number */
+ olm->extLightmapNum = numExtLightmaps;
- /* write deluxemap */
- if ( deluxemap ) {
+ /* write lightmap */
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
numExtLightmaps++;
- if ( debugDeluxemap ) {
- olm->extLightmapNum++;
+ /* write deluxemap */
+ if ( deluxemap ) {
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
+ Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
+ WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ numExtLightmaps++;
+
+ if ( debugDeluxemap ) {
+ olm->extLightmapNum++;
+ }
}
}
}
- }
-
- if ( numExtLightmaps > 0 ) {
- Sys_FPrintf( SYS_VRB, "\n" );
- }
- /* delete unused external lightmaps */
- for ( i = numExtLightmaps; i; i++ )
- {
- /* determine if file exists */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
- if ( !FileExists( filename ) ) {
- break;
+ if ( numExtLightmaps > 0 ) {
+ Sys_FPrintf( SYS_VRB, "\n" );
}
- /* delete it */
- remove( filename );
+ /* delete unused external lightmaps */
+ for ( i = numExtLightmaps; i; i++ )
+ {
+ /* determine if file exists */
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
+ if ( !FileExists( filename ) ) {
+ break;
+ }
+
+ /* delete it */
+ remove( filename );
+ }
}
/* -----------------------------------------------------------------
project the lightmaps onto the bsp surfaces
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "projecting..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "projecting..." );
- /* walk the list of surfaces */
- for ( i = 0; i < numBSPDrawSurfaces; i++ )
- {
- /* get the surface and info */
- ds = &bspDrawSurfaces[ i ];
- info = &surfaceInfos[ i ];
- lm = info->lm;
- olm = NULL;
-
- /* handle surfaces with identical parent */
- if ( info->parentSurfaceNum >= 0 ) {
- /* preserve original data and get parent */
- parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
- memcpy( &dsTemp, ds, sizeof( *ds ) );
-
- /* overwrite child with parent data */
- memcpy( ds, parent, sizeof( *ds ) );
-
- /* restore key parts */
- ds->fogNum = dsTemp.fogNum;
- ds->firstVert = dsTemp.firstVert;
- ds->firstIndex = dsTemp.firstIndex;
- memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
-
- /* set vertex data */
- dv = &bspDrawVerts[ ds->firstVert ];
- dvParent = &bspDrawVerts[ parent->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
- memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
- }
+ /* walk the list of surfaces */
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
+ {
+ /* get the surface and info */
+ ds = &bspDrawSurfaces[ i ];
+ info = &surfaceInfos[ i ];
+ lm = info->lm;
+ olm = NULL;
- /* skip the rest */
- continue;
- }
+ /* handle surfaces with identical parent */
+ if ( info->parentSurfaceNum >= 0 ) {
+ /* preserve original data and get parent */
+ parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
+ memcpy( &dsTemp, ds, sizeof( *ds ) );
- /* handle vertex lit or approximated surfaces */
- else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- ds->lightmapNum[ lightmapNum ] = -3;
- ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
- }
- }
+ /* overwrite child with parent data */
+ memcpy( ds, parent, sizeof( *ds ) );
- /* handle lightmapped surfaces */
- else
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* set style */
- ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
+ /* restore key parts */
+ ds->fogNum = dsTemp.fogNum;
+ ds->firstVert = dsTemp.firstVert;
+ ds->firstIndex = dsTemp.firstIndex;
+ memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
- /* handle unused style */
- if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ /* set vertex data */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ dvParent = &bspDrawVerts[ parent->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
+ {
+ memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
+ memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
+ }
+
+ /* skip the rest */
+ continue;
+ }
+
+ /* handle vertex lit or approximated surfaces */
+ else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
ds->lightmapNum[ lightmapNum ] = -3;
- continue;
+ ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
}
+ }
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* handle lightmapped surfaces */
+ else
+ {
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* set style */
+ ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
- /* set bsp lightmap number */
- ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
+ /* handle unused style */
+ if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ ds->lightmapNum[ lightmapNum ] = -3;
+ continue;
+ }
- /* deluxemap debugging makes the deluxemap visible */
- if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
- ds->lightmapNum[ lightmapNum ]++;
- }
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
- /* calc lightmap origin in texture space */
- lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
- lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+ /* set bsp lightmap number */
+ ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
- /* calc lightmap st coords */
- dv = &bspDrawVerts[ ds->firstVert ];
- ydv = &yDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- if ( lm->solid[ lightmapNum ] ) {
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ /* deluxemap debugging makes the deluxemap visible */
+ if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
+ ds->lightmapNum[ lightmapNum ]++;
}
- else
+
+ /* calc lightmap origin in texture space */
+ lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
+ lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+
+ /* calc lightmap st coords */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ ydv = &yDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ if ( lm->solid[ lightmapNum ] ) {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ }
+ else
+ {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ }
}
}
}
- }
- /* store vertex colors */
- dv = &bspDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* store vertex colors */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- /* handle unused style */
- if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
- VectorClear( color );
- }
- else
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
- /* get vertex color */
- luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
- VectorCopy( luxel, color );
+ /* handle unused style */
+ if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
+ VectorClear( color );
+ }
+ else
+ {
+ /* get vertex color */
+ luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
+ VectorCopy( luxel, color );
- /* set minimum light */
- if ( lightmapNum == 0 ) {
- for ( k = 0; k < 3; k++ )
- if ( color[ k ] < minVertexLight[ k ] ) {
- color[ k ] = minVertexLight[ k ];
- }
+ /* set minimum light */
+ if ( lightmapNum == 0 ) {
+ for ( k = 0; k < 3; k++ )
+ if ( color[ k ] < minVertexLight[ k ] ) {
+ color[ k ] = minVertexLight[ k ];
+ }
+ }
}
- }
- /* store to bytes */
- if ( !info->si->noVertexLight ) {
- ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ /* store to bytes */
+ if ( !info->si->noVertexLight ) {
+ ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ }
}
}
- }
-
- /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
- if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
- qboolean dfEqual;
- char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
-
- /* setup */
- sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
- dv = &bspDrawVerts[ ds->firstVert ];
-
- /* depthFunc equal? */
- if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
- dfEqual = qtrue;
- }
- else{
- dfEqual = qfalse;
- }
+ /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
+ if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
+ qboolean dfEqual;
+ char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
- /* generate stages for styled lightmaps */
- for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* early out */
- style = lm->styles[ lightmapNum ];
- if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
- continue;
- }
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* setup */
+ sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
+ dv = &bspDrawVerts[ ds->firstVert ];
- /* lightmap name */
- if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
- strcpy( lightmapName, "$lightmap" );
+ /* depthFunc equal? */
+ if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
+ dfEqual = qtrue;
}
else{
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ dfEqual = qfalse;
}
- /* get rgbgen string */
- if ( rgbGenValues[ style ] == NULL ) {
- sprintf( key, "_style%drgbgen", style );
- rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
- if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
- rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ /* generate stages for styled lightmaps */
+ for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* early out */
+ style = lm->styles[ lightmapNum ];
+ if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ continue;
+ }
+
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+
+ /* lightmap name */
+ if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
+ strcpy( lightmapName, "$lightmap" );
+ }
+ else{
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ }
+
+ /* get rgbgen string */
+ if ( rgbGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%drgbgen", style );
+ rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
+ rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ }
}
- }
- rgbGen[ 0 ] = '\0';
- if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
- }
- else{
rgbGen[ 0 ] = '\0';
- }
+ if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
+ }
+ else{
+ rgbGen[ 0 ] = '\0';
+ }
- /* get alphagen string */
- if ( alphaGenValues[ style ] == NULL ) {
- sprintf( key, "_style%dalphagen", style );
- alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
- }
- if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
- }
- else{
- alphaGen[ 0 ] = '\0';
- }
+ /* get alphagen string */
+ if ( alphaGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%dalphagen", style );
+ alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ }
+ if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
+ }
+ else{
+ alphaGen[ 0 ] = '\0';
+ }
- /* calculate st offset */
- lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
- lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
-
- /* create additional stage */
- if ( lmx == 0.0f && lmy == 0.0f ) {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen );
+ /* calculate st offset */
+ lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
+ lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
+
+ /* create additional stage */
+ if ( lmx == 0.0f && lmy == 0.0f ) {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen );
+ }
+ else
+ {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen,
+ lmx, lmy );
+
+ }
+
+ /* concatenate */
+ strcat( styleStages, styleStage );
}
- else
- {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen,
- lmx, lmy );
+ /* create custom shader */
+ if ( info->si->styleMarker == 2 ) {
+ csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
+ }
+ else{
+ csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
}
- /* concatenate */
- strcat( styleStages, styleStage );
- }
+ /* emit remap command */
+ //% EmitVertexRemapShader( csi->shader, info->si->shader );
- /* create custom shader */
- if ( info->si->styleMarker == 2 ) {
- csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
- }
- else{
- csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
}
- /* emit remap command */
- //% EmitVertexRemapShader( csi->shader, info->si->shader );
-
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
-
- /* devise a custom shader for this surface (fixme: make this work with light styles) */
- else if ( olm != NULL && lm != NULL && !externalLightmaps &&
- ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
+ /* devise a custom shader for this surface (fixme: make this work with light styles) */
+ else if ( olm != NULL && lm != NULL && !externalLightmaps &&
+ ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
- /* do some name mangling */
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ /* do some name mangling */
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
- /* create custom shader */
- csi = CustomShader( info->si, "$lightmap", lightmapName );
+ /* create custom shader */
+ csi = CustomShader( info->si, "$lightmap", lightmapName );
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
+ }
- /* use the normal plain-jane shader */
- else{
- ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ /* use the normal plain-jane shader */
+ else{
+ ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ }
}
}
? 0
: (float) numUsed / (float) numStored;
- /* print stats */
- Sys_Printf( "%9d luxels used\n", numUsed );
- Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
- Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
- Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
- Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
- Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
- Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
- Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
- Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
-
- /* write map shader file */
- WriteMapShaderFile();
+ if ( storeForReal ) {
+ /* print stats */
+ Sys_Printf( "%9d luxels used\n", numUsed );
+ Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
+ Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
+ Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
+ Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
+ Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
+ Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
+ Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
+ Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
+
+ /* write map shader file */
+ WriteMapShaderFile();
+ }
}
------------------------------------------------------------------------------- */
/* platform-specific */
-#if GDEF_OS_LINUX || GDEF_OS_MACOS
- #define Q_UNIX
-#endif
-
-#ifdef Q_UNIX
+#if GDEF_OS_POSIX
#include <unistd.h>
#include <pwd.h>
#include <limits.h>
/* general */
-#include "version.h" /* ttimo: might want to guard that if built outside of the GtkRadiant tree */
-
#include "cmdlib.h"
#include "mathlib.h"
#include "md5lib.h"
------------------------------------------------------------------------------- */
-#define MAC_STATIC_HACK 0
-#if GDEF_OS_MACOS && MAC_STATIC_HACK
- #define MAC_STATIC static
-#else
- #define MAC_STATIC
-#endif
-
-#if 1
#if GDEF_OS_WINDOWS
#define Q_stricmp stricmp
#define Q_strncasecmp strnicmp
#define Q_stricmp strcasecmp
#define Q_strncasecmp strncasecmp
#endif
+
+// hack to declare and define in the same file
+#ifdef MAIN_C
+ #define Q_EXTERN
+ #define Q_ASSIGN( a ) = a
+#else
+ #define Q_EXTERN extern
+ #define Q_ASSIGN( a )
#endif
/* macro version */
/* general */
#define MAX_QPATH 64
-#define MAX_IMAGES 512
+#define MAX_IMAGES 2048
#define DEFAULT_IMAGE "*default"
-#define MAX_MODELS 512
+#define MAX_MODELS 2048
#define DEF_BACKSPLASH_FRACTION 0.05f /* 5% backsplash by default */
#define DEF_BACKSPLASH_DISTANCE 23
#define C_DETAIL 0x08000000 /* THIS MUST BE THE SAME AS IN RADIANT! */
+/* new tex surface flags, like Smokin'Guns */
+#define TEX_SURF_METAL 0x00001000
+#define TEX_SURF_WOOD 0x00080000
+#define TEX_SURF_CLOTH 0x00100000
+#define TEX_SURF_DIRT 0x00200000
+#define TEX_SURF_GLASS 0x00400000
+#define TEX_SURF_PLANT 0x00800000
+#define TEX_SURF_SAND 0x01000000
+#define TEX_SURF_SNOW 0x02000000
+#define TEX_SURF_STONE 0x04000000
+#define TEX_SURF_WATER 0x08000000
+#define TEX_SURF_GRASS 0x10000000
+#define TEX_SURF_BREAKABLE 0x20000000
+
+
/* shadow flags */
#define WORLDSPAWN_CAST_SHADOWS 1
#define WORLDSPAWN_RECV_SHADOWS 1
#define HINT_PRIORITY 1000 /* ydnar: force hint splits first and antiportal/areaportal splits last */
#define ANTIPORTAL_PRIORITY -1000
#define AREAPORTAL_PRIORITY -1000
-#define DETAIL_PRIORITY -3000
+#define DETAIL_PRIORITY -3000
#define PSIDE_FRONT 1
#define PSIDE_BACK 2
#define RAD_LUXEL_SIZE 3
#define SUPER_LUXEL_SIZE 4
#define SUPER_FLAG_SIZE 4
-#define FLAG_FORCE_SUBSAMPLING 1
+#define FLAG_FORCE_SUBSAMPLING 1
#define FLAG_ALREADY_SUBSAMPLED 2
#define SUPER_ORIGIN_SIZE 3
#define SUPER_NORMAL_SIZE 4
}
miniMapMode_t;
+typedef enum
+{
+ MINIMAP_SIDECAR_NONE,
+ MINIMAP_SIDECAR_UNVANQUISHED
+}
+miniMapSidecarFormat_t;
+
typedef struct game_s
{
char *arg; /* -game matches this */
int maxLMSurfaceVerts; /* default maximum meta surface verts */
int maxSurfaceVerts; /* default maximum surface verts */
int maxSurfaceIndexes; /* default maximum surface indexes (tris * 3) */
+ qboolean texFile; /* enable per shader prefix surface flags and .tex file */
qboolean emitFlares; /* when true, emit flare surfaces */
char *flareShader; /* default flare shader (MUST BE SET) */
qboolean wolfLight; /* when true, lights work like wolf q3map */
qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */
miniMapMode_t miniMapMode; /* minimap mode */
char *miniMapNameFormat; /* minimap name format */
+ miniMapSidecarFormat_t miniMapSidecarFormat; /* minimap sidecar format */
char *bspIdent; /* 4-letter bsp file prefix */
int bspVersion; /* bsp version to use */
qboolean lumpSwap; /* cod-style len/ofs order */
sun_t *sun; /* ydnar */
vec3_t color; /* normalized color */
- vec3_t averageColor;
+ vec4_t averageColor;
byte lightStyle;
/* vortex: per-surface floodlight */
struct face_s *next;
int planenum;
int priority;
- //qboolean checked;
+ //qboolean checked;
int compileFlags;
winding_t *w;
}
}
surfaceType_t;
-char *surfaceTypes[ NUM_SURFACE_TYPES ]
+Q_EXTERN char *surfaceTypes[ NUM_SURFACE_TYPES ]
#ifndef MAIN_C
;
#else
float *bspLuxels[ MAX_LIGHTMAPS ];
float *radLuxels[ MAX_LIGHTMAPS ];
float *superLuxels[ MAX_LIGHTMAPS ];
- unsigned char *superFlags;
+ unsigned char *superFlags;
float *superOrigins;
float *superNormals;
int *superClusters;
/* light_ydnar.c */
void ColorToBytes( const float *color, byte *colorBytes, float scale );
+void ColorToBytesNonZero( const float *color, byte *colorBytes, float scale );
void SmoothNormals( void );
void MapRawLightmap( int num );
void SetupSurfaceLightmaps( void );
void StitchSurfaceLightmaps( void );
-void StoreSurfaceLightmaps( qboolean fastAllocate );
+void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal );
/* exportents.c */
void WriteBSPFile( const char *filename );
void PrintBSPFileSizes( void );
+void WriteTexFile( char *name );
+void LoadSurfaceFlags( char *filename );
+int GetSurfaceParm( const char *tex );
+void RestoreSurfaceFlags( char *filename );
+
epair_t *ParseEPair( void );
void ParseEntities( void );
void UnparseEntities( void );
------------------------------------------------------------------------------- */
-#ifdef MAIN_C
- #define Q_EXTERN
- #define Q_ASSIGN( a ) = a
-#else
- #define Q_EXTERN extern
- #define Q_ASSIGN( a )
-#endif
-
/* game support */
Q_EXTERN game_t games[]
#ifndef MAIN_C
=
{
#include "game_quake3.h"
+ ,
+ #include "game_nexuiz.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_oa.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_q3rally.h" /* must be after game_quake3.h as they share defines! */
,
#include "game_quakelive.h" /* must be after game_quake3.h as they share defines! */
,
- #include "game_nexuiz.h" /* must be after game_quake3.h as they share defines! */
+ #include "game_reaction.h" /* must be after game_quake3.h */
,
- #include "game_xonotic.h" /* must be after game_quake3.h as they share defines! */
+ #include "game_smokinguns.h" /* must be after game_quake3.h */
,
#include "game_tremulous.h" /*LinuxManMikeC: must be after game_quake3.h, depends on #define's set in it */
,
#include "game_unvanquished.h" /* must be after game_tremulous.h as they share defines! */
+ ,
+ #include "game_wop.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_xonotic.h" /* must be after game_quake3.h as they share defines! */
,
#include "game_tenebrae.h"
,
,
#include "game_qfusion.h" /* qfusion game */
,
- #include "game_reaction.h" /* must be after game_quake3.h */
+ #include "game_warsow.h" /* must be after game_qfusion.h as they share defines! */
+ ,
+ #include "game_warfork.h" /* must be after game_qfusion.h as they share defines! */
,
- #include "game_darkplaces.h" /* vortex: darkplaces q1 engine */
+ #include "game_darkplaces.h" /* darkplaces q1 engine */
,
- #include "game_dq.h" /* vortex: deluxe quake game ( darkplaces q1 engine) */
+ #include "game_dq.h" /* deluxe quake game ( darkplaces q1 engine) */
,
#include "game_prophecy.h" /* vortex: prophecy game ( darkplaces q1 engine) */
,
/* commandline arguments */
Q_EXTERN qboolean nocmdline Q_ASSIGN( qfalse );
-Q_EXTERN qboolean verbose;
Q_EXTERN qboolean verboseEntities Q_ASSIGN( qfalse );
Q_EXTERN qboolean force Q_ASSIGN( qfalse );
Q_EXTERN qboolean infoMode Q_ASSIGN( qfalse );
Q_EXTERN qboolean noHint Q_ASSIGN( qfalse ); /* ydnar */
Q_EXTERN qboolean renameModelShaders Q_ASSIGN( qfalse ); /* ydnar */
Q_EXTERN qboolean skyFixHack Q_ASSIGN( qfalse ); /* ydnar */
-Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */
-Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */
+Q_EXTERN qboolean bspAlternateSplitWeights Q_ASSIGN( qfalse ); /* 27 */
+Q_EXTERN qboolean deepBSP Q_ASSIGN( qfalse ); /* div0 */
Q_EXTERN qboolean maxAreaFaceSurface Q_ASSIGN( qfalse ); /* divVerent */
Q_EXTERN int patchSubdivisions Q_ASSIGN( 8 ); /* ydnar: -patchmeta subdivisions */
Q_EXTERN bspBrushSide_t* bspBrushSides Q_ASSIGN( NULL );
Q_EXTERN int numBSPLightBytes Q_ASSIGN( 0 );
-Q_EXTERN byte *bspLightBytes Q_ASSIGN( NULL );
+Q_EXTERN byte *bspLightBytes Q_ASSIGN( NULL );
//% Q_EXTERN int numBSPGridPoints Q_ASSIGN( 0 );
//% Q_EXTERN byte *bspGridPoints Q_ASSIGN( NULL );
Q_EXTERN byte bspVisBytes[ MAX_MAP_VISIBILITY ];
Q_EXTERN int numBSPDrawVerts Q_ASSIGN( 0 );
-Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL );
+Q_EXTERN bspDrawVert_t *bspDrawVerts Q_ASSIGN( NULL );
Q_EXTERN int numBSPDrawIndexes Q_ASSIGN( 0 );
Q_EXTERN int allocatedBSPDrawIndexes Q_ASSIGN( 0 );
-Q_EXTERN int *bspDrawIndexes Q_ASSIGN( NULL );
+Q_EXTERN int *bspDrawIndexes Q_ASSIGN( NULL );
Q_EXTERN int numBSPDrawSurfaces Q_ASSIGN( 0 );
Q_EXTERN bspDrawSurface_t *bspDrawSurfaces Q_ASSIGN( NULL );
Q_EXTERN int numBSPAds Q_ASSIGN( 0 );
Q_EXTERN bspAdvertisement_t bspAds[ MAX_MAP_ADVERTISEMENTS ];
-#define AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def ) \
+// Used for tex file support, Smokin'Guns globals
+Q_EXTERN qboolean compile_map;
+
+#define _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, fillWithZeros ) \
do \
{ \
+ int prevAllocated = allocated; \
if ( reqitem >= allocated ) \
{ \
if ( allocated == 0 ) { \
- allocated = def; } \
+ allocated = def; \
+ } \
while ( reqitem >= allocated && allocated ) \
+ { \
allocated *= 2; \
+ } \
if ( !allocated || allocated > 2147483647 / (int)sizeof( *ptr ) ) \
{ \
- Error( # ptr " over 2 GB" ); \
+ Error( #ptr " over 2 GB" ); \
} \
ptr = realloc( ptr, sizeof( *ptr ) * allocated ); \
if ( !ptr ) { \
- Error( # ptr " out of memory" ); } \
+ Error( #ptr " out of memory" ); \
+ } \
+ if ( fillWithZeros ) \
+ { \
+ memset( ptr + ( sizeof( *ptr ) * prevAllocated ), 0 , sizeof( *ptr ) * ( allocated - prevAllocated ) ); \
+ } \
} \
} \
while ( 0 )
-#define AUTOEXPAND_BY_REALLOC_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC( bsp ## suffix, numBSP ## suffix, allocatedBSP ## suffix, def )
+#define AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def ) _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, qfalse )
+
+#define AUTOEXPAND_BY_REALLOC0( ptr, reqitem, allocated, def ) _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, qtrue )
+
+#define AUTOEXPAND_BY_REALLOC_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC( bsp##suffix, numBSP##suffix, allocatedBSP##suffix, def )
+
+#define AUTOEXPAND_BY_REALLOC0_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC0( bsp##suffix, numBSP##suffix, allocatedBSP##suffix, def )
#define Image_LinearFloatFromsRGBFloat( c ) ( ( ( c ) <= 0.04045f ) ? ( c ) * ( 1.0f / 12.92f ) : (float)pow( ( ( c ) + 0.055f ) * ( 1.0f / 1.055f ), 2.4f ) )
#define Image_sRGBFloatFromLinearFloat( c ) ( ( ( c ) < 0.0031308f ) ? ( c ) * 12.92f : 1.055f * (float)pow( ( c ), 1.0f / 2.4f ) - 0.055f )
if ( VectorLength( si->color ) <= 0.0f ) {
ColorNormalize( color, si->color );
VectorScale( color, ( 1.0f / count ), si->averageColor );
+ si->averageColor[ 3 ] = color[ 3 ] / count;
}
else
{
VectorCopy( si->color, si->averageColor );
+ si->averageColor[ 3 ] = 1.0f;
}
}
else if ( !Q_stricmp( token, "sun" ) /* sof2 */ || !Q_stricmp( token, "q3map_sun" ) || !Q_stricmp( token, "q3map_sunExt" ) ) {
float a, b;
sun_t *sun;
- qboolean ext;
-
+ qboolean ext = qfalse;
/* ydnar: extended sun directive? */
if ( !Q_stricmp( token, "q3map_sunext" ) ) {
}
/* allocate sun */
- sun = safe_malloc( sizeof( *sun ) );
- memset( sun, 0, sizeof( *sun ) );
+ sun = safe_malloc0( sizeof( *sun ) );
/* set style */
sun->style = si->lightStyle;
surfaceModel_t *model;
/* allocate new model and attach it */
- model = safe_malloc( sizeof( *model ) );
- memset( model, 0, sizeof( *model ) );
+ model = safe_malloc0( sizeof( *model ) );
model->next = si->surfaceModel;
si->surfaceModel = model;
/* allocate new foliage struct and attach it */
- foliage = safe_malloc( sizeof( *foliage ) );
- memset( foliage, 0, sizeof( *foliage ) );
+ foliage = safe_malloc0( sizeof( *foliage ) );
foliage->next = si->foliage;
si->foliage = foliage;
alpha = ( !Q_stricmp( token, "q3map_alphaGen" ) || !Q_stricmp( token, "q3map_alphaMod" ) ) ? 1 : 0;
/* allocate new colormod */
- cm = safe_malloc( sizeof( *cm ) );
- memset( cm, 0, sizeof( *cm ) );
+ cm = safe_malloc0( sizeof( *cm ) );
/* attach to shader */
if ( si->colorMod == NULL ) {
/* add a new vertex at the beginning of the surface */
verts = safe_malloc( ( ds->numVerts + 1 ) * sizeof( bspDrawVert_t ) );
+ /* beware to only zero the new vertexi at the beginning, nor more! */
memset( verts, 0, sizeof( bspDrawVert_t ) );
memcpy( &verts[ 1 ], ds->verts, ds->numVerts * sizeof( bspDrawVert_t ) );
free( ds->verts );
typedef struct edge_s
{
- vec3_t origin, edge;
+ vec3_t origin;
+ vec4_t edge;
vec_t length, kingpinLength;
int kingpin;
vec4_t plane;
Sys_FPrintf( SYS_VRB, "--- SmoothMetaTriangles ---\n" );
/* allocate shade angle table */
- shadeAngles = safe_malloc( numMetaVerts * sizeof( float ) );
- memset( shadeAngles, 0, numMetaVerts * sizeof( float ) );
+ shadeAngles = safe_malloc0( numMetaVerts * sizeof( float ) );
/* allocate smoothed table */
cs = ( numMetaVerts / 8 ) + 1;
- smoothed = safe_malloc( cs );
- memset( smoothed, 0, cs );
+ smoothed = safe_malloc0( cs );
/* set default shade angle */
defaultShadeAngle = DEG2RAD( npDegrees );