From b017c473e86330d5908858b8add1b16674b0a1a8 Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 1 Aug 2017 14:23:38 +0300 Subject: [PATCH] Radiant: menus... * help+: Blendmodes cheatsheet misc... * fix treemodel Clang compilation * fix: 1x1 textures crash and appearence * fix of: create func static in non doom3 gametype = group entity w/o objects * merged tex bro textures borders; stipple indicates shaders * realigned tex bro text, so one doesn't collide with textures borders * fix of texture focusing in tex bro * grayscale RLE TGA support * unsupported Doom 3 entity keys: popup->log warning * patch inspector: +flip texture buttons * disabled texture lock by default (confuses novices, suddenly) * added MeshTex plugin src to project, compiled, fixed (works now-) --- .gitignore | 1 + contrib/meshtex/AllocatedMatrix.h | 13 ++-- contrib/meshtex/PluginUI.cpp | 9 ++- contrib/meshtex/PluginUI.h | 11 ++- docs/index.html | 2 +- libs/string/string.h | 7 ++ plugins/image/tga.cpp | 53 +++++++++++++-- radiant/brush.cpp | 2 +- radiant/eclass_doom3.cpp | 5 +- radiant/entity.cpp | 2 +- radiant/mainframe.cpp | 13 ++-- radiant/patchdialog.cpp | 62 ++++++++++------- radiant/patchmanip.cpp | 34 +++++++--- radiant/patchmanip.h | 7 ++ radiant/surfacedialog.cpp | 12 ++-- radiant/texwindow.cpp | 107 ++++++++++++++++-------------- radiant/treemodel.cpp | 21 ++++-- setup/data/tools/global.xlink | 1 + 18 files changed, 240 insertions(+), 122 deletions(-) diff --git a/.gitignore b/.gitignore index b1c030fc..1bab8616 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.[oda] install +games diff --git a/contrib/meshtex/AllocatedMatrix.h b/contrib/meshtex/AllocatedMatrix.h index db3850fb..3967d6c8 100644 --- a/contrib/meshtex/AllocatedMatrix.h +++ b/contrib/meshtex/AllocatedMatrix.h @@ -38,8 +38,8 @@ template class AllocatedMatrix : public Matrix { - std::size_t m_x, m_y; - Element* m_data; + //std::size_t m_x, m_y; + //Element* m_data; public: // public methods /** @@ -48,8 +48,11 @@ public: // public methods * @param x Matrix x dimension. * @param y Matrix y dimension. */ - AllocatedMatrix(std::size_t x, std::size_t y) : m_x(x), m_y(y), m_data(_allocated = new Element[x*y]){} -// Matrix(x, y, (_allocated = new Element[x*y])) {} + //AllocatedMatrix(std::size_t x, std::size_t y) : m_x(x), m_y(y), m_data(_allocated = new Element[x*y]){} //doesnt work. + //AllocatedMatrix(std::size_t x, std::size_t y) : Matrix(x, y, (_allocated = new Element[x*y])) {} //msvc + typedef Matrix matrix_type; + AllocatedMatrix(std::size_t x, std::size_t y) : matrix_type(x, y, (_allocated = new Element[x*y])) {} + /** * Destructor. Deallocates the data array. @@ -64,4 +67,4 @@ private: // private member vars Element *_allocated; }; -#endif // #if !defined(INCLUDED_ALLOCATEDMATRIX_H) \ No newline at end of file +#endif // #if !defined(INCLUDED_ALLOCATEDMATRIX_H) diff --git a/contrib/meshtex/PluginUI.cpp b/contrib/meshtex/PluginUI.cpp index b0f6ad88..fcbeef44 100644 --- a/contrib/meshtex/PluginUI.cpp +++ b/contrib/meshtex/PluginUI.cpp @@ -36,6 +36,7 @@ */ PluginUI::PluginUI() { + PluginUI::singleton = this; // Instantiate and register the Set S/T Scale dialog. We need a non-generic // handle on this one too, because it will be used as input to the Get Info // dialog constructor below. @@ -69,6 +70,7 @@ PluginUI::~PluginUI() { } +PluginUI* PluginUI::singleton = 0; /** * Get the singleton instance of the UI manager. Note that callers should * almost certainly invoke the UIInstance global function instead of using @@ -79,8 +81,11 @@ PluginUI::~PluginUI() PluginUI& PluginUI::Instance() { - static PluginUI singleton; - return singleton; + //static PluginUI singleton; + //return singleton; + if(!singleton) + singleton = new PluginUI(); + return *singleton; } /** diff --git a/contrib/meshtex/PluginUI.h b/contrib/meshtex/PluginUI.h index 6d9e08f1..9dcb0842 100644 --- a/contrib/meshtex/PluginUI.h +++ b/contrib/meshtex/PluginUI.h @@ -43,10 +43,19 @@ private: // private methods PluginUI(); ~PluginUI(); //@} + // C++ 03 + // ======== + // Dont forget to declare these two. You want to make sure they + // are unacceptable otherwise you may accidentally get copies of + // your singleton appearing. + PluginUI(PluginUI const&); // Don't Implement + void operator=(PluginUI const&); // Don't implement + + static PluginUI* singleton; public: // public methods static PluginUI& Instance(); }; -#endif // #if !defined(INCLUDED_PLUGINUI_H) \ No newline at end of file +#endif // #if !defined(INCLUDED_PLUGINUI_H) diff --git a/docs/index.html b/docs/index.html index 68811708..60d0ed4c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -11,6 +11,6 @@ -

