+# TODO: when deleting this Makefile, don't forget to also delete conftest.cpp
+# which is only required by this Makefile
+
+ifeq ($(I_KNOW_MAKEFILE_IS_DEPRECATED),)
+ $(shell printf 'ERROR: Makefile build is deprecated, use CMake instead, see README.md\n\n' >&2)
+ $(error I_KNOW_MAKEFILE_IS_DEPRECATED is not set)
+else
+ $(shell printf 'WARNING: deprecated Makefile build enforced\n\n' >&2)
+endif
+
MAKEFILE_CONF ?= Makefile.conf
-include $(MAKEFILE_CONF)
CPPFLAGS ?=
LIBS ?=
RADIANT_ABOUTMSG ?= Custom build
+RADIANT_NAME ?= NetRadiant
+RADIANT_BASENAME ?= netradiant
# warning: this directory may NOT contain any files other than the ones written by this Makefile!
# NEVER SET THIS TO A SYSTEM WIDE "bin" DIRECTORY!
else
ifeq ($(OS),Win32)
- CPPFLAGS_COMMON += -DWIN32 -D_WIN32 -D_inline=inline
+ CPPFLAGS_COMMON += -DWIN32 -D_WIN32 -D_inline=inline -DWORKAROUND_WINDOWS_FLOATING_WINDOW=1 -DWORKAROUND_WINDOWS_GTK2_GLWIDGET=1
CFLAGS_COMMON += -mms-bitfields
LDFLAGS_DLL = -Wl,--add-stdcall-alias
LIBS_COMMON = -lws2_32 -luser32 -lgdi32 -lole32
RADIANT_VERSION = $(RADIANT_VERSION_NUMBER)n
Q3MAP_VERSION = 2.5.17n
-# Executable extension
-RADIANT_EXECUTABLE := $(EXE)
-
GIT_VERSION := $(shell $(GIT) rev-parse --short HEAD $(STDERR_TO_DEVNULL))
ifneq ($(GIT_VERSION),)
RADIANT_VERSION := $(RADIANT_VERSION)-git-$(GIT_VERSION)
Q3MAP_VERSION := $(Q3MAP_VERSION)-git-$(GIT_VERSION)
endif
-CPPFLAGS += -DRADIANT_VERSION="\"$(RADIANT_VERSION)\"" -DRADIANT_MAJOR_VERSION="\"$(RADIANT_MAJOR_VERSION)\"" -DRADIANT_MINOR_VERSION="\"$(RADIANT_MINOR_VERSION)\"" -DRADIANT_PATCH_VERSION="\"$(RADIANT_PATCH_VERSION)\"" -DRADIANT_ABOUTMSG="\"$(RADIANT_ABOUTMSG)\"" -DQ3MAP_VERSION="\"$(Q3MAP_VERSION)\"" -DRADIANT_EXECUTABLE="\"$(RADIANT_EXECUTABLE)\""
+CPPFLAGS += -DRADIANT_VERSION="\"$(RADIANT_VERSION)\"" -DRADIANT_VERSION_STRING="\"$(RADIANT_VERSION_STRING)\"" -DRADIANT_ABOUTMSG="\"$(RADIANT_ABOUTMSG)\"" -DRADIANT_NAME="\"${RADIANT_NAME}\"" -DRADIANT_BASENAME="\"${RADIANT_BASENAME}\"" -DQ3MAP_VERSION="\"$(Q3MAP_VERSION)\""
CPPFLAGS += -DGTK_TARGET=2
.PHONY: all
.PHONY: binaries-h2data
binaries-h2data: \
- $(INSTALLDIR)/heretic2/h2data.$(EXE) \
- $(INSTALLDIR)/heretic2/h2data \
+ $(INSTALLDIR)/h2data.$(EXE) \
+ $(INSTALLDIR)/h2data \
.PHONY: binaries-tools-quake3
binaries-tools-quake3: \
%.o: %.c $(if $(findstring $(DEPEND_ON_MAKEFILE),yes),$(wildcard Makefile*),) | dependencies-check
$(CC) $< $(CFLAGS) $(CFLAGS_COMMON) $(CPPFLAGS_EXTRA) $(CPPFLAGS_COMMON) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@
- $(INSTALLDIR)/q3map2.$(EXE): LDFLAGS_EXTRA := -Wl,--large-address-aware
+ ifeq ($(OS),Win32)
+ $(INSTALLDIR)/q3map2.$(EXE): LDFLAGS_EXTRA := -Wl,--large-address-aware,--stack,4194304
+ endif
$(INSTALLDIR)/q3map2.$(EXE): LIBS_EXTRA := $(LIBS_XML) $(LIBS_GLIB) $(LIBS_PNG) $(LIBS_JPEG) $(LIBS_WEBP) $(LIBS_ZLIB)
$(INSTALLDIR)/q3map2.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) $(CPPFLAGS_PNG) $(CPPFLAGS_JPEG) $(CPPFLAGS_WEBP) -Itools/quake3/common -Ilibs -Iinclude
$(INSTALLDIR)/q3map2.$(EXE): \
contrib/bkgrnd2d/dialog.o \
contrib/bkgrnd2d/plugin.o \
-$(INSTALLDIR)/heretic2/h2data.$(EXE): LIBS_EXTRA := $(LIBS_XML)
-$(INSTALLDIR)/heretic2/h2data.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) -Itools/quake2/qdata_heretic2/common -Itools/quake2/qdata_heretic2/qcommon -Itools/quake2/qdata_heretic2 -Itools/quake2/common -Ilibs -Iinclude
-$(INSTALLDIR)/heretic2/h2data.$(EXE): \
- tools/quake2/qdata_heretic2/common/bspfile.o \
- tools/quake2/qdata_heretic2/common/cmdlib.o \
- tools/quake2/qdata_heretic2/common/inout.o \
- tools/quake2/qdata_heretic2/common/l3dslib.o \
- tools/quake2/qdata_heretic2/common/lbmlib.o \
- tools/quake2/qdata_heretic2/common/mathlib.o \
- tools/quake2/qdata_heretic2/common/md4.o \
- tools/quake2/qdata_heretic2/common/path_init.o \
- tools/quake2/qdata_heretic2/common/qfiles.o \
- tools/quake2/qdata_heretic2/common/scriplib.o \
- tools/quake2/qdata_heretic2/common/threads.o \
- tools/quake2/qdata_heretic2/common/token.o \
- tools/quake2/qdata_heretic2/common/trilib.o \
- tools/quake2/qdata_heretic2/qcommon/reference.o \
- tools/quake2/qdata_heretic2/qcommon/resourcemanager.o \
- tools/quake2/qdata_heretic2/qcommon/skeletons.o \
- tools/quake2/qdata_heretic2/animcomp.o \
- tools/quake2/qdata_heretic2/book.o \
- tools/quake2/qdata_heretic2/fmodels.o \
- tools/quake2/qdata_heretic2/images.o \
- tools/quake2/qdata_heretic2/jointed.o \
- tools/quake2/qdata_heretic2/models.o \
- tools/quake2/qdata_heretic2/pics.o \
- tools/quake2/qdata_heretic2/qdata.o \
- tools/quake2/qdata_heretic2/qd_skeletons.o \
- tools/quake2/qdata_heretic2/sprites.o \
- tools/quake2/qdata_heretic2/svdcmp.o \
- tools/quake2/qdata_heretic2/tables.o \
- tools/quake2/qdata_heretic2/tmix.o \
- tools/quake2/qdata_heretic2/video.o \
+$(INSTALLDIR)/h2data.$(EXE): LIBS_EXTRA := $(LIBS_XML)
+$(INSTALLDIR)/h2data.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) -Itools/heretic2/common -Itools/heretic2/qcommon -Itools/heretic2/h2data -Itools/quake2/common -Ilibs -Iinclude
+$(INSTALLDIR)/h2data.$(EXE): \
+ tools/heretic2/common/bspfile.o \
+ tools/heretic2/common/cmdlib.o \
+ tools/heretic2/common/inout.o \
+ tools/heretic2/common/l3dslib.o \
+ tools/heretic2/common/lbmlib.o \
+ tools/heretic2/common/mathlib.o \
+ tools/heretic2/common/md4.o \
+ tools/heretic2/common/path_init.o \
+ tools/heretic2/common/qfiles.o \
+ tools/heretic2/common/scriplib.o \
+ tools/heretic2/common/threads.o \
+ tools/heretic2/common/token.o \
+ tools/heretic2/common/trilib.o \
+ tools/heretic2/qcommon/reference.o \
+ tools/heretic2/qcommon/resourcemanager.o \
+ tools/heretic2/qcommon/skeletons.o \
+ tools/heretic2/h2data/animcomp.o \
+ tools/heretic2/h2data/book.o \
+ tools/heretic2/h2data/fmodels.o \
+ tools/heretic2/h2data/images.o \
+ tools/heretic2/h2data/jointed.o \
+ tools/heretic2/h2data/models.o \
+ tools/heretic2/h2data/pics.o \
+ tools/heretic2/h2data/qdata.o \
+ tools/heretic2/h2data/qd_skeletons.o \
+ tools/heretic2/h2data/sprites.o \
+ tools/heretic2/h2data/svdcmp.o \
+ tools/heretic2/h2data/tables.o \
+ tools/heretic2/h2data/tmix.o \
+ tools/heretic2/h2data/video.o \
libl_net.$(A) \
$(if $(findstring $(OS),Win32),icons/h2data.o,) \
.PHONY: install-data
install-data: binaries
- $(MKDIR) $(INSTALLDIR)/games
- DOWNLOAD_GAMEPACKS="$(DOWNLOAD_GAMEPACKS)" DOWNLOADDIR="$(DOWNLOADDIR)" INSTALLDIR="$(INSTALLDIR)" GIT="$(GIT)" SVN="$(SVN)" WGET="$(WGET)" RM_R="$(RM_R)" MV="$(MV)" UNZIPPER="$(UNZIPPER)" ECHO="$(ECHO)" SH="$(SH)" CP="$(CP)" CP_R="$(CP_R)" $(SH) gamepack-manager
+ DOWNLOAD_GAMEPACKS="$(DOWNLOAD_GAMEPACKS)" DOWNLOADDIR="$(DOWNLOADDIR)" INSTALLDIR="$(INSTALLDIR)/gamepacks" GIT="$(GIT)" SVN="$(SVN)" WGET="$(WGET)" RM_R="$(RM_R)" MV="$(MV)" UNZIPPER="$(UNZIPPER)" ECHO="$(ECHO)" CP="$(CP)" CP_R="$(CP_R)" ./gamepack-manager
$(ECHO) $(RADIANT_MAJOR_VERSION) > $(INSTALLDIR)/RADIANT_MAJOR
$(ECHO) $(RADIANT_MINOR_VERSION) > $(INSTALLDIR)/RADIANT_MINOR
$(ECHO) $(RADIANT_PATCH_VERSION) > $(INSTALLDIR)/RADIANT_PATCH
return string_equal_n( s , suffix, string_length( suffix ) );
}
+ inline bool string_equal_suffix_nocase( const char* string, const char* suffix){
+ const char *s = string + string_length( string ) - string_length( suffix );
+ return string_equal_nocase_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)
/// \brief A re-entrant string tokeniser similar to strchr.
class StringTokeniser
{
-bool istoken( char c ) const {
- if ( strchr( m_delimiters, c ) != 0 ) {
- return false;
- }
- return true;
-}
-const char* advance(){
- const char* token = m_pos;
- bool intoken = true;
- while ( !string_empty( m_pos ) )
- {
- if ( !istoken( *m_pos ) ) {
- *m_pos = '\0';
- intoken = false;
+private:
+ bool istoken( char c ) const {
+ if ( strchr( m_delimiters, c ) != 0 ) {
+ return false;
}
- else if ( !intoken ) {
- return token;
+ return true;
+ }
+ const char* advance(){
+ const char* token = m_pos;
+ bool intoken = true;
+ while ( !string_empty( m_pos ) )
+ {
+ if ( !istoken( *m_pos ) ) {
+ *m_pos = '\0';
+ intoken = false;
+ }
+ else if ( !intoken ) {
+ return token;
+ }
+ ++m_pos;
}
- ++m_pos;
+ return token;
}
- return token;
-}
-std::size_t m_length;
-char* m_string;
-char* m_pos;
-const char* m_delimiters;
+ std::size_t m_length;
+ char* m_string;
+ char* m_pos;
+ const char* m_delimiters;
+
public:
-StringTokeniser( const char* string, const char* delimiters = " \n\r\t\v" ) :
- m_length( string_length( string ) ),
- m_string( string_copy( string_new( m_length ), string ) ),
- m_pos( m_string ),
- m_delimiters( delimiters ){
- while ( !string_empty( m_pos ) && !istoken( *m_pos ) )
- {
- ++m_pos;
+ StringTokeniser( const char* string, const char* delimiters = " \n\r\t\v" ) :
+ m_length( string_length( string ) ),
+ m_string( string_copy( string_new( m_length ), string ) ),
+ m_pos( m_string ),
+ m_delimiters( delimiters ){
+ while ( !string_empty( m_pos ) && !istoken( *m_pos ) )
+ {
+ ++m_pos;
+ }
+ }
+ ~StringTokeniser(){
+ string_release( m_string, m_length );
+ }
+ /// \brief Returns the next token or "" if there are no more tokens available.
+ const char* getToken(){
+ return advance();
}
-}
-~StringTokeniser(){
- string_release( m_string, m_length );
-}
-/// \brief Returns the next token or "" if there are no more tokens available.
-const char* getToken(){
- return advance();
-}
};
/// \brief A non-mutable c-style string.
class String : public Buffer
{
public:
+ String()
+ : Buffer(){
+ }
+ String( const char* string )
+ : Buffer( string ){
+ }
+ String( StringRange range )
+ : Buffer( range ){
+ }
-String()
- : Buffer(){
-}
-String( const char* string )
- : Buffer( string ){
-}
-String( StringRange range )
- : Buffer( range ){
-}
+ String(const String&) = default;
-String& operator=( const String& other ){
- String temp( other );
- temp.swap( *this );
- return *this;
-}
-String& operator=( const char* string ){
- String temp( string );
- temp.swap( *this );
- return *this;
-}
-String& operator=( StringRange range ){
- String temp( range );
- temp.swap( *this );
- return *this;
-}
+ String& operator=( const String& other ){
+ String temp( other );
+ temp.swap( *this );
+ return *this;
+ }
+ String& operator=( const char* string ){
+ String temp( string );
+ temp.swap( *this );
+ return *this;
+ }
+ String& operator=( StringRange range ){
+ String temp( range );
+ temp.swap( *this );
+ return *this;
+ }
-void swap( String& other ){
- Buffer::swap( other );
-}
+ void swap( String& other ){
+ Buffer::swap( other );
+ }
-bool empty() const {
- return string_empty( Buffer::c_str() );
-}
+ bool empty() const {
+ return string_empty( Buffer::c_str() );
+ }
};
template<typename Buffer>
template<typename Allocator>
class CopiedBuffer : private Allocator
{
-char* m_string;
+ char* m_string;
-char* copy_range( StringRange range ){
- return string_clone_range( range, static_cast<Allocator&>( *this ) );
-}
-char* copy( const char* other ){
- return string_clone( other, static_cast<Allocator&>( *this ) );
-}
-void destroy( char* string ){
- string_release( string, string_length( string ), static_cast<Allocator&>( *this ) );
-}
+ char* copy_range( StringRange range ){
+ return string_clone_range( range, static_cast<Allocator&>( *this ) );
+ }
+ char* copy( const char* other ){
+ return string_clone( other, static_cast<Allocator&>( *this ) );
+ }
+ void destroy( char* string ){
+ string_release( string, string_length( string ), static_cast<Allocator&>( *this ) );
+ }
protected:
-~CopiedBuffer(){
- destroy( m_string );
-}
+ ~CopiedBuffer(){
+ destroy( m_string );
+ }
+
public:
-CopiedBuffer()
- : m_string( copy( "" ) ){
-}
-explicit CopiedBuffer( const Allocator& allocator )
- : Allocator( allocator ), m_string( copy( "" ) ){
-}
-CopiedBuffer( const CopiedBuffer& other )
- : Allocator( other ), m_string( copy( other.m_string ) ){
-}
-CopiedBuffer( const char* string, const Allocator& allocator = Allocator() )
- : Allocator( allocator ), m_string( copy( string ) ){
-}
-CopiedBuffer( StringRange range, const Allocator& allocator = Allocator() )
- : Allocator( allocator ), m_string( copy_range( range ) ){
-}
-const char* c_str() const {
- return m_string;
-}
-void swap( CopiedBuffer& other ){
- string_swap( m_string, other.m_string );
-}
+ CopiedBuffer()
+ : m_string( copy( "" ) ){
+ }
+ explicit CopiedBuffer( const Allocator& allocator )
+ : Allocator( allocator ), m_string( copy( "" ) ){
+ }
+ CopiedBuffer( const CopiedBuffer& other )
+ : Allocator( other ), m_string( copy( other.m_string ) ){
+ }
+ CopiedBuffer( const char* string, const Allocator& allocator = Allocator() )
+ : Allocator( allocator ), m_string( copy( string ) ){
+ }
+ CopiedBuffer( StringRange range, const Allocator& allocator = Allocator() )
+ : Allocator( allocator ), m_string( copy_range( range ) ){
+ }
+ const char* c_str() const {
+ return m_string;
+ }
+ void swap( CopiedBuffer& other ){
+ string_swap( m_string, other.m_string );
+ }
};
/// \brief A non-mutable string which uses copy-by-value for assignment.
template<typename Allocator>
class SmartBuffer : private Allocator
{
-char* m_buffer;
-
-char* copy_range( StringRange range ){
- char* buffer = Allocator::allocate( sizeof( std::size_t ) + ( range.last - range.first ) + 1 );
- strncpy( buffer + sizeof( std::size_t ), range.first, range.last - range.first );
- buffer[sizeof( std::size_t ) + ( range.last - range.first )] = '\0';
- *reinterpret_cast<std::size_t*>( buffer ) = 0;
- return buffer;
-}
-char* copy( const char* string ){
- char* buffer = Allocator::allocate( sizeof( std::size_t ) + string_length( string ) + 1 );
- strcpy( buffer + sizeof( std::size_t ), string );
- *reinterpret_cast<std::size_t*>( buffer ) = 0;
- return buffer;
-}
-void destroy( char* buffer ){
- Allocator::deallocate( buffer, sizeof( std::size_t ) + string_length( c_str() ) + 1 );
-}
+private:
+ char* m_buffer;
+
+ char* copy_range( StringRange range ){
+ char* buffer = Allocator::allocate( sizeof( std::size_t ) + ( range.last - range.first ) + 1 );
+ strncpy( buffer + sizeof( std::size_t ), range.first, range.last - range.first );
+ buffer[sizeof( std::size_t ) + ( range.last - range.first )] = '\0';
+ *reinterpret_cast<std::size_t*>( buffer ) = 0;
+ return buffer;
+ }
+ char* copy( const char* string ){
+ char* buffer = Allocator::allocate( sizeof( std::size_t ) + string_length( string ) + 1 );
+ strcpy( buffer + sizeof( std::size_t ), string );
+ *reinterpret_cast<std::size_t*>( buffer ) = 0;
+ return buffer;
+ }
+ void destroy( char* buffer ){
+ Allocator::deallocate( buffer, sizeof( std::size_t ) + string_length( c_str() ) + 1 );
+ }
-void incref( char* buffer ){
- ++( *reinterpret_cast<std::size_t*>( buffer ) );
-}
-void decref( char* buffer ){
- if ( --( *reinterpret_cast<std::size_t*>( buffer ) ) == 0 ) {
- destroy( buffer );
+ void incref( char* buffer ){
+ ++( *reinterpret_cast<std::size_t*>( buffer ) );
+ }
+ void decref( char* buffer ){
+ if ( --( *reinterpret_cast<std::size_t*>( buffer ) ) == 0 ) {
+ destroy( buffer );
+ }
}
-}
protected:
-~SmartBuffer(){
- decref( m_buffer );
-}
+ ~SmartBuffer(){
+ decref( m_buffer );
+ }
+
public:
-SmartBuffer()
- : m_buffer( copy( "" ) ){
- incref( m_buffer );
-}
-explicit SmartBuffer( const Allocator& allocator )
- : Allocator( allocator ), m_buffer( copy( "" ) ){
- incref( m_buffer );
-}
-SmartBuffer( const SmartBuffer& other )
- : Allocator( other ), m_buffer( other.m_buffer ){
- incref( m_buffer );
-}
-SmartBuffer( const char* string, const Allocator& allocator = Allocator() )
- : Allocator( allocator ), m_buffer( copy( string ) ){
- incref( m_buffer );
-}
-SmartBuffer( StringRange range, const Allocator& allocator = Allocator() )
- : Allocator( allocator ), m_buffer( copy_range( range ) ){
- incref( m_buffer );
-}
-const char* c_str() const {
- return m_buffer + sizeof( std::size_t );
-}
-void swap( SmartBuffer& other ){
- string_swap( m_buffer, other.m_buffer );
-}
+ SmartBuffer()
+ : m_buffer( copy( "" ) ){
+ incref( m_buffer );
+ }
+ explicit SmartBuffer( const Allocator& allocator )
+ : Allocator( allocator ), m_buffer( copy( "" ) ){
+ incref( m_buffer );
+ }
+ SmartBuffer( const SmartBuffer& other )
+ : Allocator( other ), m_buffer( other.m_buffer ){
+ incref( m_buffer );
+ }
+ SmartBuffer( const char* string, const Allocator& allocator = Allocator() )
+ : Allocator( allocator ), m_buffer( copy( string ) ){
+ incref( m_buffer );
+ }
+ SmartBuffer( StringRange range, const Allocator& allocator = Allocator() )
+ : Allocator( allocator ), m_buffer( copy_range( range ) ){
+ incref( m_buffer );
+ }
+ const char* c_str() const {
+ return m_buffer + sizeof( std::size_t );
+ }
+ void swap( SmartBuffer& other ){
+ string_swap( m_buffer, other.m_buffer );
+ }
};
/// \brief A non-mutable string which uses copy-by-reference for assignment of SmartString.
class StringEqualNoCase
{
public:
-bool operator()( const CopiedString& key, const CopiedString& other ) const {
- return string_equal_nocase( key.c_str(), other.c_str() );
-}
+ bool operator()( const CopiedString& key, const CopiedString& other ) const {
+ return string_equal_nocase( key.c_str(), other.c_str() );
+ }
};
struct StringLessNoCase
g_build_variables[name] = value;
}
-const char* build_get_variable( const char* name ){
- Variables::iterator i = g_build_variables.find( name );
+const char* build_get_variable( const std::string& name ){
+ Variables::iterator i = g_build_variables.find( name.c_str() );
if ( i != g_build_variables.end() ) {
return ( *i ).second.c_str();
}
- globalErrorStream() << "undefined build variable: " << makeQuoted( name ) << "\n";
+ globalErrorStream() << "undefined build variable: " << makeQuoted( name.c_str() ) << "\n";
return "";
}
{
public:
virtual ~Evaluatable() = default;
-virtual void evaluate( StringBuffer& output ) = 0;
+virtual std::string evaluate() = 0;
virtual void exportXML( XMLImporter& importer ) = 0;
};
class VariableString : public Evaluatable
{
-CopiedString m_string;
+std::string m_string;
public:
VariableString() : m_string(){
}
-VariableString( const char* string ) : m_string( string ){
+VariableString( std::string string ) : m_string( std::move(string) ){
}
const char* c_str() const {
return m_string.c_str();
}
-void setString( const char* string ){
+void setString( const std::string& string ){
m_string = string;
}
-void evaluate( StringBuffer& output ){
- StringBuffer variable;
+std::string evaluate(){
+ // replace ".[ExecutableType]" with "[ExecutableExt]"
+ {
+ size_t pos;
+ const std::string pattern = ".[ExecutableType]";
+ while ( ( pos = m_string.find(pattern) ) != std::string::npos ) {
+ m_string.replace(pos, pattern.length(), "[ExecutableExt]");
+ }
+ }
+
+ // add missing [ExtraQ3map2Args] if "[RadiantPath]q3map2[ExecutableExt]"
+ {
+ size_t pos;
+ const std::string pattern = "\"[RadiantPath]q3map2[ExecutableExt]\"";
+ const std::string extra = "[ExtraQ3map2Args]";
+ if ( ( pos = m_string.find(pattern) ) != std::string::npos
+ && m_string.find(extra) == std::string::npos )
+ {
+ m_string.insert(pos + pattern.size(), " ");
+ m_string.insert(pos + pattern.size() + 1, extra);
+ }
+ }
+
+ std::string output;
+ std::string variable_name;
bool in_variable = false;
- for ( const char* i = m_string.c_str(); *i != '\0'; ++i )
+ for ( const char c : m_string )
{
if ( !in_variable ) {
- switch ( *i )
+ switch ( c )
{
case '[':
in_variable = true;
break;
default:
- output.push_back( *i );
+ output += c;
break;
}
}
else
{
- switch ( *i )
+ switch ( c )
{
case ']':
in_variable = false;
- output.push_string( build_get_variable( variable.c_str() ) );
- variable.clear();
+ output += build_get_variable( variable_name );
+ variable_name.clear();
break;
default:
- variable.push_back( *i );
+ variable_name += c;
break;
}
}
}
+
+ return output;
}
void exportXML( XMLImporter& importer ){
importer << c_str();
delete m_test;
delete m_result;
}
-void evaluate( StringBuffer& output ){
- StringBuffer buffer;
- m_test->evaluate( buffer );
- if ( !string_empty( buffer.c_str() ) ) {
- m_result->evaluate( output );
+std::string evaluate(){
+ std::string result = m_test->evaluate();
+ if ( result.empty() ) {
+ return result;
}
+ return m_result->evaluate();
}
void exportXML( XMLImporter& importer ){
StaticElement conditionElement( "cond" );
void push_back( Evaluatable* evaluatable ){
m_evaluatables.push_back( evaluatable );
}
-void evaluate( StringBuffer& output ){
+std::string evaluate(){
+ std::string result;
for ( Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i )
{
- ( *i )->evaluate( output );
+ result += ( *i )->evaluate();
}
+ return result;
}
void exportXML( XMLImporter& importer ){
for ( Evaluatables::iterator i = m_evaluatables.begin(); i != m_evaluatables.end(); ++i )
class VariableStringXMLConstructor : public XMLElementParser
{
-StringBuffer m_buffer;
+std::string m_buffer;
VariableString& m_variableString;
public:
VariableStringXMLConstructor( VariableString& variableString ) : m_variableString( variableString ){
}
~VariableStringXMLConstructor(){
- m_variableString.setString( m_buffer.c_str() );
+ m_variableString.setString( std::move(m_buffer) );
}
std::size_t write( const char* buffer, std::size_t length ){
- m_buffer.push_range( buffer, buffer + length );
+ m_buffer.append( buffer, length );
return length;
}
XMLElementParser& pushElement( const XMLElement& element ){
class ConditionalXMLConstructor : public XMLElementParser
{
-StringBuffer m_buffer;
+std::string m_buffer;
Conditional& m_conditional;
public:
ConditionalXMLConstructor( Conditional& conditional ) : m_conditional( conditional ){
}
~ConditionalXMLConstructor(){
- m_conditional.m_result = new VariableString( m_buffer.c_str() );
+ m_conditional.m_result = new VariableString( std::move( m_buffer ) );
}
std::size_t write( const char* buffer, std::size_t length ){
- m_buffer.push_range( buffer, buffer + length );
+ m_buffer.append( buffer, length );
return length;
}
XMLElementParser& pushElement( const XMLElement& element ){
class ToolXMLConstructor : public XMLElementParser
{
-StringBuffer m_buffer;
+std::string m_buffer;
Tool& m_tool;
ConditionalXMLConstructor* m_conditional;
public:
flush();
}
std::size_t write( const char* buffer, std::size_t length ){
- m_buffer.push_range( buffer, buffer + length );
+ m_buffer.append( buffer, length );
return length;
}
XMLElementParser& pushElement( const XMLElement& element ){
void flush(){
if ( !m_buffer.empty() ) {
- m_tool.push_back( new VariableString( m_buffer.c_str() ) );
+ m_tool.push_back( new VariableString( std::move( m_buffer ) ) );
m_buffer.clear();
}
}
void build_run( const char* name, CommandListener& listener ){
for ( Tools::iterator i = g_build_tools.begin(); i != g_build_tools.end(); ++i )
{
- StringBuffer output;
- ( *i ).second.evaluate( output );
+ std::string output = ( *i ).second.evaluate();
build_set_variable( ( *i ).first.c_str(), output.c_str() );
}
Build& build = ( *i ).second;
for ( Build::iterator j = build.begin(); j != build.end(); ++j )
{
- StringBuffer output;
- ( *j ).evaluate( output );
+ std::string output = ( *j ).evaluate();
listener.execute( output.c_str() );
}
}
return FALSE;
}
-gboolean commands_cell_edited(ui::CellRendererText cell, gchar* path_string, gchar* new_text, ui::ListStore store ){
+gboolean commands_cell_edited(ui::CellRendererText cell, const gchar* path_string, const gchar* new_text, ui::ListStore store ){
if ( g_current_build == 0 ) {
return FALSE;
}
ui::Window BuildMenuDialog_construct( ModalDialog& modal, ProjectList& projectList ){
ui::Window window = MainFrame_getWindow().create_dialog_window("Build Menu", G_CALLBACK(dialog_delete_callback ), &modal, -1, 400 );
+ // FIXME: GTK_WIN_POS_CENTER_ON_PARENT must be used instead but does not work
+ // for unknown reason.
+ // It's possible MaingFrame_getWindow() does not return the main window.
+ // It's known the preferences window has same issue when using MaingFrame_getWindow().
+ gtk_window_set_position( window, GTK_WIN_POS_CENTER_ALWAYS );
+
{
auto table1 = create_dialog_table( 2, 2, 4, 4, 4 );
window.add(table1);
}
}
{
- auto frame = create_dialog_frame( "Commandline" );
+ auto frame = create_dialog_frame( "Command line" );
table1.attach(frame, {0, 1, 1, 2});
{
auto scr = create_scrolled_window( ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4 );
namespace
{
CopiedString g_buildMenu;
+ CopiedString g_lastExecutedBuild;
}
void LoadBuildMenu();
: m_name( name ), m_item( item ){
}
void run(){
+ g_lastExecutedBuild = m_name;
RunBSP( m_name );
}
typedef MemberCaller<BuildMenuItem, void(), &BuildMenuItem::run> RunCaller;
void BuildMenu_Destroy(){
SaveBuildMenu();
}
+
+
+ void Build_runRecentExecutedBuild(){
+ if( g_lastExecutedBuild.empty() ){
+ g_BuildMenuItems.begin()->run();
+ }
+ else{
+ RunBSP( g_lastExecutedBuild.c_str() );
+ }
+ }
void Face_makeBrush( Face& face, const Brush& brush, brush_vector_t& out, float offset ){
if ( face.contributes() ) {
out.push_back( new Brush( brush ) );
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
face.getPlane().offset( -offset );
face.planeChanged();
if ( newFace != 0 ) {
face.getPlane().offset( offset );
out.push_back( new Brush( brush ) );
face.getPlane().offset( -offset );
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
if ( newFace != 0 ) {
newFace->flipWinding();
newFace->planeChanged();
if( caulk ){
Brush_forEachFace( *out.back(), CaulkFace( ExclusionAxis, mindot, maxdot ) );
}
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
if ( newFace != 0 ) {
newFace->flipWinding();
}
out.push_back( new Brush( brush ) );
if( !RemoveInner && caulk )
face.SetShader( getCaulkShader() );
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
face.getPlane().offset( -offset );
face.planeChanged();
if( caulk )
out.push_back( new Brush( brush ) );
out.back()->clear();
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
if ( newFace != 0 ) {
newFace->getPlane().offset( offset );
newFace->planeChanged();
out.push_back( new Brush( brush ) );
out.back()->clear();
- Face* newFace = out.back()->addFace( face );
+ std::shared_ptr<Face> newFace = out.back()->addFace( face );
if ( newFace != 0 ) {
newFace->planeChanged();
{
( *i )->removeEmptyFaces();
if( ( *i )->hasContributingFaces() ){
- NodeSmartReference node( ( new BrushNode() )->node() );
- Node_getBrush( node )->copy( *( *i ) );
- delete ( *i );
- Node_getTraversable( path.parent() )->insert( node );
+ NodeSmartReference node( ( new BrushNode() )->node() );
+ Node_getBrush( node )->copy( *( *i ) );
+ delete ( *i );
+ Node_getTraversable( path.parent() )->insert( node );
//path.push( makeReference( node.get() ) );
//selectPath( path, true );
//Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true );
return Dereference<Functor>( functor );
}
-typedef Face* FacePointer;
-const FacePointer c_nullFacePointer = 0;
-
-template<typename Predicate>
-Face* Brush_findIf( const Brush& brush, const Predicate& predicate ){
- Brush::const_iterator i = std::find_if( brush.begin(), brush.end(), makeDereference( predicate ) );
- return i == brush.end() ? c_nullFacePointer : *i; // uses c_nullFacePointer instead of 0 because otherwise gcc 4.1 attempts conversion to int
-}
-
template<typename Caller>
class BindArguments1
{
/// \li flipped && brush is FRONT or ON
bool Brush_testPlane( const Brush& brush, const Plane3& plane, bool flipped ){
brush.evaluateBRep();
-#if 1
for ( Brush::const_iterator i( brush.begin() ); i != brush.end(); ++i )
{
if ( Face_testPlane( *( *i ), plane, flipped ) ) {
}
}
return true;
-#else
- return Brush_findIf( brush, bindArguments( FaceTestPlane(), makeReference( plane ), flipped ) ) == 0;
-#endif
}
brushsplit_t Brush_classifyPlane( const Brush& brush, const Plane3& plane ){
fragments.reserve( other.size() );
Brush back( brush );
- for ( Brush::const_iterator i( other.begin() ); i != other.end(); ++i )
+ for ( const std::shared_ptr<Face>& b : other )
{
- if ( ( *i )->contributes() ) {
- brushsplit_t split = Brush_classifyPlane( back, ( *i )->plane3() );
+ if ( b->contributes() ) {
+ brushsplit_t split = Brush_classifyPlane( back, b->plane3() );
if ( split.counts[ePlaneFront] != 0
&& split.counts[ePlaneBack] != 0 ) {
fragments.push_back( new Brush( back ) );
- Face* newFace = fragments.back()->addFace( *( *i ) );
- if ( newFace != 0 ) {
+ std::shared_ptr<Face> newFace = fragments.back()->addFace( *b );
+ if ( newFace != nullptr ) {
newFace->flipWinding();
}
- back.addFace( *( *i ) );
+ back.addFace( *b );
}
else if ( split.counts[ePlaneBack] == 0 ) {
- for ( brush_vector_t::iterator i = fragments.begin(); i != fragments.end(); ++i )
- {
- delete( *i );
+ for ( Brush *i : fragments ) {
+ delete( i );
}
+ fragments.clear();
return false;
}
}
else
{
++m_before;
- for ( brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i )
- {
+ for ( Brush *b : out ) {
++m_after;
- ( *i )->removeEmptyFaces();
- if ( !( *i )->empty() ) {
+ b->removeEmptyFaces();
+ if ( !b->empty() ) {
NodeSmartReference node( ( new BrushNode() )->node() );
- Node_getBrush( node )->copy( *( *i ) );
- delete ( *i );
+ Node_getBrush( node )->copy( *b );
Node_getTraversable( path.parent() )->insert( node );
}
- else{
- delete ( *i );
- }
+ delete b;
}
+ scene::Node& parent = path.parent();
Path_deleteTop( path );
- if( Node_getTraversable( path.parent() )->empty() ){
+ if( Node_getTraversable( parent )->empty() ){
m_eraseParent = true;
}
}
if ( selected_brushes.empty() ) {
globalOutputStream() << "CSG Subtract: No brushes selected.\n";
- }
- else
- {
+ } else {
globalOutputStream() << "CSG Subtract: Subtracting " << Unsigned( selected_brushes.size() ) << " brushes.\n";
UndoableCommand undo( "brushSubtract" );
}
void post( const scene::Path& path, scene::Instance& instance ) const {
- if ( path.top().get().visible() ) {
+ if ( !path.top().get().visible() ) {
+ return;
+ }
+
Brush* brush = Node_getBrush( path.top() );
- if ( brush != 0
- && Instance_getSelectable( instance )->isSelected() ) {
+ if ( brush == nullptr || !Instance_getSelectable( instance )->isSelected() ) {
+ return;
+ }
+
Plane3 plane( plane3_for_points( m_p0, m_p1, m_p2 ) );
- if ( plane3_valid( plane ) ) {
+ if ( !plane3_valid( plane ) ) {
+ return;
+ }
+
brushsplit_t split = Brush_classifyPlane( *brush, m_split == eFront ? plane3_flipped( plane ) : plane );
if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
// the plane intersects this brush
NodeSmartReference node( ( new BrushNode() )->node() );
Brush* fragment = Node_getBrush( node );
fragment->copy( *brush );
- Face* newFace = fragment->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
+ std::shared_ptr<Face> newFace =
+ fragment->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
if ( newFace != 0 && m_split != eFront ) {
newFace->flipWinding();
}
}
}
- Face* newFace = brush->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
+ std::shared_ptr<Face> newFace = brush->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
if ( newFace != 0 && m_split == eFront ) {
newFace->flipWinding();
}
if ( m_split != eFrontAndBack && split.counts[ePlaneBack] != 0 ) {
// the brush is "behind" the plane
Path_deleteTop( path );
- }
- }
- }
}
}
};
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;
}
return false;
}
+
+ const char* openCmdMap;
+
+ void cmdMap(){
+ openCmdMap = NULL;
+ for ( int i = 1; i < g_argc; ++i )
+ {
+ //if ( !stricmp( g_argv[i] + strlen(g_argv[i]) - 4, ".map" ) ){
+ if( string_equal_suffix_nocase( g_argv[i], ".map" ) ){
+ openCmdMap = g_argv[i];
+ }
+ }
+ }
+
#if GDEF_OS_POSIX
#include <stdlib.h>
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();
+ cmdMap();
}
#elif GDEF_OS_WINDOWS
#include <windows.h>
- char* openCmdMap;
-
- void cmdMap(){
- openCmdMap = NULL;
- for ( int i = 1; i < g_argc; ++i )
- {
- if ( !stricmp( g_argv[i] + strlen(g_argv[i]) - 4, ".map" ) ){
- openCmdMap = g_argv[i];
- }
- }
- }
-
void environment_init( int argc, char const* argv[] ){
args_init( argc, argv );
{
// 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();
}
#define INCLUDED_ENVIRONMENT_H
void environment_init( int argc, char const* argv[] );
+
+const char* environment_get_app_filepath();
+
const char* environment_get_home_path();
const char* environment_get_app_path();
+const char *environment_get_lib_path();
+const char *environment_get_data_path();
extern int g_argc;
extern char const** g_argv;
- #if defined( WIN32 )
- extern char* openCmdMap;
- #endif
-
+ extern const char* openCmdMap;
#endif
#include "main.h"
#include "globaldefs.h"
-#include "version.h"
-
#include "debugging/debugging.h"
#include "iundo.h"
ScopedLock lock( m_lock );
if (GDEF_DEBUG) {
m_buffer << "Break into the debugger?\n";
- bool handled = ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::YESNO, ui::alert_icon::Error) == ui::alert_response::NO;
+ bool handled = ui::alert(ui::root, m_buffer.c_str(), RADIANT_NAME " - Runtime Error", ui::alert_type::YESNO, ui::alert_icon::Error) == ui::alert_response::NO;
m_buffer.clear();
return handled;
} else {
m_buffer << "Please report this error to the developers\n";
- ui::alert(ui::root, m_buffer.c_str(), "Radiant - Runtime Error", ui::alert_type::OK, ui::alert_icon::Error);
+ ui::alert(ui::root, m_buffer.c_str(), RADIANT_NAME " - Runtime Error", ui::alert_type::OK, ui::alert_icon::Error);
m_buffer.clear();
}
}
Q_mkdir( g_strSettingsPath.c_str() );
+ g_strAppFilePath = environment_get_app_filepath();
g_strAppPath = environment_get_app_path();
+ g_strLibPath = environment_get_lib_path();
+ g_strDataPath = environment_get_data_path();
// radiant is installed in the parent dir of "tools/"
// NOTE: this is not very easy for debugging
// (for now I had to create symlinks)
{
StringOutputStream path( 256 );
- path << g_strAppPath.c_str() << "bitmaps/";
+ path << g_strDataPath.c_str() << "bitmaps/";
BitmapsPath_set( path.c_str() );
}
// we will set this right after the game selection is done
- g_strGameToolsPath = g_strAppPath;
+ g_strGameToolsPath = g_strDataPath;
}
bool check_version_file( const char* filename, const char* version ){
return false;
}
-bool check_version(){
- // a safe check to avoid people running broken installations
- // (otherwise, they run it, crash it, and blame us for not forcing them hard enough to pay attention while installing)
- // make something idiot proof and someone will make better idiots, this may be overkill
- // let's leave it disabled in debug mode in any case
- // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=431
- if (GDEF_DEBUG) {
- return true;
- }
- // locate and open RADIANT_MAJOR and RADIANT_MINOR
- bool bVerIsGood = true;
- {
- StringOutputStream ver_file_name(256);
- ver_file_name << AppPath_get() << "RADIANT_MAJOR";
- bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MAJOR_VERSION);
- }
- {
- StringOutputStream ver_file_name(256);
- ver_file_name << AppPath_get() << "RADIANT_MINOR";
- bVerIsGood = check_version_file(ver_file_name.c_str(), RADIANT_MINOR_VERSION);
- }
-
- if (!bVerIsGood) {
- StringOutputStream msg(256);
- msg
- << "This editor binary (" RADIANT_VERSION ") doesn't match what the latest setup has configured in this directory\n"
- "Make sure you run the right/latest editor binary you installed\n"
- << AppPath_get();
- ui::alert(ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Default);
- }
- return bVerIsGood;
-}
-
void create_global_pid(){
/*!
the global prefs loading / game selection dialog might fail for any reason we don't know about
if ( remove( g_pidFile.c_str() ) == -1 ) {
StringOutputStream msg( 256 );
msg << "WARNING: Could not delete " << g_pidFile.c_str();
- ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), RADIANT_NAME, ui::alert_type::OK, ui::alert_icon::Error );
}
// in debug, never prompt to clean registry, turn console logging auto after a failed start
if (!GDEF_DEBUG) {
StringOutputStream msg(256);
- msg << "Radiant failed to start properly the last time it was run.\n"
+ msg << RADIANT_NAME " failed to start properly the last time it was run.\n"
"The failure may be related to current global preferences.\n"
"Do you want to reset global preferences to defaults?";
- if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO, ui::alert_icon::Question) == ui::alert_response::YES) {
+ if (ui::alert(ui::root, msg.c_str(), RADIANT_NAME " - Startup Failure", ui::alert_type::YESNO, ui::alert_icon::Question) == ui::alert_response::YES) {
g_GamesDialog.Reset();
}
msg.clear();
msg << "Logging console output to " << SettingsPath_get()
- << "radiant.log\nRefer to the log if Radiant fails to start again.";
+ << "radiant.log\nRefer to the log if " RADIANT_NAME " fails to start again.";
- ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK);
+ ui::alert(ui::root, msg.c_str(), RADIANT_NAME " - Console Log", ui::alert_type::OK);
}
// set without saving, the class is not in a coherent state yet
// just do the value change and call to start logging, CGamesDialog will pickup when relevant
g_GamesDialog.m_bForceLogConsole = true;
- Sys_LogFile( true );
+ Sys_EnableLogFile( true );
}
// create a primary .pid for global init run
if ( remove( g_pidFile.c_str() ) == -1 ) {
StringOutputStream msg( 256 );
msg << "WARNING: Could not delete " << g_pidFile.c_str();
- ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), RADIANT_NAME, ui::alert_type::OK, ui::alert_icon::Error );
}
}
if ( remove( g_pidGameFile.c_str() ) == -1 ) {
StringOutputStream msg;
msg << "WARNING: Could not delete " << g_pidGameFile.c_str();
- ui::alert( ui::root, msg.c_str(), "Radiant", ui::alert_type::OK, ui::alert_icon::Error );
+ ui::alert( ui::root, msg.c_str(), RADIANT_NAME, ui::alert_type::OK, ui::alert_icon::Error );
}
// in debug, never prompt to clean registry, turn console logging auto after a failed start
if (!GDEF_DEBUG) {
StringOutputStream msg;
- msg << "Radiant failed to start properly the last time it was run.\n"
+ msg << RADIANT_NAME " failed to start properly the last time it was run.\n"
"The failure may be caused by current preferences.\n"
"Do you want to reset all preferences to defaults?";
- if (ui::alert(ui::root, msg.c_str(), "Radiant - Startup Failure", ui::alert_type::YESNO, ui::alert_icon::Question) == ui::alert_response::YES) {
+ if (ui::alert(ui::root, msg.c_str(), RADIANT_NAME " - Startup Failure", ui::alert_type::YESNO, ui::alert_icon::Question) == ui::alert_response::YES) {
Preferences_Reset();
}
msg.clear();
msg << "Logging console output to " << SettingsPath_get()
- << "radiant.log\nRefer to the log if Radiant fails to start again.";
+ << "radiant.log\nRefer to the log if " RADIANT_NAME " fails to start again.";
- ui::alert(ui::root, msg.c_str(), "Radiant - Console Log", ui::alert_type::OK);
+ ui::alert(ui::root, msg.c_str(), RADIANT_NAME " - Console Log", ui::alert_type::OK);
}
// force console logging on! (will go in prefs too)
g_GamesDialog.m_bForceLogConsole = true;
- Sys_LogFile( true );
+ Sys_EnableLogFile( true );
}
else
{
#endif // GARUX_DISABLE_GTKTHEME
}
+/* 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. */
+bool g_dontStart = false;
+
int main( int argc, char* argv[] ){
+#if GTK_TARGET == 3
+ // HACK: force legacy GL backend as we don't support GL3 yet
+ setenv("GDK_GL", "LEGACY", 0);
+#if GDEF_OS_LINUX || GDEF_OS_BSD
+ setenv("GDK_BACKEND", "x11", 0);
+#endif
+#endif // GTK_TARGET == 3
crt_init();
streams_init();
#endif
const char* mapname = NULL;
+
+#if GDEF_OS_WINDOWS
+ StringOutputStream mapname_buffer( 256 );
+#endif
+
char const *error = NULL;
+
if ( !ui::init( &argc, &argv, "<filename.map>", &error) ) {
g_print( "%s\n", error );
return -1;
// Gtk already removed parsed `--options`
if (argc == 2) {
if ( strlen( argv[1] ) > 1 ) {
- if ( g_str_has_suffix( argv[1], ".map" ) ) {
- if ( g_path_is_absolute( argv[1] ) ) {
mapname = argv[1];
+
+ if ( g_str_has_suffix( mapname, ".map" ) ) {
+ if ( !g_path_is_absolute( mapname ) ) {
+ mapname = g_build_filename( g_get_current_dir(), mapname, NULL );
}
- else {
- mapname = g_build_filename( g_get_current_dir(), argv[1], NULL );
- }
+
+#if GDEF_OS_WINDOWS
+ mapname_buffer << PathCleaned( mapname );
+ mapname = mapname_buffer.c_str();
+#endif
}
else {
- g_print( "bad file name, will not load: %s\n", argv[1] );
+ g_print( "bad file name, will not load: %s\n", mapname );
+ mapname = NULL;
}
}
}
add_local_rc_files();
- if ( !check_version() ) {
- return EXIT_FAILURE;
- }
-
show_splash();
create_global_pid();
// we may have the console turned on and want to keep it that way
// so we use a latching system
if ( g_GamesDialog.m_bForceLogConsole ) {
- Sys_LogFile( true );
+ Sys_EnableLogFile( true );
g_Console_enableLogging = true;
g_GamesDialog.m_bForceLogConsole = false;
}
hide_splash();
- #ifdef WIN32
if( openCmdMap && *openCmdMap ){
Map_LoadFile( openCmdMap );
}
- else
- #endif // WIN32
- if ( mapname != NULL ) {
+ else if ( mapname != NULL ) {
Map_LoadFile( mapname );
}
else if ( g_bLoadLastMap && !g_strLastMap.empty() ) {
remove_local_pid();
+ /* 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. */
+ if ( !g_dontStart )
+ {
ui::main();
+ }
// avoid saving prefs when the app is minimized
if ( g_pParentWnd->IsSleeping() ) {
Radiant_Shutdown();
// close the log file if any
- Sys_LogFile( false );
+ Sys_EnableLogFile( false );
return EXIT_SUCCESS;
}
#include "texwindow.h"
#include "filterbar.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
+
#define GARUX_DISABLE_GTKTHEME
#ifndef GARUX_DISABLE_GTKTHEME
#include "gtktheme.h"
#endif
-
struct layout_globals_t
{
WindowPosition m_position;
layout_globals_t() :
m_position( -1, -1, 640, 480 ),
- nXYHeight( 300 ),
- nXYWidth( 300 ),
- nCamWidth( 200 ),
- nCamHeight( 200 ),
- nState( GDK_WINDOW_STATE_MAXIMIZED ){
+ nXYHeight( 350 ),
+ nXYWidth( 600 ),
+ nCamWidth( 300 ),
+ nCamHeight( 210 ),
+ nState( 0 ){
}
};
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;
+
+// directory paths
+CopiedString g_strAppPath;
+CopiedString g_strLibPath;
+CopiedString g_strDataPath;
-CopiedString g_strAppPath; ///< holds the full path of the executable
+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 ));
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");
#ifndef GARUX_DISABLE_GTKTHEME
create_menu_item_with_mnemonic( menu_in_menu, "GTK Theme...", "gtkThemeDlg" );
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, "Customize...", "BuildMenuCustomize" );
+ create_menu_item_with_mnemonic( menu, "Run recent build", "Build_runRecentExecutedBuild" );
menu_separator( menu );
// http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=394
// create_menu_item_with_mnemonic(menu, "_Print XY View", FreeCaller<void(), WXY_Print>());
create_menu_item_with_mnemonic( menu, "_Background select", makeCallbackF(WXY_BackgroundSelect) );
+ create_menu_item_with_mnemonic( menu, "Fullscreen", "Fullscreen" );
return misc_menu_item;
}
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 );
#if GDEF_OS_WINDOWS
if ( g_multimon_globals.m_bStartOnPrimMon ) {
PositionWindowOnPrimaryScreen( g_layout_globals.m_position );
- window_set_position( window, g_layout_globals.m_position );
}
- else
#endif
- if ( g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED ) {
- gtk_window_maximize( window );
- WindowPosition default_position( -1, -1, 640, 480 );
- window_set_position( window, default_position );
- }
- else
- {
- window_set_position( window, g_layout_globals.m_position );
+ window_set_position( window, g_layout_globals.m_position );
- }
m_window = window;
window.show();
- if ( CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft ) {
+ if ( CurrentStyle() == eRegular || CurrentStyle() == eRegularLeft )
+ {
{
ui::Widget hsplit = ui::HPaned(ui::New);
m_hSplit = hsplit;
m_vSplit2 = vsplit2;
if ( CurrentStyle() == eRegular ){
- gtk_paned_add1( GTK_PANED( hsplit ), vsplit );
- gtk_paned_add2( GTK_PANED( hsplit ), vsplit2 );
+ gtk_paned_pack1( GTK_PANED( hsplit ), vsplit, TRUE, TRUE );
+ gtk_paned_pack2( GTK_PANED( hsplit ), vsplit2, TRUE, TRUE );
}
else{
- gtk_paned_add2( GTK_PANED( hsplit ), vsplit );
- gtk_paned_add1( GTK_PANED( hsplit ), vsplit2 );
+ gtk_paned_pack2( GTK_PANED( hsplit ), vsplit, TRUE, TRUE );
+ gtk_paned_pack1( GTK_PANED( hsplit ), vsplit2, TRUE, TRUE );
}
// console
ui::Widget console_window = Console_constructWindow( window );
- gtk_paned_pack2( GTK_PANED( vsplit ), console_window, FALSE, TRUE );
+ gtk_paned_pack2( GTK_PANED( vsplit ), console_window, TRUE, TRUE );
// xy
m_pXYWnd = new XYWnd();
m_pXYWnd->SetViewType( XY );
ui::Widget xy_window = ui::Widget(create_framed_widget( m_pXYWnd->GetWidget( ) ));
- gtk_paned_add1( GTK_PANED( vsplit ), xy_window );
+ gtk_paned_pack1( GTK_PANED( vsplit ), xy_window, TRUE, TRUE );
{
// camera
CamWnd_setParent( *m_pCamWnd, window );
auto camera_window = create_framed_widget( CamWnd_getWidget( *m_pCamWnd ) );
- gtk_paned_add1( GTK_PANED( vsplit2 ), camera_window );
+ gtk_paned_pack1( GTK_PANED( vsplit2 ), GTK_WIDGET( camera_window ) , TRUE, TRUE);
// textures
auto texture_window = create_framed_widget( TextureBrowser_constructWindow( window ) );
- gtk_paned_add2( GTK_PANED( vsplit2 ), texture_window );
+ gtk_paned_pack2( GTK_PANED( vsplit2 ), GTK_WIDGET( texture_window ), TRUE, TRUE );
}
}
}
-
- gtk_paned_set_position( GTK_PANED( m_vSplit ), g_layout_globals.nXYHeight );
-
- if ( CurrentStyle() == eRegular ) {
- gtk_paned_set_position( GTK_PANED( m_hSplit ), g_layout_globals.nXYWidth );
- }
- else
- {
- gtk_paned_set_position( GTK_PANED( m_hSplit ), g_layout_globals.nCamWidth );
- }
-
- 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 );
window.add(frame);
}
CamWnd_setParent( *m_pCamWnd, window );
-#define GARUX_GTK_WORKAROUND
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( window ), "glwidget", CamWnd_getWidget( *m_pCamWnd ) );
-#endif
+
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, CamWnd_getWidget( *m_pCamWnd ) );
g_floating_windows.push_back( window );
}
window.add(frame);
}
XY_Top_Shown_Construct( window );
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( window ), "glwidget", m_pXYWnd->GetWidget() );
-#endif
+
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXYWnd->GetWidget() );
g_floating_windows.push_back( window );
}
}
XZ_Front_Shown_Construct( window );
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( window ), "glwidget", m_pXZWnd->GetWidget() );
-#endif
+
+ WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXZWnd->GetWidget() );
g_floating_windows.push_back( window );
}
}
YZ_Side_Shown_Construct( window );
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( window ), "glwidget", m_pYZWnd->GetWidget() );
-#endif
+
+ 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() );
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( GroupDialog_getWindow() ), "glwidget", TextureBrowser_getGLWidget() );
-#endif
+ 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( GroupDialog_getWindow() ) );
g_page_textures = GroupDialog_addPage( "Textures", frame, TextureBrowserExportTitleCaller() );
-#ifndef GARUX_GTK_WORKAROUND
- /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */
- g_object_set_data( G_OBJECT( GroupDialog_getWindow() ), "glwidget", TextureBrowser_getGLWidget() );
-#endif
+
+ 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 );
EverySecondTimer_enable();
+ if ( g_layout_globals.nState & GDK_WINDOW_STATE_MAXIMIZED ) {
+ gtk_window_maximize( window );
+ }
+ if ( g_layout_globals.nState & GDK_WINDOW_STATE_FULLSCREEN ) {
+ gtk_window_fullscreen( window );
+ }
+ if ( !FloatingGroupDialog() ) {
+ gtk_paned_set_position( GTK_PANED( m_vSplit ), g_layout_globals.nXYHeight );
+
+ if ( CurrentStyle() == eRegular ) {
+ gtk_paned_set_position( GTK_PANED( m_hSplit ), g_layout_globals.nXYWidth );
+ }
+ else
+ {
+ gtk_paned_set_position( GTK_PANED( m_hSplit ), g_layout_globals.nCamWidth );
+ }
+
+ gtk_paned_set_position( GTK_PANED( m_vSplit2 ), g_layout_globals.nCamHeight );
+ }
//GlobalShortcuts_reportUnregistered();
}
g_layout_globals.nCamHeight = gtk_paned_get_position( GTK_PANED( m_vSplit2 ) );
}
- g_layout_globals.m_position = m_position_tracker.getPosition();
+ if( gdk_window_get_state( GTK_WIDGET( m_window )->window ) == 0 ){
+ g_layout_globals.m_position = m_position_tracker.getPosition();
+ }
g_layout_globals.nState = gdk_window_get_state( gtk_widget_get_window(m_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) );
}
-
+ void MainFrame_toggleFullscreen(){
+ GtkWindow* wnd = MainFrame_getWindow();
+ if( gdk_window_get_state( GTK_WIDGET( wnd )->window ) & GDK_WINDOW_STATE_FULLSCREEN ){
+ //some portion of buttsex, because gtk_window_unfullscreen doesn't work correctly after calling some modal window
+ bool maximize = ( gdk_window_get_state( GTK_WIDGET( wnd )->window ) & GDK_WINDOW_STATE_MAXIMIZED );
+ gtk_window_unfullscreen( wnd );
+ if( maximize ){
+ gtk_window_unmaximize( wnd );
+ gtk_window_maximize( wnd );
+ }
+ else{
+ gtk_window_move( wnd, g_layout_globals.m_position.x, g_layout_globals.m_position.y );
+ gtk_window_resize( wnd, g_layout_globals.m_position.w, g_layout_globals.m_position.h );
+ }
+ }
+ else{
+ gtk_window_fullscreen( wnd );
+ }
+ }
+
#include "preferencesystem.h"
#include "stringio.h"
+#include "transformpath/transformpath.h"
void MainFrame_Construct(){
GlobalCommands_insert( "OpenManual", makeCallbackF(OpenHelpURL), Accelerator( GDK_KEY_F1 ) );
GlobalCommands_insert( "ArbitraryScale", makeCallbackF(DoScaleDlg) );
GlobalCommands_insert( "BuildMenuCustomize", makeCallbackF(DoBuildMenu) );
+ GlobalCommands_insert( "Build_runRecentExecutedBuild", makeCallbackF(Build_runRecentExecutedBuild), Accelerator( GDK_F5 ) );
GlobalCommands_insert( "FindBrush", makeCallbackF(DoFind) );
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 ) );
GlobalCommands_insert( "ChooseClipperColor", makeCallback( g_ColoursMenu.m_clipper ) );
GlobalCommands_insert( "ChooseOrthoViewNameColor", makeCallback( g_ColoursMenu.m_viewname ) );
+ GlobalCommands_insert( "Fullscreen", makeCallbackF( MainFrame_toggleFullscreen ), Accelerator( GDK_F11 ) );
+
GlobalCommands_insert( "CSGSubtract", makeCallbackF(CSG_Subtract), Accelerator( 'U', (GdkModifierType)GDK_SHIFT_MASK ) );
GlobalCommands_insert( "CSGMerge", makeCallbackF(CSG_Merge), Accelerator( 'U', (GdkModifierType) GDK_CONTROL_MASK ) );
#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 ) );
}
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
}
else if ( Map_Modified( g_map ) ) {
Map_Save();
- #ifdef WIN32
MRU_AddFile( g_map.m_name.c_str() ); //add on saving, but not opening via cmd line: spoils the list
- #endif
}
}
#include <dlfcn.h>
+#if GDEF_OS_MACOS
#ifndef RTLD_DEEPBIND
#define RTLD_DEEPBIND 0
-#endif
+#endif // RTLD_DEEPBIND
+#endif // GDEF_OS_MACOS
class DynamicLibrary {
void *m_library;
typedef int ( *FunctionPointer )();
DynamicLibrary( const char* filename ){
- m_library = dlopen( filename, RTLD_NOW );
+ m_library = dlopen( filename, RTLD_NOW | (RTLD_DEEPBIND + 0) );
}
~DynamicLibrary(){
if ( !failed() ) {
}
};
-#else
+#else // !GDEF_OS_POSIX
#error "unsupported platform"
-#endif
+#endif // !GDEF_OS_POSIX
class DynamicLibraryModule
{
size_t c;
/* allocate and clear */
- if ( numSides <= 0 ) {
+ /*if ( numSides <= 0 ) {
Error( "AllocBrush called with numsides = %d", numSides );
}
- c = (size_t)&( ( (brush_t*) 0 )->sides[ numSides ] );
+ c = (size_t)&( ( (brush_t*) 0 )->sides[ numSides ] );*/
+ c = sizeof(*bb) + (numSides > 6 ? sizeof(side_t)*(numSides - 6) : 0);
- bb = safe_malloc( c );
- memset( bb, 0, c );
+ bb = safe_malloc0( c );
if ( numthreads == 1 ) {
numActiveBrushes++;
}
tree_t *AllocTree( void ){
tree_t *tree;
- tree = safe_malloc( sizeof( *tree ) );
- memset( tree, 0, sizeof( *tree ) );
+ tree = safe_malloc0( sizeof( *tree ) );
ClearBounds( tree->mins, tree->maxs );
return tree;
node_t *AllocNode( void ){
node_t *node;
- node = safe_malloc( sizeof( *node ) );
- memset( node, 0, sizeof( *node ) );
+ node = safe_malloc0( sizeof( *node ) );
return node;
}
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 ) ) {
char *sentinel = newCommandLine + sizeof( newCommandLine ) - 1;
int i;
- if (nocmdline)
- {
- return;
- }
+ if ( nocmdline ){
+ return;
+ }
previousCommandLine = ValueForKey( &entities[0], "_q3map2_cmdline" );
if ( previousCommandLine && *previousCommandLine ) {
inpos = previousCommandLine;
for ( i = beginArgs; i < endArgs; ++i )
{
+ if ( argv[i] == NULL ) {
+ continue;
+ }
if ( outpos != sentinel && i != beginArgs ) {
*outpos++ = ' ';
}
Sys_Printf( "++%s\n", temp );
continue;
}
- Sys_Printf( " !FAIL! %s\n", pk3Shaders + i*65 );
- if ( i != pk3ShadersN - 1 ) packFAIL = qtrue; //levelshot typically
+
+ if ( i == pk3ShadersN - 1 ){ //levelshot typically
+ Sys_Printf( " ~fail %s\n", pk3Shaders + i*65 );
+ }
+ else{
+ Sys_Printf( " !FAIL! %s\n", pk3Shaders + i*65 );
+ packFAIL = qtrue;
+ }
}
}
Sys_Printf( "++%s\n", temp );
}
else{
- Sys_Printf( " !FAIL! %s\n", temp );
+ Sys_Printf( " ~fail %s\n", temp );
}
sprintf( temp, "scripts/%s.arena", nameOFmap );
Sys_Printf( "++%s\n", temp );
}
else{
- Sys_Printf( " !FAIL! %s\n", temp );
+ Sys_Printf( " ~fail %s\n", temp );
}
sprintf( temp, "scripts/%s.defi", nameOFmap );
Sys_Printf( "++%s\n", temp );
}
else{
- Sys_Printf( " !FAIL! %s\n", temp );
+ Sys_Printf( " ~fail %s\n", temp );
}
if ( !packFAIL ){
/* -help */
if ( !strcmp( argv[ i ], "-h" ) || !strcmp( argv[ i ], "--help" )
|| !strcmp( argv[ i ], "-help" ) ) {
- HelpMain(argv[i+1]);
+ HelpMain( ( i + 1 < argc ) ? argv[ i + 1 ] : NULL );
return 0;
}
/* -connect */
if ( !strcmp( argv[ i ], "-connect" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No address specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
Broadcast_Setup( argv[ i ] );
argv[ i ] = NULL;
}
/* patch subdivisions */
else if ( !strcmp( argv[ i ], "-subdivisions" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No value specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
patchSubdivisions = atoi( argv[ i ] );
argv[ i ] = NULL;
if ( patchSubdivisions <= 0 ) {
/* threads */
else if ( !strcmp( argv[ i ], "-threads" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No value specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
numthreads = atoi( argv[ i ] );
argv[ i ] = NULL;
}
Sys_Printf( "Q3Map - v1.0r (c) 1999 Id Software Inc.\n" );
Sys_Printf( "Q3Map (ydnar) - v" Q3MAP_VERSION "\n" );
- Sys_Printf( "NetRadiant - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" );
+ Sys_Printf( RADIANT_NAME " - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" );
Sys_Printf( "%s\n", Q3MAP_MOTD );
Sys_Printf( "%s\n", argv[0] );
/* ydnar: otherwise create a bsp */
else{
+ /* used to write Smokin'Guns like tex file */
+ compile_map = qtrue;
+
r = BSPMain( argc, argv );
}
------------------------------------------------------------------------------- */
/* 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 */
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) */
,
/* ydnar: sinusoid samples */
Q_EXTERN float jitters[ MAX_JITTERS ];
-/* can't code */
+/*can't code*/
Q_EXTERN qboolean doingBSP Q_ASSIGN( qfalse );
/* 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 qboolean nocmdline Q_ASSIGN( qfalse );
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 )