Xonotic Mapping Wiki

+

Xonotic Mapping Wiki

diff --git a/libs/string/string.h b/libs/string/string.h index a6de0673..826d4a93 100644 --- a/libs/string/string.h +++ b/libs/string/string.h @@ -141,6 +141,13 @@ inline bool string_equal_prefix( const char* string, const char* prefix ){ return string_equal_n( string, prefix, string_length( prefix ) ); } +/// \brief Returns true if the ending of \p string is equal to \p suffix. +/// O(n) +inline bool string_equal_suffix( const char* string, const char* suffix){ + const char *s = string + string_length( string ) - string_length( suffix ); + return string_equal_n( s , suffix, string_length( suffix ) ); +} + /// \brief Copies \p other into \p string and returns \p string. /// Assumes that the space allocated for \p string is at least string_length(other) + 1. /// O(n) diff --git a/plugins/image/tga.cpp b/plugins/image/tga.cpp index bc498a8f..88233a9a 100644 --- a/plugins/image/tga.cpp +++ b/plugins/image/tga.cpp @@ -165,6 +165,42 @@ inline TargaPacketSize targa_packet_size( const TargaPacket& packet ){ } +class TargaDecodeGrayPixelRLE +{ +TargaPacketSize m_packetSize; +RGBAPixel m_pixel; +TargaPacket m_packet; +public: +TargaDecodeGrayPixelRLE() : m_packetSize( 0 ){ +} +void operator()( PointerInputStream& istream, RGBAPixel& pixel ){ + if ( m_packetSize == 0 ) { + targa_packet_read_istream( m_packet, istream ); + m_packetSize = targa_packet_size( m_packet ); + + if ( targa_packet_is_rle( m_packet ) ) { + istream_read_gray( istream, m_pixel ); + } + } + + if ( targa_packet_is_rle( m_packet ) ) { + pixel = m_pixel; + } + else + { + istream_read_gray( istream, pixel ); + } + + --m_packetSize; +} +}; + +template +void targa_decode_rle_grayscale( PointerInputStream& istream, RGBAImage& image, const Flip& flip ){ + TargaDecodeGrayPixelRLE decode; + image_decode( istream, decode, image, flip ); +} + class TargaDecodeRGBPixelRLE { TargaPacketSize m_packetSize; @@ -305,9 +341,12 @@ Image* Targa_decodeImageData( const TargaHeader& targa_header, PointerInputStrea return 0; } } - else if ( targa_header.image_type == 10 ) { + else if ( targa_header.image_type == 10 || targa_header.image_type == 11 ) { switch ( targa_header.pixel_size ) { + case 8: + targa_decode_rle_grayscale( istream, *image, flip ); + break; case 24: targa_decode_rle_rgb( istream, *image, flip ); break; @@ -333,9 +372,9 @@ Image* LoadTGABuff( const byte* buffer ){ targa_header_read_istream( targa_header, istream ); - if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) { + if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 && targa_header.image_type != 11 ) { globalErrorStream() << "LoadTGA: TGA type " << targa_header.image_type << " not supported\n"; - globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n"; + globalErrorStream() << "LoadTGA: Only type 2 (RGB), 3 (gray), 10 (RGB), and 11 (gray) TGA images supported\n"; return 0; } @@ -344,9 +383,9 @@ Image* LoadTGABuff( const byte* buffer ){ return 0; } - if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) - && targa_header.image_type != 3 ) { - globalErrorStream() << "LoadTGA: Only 32 or 24 bit images supported\n"; + if ( ( ( targa_header.image_type == 2 || targa_header.image_type == 10 ) && targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) || + ( ( targa_header.image_type == 3 || targa_header.image_type == 11 ) && targa_header.pixel_size != 8 ) ) { + globalErrorStream() << "LoadTGA: Only 32, 24 or 8 bit images supported\n"; return 0; } @@ -374,4 +413,4 @@ Image* LoadTGABuff( const byte* buffer ){ Image* LoadTGA( ArchiveFile& file ){ ScopedArchiveBuffer buffer( file ); return LoadTGABuff( buffer.buffer ); -} +} \ No newline at end of file diff --git a/radiant/brush.cpp b/radiant/brush.cpp index 5e38cc1d..443a69ec 100644 --- a/radiant/brush.cpp +++ b/radiant/brush.cpp @@ -35,7 +35,7 @@ void Brush_textureChanged(){ QuantiseFunc Face::m_quantise; EBrushType Face::m_type; EBrushType FacePlane::m_type; -bool g_brush_texturelock_enabled = true; +bool g_brush_texturelock_enabled = false; EBrushType Brush::m_type; double Brush::m_maxWorldCoord = 0; diff --git a/radiant/eclass_doom3.cpp b/radiant/eclass_doom3.cpp index 620cc276..61380f78 100644 --- a/radiant/eclass_doom3.cpp +++ b/radiant/eclass_doom3.cpp @@ -502,7 +502,10 @@ static bool EntityClass_parse( EntityClass& entityClass, Tokeniser& tokeniser ){ else { CopiedString tmp( key ); - ASSERT_MESSAGE( !string_equal_n( key, "editor_", 7 ), "unsupported editor key: " << makeQuoted( key ) ); + //ASSERT_MESSAGE( !string_equal_n( key, "editor_", 7 ), "unsupported editor key: " << makeQuoted( key ) ); + if ( string_equal_n( key, "editor_", 7 ) ) { + globalErrorStream() << "unsupported editor key " << makeQuoted( key ) ; + } EntityClassAttribute& attribute = EntityClass_insertAttribute( entityClass, key ).second; attribute.m_type = "string"; const char* value; diff --git a/radiant/entity.cpp b/radiant/entity.cpp index cc863c61..eb63dc33 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -299,7 +299,7 @@ void Entity_createFromSelection( const char* name, const Vector3& origin ){ bool isModel = ( string_compare_nocase_n( name, "misc_", 5 ) == 0 && string_equal_nocase( name + string_length( name ) - 5, "model" ) ) // misc_*model (also misc_model) || string_equal_nocase( name, "model_static" ) - || ( GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase( name, "func_static" ) ); + || ( GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase( name, "func_static" ) && g_pGameDescription->mGameType == "doom3" ); bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0; diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 60f3a5eb..6fbb4669 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1861,8 +1861,6 @@ GtkMenuItem* create_edit_menu(){ create_menu_item_with_mnemonic( menu, "_Duplicate", "CloneSelection" ); create_menu_item_with_mnemonic( menu, "Duplicate, make uni_que", "CloneSelectionAndMakeUnique" ); create_menu_item_with_mnemonic( menu, "D_elete", "DeleteSelection" ); - menu_separator( menu ); - create_menu_item_with_mnemonic( menu, "Snap To Grid", "SnapToGrid" ); //create_menu_item_with_mnemonic( menu, "Pa_rent", "ParentSelection" ); menu_separator( menu ); create_menu_item_with_mnemonic( menu, "C_lear Selection", "UnSelectSelection" ); @@ -2048,6 +2046,9 @@ GtkMenuItem* create_selection_menu(){ create_check_menu_item_with_mnemonic( menu_in_menu, "_Faces", "DragFaces" ); } + menu_separator( menu ); + create_menu_item_with_mnemonic( menu, "Snap To Grid", "SnapToGrid" ); + menu_separator( menu ); { @@ -2227,10 +2228,10 @@ void PatchInspector_registerShortcuts(){ void Patch_registerShortcuts(){ // command_connect_accelerator( "InvertCurveTextureX" ); // command_connect_accelerator( "InvertCurveTextureY" ); - command_connect_accelerator( "IncPatchColumn" ); - command_connect_accelerator( "IncPatchRow" ); - command_connect_accelerator( "DecPatchColumn" ); - command_connect_accelerator( "DecPatchRow" ); +// command_connect_accelerator( "PatchInsertInsertColumn" ); +// command_connect_accelerator( "PatchInsertInsertRow" ); +// command_connect_accelerator( "PatchDeleteLastColumn" ); +// command_connect_accelerator( "PatchDeleteLastRow" ); // command_connect_accelerator( "NaturalizePatch" ); //command_connect_accelerator("CapCurrentCurve"); } diff --git a/radiant/patchdialog.cpp b/radiant/patchdialog.cpp index daa79f65..62822dc2 100644 --- a/radiant/patchdialog.cpp +++ b/radiant/patchdialog.cpp @@ -376,29 +376,27 @@ void Scene_PatchTileTexture_Selected( scene::Graph& graph, float s, float t ){ } static void OnBtnPatchdetails( GtkWidget *widget, gpointer data ){ - UndoableCommand command( "patchCapTexture" ); - - Scene_PatchCapTexture_Selected( GlobalSceneGraph() ); + Patch_CapTexture(); } static void OnBtnPatchfit( GtkWidget *widget, gpointer data ){ - UndoableCommand command( "patchFitTexture" ); - - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), 1, 1 ); + Patch_FitTexture(); } static void OnBtnPatchnatural( GtkWidget *widget, gpointer data ){ - UndoableCommand command( "patchNaturalTexture" ); - - Scene_PatchNaturalTexture_Selected( GlobalSceneGraph() ); + Patch_NaturalTexture(); } static void OnBtnPatchreset( GtkWidget *widget, gpointer data ){ - float fx, fy; - if ( DoTextureLayout( &fx, &fy ) == eIDOK ) { - UndoableCommand command( "patchTileTexture" ); - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), fx, fy ); - } + Patch_ResetTexture(); +} + +static void OnBtnPatchFlipX( GtkWidget *widget, gpointer data ){ + Patch_FlipTextureX(); +} + +static void OnBtnPatchFlipY( GtkWidget *widget, gpointer data ){ + Patch_FlipTextureY(); } struct PatchRotateTexture @@ -825,7 +823,7 @@ GtkWindow* PatchInspector::BuildDialog(){ g_signal_connect( G_OBJECT( entry ), "key_press_event", G_CALLBACK( OnDialogKey ), 0 ); } { - GtkTable* table = GTK_TABLE( gtk_table_new( 5, 3, FALSE ) ); + GtkTable* table = GTK_TABLE( gtk_table_new( 5, 4, FALSE ) ); gtk_widget_show( GTK_WIDGET( table ) ); gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); gtk_table_set_row_spacings( table, 5 ); @@ -833,16 +831,16 @@ GtkWindow* PatchInspector::BuildDialog(){ { GtkLabel* label = GTK_LABEL( gtk_label_new( "Horizontal Shift Step" ) ); gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 0, 1, - (GtkAttachOptions)( GTK_FILL ), + gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 0, 1, + (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), (GtkAttachOptions)( 0 ), 0, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); } { GtkLabel* label = GTK_LABEL( gtk_label_new( "Vertical Shift Step" ) ); gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 1, 2, - (GtkAttachOptions)( GTK_FILL ), + gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 1, 2, + (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), (GtkAttachOptions)( 0 ), 0, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); } @@ -850,23 +848,41 @@ GtkWindow* PatchInspector::BuildDialog(){ GtkLabel* label = GTK_LABEL( gtk_label_new( "Horizontal Stretch Step" ) ); gtk_widget_show( GTK_WIDGET( label ) ); gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 2, 3, - (GtkAttachOptions)( GTK_FILL ), + (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), (GtkAttachOptions)( 0 ), 0, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); } + { + GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "FlipX" ) ); + gtk_widget_show( GTK_WIDGET( button ) ); + gtk_table_attach( table, GTK_WIDGET( button ), 3, 4, 2, 3, + (GtkAttachOptions)( GTK_FILL ), + (GtkAttachOptions)( 0 ), 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFlipX ), 0 ); + gtk_widget_set_usize( GTK_WIDGET( button ), 60, -1 ); + } { GtkLabel* label = GTK_LABEL( gtk_label_new( "Vertical Stretch Step" ) ); gtk_widget_show( GTK_WIDGET( label ) ); gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 3, 4, - (GtkAttachOptions)( GTK_FILL ), + (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), (GtkAttachOptions)( 0 ), 0, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); } + { + GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "FlipY" ) ); + gtk_widget_show( GTK_WIDGET( button ) ); + gtk_table_attach( table, GTK_WIDGET( button ), 3, 4, 3, 4, + (GtkAttachOptions)( GTK_FILL ), + (GtkAttachOptions)( 0 ), 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( OnBtnPatchFlipY ), 0 ); + gtk_widget_set_usize( GTK_WIDGET( button ), 60, -1 ); + } { GtkLabel* label = GTK_LABEL( gtk_label_new( "Rotate Step" ) ); gtk_widget_show( GTK_WIDGET( label ) ); - gtk_table_attach( table, GTK_WIDGET( label ), 2, 3, 4, 5, - (GtkAttachOptions)( GTK_FILL ), + gtk_table_attach( table, GTK_WIDGET( label ), 2, 4, 4, 5, + (GtkAttachOptions)( GTK_FILL|GTK_EXPAND ), (GtkAttachOptions)( 0 ), 0, 0 ); gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); } diff --git a/radiant/patchmanip.cpp b/radiant/patchmanip.cpp index 5a6db29c..7ca446c1 100644 --- a/radiant/patchmanip.cpp +++ b/radiant/patchmanip.cpp @@ -687,6 +687,24 @@ void Patch_NaturalTexture(){ Scene_PatchNaturalTexture_Selected( GlobalSceneGraph() ); } +void Patch_CapTexture(){ + UndoableCommand command( "patchCapTexture" ); + Scene_PatchCapTexture_Selected( GlobalSceneGraph() ); +} + +void Patch_ResetTexture(){ + float fx, fy; + if ( DoTextureLayout( &fx, &fy ) == eIDOK ) { + UndoableCommand command( "patchTileTexture" ); + Scene_PatchTileTexture_Selected( GlobalSceneGraph(), fx, fy ); + } +} + +void Patch_FitTexture(){ + UndoableCommand command( "patchFitTexture" ); + Scene_PatchTileTexture_Selected( GlobalSceneGraph(), 1, 1 ); +} + void DoPatchDeformDlg(); void Patch_Deform(){ @@ -778,10 +796,6 @@ void PatchPreferences_construct(){ void Patch_registerCommands(){ GlobalCommands_insert( "InvertCurveTextureX", FreeCaller(), Accelerator( 'I', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); GlobalCommands_insert( "InvertCurveTextureY", FreeCaller(), Accelerator( 'I', (GdkModifierType)GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "IncPatchColumn", FreeCaller(), Accelerator( GDK_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "IncPatchRow", FreeCaller(), Accelerator( GDK_KP_Add, (GdkModifierType)GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "DecPatchColumn", FreeCaller(), Accelerator( GDK_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); - GlobalCommands_insert( "DecPatchRow", FreeCaller(), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "NaturalizePatch", FreeCaller(), Accelerator( 'N', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "PatchCylinder", FreeCaller() ); GlobalCommands_insert( "PatchDenseCylinder", FreeCaller() ); @@ -797,14 +811,14 @@ void Patch_registerCommands(){ GlobalCommands_insert( "PatchCone", FreeCaller() ); GlobalCommands_insert( "PatchSphere", FreeCaller() ); GlobalCommands_insert( "SimplePatchMesh", FreeCaller(), Accelerator( 'P', (GdkModifierType)GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "PatchInsertInsertColumn", FreeCaller() ); + GlobalCommands_insert( "PatchInsertInsertColumn", FreeCaller(), Accelerator( GDK_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); GlobalCommands_insert( "PatchInsertAddColumn", FreeCaller() ); - GlobalCommands_insert( "PatchInsertInsertRow", FreeCaller() ); + GlobalCommands_insert( "PatchInsertInsertRow", FreeCaller(), Accelerator( GDK_KP_Add, (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "PatchInsertAddRow", FreeCaller() ); GlobalCommands_insert( "PatchDeleteFirstColumn", FreeCaller() ); - GlobalCommands_insert( "PatchDeleteLastColumn", FreeCaller() ); + GlobalCommands_insert( "PatchDeleteLastColumn", FreeCaller(), Accelerator( GDK_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); GlobalCommands_insert( "PatchDeleteFirstRow", FreeCaller() ); - GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller() ); + GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller(), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "InvertCurve", FreeCaller(), Accelerator( 'I', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "RedisperseRows", FreeCaller(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) ); GlobalCommands_insert( "RedisperseCols", FreeCaller(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); @@ -860,11 +874,11 @@ void Patch_constructMenu( GtkMenu* menu ){ if ( g_Layout_enableDetachableMenus.m_value ) { menu_tearoff( menu_in_menu ); } - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Columns", "PatchInsertInsertColumn" ); create_menu_item_with_mnemonic( menu_in_menu, "Add (2) Columns", "PatchInsertAddColumn" ); + create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Columns", "PatchInsertInsertColumn" ); menu_separator( menu_in_menu ); - create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Rows", "PatchInsertInsertRow" ); create_menu_item_with_mnemonic( menu_in_menu, "Add (2) Rows", "PatchInsertAddRow" ); + create_menu_item_with_mnemonic( menu_in_menu, "Insert (2) Rows", "PatchInsertInsertRow" ); } { GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "Delete" ); diff --git a/radiant/patchmanip.h b/radiant/patchmanip.h index 4666ae73..d6d8764c 100644 --- a/radiant/patchmanip.h +++ b/radiant/patchmanip.h @@ -51,6 +51,13 @@ void PatchPreferences_construct(); void Patch_registerPreferencesPage(); +void Patch_NaturalTexture(); +void Patch_CapTexture(); +void Patch_ResetTexture(); +void Patch_FitTexture(); +void Patch_FlipTextureX(); +void Patch_FlipTextureY(); + class PatchCreator; extern PatchCreator* g_patchCreator; diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index e48f9b02..55946cfe 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -452,23 +452,19 @@ void SurfaceInspector_FitTextureH(){ } static void OnBtnPatchdetails( GtkWidget *widget, gpointer data ){ - Scene_PatchCapTexture_Selected( GlobalSceneGraph() ); + Patch_CapTexture(); } static void OnBtnPatchnatural( GtkWidget *widget, gpointer data ){ - Scene_PatchNaturalTexture_Selected( GlobalSceneGraph() ); + Patch_NaturalTexture(); } static void OnBtnPatchreset( GtkWidget *widget, gpointer data ){ - float fx, fy; - - if ( DoTextureLayout( &fx, &fy ) == eIDOK ) { - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), fx, fy ); - } + Patch_ResetTexture(); } static void OnBtnPatchFit( GtkWidget *widget, gpointer data ){ - Scene_PatchTileTexture_Selected( GlobalSceneGraph(), 1, 1 ); + Patch_FitTexture(); } static void OnBtnAxial( GtkWidget *widget, gpointer data ){ diff --git a/radiant/texwindow.cpp b/radiant/texwindow.cpp index d18a152e..8bf0efb0 100644 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@ -319,6 +319,8 @@ void getTextureWH( qtexture_t* tex, int &W, int &H ){ // Don't use uniform size W = (int)( tex->width * ( (float)m_textureScale / 100 ) ); H = (int)( tex->height * ( (float)m_textureScale / 100 ) ); + if ( W < 1 ) W = 1; + if ( H < 1 ) H = 1; if ( g_TextureBrowser_fixedSize ){ if ( W >= H ) { @@ -475,7 +477,7 @@ void Texture_NextPos( TextureBrowser& textureBrowser, TextureLayout& layout, qte 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; + layout.current_y -= layout.current_row + TextureBrowser_fontHeight( textureBrowser ) + 4;//+4 layout.current_row = 0; } @@ -947,12 +949,15 @@ void TextureBrowser_Focus( TextureBrowser& textureBrowser, const char* name ){ // we have found when texdef->name and the shader name match // NOTE: as everywhere else for our comparisons, we are not case sensitive if ( shader_equal( name, shader->getName() ) ) { - int textureHeight = (int)( q->height * ( (float)textureBrowser.m_textureScale / 100 ) ) - + 2 * TextureBrowser_fontHeight( textureBrowser ); + //int textureHeight = (int)( q->height * ( (float)textureBrowser.m_textureScale / 100 ) ) + 2 * TextureBrowser_fontHeight( textureBrowser ); + int textureWidth, textureHeight; + textureBrowser.getTextureWH( q, textureWidth, textureHeight ); + textureHeight += 2 * TextureBrowser_fontHeight( textureBrowser ); + int originy = TextureBrowser_getOriginY( textureBrowser ); if ( y > originy ) { - originy = y; + originy = y + 4; } if ( y - textureHeight < originy - textureBrowser.height ) { @@ -1142,38 +1147,14 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ // if !texture_showinuse: (some textures displayed may not be in use) // draw an additional square around with 0.5 1 0.5 color glLineWidth( 1 ); - // shader border: - if ( !shader->IsDefault() ) { - //real 1px white/black stipple - glColor3f( 0, 0, 0 ); - glDisable( GL_TEXTURE_2D ); - - float xf = (float)x; - float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) ); - glBegin( GL_LINE_LOOP ); - glVertex2f( xf - 1.5,yf + 1.5 ); - glVertex2f( xf - 1.5,yf - nHeight - 1.5 ); - glVertex2f( xf + 1.5 + nWidth,yf - nHeight - 1.5 ); - glVertex2f( xf + 1.5 + nWidth,yf + 1.5 ); - - glEnd(); - - glEnable( GL_LINE_STIPPLE ); - glLineStipple( 1, 0x0FFF ); - - glBegin( GL_LINE_LOOP ); - glColor3f( 1, 1, 1 ); - - glVertex2f( xf - 1.5,yf + 1.5 ); - glVertex2f( xf - 1.5,yf - nHeight - 1.5 ); - glVertex2f( xf + 1.5 + nWidth,yf - nHeight - 1.5 ); - glVertex2f( xf + 1.5 + nWidth,yf + 1.5 ); - - glEnd(); - glDisable( GL_LINE_STIPPLE ); - glEnable( GL_TEXTURE_2D ); - - } + const float xf = (float)x; + const float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) ); + float xfMax = xf + 1.5 + nWidth; + float xfMin = xf - 1.5; + float yfMax = yf + 1.5; + float yfMin = yf - nHeight - 1.5; + + //selected texture if ( shader_equal( TextureBrowser_GetSelectedShader( textureBrowser ), shader->getName() ) ) { glLineWidth( 2 ); if ( textureBrowser.m_rmbSelected ) { @@ -1182,31 +1163,55 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ else { glColor3f( 1,0,0 ); } + xfMax += .5; + xfMin -= .5; + yfMax += .5; + yfMin -= .5; glDisable( GL_TEXTURE_2D ); - glBegin( GL_LINE_LOOP ); - glVertex2i( x - 4,y - TextureBrowser_fontHeight( textureBrowser ) + 4 ); - glVertex2i( x - 4,y - TextureBrowser_fontHeight( textureBrowser ) - nHeight - 4 ); - glVertex2i( x + 4 + nWidth,y - TextureBrowser_fontHeight( textureBrowser ) - nHeight - 4 ); - glVertex2i( x + 4 + nWidth,y - TextureBrowser_fontHeight( textureBrowser ) + 4 ); + glVertex2f( xfMin ,yfMax ); + glVertex2f( xfMin ,yfMin ); + glVertex2f( xfMax ,yfMin ); + glVertex2f( xfMax ,yfMax ); glEnd(); - glEnable( GL_TEXTURE_2D ); - glLineWidth( 1 ); } // highlight in-use textures else if ( !textureBrowser.m_hideUnused && shader->IsInUse() ) { - //1px with float - float xf = (float)x; - float yf = (float)( y - TextureBrowser_fontHeight( textureBrowser ) ); glColor3f( 0.5,1,0.5 ); glDisable( GL_TEXTURE_2D ); glBegin( GL_LINE_LOOP ); - glVertex2f( xf - 3.5,yf + 3.5 ); - glVertex2f( xf - 3.5,yf - nHeight - 3.5 ); - glVertex2f( xf + 3.5 + nWidth,yf - nHeight - 3.5 ); - glVertex2f( xf + 3.5 + nWidth,yf + 3.5 ); + glVertex2f( xfMin ,yfMax ); + glVertex2f( xfMin ,yfMin ); + glVertex2f( xfMax ,yfMin ); + glVertex2f( xfMax ,yfMax ); + glEnd(); + glEnable( GL_TEXTURE_2D ); + } + // shader white border: + else if ( !shader->IsDefault() ) { + glColor3f( 1, 1, 1 ); + glDisable( GL_TEXTURE_2D ); + glBegin( GL_LINE_LOOP ); + glVertex2f( xfMin ,yfMax ); + glVertex2f( xfMin ,yfMin ); + glVertex2f( xfMax ,yfMin ); + glVertex2f( xfMax ,yfMax ); glEnd(); + } + + // shader stipple: + if ( !shader->IsDefault() ) { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, 0xF000 ); + glBegin( GL_LINE_LOOP ); + glColor3f( 0, 0, 0 ); + glVertex2f( xfMin ,yfMax ); + glVertex2f( xfMin ,yfMin ); + glVertex2f( xfMax ,yfMin ); + glVertex2f( xfMax ,yfMax ); + glEnd(); + glDisable( GL_LINE_STIPPLE ); glEnable( GL_TEXTURE_2D ); } @@ -1253,7 +1258,7 @@ void Texture_Draw( TextureBrowser& textureBrowser ){ glDisable( GL_TEXTURE_2D ); glColor3f( 1,1,1 ); - glRasterPos2i( x, y - TextureBrowser_fontHeight( textureBrowser ) + 5 ); + glRasterPos2i( x, y - TextureBrowser_fontHeight( textureBrowser ) + 2 );//+5 // don't draw the directory name const char* name = shader->getName(); diff --git a/radiant/treemodel.cpp b/radiant/treemodel.cpp index 4d2f8238..647e88ad 100644 --- a/radiant/treemodel.cpp +++ b/radiant/treemodel.cpp @@ -647,7 +647,13 @@ void detach( const NameCallback& callback ){ }; void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - if ( &node != 0 ) { + // line 650: Reference cannot be bound to dereferenced null pointer in well-defined + // C++ code, and Clang will assume that comparison below always evaluates + // to true, resulting in a segmentation fault. Use a dirty hack to force + // Clang to check those "bad" references for null nonetheless. + volatile intptr_t n = (intptr_t)&node; + + if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { nameable->attach( callback ); @@ -655,7 +661,9 @@ void node_attach_name_changed_callback( scene::Node& node, const NameCallback& c } } void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - if ( &node != 0 ) { + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 + + if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { nameable->detach( callback ); @@ -1124,7 +1132,8 @@ void graph_tree_model_row_deleted( GraphTreeModel& model, GraphTreeNode::iterato const char* node_get_name( scene::Node& node ); const char* node_get_name_safe( scene::Node& node ){ - if ( &node == 0 ) { + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 + if ( n == 0 ) { return ""; } return node_get_name( node ); @@ -1142,7 +1151,8 @@ GraphTreeNode* graph_tree_model_find_parent( GraphTreeModel* model, const scene: } void node_attach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - if ( &node != 0 ) { + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 + if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { nameable->attach( callback ); @@ -1150,7 +1160,8 @@ void node_attach_name_changed_callback( scene::Node& node, const NameCallback& c } } void node_detach_name_changed_callback( scene::Node& node, const NameCallback& callback ){ - if ( &node != 0 ) { + volatile intptr_t n = (intptr_t)&node; // see the comment on line 650 + if ( n != 0 ) { Nameable* nameable = Node_getNameable( node ); if ( nameable != 0 ) { nameable->detach( callback ); diff --git a/setup/data/tools/global.xlink b/setup/data/tools/global.xlink index 86b2945f..1e16121f 100644 --- a/setup/data/tools/global.xlink +++ b/setup/data/tools/global.xlink @@ -12,5 +12,6 @@ + -- 2.39.2